diff --git a/Makefile b/Makefile index 007c59a..193c83e 100644 --- a/Makefile +++ b/Makefile @@ -18,9 +18,11 @@ $(LIB): $(OBJ) ar scr $@ $(OBJ) $(BUILDDIR)/%.o: $(SRCDIR)/%.cpp + @mkdir -p $(@D) $(CXX) $(CFLAGS) -c $< -o $@ $(BUILDDIR)/%.d: $(SRCDIR)/%.cpp + @mkdir -p $(@D) $(CXX) -MM -MT '$(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$<)' $(CFLAGS) $< > $@ clean: diff --git a/Makefile.mingw b/Makefile.mingw index a78acbf..834049f 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -18,9 +18,11 @@ $(LIB): $(OBJ) ar scr $@ $(OBJ) $(BUILDDIR)/%.o: $(SRCDIR)/%.cpp + @mkdir -p $(@D) $(CXX) $(CFLAGS) -c $< -o $@ $(BUILDDIR)/%.d: $(SRCDIR)/%.cpp + @mkdir -p $(@D) $(CXX) -MM -MT '$(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$<)' $(CFLAGS) $< > $@ clean: diff --git a/Makefile.ps2 b/Makefile.ps2 index cf5c8f3..7ebfe81 100644 --- a/Makefile.ps2 +++ b/Makefile.ps2 @@ -20,9 +20,11 @@ $(LIB): $(OBJ) ar scr $@ $(OBJ) $(BUILDDIR)/%.o: $(SRCDIR)/%.cpp + @mkdir -p $(@D) $(CXX) $(CFLAGS) $(INCPATH) -c $< -o $@ $(BUILDDIR)/%.d: $(SRCDIR)/%.cpp + @mkdir -p $(@D) $(CXX) -MM -MT '$(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$<)' $(CFLAGS) $< > $@ clean: diff --git a/README.md b/README.md index 41ddb86..27c3a33 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,4 @@ librw ===== This work in progress. -The basics of DFFs and a few plugins are implemented. +The basics of DFFs and many plugins are implemented (at least read&write). diff --git a/tests/ps2/Makefile b/tests/ps2/Makefile new file mode 100755 index 0000000..50dd8ad --- /dev/null +++ b/tests/ps2/Makefile @@ -0,0 +1,39 @@ +CC=ee-gcc +CXX=ee-g++ +AS=ee-g++ +LD=ee-g++ +DVPAS=ee-dvp-as + +LINK=-T$(PS2SDK)/ee/startup/linkfile +LIBPATH=-L$(PS2SDK)/ee/lib +INCPATH=-I$(PS2SDK)/ee/include -I$(PS2SDK)/common/include -I$(HOME)/src/librw +LIBS=$(HOME)/src/librw/librw-ps2.a -lc -lc -lkernel -lmf # g++ throws one -lc away, why? (unless -nostdlib) + +CFLAGS = -c -Wall -nostdlib -fno-common -DPS2_EE $(INCPATH) +ASFLAGS = -c -xassembler-with-cpp +LDFLAGS = -mno-crt0 $(LIBPATH) +OUT=test + +C_SRC=main.cpp gs.cpp dma.cpp math.cpp mesh.cpp +#S_SRC=crt0.s low.s +HEADER=dma.h ee_regs.h gif.h gs.h mips_regs.h ps2.h math.h mesh.h +OBJ=$(C_SRC:.cpp=.o) $(S_SRC:.s=.o) vu.o defaultpipe.o skinpipe.o + +$(OUT).elf: $(OBJ) $(HEADER) + $(LD) $(LDFLAGS) $(PS2SDK)/ee/startup/crt0.o \ + $(LINK) $(OBJ) $(LIBS) -o $(OUT).elf + +.cpp.o: $(HEADER) + $(CXX) $(CFLAGS) $< -o $@ + +.s.o: $(HEADER) + $(AS) $(ASFLAGS) $< -o $@ + +%.o: %.dsm + $(DVPAS) $< -o $@ + +$(C_SRC) $(S_SRC): $(HEADER) + +clean: + rm -f $(OBJ) + diff --git a/tests/ps2/README.md b/tests/ps2/README.md new file mode 100644 index 0000000..f587b32 --- /dev/null +++ b/tests/ps2/README.md @@ -0,0 +1,14 @@ +PS2 test renderer +================= + +This is a basic RW renderer for PS2. +There is a bunch of unrelated code since I adapted an earlier program of mine. + +To compile you need the ps2toolchain and ee-dvp-as from the Sony SDK +(dvp-as from the ps2toolchain segfaults when encountering MPG, +this should be fixed). + +So far the program can render PS2 native geometry (no generic geometry atm) +in the default or skin format (no PDS pipes as used in San Andreas supported yet). +The files are read from host: (see main.cpp) +so you can use e.g. ps2link on a real PS2 or pcsx2 with the host device enabled. diff --git a/tests/ps2/defaultpipe.dsm b/tests/ps2/defaultpipe.dsm new file mode 100644 index 0000000..e973efb --- /dev/null +++ b/tests/ps2/defaultpipe.dsm @@ -0,0 +1,90 @@ +.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 lightDir, 0x3d0 +.equ matrix, 0x3f0 +.equ screenOffset, 0x3f9 +.equ gifTag, 0x3fa +.equ matColor, 0x3fb +.equ ambientLight, 0x3fd + +.balign 16,0 +defaultPipe: +DMAret * +MPG 0, * +.vu +Start: + NOP LQ VF25, screenOffset(VI00) + NOP LQ VF28, matrix(VI00) + NOP LQ VF29, matrix+1(VI00) + NOP LQ VF30, matrix+2(VI00) + NOP LQ VF31, matrix+3(VI00) + NOP IADDIU VI12, VI00, outBuf1 + NOP IADDIU VI13, VI00, outBuf2 +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 + +Loop: + NOP LQI VF01, (VI02++) ; vertex + NOP LQI VF02, (VI02++) ; UV - ignore + NOP LQI VF02, (VI02++) ; color + NOP LQI VF03, (VI02++) ; normal + + MULAw.xyzw ACC, VF31, VF00w NOP + MADDAx.xyzw ACC, VF28, VF01x NOP + MADDAy.xyzw ACC, VF29, VF01y NOP + MADDz.xyzw VF01, VF30, VF01z NOP + ITOF0 VF02, VF02 NOP + ITOF0[I] VF03, VF03 LOI 0.0078125 ; - normal scale + NOP NOP + NOP DIV Q, VF00w, VF01w + NOP WAITQ + MULq VF01, VF01, Q NOP ; perspective division + MULi VF03, VF03, I NOP ; scale normal + NOP NOP + NOP NOP + SUB.w VF01, VF01, VF01 NOP + NOP SQ VF03, -1(VI02) ; store scaled normal + NOP NOP + NOP NOP + ADD.xy VF01, VF01, VF25 NOP + NOP NOP + NOP NOP + FTOI0 VF02, VF02 NOP + FTOI4 VF01, VF01 NOP + NOP NOP + NOP IADDI VI01, VI01, -1 + NOP SQI VF02, (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/tests/ps2/dma.cpp b/tests/ps2/dma.cpp new file mode 100755 index 0000000..1501c07 --- /dev/null +++ b/tests/ps2/dma.cpp @@ -0,0 +1,60 @@ +#include +#include "ps2.h" +#include "ee_regs.h" +#include "dma.h" + +struct DmaChannel { + uint64 chcr; uint64 pad0; + uint64 madr; uint64 pad1; + uint64 qwc; uint64 pad2; + uint64 tadr; uint64 pad3; + uint64 asr0; uint64 pad4; + uint64 asr1; uint64 pad5; + uint64 pad6[4]; + uint64 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(int enable) +{ + /* don't clear the SIF channels */ + int doclear[] = { 1, 1, 1, 1, 1, 0, 0, 0, 1, 1 }; + int i; + + printf("%x %x %x %x %x %x %x\n", + &dmaChannels[0]->chcr, + &dmaChannels[0]->madr, + &dmaChannels[0]->qwc, + &dmaChannels[0]->tadr, + &dmaChannels[0]->asr0, + &dmaChannels[0]->asr1, + &dmaChannels[0]->sadr); + + SET_REG64(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; + } + + if(enable) + SET_REG64(D_CTRL, MAKE_D_CTRL(1,0,0,0,0,0)); +} diff --git a/tests/ps2/dma.h b/tests/ps2/dma.h new file mode 100755 index 0000000..c083c71 --- /dev/null +++ b/tests/ps2/dma.h @@ -0,0 +1,131 @@ +#ifndef DMA_H +#define DMA_H +#include "ps2.h" +#include "ee_regs.h" + +void dmaReset(int enable); + +#define DMA_WAIT(REG) \ + while (GET_REG32(REG) & (1<<8)) + +/* + * Common Registers + */ + +#define MAKE_D_CTRL(DMAE,RELE,MFD,STS,STD,RCYC) \ + (BIT32(DMAE, 0) | \ + BIT32(RELE, 1) | \ + BIT32(MFD, 2) | \ + BIT32(STS, 4) | \ + BIT32(STD, 6) | \ + BIT32(RCYC, 8)) + +#define MAKE_D_STAT(CIS0,CIS1,CIS2,CIS3,CIS4,CIS5,CIS6,CIS7,CIS8,CIS9,\ + SIS,MEIS,BEIS,\ + CIM0,CIM1,CIM2,CIM3,CIM4,CIM5,CIM6,CIM7,CIM8,CIM9,\ + SIM,MEIM) \ + (BIT32(CIS0, 0) | \ + BIT32(CIS1, 1) | \ + BIT32(CIS2, 2) | \ + BIT32(CIS3, 3) | \ + BIT32(CIS4, 4) | \ + BIT32(CIS5, 5) | \ + BIT32(CIS6, 6) | \ + BIT32(CIS7, 7) | \ + BIT32(CIS8, 8) | \ + BIT32(CIS9, 9) | \ + BIT32(SIS, 13) | \ + BIT32(MEIS, 14) | \ + BIT32(BEIS, 15) | \ + BIT32(CIM0, 16) | \ + BIT32(CIM1, 17) | \ + BIT32(CIM2, 18) | \ + BIT32(CIM3, 19) | \ + BIT32(CIM4, 20) | \ + BIT32(CIM5, 21) | \ + BIT32(CIM6, 21) | \ + BIT32(CIM7, 22) | \ + BIT32(CIM8, 23) | \ + BIT32(CIM9, 24) | \ + BIT32(SIM, 29) | \ + BIT32(MEIM, 30)) + +#define MAKE_D_PCR(CPC0,CPC1,CPC2,CPC3,CPC4,CPC5,CPC6,CPC7,CPC8,CPC9,\ + CDE0,CDE1,CDE2,CDE3,CDE4,CDE5,CDE6,CDE7,CDE8,CDE9, PCE) \ + (BIT32(CPC0, 0) | \ + BIT32(CPC1, 1) | \ + BIT32(CPC2, 2) | \ + BIT32(CPC3, 3) | \ + BIT32(CPC4, 4) | \ + BIT32(CPC5, 5) | \ + BIT32(CPC6, 6) | \ + BIT32(CPC7, 7) | \ + BIT32(CPC8, 8) | \ + BIT32(CPC9, 9) | \ + BIT32(CDE0, 16) | \ + BIT32(CDE1, 17) | \ + BIT32(CDE2, 18) | \ + BIT32(CDE3, 19) | \ + BIT32(CDE4, 20) | \ + BIT32(CDE5, 21) | \ + BIT32(CDE6, 22) | \ + BIT32(CDE7, 23) | \ + BIT32(CDE8, 24) | \ + BIT32(CDE9, 25) | \ + BIT32(PCE, 31)) + +#define MAKE_D_SQWC(SQWC,TQWC) \ + (BIT32(SQWC, 0) | \ + BIT32(TQWC, 16)) + +#define MAKE_D_RBSR(RMSK) \ + (BIT32(RMSK, 4)) + +#define MAKE_D_RBOR(ADDR) \ + (BIT32(ADDR, 0)) + +#define MAKE_D_STADR(ADDR) \ + (BIT32(ADDR, 0)) + +#define MAKE_D_ENABLER(CPND) \ + (BIT32(CPND, 16)) + +#define MAKE_D_ENABLEW(CPND) \ + (BIT32(CPND, 16)) + +/* + * Channel Registers + */ + +#define MAKE_DN_CHCR(DIR,MOD,ASP,TTE,TIE,STR) \ + (BIT32(DIR, 0) | \ + BIT32(MOD, 2) | \ + BIT32(ASP, 4) | \ + BIT32(TTE, 6) | \ + BIT32(TIE, 7) | \ + BIT32(STR, 8)) + +#define MAKE_DN_MADR(ADDR,SPR) \ + (BIT32(ADDR, 0) | \ + BIT32(SPR, 31)) + +#define MAKE_DN_TADR(ADDR,SPR) \ + (BIT32(ADDR, 0) | \ + BIT32(SPR, 31)) + +#define MAKE_DN_ASR(ADDR,SPR) \ + (BIT32(ADDR, 0) | \ + BIT32(SPR, 31)) + +#define MAKE_DN_ASR(ADDR,SPR) \ + (BIT32(ADDR, 0) | \ + BIT32(SPR, 31)) + +#define MAKE_DN_SADR(ADDR) \ + (BIT32(ADDR, 0)) + +#define MAKE_DN_QWC(QWC) \ + (BIT32(QWC, 0)) + +#endif + diff --git a/tests/ps2/ee_regs.h b/tests/ps2/ee_regs.h new file mode 100755 index 0000000..ef9088b --- /dev/null +++ b/tests/ps2/ee_regs.h @@ -0,0 +1,204 @@ +#ifndef EE_REGS_H +#define EE_REGS_H +#include "ps2.h" + +/* + * EE Registers + */ + +#define SET_REG32(r, x) \ + *((volatile uint32 *) r) = (x) +#define SET_REG64(r, x) \ + *((volatile uint64 *) r) = (x) +#define SET_REG128(r, x) \ + *((volatile uint128 *) r) = (x) + +#define GET_REG32(r) \ + *((volatile uint32 *) r) +#define GET_REG64(r) \ + *((volatile uint64 *) r) +#define GET_REG128(r) \ + *((volatile uint128 *) r) + +/* Module TIMER */ +#define T0_COUNT 0x10000000 +#define T0_MODE 0x10000010 +#define T0_COMP 0x10000020 +#define T0_HOLD 0x10000030 +#define T1_COUNT 0x10000800 +#define T1_MODE 0x10000810 +#define T1_COMP 0x10000820 +#define T1_HOLD 0x10000830 +#define T2_COUNT 0x10001000 +#define T2_MODE 0x10001010 +#define T2_COMP 0x10001020 +#define T3_COUNT 0x10001800 +#define T3_MODE 0x10001810 +#define T3_COMP 0x10001820 + +/* Module IPU */ +#define IPU_CMD 0x10002000 +#define IPU_CTRL 0x10002010 +#define IPU_BP 0x10002020 +#define IPU_TOP 0x10002030 + +/* Module GIF */ +#define GIF_CTRL 0x10003000 +#define GIF_MODE 0x10003010 +#define GIF_STAT 0x10003020 +#define GIF_TAG0 0x10003040 +#define GIF_TAG1 0x10003050 +#define GIF_TAG2 0x10003060 +#define GIF_TAG3 0x10003070 +#define GIF_CNT 0x10003080 +#define GIF_P3CNT 0x10003090 +#define GIF_P3TAG 0x100030a0 + +/* Module VIF0 */ +#define VIF0_STAT 0x10003800 +#define VIF0_FBRST 0x10003810 +#define VIF0_ERR 0x10003820 +#define VIF0_MARK 0x10003830 +#define VIF0_CYCLE 0x10003840 +#define VIF0_MODE 0x10003850 +#define VIF0_NUM 0x10003860 +#define VIF0_MASK 0x10003870 +#define VIF0_CODE 0x10003880 +#define VIF0_ITOPS 0x10003890 +#define VIF0_ITOP 0x100038d0 +#define VIF0_R0 0x10003900 +#define VIF0_R1 0x10003910 +#define VIF0_R2 0x10003920 +#define VIF0_R3 0x10003930 +#define VIF0_C0 0x10003940 +#define VIF0_C1 0x10003950 +#define VIF0_C2 0x10003960 +#define VIF0_C3 0x10003970 + +/* Module VIF1 */ +#define VIF1_STAT 0x10003c00 +#define VIF1_FBRST 0x10003c10 +#define VIF1_ERR 0x10003c20 +#define VIF1_MARK 0x10003c30 +#define VIF1_CYCLE 0x10003c40 +#define VIF1_MODE 0x10003c50 +#define VIF1_NUM 0x10003c60 +#define VIF1_MASK 0x10003c70 +#define VIF1_CODE 0x10003c80 +#define VIF1_ITOPS 0x10003c90 +#define VIF1_BASE 0x10003ca0 +#define VIF1_OFST 0x10003cb0 +#define VIF1_TOPS 0x10003cc0 +#define VIF1_ITOP 0x10003cd0 +#define VIF1_TOP 0x10003ce0 +#define VIF1_R0 0x10003d00 +#define VIF1_R1 0x10003d10 +#define VIF1_R2 0x10003d20 +#define VIF1_R3 0x10003d30 +#define VIF1_C0 0x10003d40 +#define VIF1_C1 0x10003d50 +#define VIF1_C2 0x10003d60 +#define VIF1_C3 0x10003d70 + +/* Module FIFO */ +#define VIF0_FIFO 0x1000400 +#define VIF1_FIFO 0x1000500 +#define GIF_FIFO 0x1000600 +#define IPU_out_FIFO 0x1000700 +#define IPU_in_FIFO 0x1000701 + +/* Module DMAC */ +#define D0_CHCR 0x10008000 +#define D0_MADR 0x10008010 +#define D0_QWC 0x10008020 +#define D0_TADR 0x10008030 +#define D0_ASR0 0x10008040 +#define D0_ASR1 0x10008050 + +#define D1_CHCR 0x10009000 +#define D1_MADR 0x10009010 +#define D1_QWC 0x10009020 +#define D1_TADR 0x10009030 +#define D1_ASR0 0x10009040 +#define D1_ASR1 0x10009050 + +#define D2_CHCR 0x1000a000 +#define D2_MADR 0x1000a010 +#define D2_QWC 0x1000a020 +#define D2_TADR 0x1000a030 +#define D2_ASR0 0x1000a040 +#define D2_ASR1 0x1000a050 + +#define D3_CHCR 0x1000b000 +#define D3_MADR 0x1000b010 +#define D3_QWC 0x1000b020 + +#define D4_CHCR 0x1000b400 +#define D4_MADR 0x1000b410 +#define D4_QWC 0x1000b420 +#define D4_TADR 0x1000b430 + +#define D5_CHCR 0x1000c000 +#define D5_MADR 0x1000c010 +#define D5_QWC 0x1000c020 + +#define D6_CHCR 0x1000c400 +#define D6_MADR 0x1000c410 +#define D6_QWC 0x1000c420 +#define D6_TADR 0x1000c430 + +#define D7_CHCR 0x1000c800 +#define D7_MADR 0x1000c810 +#define D7_QWC 0x1000c820 + +#define D8_CHCR 0x1000d000 +#define D8_MADR 0x1000d010 +#define D8_QWC 0x1000d020 +#define D8_SADR 0x1000d080 + +#define D9_CHCR 0x1000d400 +#define D9_MADR 0x1000d410 +#define D9_QWC 0x1000d420 +#define D9_TADR 0x1000d430 +#define D9_SADR 0x1000d480 + +#define D_CTRL 0x1000e000 +#define D_STAT 0x1000e010 +#define D_PCR 0x1000e020 +#define D_SQWC 0x1000e030 +#define D_RBSR 0x1000e040 +#define D_RBOR 0x1000e050 +#define D_STADR 0x1000e060 + +#define D_ENABLER 0x1000f520 +#define D_ENABLEW 0x1000f590 + +/* Module INTC */ +#define I_STAT 0x1000f000 +#define I_MASK 0x1000f010 + +/* Module SIF */ +#define SB_SMFLG 0x1000f230 + +/* Module GS Special */ +#define GS_PMODE 0x12000000 +#define GS_SMODE1 0x12000010 +#define GS_SMODE2 0x12000020 +#define GS_SRFSH 0x12000030 +#define GS_SYNCH1 0x12000040 +#define GS_SYNCH2 0x12000050 +#define GS_SYNCV 0x12000060 +#define GS_DISPFB1 0x12000070 +#define GS_DISPLAY1 0x12000080 +#define GS_DISPFB2 0x12000090 +#define GS_DISPLAY2 0x120000a0 +#define GS_EXTBUF 0x120000b0 +#define GS_EXTDATA 0x120000c0 +#define GS_EXTWRITE 0x120000d0 +#define GS_BGCOLOR 0x120000e0 +#define GS_CSR 0x12001000 +#define GS_IMR 0x12001010 +#define GS_BUSDIR 0x12001040 +#define GS_SIGLBLID 0x12001080 + +#endif diff --git a/tests/ps2/gif.h b/tests/ps2/gif.h new file mode 100755 index 0000000..8e25028 --- /dev/null +++ b/tests/ps2/gif.h @@ -0,0 +1,63 @@ +#ifndef GIF_H +#define GIF_H + +#include "ps2.h" +#include "ee_regs.h" +#include "dma.h" + +#define GIF_DECLARE_PACKET(NAME,N) \ + uint64 __attribute__((aligned (16))) NAME[N*2]; \ + int NAME##_cur; \ + int NAME##_size; + +#define GIF_BEGIN_PACKET(NAME) \ + NAME##_cur = 0; \ + NAME##_size = 0 + +#define MAKE_GIF_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)); + +#define GIF_TAG(NAME,NLOOP,EOP,PRE,PRIM,FLG,NREG,REGS) \ + NAME##_size += NLOOP + 1; \ + NAME[NAME##_cur++] = \ + (BIT64(NLOOP, 0) | \ + BIT64(EOP, 15) | \ + BIT64(PRE, 46) | \ + BIT64(PRIM, 47) | \ + BIT64(FLG, 58) | \ + BIT64(NREG, 60)); \ + NAME[NAME##_cur++] = REGS + +#define GIF_DATA_AD(NAME,REG,DATA) \ + NAME[NAME##_cur++] = DATA; \ + NAME[NAME##_cur++] = REG + +#define GIF_DATA_RGBAQ(NAME,R,G,B,A) \ + NAME[NAME##_cur++] = \ + (BIT64(R, 0) | \ + BIT64(G, 32)); \ + NAME[NAME##_cur++] = \ + (BIT64(B, 0) | \ + BIT64(A, 32)) + +#define GIF_DATA_XYZ2(NAME,X,Y,Z,ADC) \ + NAME[NAME##_cur++] = \ + (BIT64(X, 0) | \ + BIT64(Y, 32)); \ + NAME[NAME##_cur++] = \ + (BIT64(Z, 0) | \ + BIT64(ADC, 47)) + +#define GIF_SEND_PACKET(NAME) \ + FlushCache(0); \ + SET_REG32(D2_QWC, MAKE_DN_QWC(NAME##_cur/2)); \ + SET_REG32(D2_MADR, MAKE_DN_MADR(&(NAME), 0)); \ + SET_REG32(D2_CHCR, MAKE_DN_CHCR(1, 0, 0, 0, 0, 1)); \ + DMA_WAIT(D2_CHCR) + +#endif diff --git a/tests/ps2/gs.cpp b/tests/ps2/gs.cpp new file mode 100755 index 0000000..0de7754 --- /dev/null +++ b/tests/ps2/gs.cpp @@ -0,0 +1,321 @@ +#include +#include +#include "ps2.h" +#include "ee_regs.h" +#include "gs.h" +#include "gif.h" + +#include "math.h" +#include "mesh.h" + +GIF_DECLARE_PACKET(gifDmaBuf, 256) + +struct GsState *gsCurState; + +void +dumpdma(void) +{ + int i; + for (i = 0; i < gifDmaBuf_cur; i += 2) + printf("%016lX %016lX\n", gifDmaBuf[i+1], gifDmaBuf[i]); +} + +void +gsDumpState(void) +{ + struct GsState *g = gsCurState; + printf("mode: %d\tinterlaced: %d\tframe: %d\n" + "width,height: %d, %d\n" + "startx, starty: %d %d\n" + "dw, dh: %d %d\n" + "magh, magv: %d %d\n" + "xoff, yoff: %d %d\n" + "xmax, ymax: %d %d\n", + g->mode, g->interlaced, g->field, + g->width, g->height, + g->startx, g->starty, + g->dw, g->dh, + g->magh, g->magv, + g->xoff, g->yoff, + g->xmax, g->ymax); +} + +void +gsInitState(uint16 interlaced, uint16 mode, uint16 field) +{ + struct GsState *g = gsCurState; + int i; + + g->mode = mode; + g->interlaced = interlaced; + g->field = field; + if(mode == PAL){ + g->width = 640; + g->height = 256; + g->startx = 680; + g->starty = 37; + g->dw = 2560; + g->dh = 256; + }else{ + g->width = 640; + g->height = 224; + g->startx = 652; + g->starty = 26; + g->dw = 2560; + g->dh = 224; + } + + if(interlaced == INTERLACED){ + if(field == FIELD) + g->height *= 2; + g->dh *= 2; + g->starty = (g->starty-1)*2; + } + g->magh = 3; + g->magv = 0; + + g->xoff = 2048<<4; + g->yoff = 2048<<4; + g->xmax = g->width - 1; + g->ymax = g->height - 1; + g->psm = PSMCT32; + g->depth = 32; + g->bpp = 4; +// g->psm = PSMCT24; +// g->depth = 24; +// g->bpp = 4; + g->zpsm = PSMCZ32; + g->zdepth = 32; + g->zbpp = 4; + g->zmax = 0x0FFFFFFFF; + g->currentMemPtr = 0; + g->activeFb = 0; + g->visibleFb = 0; + + g->ztest = 1; + g->zfunc = ZTST_GREATER; + g->blend.enable = 0; + g->shadingmethod = IIP_GOURAUD; + + for(i = 0; i < 2; i++){ + g->fbAddr[i] = g->currentMemPtr; + g->currentMemPtr += g->width*g->height*g->bpp; + } + g->zbAddr = g->currentMemPtr; + g->currentMemPtr += g->width*g->height*g->zbpp; +} + +void +gsInit(void) +{ + struct GsState *g = gsCurState; + int addr0, addr1; + + g->visibleFb = 0; + g->activeFb = 1; + printf("%d %d\n", g->fbAddr[0], g->fbAddr[1]); + addr0 = g->fbAddr[g->visibleFb]/4/2048; + addr1 = g->fbAddr[g->activeFb]/4/2048; + + GS_RESET(); + __asm__("sync.p; nop"); + SET_REG64(GS_CSR, 0); + GsPutIMR(0xff00); + SetGsCrt(g->interlaced, g->mode, g->field); + + SET_REG64(GS_PMODE, MAKE_GS_PMODE(0, 1, 0, 1, 0, 0xFF)); + SET_REG64(GS_DISPFB2, MAKE_GS_DISPFB(addr0, g->width/64, g->psm, 0, 0)); + SET_REG64(GS_DISPFB1, MAKE_GS_DISPFB(addr0, g->width/64, g->psm, 0, 0)); + SET_REG64(GS_DISPLAY2, MAKE_GS_DISPLAY(g->startx, g->starty, + g->magh, g->magv, + g->dw-1, g->dh-1)); + SET_REG64(GS_DISPLAY1, MAKE_GS_DISPLAY(g->startx, g->starty, + g->magh, g->magv, + g->dw-1, g->dh-1)); + SET_REG64(GS_BGCOLOR, MAKE_GS_BGCOLOR(100, 100, 100)); + + GIF_BEGIN_PACKET(gifDmaBuf); + GIF_TAG(gifDmaBuf, 7, 1, 0, 0, 0, 1, 0x0e); + GIF_DATA_AD(gifDmaBuf, GS_PRMODECONT, MAKE_GS_PRMODECONT(1)); + GIF_DATA_AD(gifDmaBuf, GS_FRAME_1, + MAKE_GS_FRAME(addr1, g->width/64, g->psm, 0)); + GIF_DATA_AD(gifDmaBuf, GS_ZBUF_1, + MAKE_GS_ZBUF(g->zbAddr/4/2048, g->zpsm, 0)); + GIF_DATA_AD(gifDmaBuf, GS_XYOFFSET_1, + MAKE_GS_XYOFFSET(g->xoff, g->yoff)); + GIF_DATA_AD(gifDmaBuf, GS_SCISSOR_1, + MAKE_GS_SCISSOR(0, g->xmax, 0, g->ymax)); + GIF_DATA_AD(gifDmaBuf, GS_TEST_1, + MAKE_GS_TEST(0, 0, 0, 0, 0, 0, g->ztest, g->zfunc)); + GIF_DATA_AD(gifDmaBuf, GS_COLCLAMP, MAKE_GS_COLCLAMP(1)); + GIF_SEND_PACKET(gifDmaBuf); +} + +void +gsUpdateContext(void) +{ + GsState *gs = gsCurState; + GIF_BEGIN_PACKET(gifDmaBuf); + GIF_TAG(gifDmaBuf, 2, 1, 0, 0, 0, 1, 0x0e); + GIF_DATA_AD(gifDmaBuf, GS_TEST_1, + MAKE_GS_TEST(0, 0, 0, 0, 0, 0, gs->ztest, gs->zfunc)); + GIF_DATA_AD(gifDmaBuf, GS_ALPHA_1, + MAKE_GS_ALPHA(gs->blend.a, gs->blend.b, gs->blend.c, + gs->blend.d, gs->blend.fix)); + GIF_SEND_PACKET(gifDmaBuf); +} + +void +gsPollVsynch(void) +{ + volatile uint64 *csr = (uint64 *) GS_CSR; + *csr &= 8; + while(!(*csr & 8)); +} + +void +gsFlip(void) +{ + struct GsState *g = gsCurState; + g->activeFb = (g->activeFb+1) & 1; + g->visibleFb = (g->visibleFb+1) & 1; + gsPollVsynch(); + gsSelectActiveFb(g->activeFb); + gsSelectVisibleFb(g->visibleFb); +} + +void +gsSelectActiveFb(int n) +{ + struct GsState *g = gsCurState; + int addr; + + addr = g->fbAddr[n]/4/2048; + GIF_BEGIN_PACKET(gifDmaBuf); + GIF_TAG(gifDmaBuf, 1, 1, 0, 0, 0, 1, 0x0e); + GIF_DATA_AD(gifDmaBuf, GS_FRAME_1, + MAKE_GS_FRAME(addr, g->width/64, g->psm, 0)); + GIF_SEND_PACKET(gifDmaBuf); +} + +void +gsSelectVisibleFb(int n) +{ + struct GsState *g = gsCurState; + int addr; + + addr = g->fbAddr[n]/4/2048; + SET_REG64(GS_DISPFB2, MAKE_GS_DISPFB(addr, g->width/64, g->psm, 0, 0)); +} + +void +gsClear(void) +{ + struct GsState *gs = gsCurState; + uint16 x, y; + int r = gs->clearcol & 0xFF; + int g = (gs->clearcol >> 8) & 0xFF; + int b = (gs->clearcol >> 16) & 0xFF; + int a = (gs->clearcol >> 24) & 0xFF; + + x = (gs->width << 4) + gs->xoff; + y = (gs->height << 4) + gs->yoff; + + GIF_BEGIN_PACKET(gifDmaBuf); + GIF_TAG(gifDmaBuf, 6, 1, 0, 0, 0, 1, 0x0e); + /* clear z-buffer too */ + GIF_DATA_AD(gifDmaBuf, GS_TEST_1, + MAKE_GS_TEST(0, 0, 0, 0, 0, 0, 1, ZTST_ALWAYS)); + GIF_DATA_AD(gifDmaBuf, GS_PRIM, + MAKE_GS_PRIM(PRIM_SPRITE, 0, 0, 0, 0, 0, 0, 0, 0)); + GIF_DATA_AD(gifDmaBuf, GS_RGBAQ, + MAKE_GS_RGBAQ(r, g, b, a, 0)); + GIF_DATA_AD(gifDmaBuf, GS_XYZ2, MAKE_GS_XYZ(0, 0, 0)); + GIF_DATA_AD(gifDmaBuf, GS_XYZ2, MAKE_GS_XYZ(x, y, 0)); + /* re-enable z-test */ + GIF_DATA_AD(gifDmaBuf, GS_TEST_1, + MAKE_GS_TEST(0, 0, 0, 0, 0, 0, gs->ztest, gs->zfunc)); + GIF_SEND_PACKET(gifDmaBuf); +} + +void +gsNormalizedToScreen(float *v1, uint32 *v2) +{ + struct GsState *g = gsCurState; + uint64 d; + + d = g->zmax & 0xFFFFFFFF; + v2[0] = (1.0f+v1[0])*g->width/2; + v2[1] = (1.0f-v1[1])*g->height/2; + v2[2] = (1.0f-v1[2])*d/2; +} + +void +drawrect(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint32 col) +{ + struct GsState *gs = gsCurState; + x1 = (x1<<4) + gs->xoff; + y1 = (y1<<4) + gs->yoff; + x2 = (x2<<4) + gs->xoff; + y2 = (y2<<4) + gs->yoff; + int r = col & 0xFF; + int g = (col >> 8) & 0xFF; + int b = (col >> 16) & 0xFF; + int a = (col >> 24) & 0xFF; + + GIF_BEGIN_PACKET(gifDmaBuf); + GIF_TAG(gifDmaBuf, 4, 1, 0, 0, 0, 1, 0x0e); + GIF_DATA_AD(gifDmaBuf, GS_PRIM, + MAKE_GS_PRIM(PRIM_SPRITE, 0, 0, 0, + gs->blend.enable, 0, 0, 0, 0)); + GIF_DATA_AD(gifDmaBuf, GS_RGBAQ, + MAKE_GS_RGBAQ(r, g, b, a, 0)); + GIF_DATA_AD(gifDmaBuf, GS_XYZ2, MAKE_GS_XYZ(x1, y1, 0)); + GIF_DATA_AD(gifDmaBuf, GS_XYZ2, MAKE_GS_XYZ(x2, y2, 0)); + GIF_SEND_PACKET(gifDmaBuf); +} + +/* +void +drawdata(float *data, int vertexCount) +{ + struct GsState *g = gsCurState; + int i; + float *verts, *colors; + Vector4f vf; + uint32 vi[3]; + uint8 c[4]; + + verts = &data[0]; + colors = &data[vertexCount*3]; + + GIF_BEGIN_PACKET(gifDmaBuf); + GIF_TAG(gifDmaBuf, vertexCount, 1, 1, + MAKE_GS_PRIM(PRIM_TRI,IIP_GOURAUD,0,0,0,0,0,0,0), 0, 2, 0x51); + + for (i = 0; i < vertexCount; i++) { + vec4fCopy(vf, &verts[i*3]); + vf[3] = 1.0f; + + matMultVec(mathModelViewMat, vf); + matMultVec(mathProjectionMat, vf); + vf[0] /= vf[3]; + vf[1] /= vf[3]; + vf[2] /= vf[3]; + + gsNormalizedToScreen(vf, vi); + + vi[0] = ((vi[0]*16) + g->xoff) & 0xFFFF; + vi[1] = ((vi[1]*16) + g->yoff) & 0xFFFF; + + c[0] = colors[i*4+0]; + c[1] = colors[i*4+1]; + c[2] = colors[i*4+2]; + c[3] = colors[i*4+3]; + + GIF_DATA_RGBAQ(gifDmaBuf, c[0], c[1], c[2], c[3]); + GIF_DATA_XYZ2(gifDmaBuf, vi[0], vi[1], vi[2], 0); + } + GIF_SEND_PACKET(gifDmaBuf); +} +*/ diff --git a/tests/ps2/gs.h b/tests/ps2/gs.h new file mode 100755 index 0000000..b2b6834 --- /dev/null +++ b/tests/ps2/gs.h @@ -0,0 +1,484 @@ +#ifndef GS_H +#define GS_H +#include "ps2.h" +#include "ee_regs.h" + +typedef struct GsState GsState; +struct GsState { + int32 mode, interlaced, field; + int32 width, height; + int32 startx, starty; + int32 dw, dh; + int32 magh, magv; + int32 xoff, yoff; + int32 xmax, ymax; + int32 psm; + int32 depth; + int32 bpp; + int32 zpsm; + int32 zdepth; + int32 zbpp; + int32 zmax; + int32 currentMemPtr; + uint32 fbAddr[2]; + uint32 zbAddr; + + int32 visibleFb; + int32 activeFb; + + uint32 clearcol; + + int32 ztest; + int32 zfunc; + struct { + int32 enable; + int32 a, b, c, d; + int32 fix; + } blend; + int32 shadingmethod; +}; + +extern GsState *gsCurState; + +void gsDumpState(void); +void gsInitState(uint16 interlaced, + uint16 mode, uint16 field); +void gsInit(void); +void gsUpdateContext(void); +void gsSelectVisibleFb(int n); +void gsSelectActiveFb(int n); +void gsFlip(void); +void gsClear(void); +void gsNormalizedToScreen(float *v1, uint32 *v2); + +void drawrect(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint32 col); +//void drawdata(float *data, int vertexCount); + + +#define NTSC 2 +#define PAL 3 +#define DTV480P 0x50 //(use with NONINTERLACED, FRAME) + +#define NONINTERLACED 0 +#define INTERLACED 1 + +#define FIELD 0 +#define FRAME 1 + +#define PSMCT32 0 +#define PSMCT24 1 +#define PSMCT16 2 +#define PSMCT16S 10 +#define PS_GPU24 18 + +#define PSMCZ32 0 +#define PSMCZ24 1 +#define PSMCZ16 2 +#define PSMCZ16S 10 + +#define ZTST_NEVER 0 +#define ZTST_ALWAYS 1 +#define ZTST_GREATER 2 +#define ZTST_GEQUAL 3 + +#define PRIM_POINT 0 +#define PRIM_LINE 1 +#define PRIM_LINE_STRIP 2 +#define PRIM_TRI 3 +#define PRIM_TRI_STRIP 4 +#define PRIM_TRI_FAN 5 +#define PRIM_SPRITE 6 +#define PRIM_NO_SPEC 7 +#define IIP_FLAT 0 +#define 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 + +#define MAKE_GS_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 MAKE_GS_RGBAQ(R,G,B,A,Q) \ + (BIT64(R, 0) | \ + BIT64(G, 8) | \ + BIT64(B, 16) | \ + BIT64(A, 24) | \ + BIT64(Q, 32)) + +#define MAKE_GS_ST(S,T) \ + (BIT64(S, 0) | \ + BIT64(T, 32)) + +#define MAKE_GS_UV(U,V) \ + (BIT64(U, 0) | \ + BIT64(V, 16)) + +#define MAKE_GS_XYZF(X,Y,Z,F) \ + (BIT64(X, 0) | \ + BIT64(Y, 16) | \ + BIT64(Z, 32) | \ + BIT64(F, 56)) + +#define MAKE_GS_XYZ(X,Y,Z) \ + (BIT64(X, 0) | \ + BIT64(Y, 16) | \ + BIT64(Z, 32)) + +#define MAKE_GS_TEX0(TBP0,TBW,PSM,TW,TH,TCC,TFX,CBP,CPSM,CSM,CSA,CLD) \ + (BIT64(TBP0, 0) | \ + BIT64(TBW, 14) | \ + BIT64(PSM, 20) | \ + BIT64(TW, 26) | \ + BIT64(TH, 30) | \ + BIT64(TCC, 34) | \ + BIT64(TFX, 35) | \ + BIT64(CBP, 37) | \ + BIT64(CPSM, 51) | \ + BIT64(CSM, 55) | \ + BIT64(CSA, 56) | \ + BIT64(CSD, 61)) + +#define MAKE_GS_CLAMP(WMS,WMT,MINU,MAXU,MINV,MAXV) \ + (BIT64(WMS, 0) | \ + BIT64(WMT, 2) | \ + BIT64(MINU, 4) | \ + BIT64(MAXU, 14) | \ + BIT64(MINV, 24) | \ + BIT64(MAXV, 34)) + +#define MAKE_GS_FOG(F) \ + (BIT64(F, 56)) + +#define MAKE_GS_TEX1(LCM,MXL,MMAG,MMIN,MTBA,L,K) \ + (BIT64(LCM, 0) | \ + BIT64(MXL, 2) | \ + BIT64(MMAG, 5) | \ + BIT64(MMIN, 6) | \ + BIT64(MTBA, 9) | \ + BIT64(L, 19) | \ + BIT64(K, 32)) + +#define MAKE_GS_TEX2(PSM,CBP,CPSM,CSM,CSA,CLD) \ + (BIT64(PSM, 20) | \ + BIT64(CBP, 37) | \ + BIT64(CPSM, 51) | \ + BIT64(CSM, 55) | \ + BIT64(CSA, 56) | \ + BIT64(CLD, 61)) + +#define MAKE_GS_XYOFFSET(OFX,OFY) \ + (BIT64(OFX, 0) | \ + BIT64(OFY, 32)) + +#define MAKE_GS_PRMODECONT(AC) \ + (BIT64(AC, 0)) + +#define MAKE_GS_PRMODE(IIP,TME,FGE,ABE,AA1,FST,CTXT,FIX) \ + (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 MAKE_GS_TEXCLUT(CBW,COU,COV) \ + (BIT64(CBW, 0) | \ + BIT64(COU, 6) | \ + BIT64(COV, 12)) + +#define MAKE_GS_SCANMSK(MSK) \ + (BIT64(MSK, 0)) + +#define MAKE_GS_MIPTBP1(TBP1,TBW1,TBP2,TBW2,TBP3,TBW3) \ + (BIT64(TBP1, 0) | \ + BIT64(TBW1, 14) | \ + BIT64(TBP2, 20) | \ + BIT64(TBW2, 34) | \ + BIT64(TBP3, 40) | \ + BIT64(TBW3, 54)) + +#define MAKE_GS_MIPTBP2(TBP4,TBW4,TBP5,TBW5,TBP6,TBW6) \ + (BIT64(TBP4, 0) | \ + BIT64(TBW4, 14) | \ + BIT64(TBP5, 20) | \ + BIT64(TBW5, 34) | \ + BIT64(TBP6, 40) | \ + BIT64(TBW6, 54)) + +#define MAKE_GS_TEXA(TA0,AEM,TA1) \ + (BIT64(TA0, 0) | \ + BIT64(AEM, 15) | \ + BIT64(TA1, 32)) + +#define MAKE_GS_FOGCOL(FCR,FCG,FCB) \ + (BIT64(FCR, 0) | \ + BIT64(FCG, 8) | \ + BIT64(FCB, 16)) + +/* GS_TEXFLUSH */ + +#define MAKE_GS_SCISSOR(SCAX0,SCAX1,SCAY0,SCAY1) \ + (BIT64(SCAX0, 0) | \ + BIT64(SCAX1, 16) | \ + BIT64(SCAY0, 32) | \ + BIT64(SCAY1, 48)) + +#define MAKE_GS_ALPHA(A,B,C,D,FIX) \ + (BIT64(A, 0) | \ + BIT64(B, 2) | \ + BIT64(C, 4) | \ + BIT64(D, 6) | \ + BIT64(FIX, 32)) + +#define MAKE_GS_DIMX(DM00,DM01,DM02,DM03, \ + DM10,DM11,DM12,DM13, \ + DM20,DM21,DM22,DM23, \ + DM30,DM31,DM32,DM33) \ + (BIT64(DM00, 0) | \ + BIT64(DM01, 4) | \ + BIT64(DM02, 8) | \ + BIT64(DM03, 12) | \ + BIT64(DM10, 16) | \ + BIT64(DM11, 20) | \ + BIT64(DM12, 24) | \ + BIT64(DM13, 28) | \ + BIT64(DM20, 32) | \ + BIT64(DM21, 36) | \ + BIT64(DM22, 40) | \ + BIT64(DM23, 44) | \ + BIT64(DM30, 48) | \ + BIT64(DM31, 52) | \ + BIT64(DM32, 56) | \ + BIT64(DM33, 60)) + +#define MAKE_GS_DITHE(DTHE) \ + (BIT64(DTHE, 0)) + +#define MAKE_GS_COLCLAMP(CLAMP) \ + (BIT64(CLAMP, 0)) + +#define MAKE_GS_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 MAKE_GS_PABE(PABE) \ + (BIT64(PABE, 0)) + +#define MAKE_GS_FBA(FBA) \ + (BIT64(FBA, 0)) + +#define MAKE_GS_FRAME(FBP,FBW,PSM,FBMSK) \ + (BIT64(FBP, 0) | \ + BIT64(FBW, 16) | \ + BIT64(PSM, 24) | \ + BIT64(FBMSK, 32)) + +#define MAKE_GS_ZBUF(ZBP,PSM,ZMSK) \ + (BIT64(ZBP, 0) | \ + BIT64(PSM, 24) | \ + BIT64(ZMSK, 32)) + +#define MAKE_GS_BITBLTBUF(SBP,SBW,SPSM,DBP,DBW,DPSM) \ + (BIT64(SBP, 0) | \ + BIT64(SBW, 16) | \ + BIT64(SPSM, 24) | \ + BIT64(DBP, 32) | \ + BIT64(DBW, 48) | \ + BIT64(DPSM, 56)) + +#define MAKE_GS_TRXPOS(SSAX,SSAY,DSAX,DSAY,DIR) \ + (BIT64(SSAX, 0) | \ + BIT64(SSAY, 16) | \ + BIT64(DSAX, 32) | \ + BIT64(DSAY, 48) | \ + BIT64(DIR, 59)) + +#define MAKE_GS_TRXREG(RRW,RRH) \ + (BIT64(RRW, 0) | \ + BIT64(RRH, 32)) + +#define MAKE_GS_TRXDIR(XDIR) \ + (BIT64(XDIR, 0)) + +#define MAKE_GS_HWREG(DATA) \ + (BIT64(DATA, 0)) + +#define MAKE_GS_SIGNAL(ID,IDMSK) \ + (BIT64(ID, 0) | \ + BIT64(IDMSK, 32)) + +/* GS_FINISH */ + +#define MAKE_GS_LABEL(ID,IDMSK) \ + (BIT64(ID, 0) | \ + BIT64(IDMSK, 32)) + + +/* + * No documentation about these: + * GS_SRFSH + * GS_SYNCH1 + * GS_SYNCH2 + * GS_SYNCV + */ + +#define MAKE_GS_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)) + +#define MAKE_GS_SMODE(INT,FFMD,DPMS) \ + (BIT64(INT, 0) | \ + BIT64(FFMD, 1) | \ + BIT64(DPMS, 2)) + +#define MAKE_GS_DISPFB(FBP,FBW,PSM,DBX,DBY) \ + (BIT64(FBP, 0) | \ + BIT64(FBW, 9) | \ + BIT64(PSM, 15) | \ + BIT64(DBX, 32) | \ + BIT64(DBY, 43)) + +#define MAKE_GS_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)) + +#define MAKE_GS_EXTBUF(EXBP,EXBW,FBIN,WFFMD,EMODE,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)) + +#define MAKE_GS_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)) + +#define MAKE_GS_EXTWRITE(WRITE) \ + (BIT64(WRITE, 0)) + +#define MAKE_GS_BGCOLOR(R,G,B) \ + (BIT64(R, 0) | \ + BIT64(G, 8) | \ + BIT64(B, 16)) + +#define MAKE_GS_CSR(SIGNAL,FINISH,HSINT,VSINT,EDWINT,FLUSH,RESET,NFIELD,\ + FIELD,FIFO,REV,ID) \ + (BIT64(SIGNAL, 0) | \ + BIT64(FINISH, 1) | \ + BIT64(HSINT, 2) | \ + BIT64(VSINT, 3) | \ + BIT64(EDWINT, 4) | \ + BIT64(FLUSH, 8) | \ + BIT64(RESET, 9) | \ + BIT64(NFIELD, 12) | \ + BIT64(FIELD, 13) | \ + BIT64(FIFO, 14) | \ + BIT64(REV, 16) | \ + BIT64(ID, 24)) + +#define MAKE_GS_IMR(SIGMSK,FINISHMSK,HSMSK,VSMSK,EDWMSK) \ + (BIT64(SIGMSK, 8) | \ + BIT64(FINISHMSK, 9) | \ + BIT64(HSMSK, 10) | \ + BIT64(VSMSK, 11) | \ + BIT64(EDWMSK, 12)) + +#define MAKE_GS_BUSDIR(DIR) \ + (BIT64(DIR, 0)) + +#define MAKE_GS_SIGLBLID(SIGID,LBLID) \ + (BIT64(SIGID, 0) | \ + BIT64(LBLID, 32)) + +#define GS_RESET() \ + SET_REG64(GS_CSR, BIT64(1, 9)) + +#endif diff --git a/tests/ps2/light.vu b/tests/ps2/light.vu new file mode 100644 index 0000000..8443409 --- /dev/null +++ b/tests/ps2/light.vu @@ -0,0 +1,94 @@ +; Ambient light: + NOP LQ VF26, ambientLight(VI00) + NOP XITOP VI01 + NOP IADDIU VI03, VI12, 1 +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, 2 ; numOutAttribs + NOP IBNE VI01, VI00, Ambloop + NOP SQ VF03, -2(VI03) ; numOutAttribs +; end amblight + +; Direct Light + NOP LQ VF26, lightDir(VI00) + NOP XITOP VI01 + NOP XTOP VI02 + NOP IADDIU VI03, VI12, 1 + 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, 2 ; numOutAttribs + NOP IBNE VI01, VI00, Dirloop + NOP SQ VF02, -2(VI03) ; numOutAttribs +; end dirlight + +; Material color and clamp + NOP LQ VF27, matColor(VI00) + NOP XITOP VI01 + NOP IADDIU VI03, VI12, 1 +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, 2 ; numOutAttribs + NOP IBNE VI01, VI00, Colorloop + NOP SQ VF03, -2(VI03) ; numOutAttribs +; end material color diff --git a/tests/ps2/main.cpp b/tests/ps2/main.cpp new file mode 100755 index 0000000..ffde3f9 --- /dev/null +++ b/tests/ps2/main.cpp @@ -0,0 +1,202 @@ +#include + +#include +#include "ps2.h" +#include "dma.h" +#include "gif.h" +#include "gs.h" + +#include "math.h" +#include "mesh.h" + +#include +#include + +using namespace std; + +extern uint32 MyDmaPacket[]; +extern Matrix vuMat; +extern float vuOffset[]; +extern uint64 vuGIFtag[]; +extern float vuMatcolor[]; +extern float vuSurfProps[]; +extern uint32 vuGeometry[]; +extern uint32 mpgCall[]; +extern uint32 geometryCall[]; +extern uint32 defaultPipe[]; +extern uint32 skinPipe[]; + +Rw::Clump *clump; + +void +drawAtomic(Rw::Atomic *atomic) +{ + Rw::Geometry *geo = atomic->geometry; + assert(geo->instData != NULL); + Rw::Ps2::InstanceDataHeader *instData = + (Rw::Ps2::InstanceDataHeader*)geo->instData; + + atomic->frame->updateLTM(); + matMult(vuMat, atomic->frame->ltm); + for(int i = 0; i < instData->numMeshes; i++){ + if(instData->instanceMeshes[i].arePointersFixed == 0) + Rw::Ps2::fixDmaOffsets(&instData->instanceMeshes[i]); + geometryCall[1] = (uint32)instData->instanceMeshes[i].data; + + vuGIFtag[0] = MAKE_GIF_TAG(0,1,1,0xC,0,2); + vuGIFtag[1] = 0x41; + vuMatcolor[0] = 1.0f; + vuMatcolor[1] = 1.0f; + vuMatcolor[2] = 1.0f; + vuMatcolor[3] = 0.5f; + Rw::Skin *skin = + *PLUGINOFFSET(Rw::Skin*, geo, Rw::SkinGlobals.offset); + if(Rw::SkinGlobals.offset && skin){ + geometryCall[3] = 0x020000DC; + mpgCall[1] = (uint32)skinPipe; + }else{ + geometryCall[3] = 0x02000114; + mpgCall[1] = (uint32)defaultPipe; + } + + SET_REG32(D1_QWC, 0x00); + SET_REG32(D1_TADR, (uint)MyDmaPacket & 0x0FFFFFFF); + FlushCache(0); + SET_REG32(D1_CHCR, MAKE_DN_CHCR(1, 1, 0, 1, 0, 1)); + DMA_WAIT(D1_CHCR); + } + +} + +void +draw(void) +{ + Matrix m; + static float rot = 0.0f; + + gsClear(); + + matMakeIdentity(mathModelViewMat); + matTranslate(mathModelViewMat, 0.0f, 0.0f, -34.0f); +// matTranslate(mathModelViewMat, 0.0f, 0.0f, -10.0f); +// matTranslate(mathModelViewMat, 0.0f, 0.0f, -8.0f); + matRotateX(mathModelViewMat, rot); + matRotateY(mathModelViewMat, rot); + matRotateZ(mathModelViewMat, rot); + matInverse(mathNormalMat, mathModelViewMat); + + matCopy(vuMat, mathProjectionMat); + matMult(vuMat, mathModelViewMat); + + for(int i = 0; i < clump->numAtomics; i++){ + char *name = PLUGINOFFSET(char, clump->atomicList[i]->frame, + Rw::NodeNameOffset); + if(strstr(name, "_dam") || strstr(name, "_vlo")) + continue; + matCopy(m, vuMat); + drawAtomic(clump->atomicList[i]); + matCopy(vuMat, m); + } + + rot += 0.01f; + if(rot > 2*M_PI) + rot -= 2*M_PI; +} + +int +main() +{ + GsState gss; + gsCurState = &gss; + + dmaReset(1); + +// gsInitState(NONINTERLACED, PAL, FRAME); +// gsInitState(INTERLACED, PAL, FRAME); + gsInitState(INTERLACED, PAL, FIELD); + gsCurState->clearcol = 0x80404040; + + gsInit(); + printf("hallo\n"); + + Rw::RegisterMaterialRightsPlugin(); + Rw::RegisterMatFXPlugin(); + Rw::RegisterAtomicRightsPlugin(); + Rw::RegisterNodeNamePlugin(); + Rw::RegisterBreakableModelPlugin(); + Rw::RegisterExtraVertColorPlugin(); + Rw::Ps2::RegisterADCPlugin(); + Rw::RegisterSkinPlugin(); + Rw::RegisterNativeDataPlugin(); +// Rw::Ps2::RegisterNativeDataPlugin(); + Rw::RegisterMeshPlugin(); + +// Rw::StreamFile in; +// in.open("host:player-vc-ps2.dff", "rb"); + +// FILE *cf = fopen("host:player-vc-ps2.dff", "rb"); + FILE *cf = fopen("host:od_newscafe_dy-ps2.dff", "rb"); +// FILE *cf = fopen("host:admiral-ps2.dff", "rb"); + assert(cf != NULL); + fseek(cf, 0, SEEK_END); + Rw::uint32 len = ftell(cf); + fseek(cf, 0, SEEK_SET); + Rw::uint8 *data = new Rw::uint8[len]; + fread(data, len, 1, cf); + fclose(cf); + Rw::StreamMemory in; + in.open(data, len); + + printf("opened file\n"); + Rw::FindChunk(&in, Rw::ID_CLUMP, NULL, NULL); + printf("found chunk\n"); + clump = Rw::Clump::streamRead(&in); + printf("read file\n"); + in.close(); + printf("closed file\n"); + delete[] data; + + data = new Rw::uint8[256*1024]; + Rw::StreamMemory out; + out.open(data, 0, 256*1024); + clump->streamWrite(&out); +// cf = fopen("host:out-ps2.dff", "wb"); +// assert(cf != NULL); +// fwrite(data, out.getLength(), 1, cf); +// fclose(cf); + out.close(); + delete[] data; + +// Rw::StreamFile out; +// out.open("host:out-ps2.dff", "wb"); +// c->streamWrite(&out); +// out.close(); +// +// printf("wrote file\n"); + + vuOffset[0] = 2048.0f; + vuOffset[1] = 2048.0f; + + for(int i = 0; i < clump->numAtomics; i++){ + Rw::Atomic *a = clump->atomicList[i]; + char *name = + PLUGINOFFSET(char, a->frame, Rw::NodeNameOffset); + printf("%s\n", name); + } + +// gsDumpState(); + +// matPerspective(mathProjectionMat, 60.0f, (float)gss.width/gss.height, +// matPerspective(mathProjectionMat, 60.0f, (float)gss.width/gss.dh, +// matPerspective(mathProjectionMat, 60.0f, 4.0/3.0, 1.0f, 100.0f); +// matPerspective(mathProjectionMat, 60.0f, 16.0/9.0, 1.0f, 100.0f); + matPerspective2(mathProjectionMat, 60.0f, 4.0/3.0, gss.width,gss.height, + 1.0f, 100.0f, 16777216, 1); + + for(;;){ + draw(); + gsFlip(); + } + + return 0; +} diff --git a/tests/ps2/math.cpp b/tests/ps2/math.cpp new file mode 100755 index 0000000..caf881e --- /dev/null +++ b/tests/ps2/math.cpp @@ -0,0 +1,238 @@ +#include +#include +#include "math.h" + +Matrix mathModelViewMat; +Matrix mathNormalMat; +Matrix mathProjectionMat; + +void +matDump(Matrix m) +{ + int i, j; +#define M(i,j) m[i*4+j] + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) + printf("%f ", M(j,i)); + printf("\n"); + } +#undef M + printf("\n"); +} + +void +matMakeIdentity(Matrix m) +{ + int i, j; + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) + m[i*4+j] = (i == j) ? 1.0f : 0.0f; +} + +void +matCopy(Matrix m1, Matrix m2) +{ + int i; + for (i = 0; i < 16; i++) + m1[i] = m2[i]; +} + +void +matMult(Matrix m1, Matrix m2) +{ + int i, j; + Matrix newmat; +#define M1(i,j) m1[i*4+j] +#define M2(i,j) m2[i*4+j] +#define NEW(i,j) newmat[i*4+j] + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) + NEW(i,j) = M1(0,j)*M2(i,0) + + M1(1,j)*M2(i,1) + + M1(2,j)*M2(i,2) + + M1(3,j)*M2(i,3); +#undef M1 +#undef M2 +#undef NEW + matCopy(m1, newmat); +} + +void +matMultVec(Matrix m, Vector4f v) +{ + int i; + Vector4f newmat; +#define M(i,j) m[i*4+j] + for (i = 0; i < 4; i++) + newmat[i] = M(0,i)*v[0] + + M(1,i)*v[1] + + M(2,i)*v[2] + + M(3,i)*v[3]; +#undef M + vec4fCopy(v, newmat); +} + +void +matInverse(Matrix m1, Matrix m2) +{ + float det; + +#define N(i,j) m1[i*4+j] +#define M(i,j) m2[i*4+j] + det = M(0,0)*(M(2,2)*M(1,1) - M(1,2)*M(2,1)) + - M(0,1)*(M(2,2)*M(1,0) - M(1,2)*M(2,0)) + + M(0,2)*(M(2,1)*M(1,0) - M(1,1)*M(2,0)); + matMakeIdentity(m1); + N(0,0) = (M(2,2)*M(1,1) - M(1,2)*M(2,1))/det; + N(0,1) = (M(1,2)*M(2,0) - M(2,2)*M(1,0))/det; + N(0,2) = (M(2,1)*M(1,0) - M(1,1)*M(2,0))/det; + N(1,0) = (M(0,2)*M(2,1) - M(2,2)*M(0,1))/det; + N(1,1) = (M(2,2)*M(0,0) - M(0,2)*M(2,0))/det; + N(1,2) = (M(0,1)*M(2,0) - M(2,1)*M(0,0))/det; + N(2,0) = (M(1,2)*M(0,1) - M(0,2)*M(1,1))/det; + N(2,1) = (M(0,2)*M(1,0) - M(1,2)*M(0,0))/det; + N(2,2) = (M(1,1)*M(0,0) - M(0,1)*M(1,0))/det; +#undef M +#undef N +} + +void +vec4fCopy(Vector4f v1, Vector4f v2) +{ + v1[0] = v2[0]; + v1[1] = v2[1]; + v1[2] = v2[2]; + v1[3] = v2[3]; +} + +float +vec3fDot(Vector3f v1, Vector3f v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; +} + +void +vec3fNormalize(Vector3f v) +{ + float d; + + d = sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + v[0] /= d; + v[1] /= d; + v[2] /= d; +} + +void +matRotateX(Matrix m, float ang) +{ + Matrix rot; + matMakeIdentity(rot); +#define M(i,j) rot[i*4+j] + M(1,1) = cosf(ang); + M(1,2) = sinf(ang); + M(2,1) = -sinf(ang); + M(2,2) = cosf(ang); +#undef M + matMult(m, rot); +} + +void +matRotateY(Matrix m, float ang) +{ + Matrix rot; + matMakeIdentity(rot); +#define M(i,j) rot[i*4+j] + M(0,0) = cosf(ang); + M(2,0) = sinf(ang); + M(0,2) = -sinf(ang); + M(2,2) = cosf(ang); +#undef M + matMult(m, rot); +} + +void +matRotateZ(Matrix m, float ang) +{ + Matrix rot; + matMakeIdentity(rot); +#define M(i,j) rot[i*4+j] + M(0,0) = cosf(ang); + M(0,1) = sinf(ang); + M(1,0) = -sinf(ang); + M(1,1) = cosf(ang); +#undef M + matMult(m, rot); +} + +void +matTranslate(Matrix m, float x, float y, float z) +{ + Matrix trans; + matMakeIdentity(trans); +#define M(i,j) trans[i*4+j] + M(3,0) = x; + M(3,1) = y; + M(3,2) = z; +#undef M + matMult(m, trans); +} + +void +matFrustum2(Matrix m, float l, float r, float xl, float xr, + float b, float t, float yb, float yt, + float n, float f, float zn, float zf) +{ + matMakeIdentity(m); +#define M(i,j) m[i*4+j] + M(0,0) = ((xr-xl)*n)/(r-l); + M(1,1) = ((yt-yb)*n)/(t-b); + M(2,0) = (l*xr-r*xl)/(r-l); + M(2,1) = (b*yt-t*yb)/(t-b); + M(2,2) = -(f*zf+n*zn)/(f-n); + M(2,3) = -1.0f; + M(3,2) = (zn-zf)*f*n/(f-n); + M(3,3) = 0.0f; +#undef M +} + +void +matFrustum(Matrix m, float l, float r, float b, float t, + float n, float f) +{ + matMakeIdentity(m); +#define M(i,j) m[i*4+j] + M(0,0) = (2.0f*n)/(r-l); + M(1,1) = (2.0f*n)/(t-b); + M(2,0) = (r+l)/(r-l); + M(2,1) = (t+b)/(t-b); + M(2,2) = -(f+n)/(f-n); + M(2,3) = -1.0f; + M(3,2) = -2.0f*f*n/(f-n); + M(3,3) = 0.0f; +#undef M +} + +void +matPerspective2(Matrix m, float fov, float ratio, float width, float height, + float n, float f, float znear, float zfar) +{ + float r, t; + + r = n*tanf(fov*M_PI/360.0f); + t = r/ratio; + + matFrustum2(m, -r, r, 0, width, + -t, t, height, 0, + n, f, znear, zfar); +} + +void +matPerspective(Matrix m, float fov, float ratio, float n, float f) +{ + float r, t; + + r = n*tanf(fov*M_PI/360.0f); + t = r/ratio; + + matFrustum(m, -r, r, -t, t, n, f); +} diff --git a/tests/ps2/math.h b/tests/ps2/math.h new file mode 100755 index 0000000..8211749 --- /dev/null +++ b/tests/ps2/math.h @@ -0,0 +1,37 @@ +#ifndef MATH_H +#define MATH_H +#include "ps2.h" + +typedef float Matrix[16]; +typedef float Vector2f[2]; +typedef float Vector3f[3]; +typedef float Vector4f[4]; +typedef uint8 Vector4b[4]; + +extern Matrix mathModelViewMat; +extern Matrix mathNormalMat; +extern Matrix mathProjectionMat; + +void matDump(Matrix m); +void matMakeIdentity(Matrix m); +void matCopy(Matrix m1, Matrix m2); +void matMult(Matrix m1, Matrix m2); +void matMultVec(Matrix m, Vector4f v); +void vec4fCopy(Vector4f v1, Vector4f v2); +float vec3fDot(Vector3f v1, Vector3f v2); +void vec3fNormalize(Vector3f v); +void matRotateX(Matrix m, float ang); +void matRotateY(Matrix m, float ang); +void matRotateZ(Matrix m, float ang); +void matFrustum2(Matrix m, float l, float r, float xl, float xr, + float b, float t, float yb, float yt, + float n, float f, float zn, float zf); +void matFrustum(Matrix m, float l, float r, float b, float t, + float n, float f); +void matPerspective2(Matrix m, float fov, float ratio, float width, float height, + float n, float f, float znear, float zfar); +void matPerspective(Matrix m, float fov, float ratio, float n, float f); +void matTranslate(Matrix m, float x, float y, float z); +void matInverse(Matrix m1, Matrix m2); + +#endif diff --git a/tests/ps2/mesh.cpp b/tests/ps2/mesh.cpp new file mode 100755 index 0000000..6550abe --- /dev/null +++ b/tests/ps2/mesh.cpp @@ -0,0 +1,135 @@ +#include +#include +#include "ps2.h" +#include "gs.h" +#include "gif.h" + +#include "math.h" +#include "mesh.h" + +//Mesh testmesh = +// #include "test.msh" +// +//Mesh playermesh = +// #include "player.msh" + +GIF_DECLARE_PACKET(meshGifBuf, 256) + +void meshDump(Mesh *m) +{ +// int i; + + printf("primitive: %d\n" + "attribs: %d\n" + "vertexCount: %d\n", m->primitive, m->attribs, m->vertexCount); + printf("vertices:\n"); + +/* + for (i = 0; i < m->vertexCount; i++) { + printf("%f %f %f\n", m->vertices[i][0], + m->vertices[i][1], + m->vertices[i][2]); + } +*/ +} + +void meshDraw(Mesh *m) +{ + struct GsState *g = gsCurState; + int i, j; + Vector4f vf; + Vector4f n; + Vector4f lightdir = {1.0f, 1.0f, 1.0f }; + float intens; + uint32 vi[3]; + uint8 c[4]; + int blockCount; + int vertexCount; + int blockVertCount; + int vertexOffset; + uint64 regs, numRegs; + uint64 prim; + int ind; + + vec3fNormalize(lightdir); + + if (m->attribs & MESHATTR_INDEXED) + vertexCount = m->indexCount; + else + vertexCount = m->vertexCount; + blockCount = vertexCount/39 + ((vertexCount%39) ? 1 : 0); + + regs = 0x5; // XYZ + numRegs = 1; + if (m->attribs & MESHATTR_COLORS || m->attribs & MESHATTR_NORMALS) { + regs = (regs << 4) | 0x1; // RGBAQ + numRegs++; + } + // TODO: texcoords and normals + + prim = MAKE_GS_PRIM(m->primitive,IIP_GOURAUD,0,0,0,0,0,0,0); + + vertexOffset = 0; + for (i = 0; i < blockCount; i++) { + blockVertCount = 39; + if (i == blockCount-1) { + blockVertCount = vertexCount % 39; + if (blockVertCount == 0) + blockVertCount = 39; + } + + if (m->primitive == PRIM_TRI_STRIP && vertexOffset > 0) { + vertexOffset -= 2; + blockVertCount += 2; + } + + GIF_BEGIN_PACKET(meshGifBuf); + GIF_TAG(meshGifBuf,blockVertCount,1,1,prim,0,numRegs,regs); + for (j = 0; j < blockVertCount; j++) { + if (m->attribs & MESHATTR_INDEXED) + ind = m->indices[j + vertexOffset]; + else + ind = j + vertexOffset; + vec4fCopy(vf, m->vertices[ind]); + vf[3] = 1.0f; + + matMultVec(mathModelViewMat, vf); + matMultVec(mathProjectionMat, vf); + vf[0] /= vf[3]; + vf[1] /= vf[3]; + vf[2] /= vf[3]; + + gsNormalizedToScreen(vf, vi); + + vi[0] = ((vi[0]*16) + g->xoff) & 0xFFFF; + vi[1] = ((vi[1]*16) + g->yoff) & 0xFFFF; + + if (m->attribs & MESHATTR_COLORS) { + c[0] = m->colors[ind][0]; + c[1] = m->colors[ind][1]; + c[2] = m->colors[ind][2]; + c[3] = m->colors[ind][3]; + + GIF_DATA_RGBAQ(meshGifBuf,c[0],c[1],c[2],c[3]); + } else if (m->attribs & MESHATTR_NORMALS) { + vec4fCopy(n, m->normals[ind]); + + matMultVec(mathNormalMat, n); + vec3fNormalize(n); + intens = vec3fDot(n, lightdir); + intens = intens > 0.0f ? intens : 0.0f; + + c[0] = intens * 255.0f; + c[1] = intens * 0.0f; + c[2] = intens * 255.0f; + c[3] = 128.0f; + + GIF_DATA_RGBAQ(meshGifBuf,c[0],c[1],c[2],c[3]); + } + GIF_DATA_XYZ2(meshGifBuf,vi[0],vi[1],vi[2],0); + } + + GIF_SEND_PACKET(meshGifBuf); + vertexOffset += blockVertCount; + } +} diff --git a/tests/ps2/mesh.h b/tests/ps2/mesh.h new file mode 100755 index 0000000..b83ebe8 --- /dev/null +++ b/tests/ps2/mesh.h @@ -0,0 +1,43 @@ +#ifndef MESH_H +#define MESH_H + +#include "ps2.h" +#include "math.h" + +enum meshAttribs { + MESHATTR_VERTICES = 0x1, + MESHATTR_NORMALS = 0x2, + MESHATTR_COLORS = 0x4, + MESHATTR_TEXCOORDS = 0x8, + MESHATTR_INDEXED = 0x10 +}; + +typedef struct Mesh Mesh; +struct Mesh { +/* + Vector3f *vertices; + Vector3f *normals; + Vector4b *colors; + Vector2f *texCoords; +*/ + int primitive; + enum meshAttribs attribs; + + int vertexCount; + float **vertices; + float **normals; + uint8 **colors; + float **texCoords; + + int indexCount; + int *indices; + +}; + +void meshDump(Mesh *m); +void meshDraw(Mesh *m); + +extern Mesh testmesh; +extern Mesh playermesh; + +#endif diff --git a/tests/ps2/mips_regs.h b/tests/ps2/mips_regs.h new file mode 100755 index 0000000..e5c311b --- /dev/null +++ b/tests/ps2/mips_regs.h @@ -0,0 +1,40 @@ +#ifndef MIPS_MIPS_REGS_H +#define REGS_H + +/* + * MIPS Registers + */ + +#define zero $0 +#define at $1 +#define v0 $2 +#define v1 $3 +#define a0 $4 +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define s0 $16 +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 +#define t9 $25 +#define k0 $26 +#define k1 $27 +#define gp $28 +#define sp $29 +#define fp $30 +#define ra $31 +#endif diff --git a/tests/ps2/ps2.h b/tests/ps2/ps2.h new file mode 100755 index 0000000..b5bacc7 --- /dev/null +++ b/tests/ps2/ps2.h @@ -0,0 +1,35 @@ +#ifndef PS2_H +#define PS2_H + +typedef char int8; +typedef short int16; +typedef int int32; +typedef long int64; +typedef int int128 __attribute__ ((mode (TI))); + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef unsigned long uint64; +typedef unsigned int uint128 __attribute__ ((mode (TI))); + +#define BIT32(a,b) \ + ((uint32) (a) << (b)) + +#define BIT64(a,b) \ + ((uint64) (a) << (b)) + +#define BIT128(a,b) \ + ((uint128) (a) << (b)) +/* +#ifndef NULL + #define NULL ((void *)0) +#endif + +#define FALSE 0 +#define TRUE (!FALSE) +*/ + +#define FTOI4(x) ((int16)(x)*16.0f) + +#endif diff --git a/tests/ps2/skinpipe.dsm b/tests/ps2/skinpipe.dsm new file mode 100644 index 0000000..440997d --- /dev/null +++ b/tests/ps2/skinpipe.dsm @@ -0,0 +1,91 @@ +.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 lightDir, 0x3d0 +.equ matrix, 0x3f0 +.equ screenOffset, 0x3f9 +.equ gifTag, 0x3fa +.equ matColor, 0x3fb +.equ ambientLight, 0x3fd + +.balign 16,0 +skinPipe: +DMAret * +MPG 0, * +.vu +Start: + NOP LQ VF25, screenOffset(VI00) + NOP LQ VF28, matrix(VI00) + NOP LQ VF29, matrix+1(VI00) + NOP LQ VF30, matrix+2(VI00) + NOP LQ VF31, matrix+3(VI00) + NOP IADDIU VI12, VI00, outBuf1 + NOP IADDIU VI13, VI00, outBuf2 +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 + +Loop: + NOP LQI VF01, (VI02++) ; vertex + NOP LQI VF02, (VI02++) ; UV - skip + NOP LQI VF02, (VI02++) ; color + NOP LQI VF03, (VI02++) ; normal + NOP IADDIU VI02, VI02, 1 ; skip weights + + MULAw.xyzw ACC, VF31, VF00w NOP + MADDAx.xyzw ACC, VF28, VF01x NOP + MADDAy.xyzw ACC, VF29, VF01y NOP + MADDz.xyzw VF01, VF30, VF01z NOP + ITOF0 VF02, VF02 NOP + ITOF0[I] VF03, VF03 LOI 0.0078125 ; - normal scale + NOP NOP + NOP DIV Q, VF00w, VF01w + NOP WAITQ + MULq VF01, VF01, Q NOP ; perspective division + MULi VF03, VF03, I NOP ; scale normal + NOP NOP + NOP NOP + SUB.w VF01, VF01, VF01 NOP + NOP SQ VF03, -2(VI02) ; store scaled normal + NOP NOP + NOP NOP + ADD.xy VF01, VF01, VF25 NOP + NOP NOP + NOP NOP + FTOI0 VF02, VF02 NOP + FTOI4 VF01, VF01 NOP + NOP NOP + NOP IADDI VI01, VI01, -1 + NOP SQI VF02, (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/tests/ps2/vu.dsm b/tests/ps2/vu.dsm new file mode 100644 index 0000000..2cf83e5 --- /dev/null +++ b/tests/ps2/vu.dsm @@ -0,0 +1,57 @@ +.data +.global MyDmaPacket +.global vuMat +.global vuOffset +.global vuGIFtag +.global vuMatcolor +.global vuSurfProps +.global mpgCall +.global geometryCall + +.align 4 + +MyDmaPacket: +DMAcnt * +.EndDmaData + +mpgCall: +DMAcall *, 0 ;vuProg +.EndDmaData + +DMAcnt * + UNPACK 4, 4, V4_32, 0x3d0, * +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, 0x3f9, * +vuOffset: + .float 0.0, 0.0, 0.0, 0.0 +vuGIFtag: + .int 0x00008000, 0x2005C000, 0x0000000041, 0x00000000 +vuMatcolor: + .float 1.0, 1.0, 1.0, 0.5 +vuSurfProps: + .float 1.0, 1.0, 1.0, 1.0 +; .float 160, 160, 160, 0 ; some ambient light + .float 20, 20, 20, 0 ; some ambient light +; .float 0, 0, 0, 0 + .EndUnpack +.EndDmaData + +geometryCall: +DMAcall *, 0 ;vuGeometry + BASE 0 + OFFSET 0x0 +.EndDmaData + +DMAend +