Added PS2 test.

This commit is contained in:
Angelo Papenhoff 2015-01-18 19:35:23 +01:00
parent fc40bbdffe
commit 8cd30a4dfd
23 changed files with 2385 additions and 1 deletions

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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).

39
tests/ps2/Makefile Executable file
View File

@ -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)

14
tests/ps2/README.md Normal file
View File

@ -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.

90
tests/ps2/defaultpipe.dsm Normal file
View File

@ -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

60
tests/ps2/dma.cpp Executable file
View File

@ -0,0 +1,60 @@
#include <stdio.h>
#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));
}

131
tests/ps2/dma.h Executable file
View File

@ -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

204
tests/ps2/ee_regs.h Executable file
View File

@ -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

63
tests/ps2/gif.h Executable file
View File

@ -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

321
tests/ps2/gs.cpp Executable file
View File

@ -0,0 +1,321 @@
#include <kernel.h>
#include <stdio.h>
#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);
}
*/

484
tests/ps2/gs.h Executable file
View File

@ -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

94
tests/ps2/light.vu Normal file
View File

@ -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

202
tests/ps2/main.cpp Executable file
View File

@ -0,0 +1,202 @@
#include <fstream>
#include <stdio.h>
#include "ps2.h"
#include "dma.h"
#include "gif.h"
#include "gs.h"
#include "math.h"
#include "mesh.h"
#include <rw.h>
#include <src/gtaplg.h>
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;
}

238
tests/ps2/math.cpp Executable file
View File

@ -0,0 +1,238 @@
#include <stdio.h>
#include <math.h>
#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);
}

37
tests/ps2/math.h Executable file
View File

@ -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

135
tests/ps2/mesh.cpp Executable file
View File

@ -0,0 +1,135 @@
#include <kernel.h>
#include <stdio.h>
#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;
}
}

43
tests/ps2/mesh.h Executable file
View File

@ -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

40
tests/ps2/mips_regs.h Executable file
View File

@ -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

35
tests/ps2/ps2.h Executable file
View File

@ -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

91
tests/ps2/skinpipe.dsm Normal file
View File

@ -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

57
tests/ps2/vu.dsm Normal file
View File

@ -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