mirror of
https://github.com/iCatButler/pcsxr.git
synced 2024-06-02 19:27:44 -04:00
Initial upload of PGXP.
This commit is contained in:
parent
106f6594c9
commit
7767ea4acb
|
@ -19,6 +19,7 @@
|
|||
#include "psxhw.h"
|
||||
#include "gpu.h"
|
||||
#include "psxdma.h"
|
||||
#include "pgxp_gte.h"
|
||||
|
||||
#define GPUSTATUS_ODDLINES 0x80000000
|
||||
#define GPUSTATUS_DMABITS 0x60000000 // Two bits
|
||||
|
@ -142,6 +143,7 @@ void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU
|
|||
#endif
|
||||
break;
|
||||
}
|
||||
GPU_pgxpMemory(madr, PGXP_GetMem());
|
||||
GPU_writeDataMem(ptr, size);
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "gte.h"
|
||||
#include "psxmem.h"
|
||||
#include "pgxp_gte.h"
|
||||
|
||||
#define GTE_SF(op) ((op >> 19) & 1)
|
||||
#define GTE_MX(op) ((op >> 17) & 3)
|
||||
|
@ -251,6 +252,7 @@ static void CTC2(u32 value, int reg) {
|
|||
void gteMFC2() {
|
||||
if (!_Rt_) return;
|
||||
psxRegs.GPR.r[_Rt_] = MFC2(_Rd_);
|
||||
PGXP_MFC2(_Rt_, _Rd_, psxRegs.CP2D.p[_Rd_].d);
|
||||
}
|
||||
|
||||
void gteCFC2() {
|
||||
|
@ -259,6 +261,7 @@ void gteCFC2() {
|
|||
}
|
||||
|
||||
void gteMTC2() {
|
||||
PGXP_MTC2(_Rt_, _Rd_, psxRegs.GPR.p[_Rt_].d);
|
||||
MTC2(psxRegs.GPR.r[_Rt_], _Rd_);
|
||||
}
|
||||
|
||||
|
@ -269,11 +272,15 @@ void gteCTC2() {
|
|||
#define _oB_ (psxRegs.GPR.r[_Rs_] + _Imm_)
|
||||
|
||||
void gteLWC2() {
|
||||
MTC2(psxMemRead32(_oB_), _Rt_);
|
||||
u32 val = psxMemRead32(_oB_);
|
||||
PGXP_LWC2(_oB_, _Rt_, val);
|
||||
MTC2(val, _Rt_);
|
||||
}
|
||||
|
||||
void gteSWC2() {
|
||||
psxMemWrite32(_oB_, MFC2(_Rt_));
|
||||
u32 val = MFC2(_Rt_);
|
||||
PGXP_SWC2(_oB_, _Rt_, val);
|
||||
psxMemWrite32(_oB_, val);
|
||||
}
|
||||
|
||||
inline s64 gte_shift(s64 a, int sf) {
|
||||
|
@ -490,10 +497,9 @@ int docop2(int op) {
|
|||
SX2 = Lm_G1(F((s64) OFX + ((s64) IR1 * h_over_sz3) * (Config.Widescreen ? 0.75 : 1)) >> 16);
|
||||
SY2 = Lm_G2(F((s64) OFY + ((s64) IR2 * h_over_sz3)) >> 16);
|
||||
|
||||
GPU_addVertex(SX2, SY2,
|
||||
Lm_G1_ia((s64) OFX + (s64)(IR1 * h_over_sz3) * (Config.Widescreen ? 0.75 : 1)),
|
||||
Lm_G2_ia((s64) OFY + (s64)(IR2 * h_over_sz3)),
|
||||
((s64)SZ3));
|
||||
PGXP_pushSXYZ2s(Lm_G1_ia((s64)OFX + (s64)(IR1 * h_over_sz3) * (Config.Widescreen ? 0.75 : 1)),
|
||||
Lm_G2_ia((s64)OFY + (s64)(IR2 * h_over_sz3)),
|
||||
SZ3);
|
||||
|
||||
MAC0 = F((s64) DQB + ((s64) DQA * h_over_sz3));
|
||||
IR0 = Lm_H(m_mac0, 1);
|
||||
|
@ -503,8 +509,10 @@ int docop2(int op) {
|
|||
#ifdef GTE_LOG
|
||||
GTELOG("%08x NCLIP", op);
|
||||
#endif
|
||||
|
||||
MAC0 = F((s64) (SX0 * SY1) + (SX1 * SY2) + (SX2 * SY0) - (SX0 * SY2) - (SX1 * SY0) - (SX2 * SY1));
|
||||
if (PGXP_NLCIP_valid())
|
||||
MAC0 = F(PGXP_NCLIP());
|
||||
else
|
||||
MAC0 = F((s64) (SX0 * SY1) + (SX1 * SY2) + (SX2 * SY0) - (SX0 * SY2) - (SX1 * SY0) - (SX2 * SY1));
|
||||
return 1;
|
||||
|
||||
case 0x0c:
|
||||
|
@ -879,10 +887,9 @@ int docop2(int op) {
|
|||
SX2 = Lm_G1(F((s64) OFX + ((s64) IR1 * h_over_sz3) * (Config.Widescreen ? 0.75 : 1)) >> 16);
|
||||
SY2 = Lm_G2(F((s64) OFY + ((s64) IR2 * h_over_sz3)) >> 16);
|
||||
|
||||
GPU_addVertex(SX2, SY2,
|
||||
Lm_G1_ia((s64) OFX + (s64)(IR1 * h_over_sz3) * (Config.Widescreen ? 0.75 : 1)),
|
||||
Lm_G2_ia((s64) OFY + (s64)(IR2 * h_over_sz3)),
|
||||
((s64)SZ3));
|
||||
PGXP_pushSXYZ2s(Lm_G1_ia((s64)OFX + (s64)(IR1 * h_over_sz3) * (Config.Widescreen ? 0.75 : 1)),
|
||||
Lm_G2_ia((s64)OFY + (s64)(IR2 * h_over_sz3)),
|
||||
SZ3);
|
||||
}
|
||||
|
||||
MAC0 = F((s64) DQB + ((s64) DQA * h_over_sz3));
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "ix86.h"
|
||||
#include <sys/mman.h>
|
||||
#include "pgxp_gte.h"
|
||||
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
|
@ -1546,14 +1547,15 @@ static void recLW() {
|
|||
// SysPrintf("unhandled r32 %x\n", addr);
|
||||
}
|
||||
|
||||
PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode
|
||||
iPushOfB();
|
||||
CALLFunc((u32)psxMemRead32);
|
||||
CALLFunc((u32)PGXP_psxMemRead32Trace);
|
||||
if (_Rt_) {
|
||||
iRegs[_Rt_].state = ST_UNK;
|
||||
MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
|
||||
}
|
||||
// ADD32ItoR(ESP, 4);
|
||||
resp+= 4;
|
||||
resp+= 8;
|
||||
}
|
||||
|
||||
extern u32 LWL_MASK[4];
|
||||
|
@ -1601,12 +1603,13 @@ void recLWL() {
|
|||
if (_Imm_) ADD32ItoR(EAX, _Imm_);
|
||||
}
|
||||
PUSH32R (EAX);
|
||||
PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode
|
||||
AND32ItoR(EAX, ~3);
|
||||
PUSH32R (EAX);
|
||||
CALLFunc((u32)psxMemRead32);
|
||||
CALLFunc((u32)PGXP_psxMemRead32Trace);
|
||||
|
||||
if (_Rt_) {
|
||||
ADD32ItoR(ESP, 4);
|
||||
ADD32ItoR(ESP, 8);
|
||||
POP32R (EDX);
|
||||
AND32ItoR(EDX, 0x3); // shift = addr & 3;
|
||||
|
||||
|
@ -1629,7 +1632,7 @@ void recLWL() {
|
|||
MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
|
||||
} else {
|
||||
// ADD32ItoR(ESP, 8);
|
||||
resp+= 8;
|
||||
resp+= 12;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1756,12 +1759,13 @@ void recLWR() {
|
|||
if (_Imm_) ADD32ItoR(EAX, _Imm_);
|
||||
}
|
||||
PUSH32R (EAX);
|
||||
PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode
|
||||
AND32ItoR(EAX, ~3);
|
||||
PUSH32R (EAX);
|
||||
CALLFunc((u32)psxMemRead32);
|
||||
CALLFunc((u32)PGXP_psxMemRead32Trace);
|
||||
|
||||
if (_Rt_) {
|
||||
ADD32ItoR(ESP, 4);
|
||||
ADD32ItoR(ESP, 8);
|
||||
POP32R (EDX);
|
||||
AND32ItoR(EDX, 0x3); // shift = addr & 3;
|
||||
|
||||
|
@ -1785,7 +1789,7 @@ void recLWR() {
|
|||
MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
|
||||
} else {
|
||||
// ADD32ItoR(ESP, 8);
|
||||
resp+= 8;
|
||||
resp+= 12;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1978,15 +1982,16 @@ static void recSW() {
|
|||
// SysPrintf("unhandled w32 %x\n", addr);
|
||||
}
|
||||
|
||||
PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode
|
||||
if (IsConst(_Rt_)) {
|
||||
PUSH32I (iRegs[_Rt_].k);
|
||||
} else {
|
||||
PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]);
|
||||
}
|
||||
iPushOfB();
|
||||
CALLFunc((u32)psxMemWrite32);
|
||||
CALLFunc((u32)PGXP_psxMemWrite32Trace);
|
||||
// ADD32ItoR(ESP, 8);
|
||||
resp+= 8;
|
||||
resp+= 12;
|
||||
}
|
||||
//#endif
|
||||
|
||||
|
@ -2104,12 +2109,13 @@ void recSWL() {
|
|||
if (_Imm_) ADD32ItoR(EAX, _Imm_);
|
||||
}
|
||||
PUSH32R (EAX);
|
||||
PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode
|
||||
AND32ItoR(EAX, ~3);
|
||||
PUSH32R (EAX);
|
||||
|
||||
CALLFunc((u32)psxMemRead32);
|
||||
CALLFunc((u32)PGXP_psxMemRead32Trace);
|
||||
|
||||
ADD32ItoR(ESP, 4);
|
||||
ADD32ItoR(ESP, 8);
|
||||
POP32R (EDX);
|
||||
AND32ItoR(EDX, 0x3); // shift = addr & 3;
|
||||
|
||||
|
@ -2126,6 +2132,8 @@ void recSWL() {
|
|||
}
|
||||
SHR32CLtoR(EDX); // _rRt_ >> SWL_SHIFT[shift]
|
||||
|
||||
PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode
|
||||
|
||||
OR32RtoR (EAX, EDX);
|
||||
PUSH32R (EAX);
|
||||
|
||||
|
@ -2137,9 +2145,9 @@ void recSWL() {
|
|||
AND32ItoR(EAX, ~3);
|
||||
PUSH32R (EAX);
|
||||
|
||||
CALLFunc((u32)psxMemWrite32);
|
||||
CALLFunc((u32)PGXP_psxMemWrite32Trace);
|
||||
// ADD32ItoR(ESP, 8);
|
||||
resp+= 8;
|
||||
resp+= 12;
|
||||
}
|
||||
|
||||
extern u32 SWR_MASK[4];
|
||||
|
@ -2186,12 +2194,13 @@ void recSWR() {
|
|||
if (_Imm_) ADD32ItoR(EAX, _Imm_);
|
||||
}
|
||||
PUSH32R (EAX);
|
||||
PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode
|
||||
AND32ItoR(EAX, ~3);
|
||||
PUSH32R (EAX);
|
||||
|
||||
CALLFunc((u32)psxMemRead32);
|
||||
CALLFunc((u32)PGXP_psxMemRead32Trace);
|
||||
|
||||
ADD32ItoR(ESP, 4);
|
||||
ADD32ItoR(ESP, 8);
|
||||
POP32R (EDX);
|
||||
AND32ItoR(EDX, 0x3); // shift = addr & 3;
|
||||
|
||||
|
@ -2208,6 +2217,8 @@ void recSWR() {
|
|||
}
|
||||
SHL32CLtoR(EDX); // _rRt_ << SWR_SHIFT[shift]
|
||||
|
||||
PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode
|
||||
|
||||
OR32RtoR (EAX, EDX);
|
||||
PUSH32R (EAX);
|
||||
|
||||
|
@ -2219,9 +2230,9 @@ void recSWR() {
|
|||
AND32ItoR(EAX, ~3);
|
||||
PUSH32R (EAX);
|
||||
|
||||
CALLFunc((u32)psxMemWrite32);
|
||||
CALLFunc((u32)PGXP_psxMemWrite32Trace);
|
||||
// ADD32ItoR(ESP, 8);
|
||||
resp += 8;
|
||||
resp += 12;
|
||||
}
|
||||
|
||||
/*REC_FUNC(SLL);
|
||||
|
|
437
libpcsxcore/pgxp_gte.c
Normal file
437
libpcsxcore/pgxp_gte.c
Normal file
|
@ -0,0 +1,437 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2016 by iCatButler *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
|
||||
***************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* pgxp_gte.c
|
||||
* PGXP - Parallel/Precision Geometry Xform Pipeline
|
||||
*
|
||||
* Created on: 12 Mar 2016
|
||||
* Author: iCatButler
|
||||
***************************************************************************/
|
||||
|
||||
#include "pgxp_gte.h"
|
||||
#include "psxmem.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
unsigned int valid;
|
||||
unsigned int count;
|
||||
} precise_value;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
s16 x;
|
||||
s16 y;
|
||||
};
|
||||
u32 word;
|
||||
} low_value;
|
||||
|
||||
#define tolerance 1.0f
|
||||
|
||||
precise_value GTE_reg[32];
|
||||
precise_value CPU_reg[32];
|
||||
|
||||
precise_value Mem[2048 * 1024 / 4]; // mirror 2MB in 32-bit words
|
||||
precise_value Scratch[2048 * 1024 / 4]; // mirror 2MB in 32-bit words
|
||||
|
||||
void PGXP_Init()
|
||||
{
|
||||
memset(Mem, 0, sizeof(Mem));
|
||||
}
|
||||
|
||||
char* PGXP_GetMem()
|
||||
{
|
||||
return (char*)(Mem);
|
||||
}
|
||||
|
||||
#define VRAM 0
|
||||
#define SCRATCH 1
|
||||
|
||||
precise_value* ReadMem(u32 addr)
|
||||
{
|
||||
u32 memType;
|
||||
uint32_t paddr = addr;
|
||||
int* ip = NULL;
|
||||
|
||||
switch (paddr >> 20)
|
||||
{
|
||||
case 0x800:
|
||||
case 0x801:
|
||||
case 0xa00:
|
||||
case 0xa01:
|
||||
case 0x000:
|
||||
case 0x001:
|
||||
memType = VRAM;
|
||||
break;
|
||||
case 0x1f8:
|
||||
memType = SCRATCH;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef GTE_LOG
|
||||
//GTE_LOG("PGXP_Read %x [%x] |", addr, paddr);
|
||||
#endif
|
||||
if (memType == VRAM)
|
||||
{
|
||||
paddr = (paddr & 0x1FFFFF) >> 2;
|
||||
return &Mem[paddr];
|
||||
}
|
||||
else if (memType == SCRATCH)
|
||||
{
|
||||
paddr = (paddr & 0x1FFFFF) >> 2;
|
||||
return &Scratch[paddr];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void WriteMem(precise_value value, u32 addr)
|
||||
{
|
||||
u32 memType;
|
||||
uint32_t paddr = addr;
|
||||
int* ip = NULL;
|
||||
|
||||
switch (paddr >> 20)
|
||||
{
|
||||
case 0x800:
|
||||
case 0x801:
|
||||
case 0xa00:
|
||||
case 0xa01:
|
||||
case 0x000:
|
||||
case 0x001:
|
||||
memType = VRAM;
|
||||
break;
|
||||
case 0x1f8:
|
||||
memType = SCRATCH;
|
||||
break;
|
||||
default:
|
||||
if (value.valid)
|
||||
*ip = 5;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef GTE_LOG
|
||||
GTE_LOG("PGXP_Write %x [%x] |", addr, paddr);
|
||||
#endif
|
||||
|
||||
// Store to RAM
|
||||
if (memType == VRAM)
|
||||
{
|
||||
paddr = (paddr & 0x1FFFFF) >> 2;
|
||||
Mem[paddr] = value;
|
||||
}
|
||||
else if (memType == SCRATCH)
|
||||
{
|
||||
paddr = (paddr & 0x1FFFFF) >> 2;// (paddr & 0x3FFF) >> 2;
|
||||
Scratch[paddr] = value;
|
||||
}
|
||||
}
|
||||
|
||||
#define SX0 (GTE_reg[ 12 ].x)
|
||||
#define SY0 (GTE_reg[ 12 ].y)
|
||||
#define SX1 (GTE_reg[ 13 ].x)
|
||||
#define SY1 (GTE_reg[ 13 ].y)
|
||||
#define SX2 (GTE_reg[ 14 ].x)
|
||||
#define SY2 (GTE_reg[ 14 ].y)
|
||||
|
||||
#define SXY0 (GTE_reg[ 12 ])
|
||||
#define SXY1 (GTE_reg[ 13 ])
|
||||
#define SXY2 (GTE_reg[ 14 ])
|
||||
#define SXYP (GTE_reg[ 15 ])
|
||||
|
||||
unsigned int PGXP_validate(float high, s16 low)
|
||||
{
|
||||
if (fabs(high - (float)(low)) < tolerance)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check that value is still within tolerance of low precision value and invalidate if not
|
||||
precise_value PGXP_validateXY(precise_value *high, u32 low)
|
||||
{
|
||||
low_value temp;
|
||||
precise_value ret;
|
||||
|
||||
ret.valid = 0;
|
||||
temp.word = low;
|
||||
|
||||
if (!high)
|
||||
return ret;
|
||||
|
||||
high->valid = (high->valid && PGXP_validate(high->x, temp.x) && PGXP_validate(high->y, temp.y));
|
||||
|
||||
// Cheat
|
||||
//if (!high->valid)
|
||||
//{
|
||||
// high->x = temp.x;
|
||||
// high->y = temp.y;
|
||||
// high->valid = 1;
|
||||
//}
|
||||
|
||||
return *high;
|
||||
}
|
||||
|
||||
u32 PGXP_compareXY(precise_value high, u32 low)
|
||||
{
|
||||
low_value temp;
|
||||
temp.word = low;
|
||||
|
||||
if (PGXP_validate(high.x, temp.x) && PGXP_validate(high.y, temp.y))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
precise_value PGXP_copyXY(u32 low)
|
||||
{
|
||||
low_value temp;
|
||||
precise_value ret;
|
||||
|
||||
ret.valid = 0;
|
||||
temp.word = low;
|
||||
|
||||
ret.x = temp.x;
|
||||
ret.y = temp.y;
|
||||
ret.count = 0;
|
||||
ret.valid = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PGXP_pushSXYZ2f(float _x, float _y, float _z)
|
||||
{
|
||||
static unsigned int uCount = 0;
|
||||
// push values down FIFO
|
||||
SXY0 = SXY1;
|
||||
SXY1 = SXY2;
|
||||
|
||||
SXY2.x = _x;
|
||||
SXY2.y = _y;
|
||||
SXY2.z = _z;
|
||||
SXY2.valid = 1;
|
||||
SXY2.count = uCount++;
|
||||
|
||||
#ifdef GTE_LOG
|
||||
GTE_LOG("PGPR_PUSH (%f, %f) %u %u|", SXY2.x, SXY2.y, SXY2.valid, SXY2.count);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PGXP_pushSXYZ2s(s64 _x, s64 _y, s64 _z)
|
||||
{
|
||||
float fx = (float)(_x) / (float)(1 << 16);
|
||||
float fy = (float)(_y) / (float)(1 << 16);
|
||||
float fz = (float)(_z);
|
||||
|
||||
PGXP_pushSXYZ2f(fx, fy, fz);
|
||||
}
|
||||
|
||||
int PGXP_NLCIP_valid()
|
||||
{
|
||||
if (SXY0.valid && SXY1.valid && SXY2.valid)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
float PGXP_NCLIP()
|
||||
{
|
||||
float nclip = ((SX0 * SY1) + (SX1 * SY2) + (SX2 * SY0) - (SX0 * SY2) - (SX1 * SY0) - (SX2 * SY1));
|
||||
|
||||
// ensure fractional values are not incorrectly rounded to 0
|
||||
if (fabs(nclip) < 1.0f)
|
||||
nclip += (nclip < 0.f ? -2 : 2);
|
||||
|
||||
return nclip;
|
||||
}
|
||||
|
||||
static precise_value PGXP_MFC2_int(u32 reg)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 15:
|
||||
GTE_reg[reg] = SXYP = SXY2;
|
||||
break;
|
||||
}
|
||||
|
||||
return GTE_reg[reg];
|
||||
}
|
||||
|
||||
|
||||
static void PGXP_MTC2_int(precise_value value, u32 reg)
|
||||
{
|
||||
switch(reg)
|
||||
{
|
||||
case 15:
|
||||
// push FIFO
|
||||
SXY0 = SXY1;
|
||||
SXY1 = SXY2;
|
||||
SXY2 = value;
|
||||
SXYP = SXY2;
|
||||
break;
|
||||
|
||||
case 31:
|
||||
return;
|
||||
}
|
||||
|
||||
GTE_reg[reg] = value;
|
||||
}
|
||||
|
||||
// copy GTE data reg to GPR reg (MFC2)
|
||||
void PGXP_MFC2(u32 gpr, u32 gtr, u32 value)
|
||||
{
|
||||
if (!gpr) return;
|
||||
#ifdef GTE_LOG
|
||||
GTE_LOG("PGXP_MFC2 [%x] [%x] %x (%u %u)|", gpr, gtr, value, GTE_reg[gtr].valid, GTE_reg[gtr].count);
|
||||
#endif
|
||||
|
||||
CPU_reg[gpr] = PGXP_validateXY(>E_reg[gtr], value);
|
||||
}
|
||||
|
||||
// copy GPR reg to GTE data reg (MTC2)
|
||||
void PGXP_MTC2(u32 gpr, u32 gtr, u32 value)
|
||||
{
|
||||
#ifdef GTE_LOG
|
||||
GTE_LOG("PGXP_MTC2 [%x] [%x] %x (%u %u)|", gpr, gtr, value, CPU_reg[gtr].valid, CPU_reg[gtr].count);
|
||||
#endif
|
||||
PGXP_MTC2_int(PGXP_validateXY(&CPU_reg[gpr], value), gtr);
|
||||
}
|
||||
|
||||
// copy memory to GTE reg
|
||||
void PGXP_LWC2(u32 addr, u32 gtr, u32 value)
|
||||
{
|
||||
#ifdef GTE_LOG
|
||||
precise_value* pp = ReadMem(addr);
|
||||
precise_value p;
|
||||
low_value temp;
|
||||
temp.word = value;
|
||||
|
||||
p.x = p.y = p.valid = 0;
|
||||
|
||||
if (pp)
|
||||
p = *pp;
|
||||
|
||||
GTE_LOG("PGXP_LWC2 %x [%x] %x (%d, %d) (%f, %f) %u %u|", addr, gtr, value, temp.x, temp.y, p.x, p.y, p.valid, p.count);
|
||||
#endif
|
||||
PGXP_MTC2_int(PGXP_validateXY(ReadMem(addr), value), gtr);
|
||||
}
|
||||
|
||||
//copy GTE reg to memory
|
||||
void PGXP_SWC2(u32 addr, u32 gtr, u32 value)
|
||||
{
|
||||
#ifdef GTE_LOG
|
||||
low_value temp;
|
||||
temp.word = value;
|
||||
|
||||
if (PGXP_compareXY(GTE_reg[gtr], value))
|
||||
GTE_LOG("PGPR_SWC2 %x [%x] %x (%d, %d) (%f, %f) %u %u|", addr, gtr, value, temp.x, temp.y, GTE_reg[gtr].x, GTE_reg[gtr].y, GTE_reg[gtr].valid, GTE_reg[gtr].count);
|
||||
#endif
|
||||
WriteMem(PGXP_validateXY(>E_reg[gtr], value), addr);
|
||||
}
|
||||
|
||||
// ltore 32bit word
|
||||
void PGPR_L32(u32 addr, u32 code, u32 value)
|
||||
{
|
||||
u32 reg = ((code >> 16) & 0x1F); // The rt part of the instruction register
|
||||
u32 op = ((code >> 26));
|
||||
precise_value p;
|
||||
|
||||
low_value temp;
|
||||
temp.word = value;
|
||||
|
||||
p.x = p.y = p.valid = p.count = 0;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 34: //LWL
|
||||
CPU_reg[reg] = PGXP_validateXY(ReadMem(addr), value);
|
||||
break;
|
||||
case 35: //LW
|
||||
CPU_reg[reg] = PGXP_validateXY(ReadMem(addr), value);
|
||||
break;
|
||||
case 37: //LWR
|
||||
CPU_reg[reg] = PGXP_validateXY(ReadMem(addr), value);
|
||||
break;
|
||||
case 50: //LWC2 (GTE vertex reads)
|
||||
GTE_reg[reg] = PGXP_validateXY(ReadMem(addr), value);
|
||||
break;
|
||||
default:
|
||||
// invalidate register
|
||||
// WriteMem(p, addr);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef GTE_LOG
|
||||
GTE_LOG("PGPR_L32 %u: %x %x[%x %x] (%d, %d) (%f, %f) %x %u|", op, addr, value, code, reg, temp.x, temp.y, CPU_reg[reg].x, CPU_reg[reg].y, CPU_reg[reg].valid, CPU_reg[reg].count);
|
||||
#endif
|
||||
}
|
||||
|
||||
// store 32bit word
|
||||
void PGPR_S32(u32 addr, u32 code, u32 value)
|
||||
{
|
||||
u32 reg = ((code >> 16) & 0x1F); // The rt part of the instruction register
|
||||
u32 op = ((code >> 26));
|
||||
precise_value p;
|
||||
|
||||
low_value temp;
|
||||
temp.word = value;
|
||||
|
||||
p.x = p.y = p.valid = p.count = 0;
|
||||
|
||||
#ifdef GTE_LOG
|
||||
GTE_LOG("PGPR_S32 %u: %x %x[%x %x] (%d, %d) (%f, %f) %x %u|", op, addr, value, code, reg, temp.x, temp.y, CPU_reg[reg].x, CPU_reg[reg].y, CPU_reg[reg].valid, CPU_reg[reg].count);
|
||||
#endif
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 42: //SWL
|
||||
WriteMem(PGXP_validateXY(&CPU_reg[reg], value), addr);
|
||||
break;
|
||||
case 43: //SW
|
||||
WriteMem(PGXP_validateXY(&CPU_reg[reg], value), addr);
|
||||
break;
|
||||
case 46: //SWR
|
||||
WriteMem(PGXP_validateXY(&CPU_reg[reg], value), addr);
|
||||
break;
|
||||
case 58: //SWC2 (GTE vertex writes)
|
||||
WriteMem(PGXP_validateXY(>E_reg[reg], value), addr);
|
||||
break;
|
||||
default:
|
||||
// invalidate memory
|
||||
// WriteMem(p, addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u32 PGXP_psxMemRead32Trace(u32 mem, u32 code)
|
||||
{
|
||||
u32 value = psxMemRead32(mem);
|
||||
PGPR_L32(mem, code, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void PGXP_psxMemWrite32Trace(u32 mem, u32 value, u32 code)
|
||||
{
|
||||
PGPR_S32(mem, code, value);
|
||||
psxMemWrite32(mem, value);
|
||||
}
|
58
libpcsxcore/pgxp_gte.h
Normal file
58
libpcsxcore/pgxp_gte.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2016 by iCatButler *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
|
||||
***************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* pgxp_gte.h
|
||||
* PGXP - Parallel/Precision Geometry Xform Pipeline
|
||||
*
|
||||
* Created on: 12 Mar 2016
|
||||
* Author: iCatButler
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _PGXP_GTE_H_
|
||||
#define _PGXP_GTE_H_
|
||||
|
||||
#include "psxcommon.h"
|
||||
|
||||
void PGXP_Init(); // initialise memory
|
||||
char* PGXP_GetMem(); // return pointer to precision memory
|
||||
|
||||
// -- GTE functions
|
||||
// Transforms
|
||||
void PGXP_pushSXYZ2f(float _x, float _y, float _z);
|
||||
void PGXP_pushSXYZ2s(s64 _x, s64 _y, s64 _z);
|
||||
int PGXP_NLCIP_valid();
|
||||
float PGXP_NCLIP();
|
||||
|
||||
// Data transfer tracking
|
||||
void PGXP_MFC2(u32 gpr, u32 gtr, u32 value); // copy GTE reg to GPR reg (MFC2)
|
||||
void PGXP_MTC2(u32 gpr, u32 gtr, u32 value); // copy GPR reg to GTR reg (MTC2)
|
||||
void PGXP_LWC2(u32 addr, u32 gtr, u32 value); // copy memory to GTE reg
|
||||
void PGXP_SWC2(u32 addr, u32 gtr, u32 value); // copy GTE reg to memory
|
||||
|
||||
// -- CPU functions
|
||||
// Data transfer tracking
|
||||
void PGPR_L32(u32 addr, u32 code, u32 value); // load 32bit word
|
||||
void PGPR_S32(u32 addr, u32 code, u32 value); // store 32bit word
|
||||
|
||||
// Memory Read/Write hooks
|
||||
u32 PGXP_psxMemRead32Trace(u32 mem, u32 code);
|
||||
void PGXP_psxMemWrite32Trace(u32 mem, u32 value, u32 code);
|
||||
|
||||
#endif /* _PGXP_GTE_H_ */
|
|
@ -54,6 +54,7 @@ GPUvBlank GPU_vBlank;
|
|||
GPUvisualVibration GPU_visualVibration;
|
||||
GPUcursor GPU_cursor;
|
||||
GPUaddVertex GPU_addVertex;
|
||||
GPUpgxpMemory GPU_pgxpMemory;
|
||||
|
||||
CDRinit CDR_init;
|
||||
CDRshutdown CDR_shutdown;
|
||||
|
@ -214,6 +215,7 @@ void CALLBACK GPU__vBlank(int val) {}
|
|||
void CALLBACK GPU__visualVibration(unsigned long iSmall, unsigned long iBig) {}
|
||||
void CALLBACK GPU__cursor(int player, int x, int y) {}
|
||||
void CALLBACK GPU__addVertex(short sx,short sy,s64 fx,s64 fy,s64 fz) {}
|
||||
void CALLBACK GPU__pgxpMemory(unsigned char* pMem, unsigned int count, unsigned int addr, unsigned char* pVRAM) {}
|
||||
|
||||
#define LoadGpuSym1(dest, name) \
|
||||
LoadSym(GPU_##dest, GPU##dest, name, TRUE);
|
||||
|
@ -259,6 +261,7 @@ static int LoadGPUplugin(const char *GPUdll) {
|
|||
LoadGpuSym0(visualVibration, "GPUvisualVibration");
|
||||
LoadGpuSym0(cursor, "GPUcursor");
|
||||
LoadGpuSym0(addVertex, "GPUaddVertex");
|
||||
LoadGpuSym0(pgxpMemory, "GPUpgxpMemory");
|
||||
LoadGpuSym0(configure, "GPUconfigure");
|
||||
LoadGpuSym0(test, "GPUtest");
|
||||
LoadGpuSym0(about, "GPUabout");
|
||||
|
|
|
@ -96,6 +96,7 @@ typedef void (CALLBACK* GPUvBlank)(int);
|
|||
typedef void (CALLBACK* GPUvisualVibration)(uint32_t, uint32_t);
|
||||
typedef void (CALLBACK* GPUcursor)(int, int, int);
|
||||
typedef void (CALLBACK* GPUaddVertex)(short,short,s64,s64,s64);
|
||||
typedef void (CALLBACK* GPUpgxpMemory)(unsigned int, unsigned char*);
|
||||
|
||||
// GPU function pointers
|
||||
extern GPUupdateLace GPU_updateLace;
|
||||
|
@ -125,6 +126,7 @@ extern GPUvBlank GPU_vBlank;
|
|||
extern GPUvisualVibration GPU_visualVibration;
|
||||
extern GPUcursor GPU_cursor;
|
||||
extern GPUaddVertex GPU_addVertex;
|
||||
extern GPUpgxpMemory GPU_pgxpMemory;
|
||||
|
||||
// CD-ROM Functions
|
||||
typedef long (CALLBACK* CDRinit)(void);
|
||||
|
|
|
@ -44,6 +44,7 @@ int psxInit() {
|
|||
Log = 0;
|
||||
|
||||
if (psxMemInit() == -1) return -1;
|
||||
PGXP_Init();
|
||||
|
||||
return psxCpu->Init();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "menu.h"
|
||||
|
||||
#include "gte_accuracy.h"
|
||||
#include "pgxp_gpu.h"
|
||||
|
||||
#if defined(_MACGL)
|
||||
// if you use it, you must include it
|
||||
|
@ -943,7 +944,7 @@ void offsetline(void)
|
|||
#define VERTEX_OFFX 0.2f
|
||||
#define VERTEX_OFFY 0.2f
|
||||
|
||||
BOOL offsetline(void)
|
||||
BOOL offsetline(unsigned int* addr)
|
||||
{
|
||||
short x0,x1,y0,y1,dx,dy;float px,py;
|
||||
|
||||
|
@ -1004,6 +1005,8 @@ BOOL offsetline(void)
|
|||
else py= 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
PGXP_GetVertices(addr, vertex);
|
||||
|
||||
vertex[0].x=(short)((float)x0-px);
|
||||
vertex[3].x=(short)((float)x0+py);
|
||||
|
@ -1040,7 +1043,7 @@ BOOL offsetline(void)
|
|||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
BOOL offset2(void)
|
||||
BOOL offset2(unsigned int* addr)
|
||||
{
|
||||
if(bDisplayNotSet)
|
||||
SetOGLDisplaySettings(1);
|
||||
|
@ -1066,6 +1069,8 @@ BOOL offset2(void)
|
|||
vertex[1].y=ly1;
|
||||
}
|
||||
|
||||
PGXP_GetVertices(addr, vertex);
|
||||
|
||||
vertex[0].x+=PSXDisplay.CumulOffset.x;
|
||||
vertex[1].x+=PSXDisplay.CumulOffset.x;
|
||||
vertex[0].y+=PSXDisplay.CumulOffset.y;
|
||||
|
@ -1076,7 +1081,7 @@ BOOL offset2(void)
|
|||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
BOOL offset3(void)
|
||||
BOOL offset3(unsigned int* addr)
|
||||
{
|
||||
if(bDisplayNotSet)
|
||||
SetOGLDisplaySettings(1);
|
||||
|
@ -1109,6 +1114,8 @@ BOOL offset3(void)
|
|||
vertex[2].y=ly2;
|
||||
}
|
||||
|
||||
PGXP_GetVertices(addr, vertex);
|
||||
|
||||
vertex[0].x+=PSXDisplay.CumulOffset.x;
|
||||
vertex[1].x+=PSXDisplay.CumulOffset.x;
|
||||
vertex[2].x+=PSXDisplay.CumulOffset.x;
|
||||
|
@ -1121,7 +1128,7 @@ BOOL offset3(void)
|
|||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
BOOL offset4(void)
|
||||
BOOL offset4(unsigned int* addr)
|
||||
{
|
||||
if(bDisplayNotSet)
|
||||
SetOGLDisplaySettings(1);
|
||||
|
@ -1161,6 +1168,8 @@ BOOL offset4(void)
|
|||
vertex[3].y=ly3;
|
||||
}
|
||||
|
||||
PGXP_GetVertices(addr, vertex);
|
||||
|
||||
vertex[0].x+=PSXDisplay.CumulOffset.x;
|
||||
vertex[1].x+=PSXDisplay.CumulOffset.x;
|
||||
vertex[2].x+=PSXDisplay.CumulOffset.x;
|
||||
|
|
|
@ -35,10 +35,10 @@ BOOL bSetupPixelFormat(HDC hDC);
|
|||
|
||||
int GLinitialize();
|
||||
void GLcleanup();
|
||||
BOOL offset2(void);
|
||||
BOOL offset3(void);
|
||||
BOOL offset4(void);
|
||||
BOOL offsetline(void);
|
||||
BOOL offset2(unsigned int* addr);
|
||||
BOOL offset3(unsigned int* addr);
|
||||
BOOL offset4(unsigned int* addr);
|
||||
BOOL offsetline(unsigned int* addr);
|
||||
void offsetST(void);
|
||||
void offsetBlk(void);
|
||||
void offsetScreenUpload(int Position);
|
||||
|
|
|
@ -48,6 +48,7 @@ static int iOldMode=0;
|
|||
#include "fps.h"
|
||||
#include "key.h"
|
||||
#include "gte_accuracy.h"
|
||||
#include "PGXP_gpu.h"
|
||||
#ifdef _WINDOWS
|
||||
#include "resource.h"
|
||||
#include "ssave.h"
|
||||
|
@ -3145,7 +3146,11 @@ long CALLBACK GPUdmaChain(uint32_t *baseAddrL, uint32_t addr)
|
|||
|
||||
dmaMem=addr+4;
|
||||
|
||||
if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);
|
||||
if (count > 0)
|
||||
{
|
||||
PGXP_SetAddress(dmaMem >> 2);
|
||||
GPUwriteDataMem(&baseAddrL[dmaMem >> 2], count);
|
||||
}
|
||||
|
||||
addr = baseAddrL[addr>>2]&0xffffff;
|
||||
}
|
||||
|
|
|
@ -3105,7 +3105,7 @@ void primPolyF4(unsigned char *baseAddr)
|
|||
lx3 = sgpuData[8];
|
||||
ly3 = sgpuData[9];
|
||||
|
||||
if(offset4()) return;
|
||||
if(offset4(baseAddr)) return;
|
||||
|
||||
bDrawTextured = FALSE;
|
||||
bDrawSmoothShaded = FALSE;
|
||||
|
@ -3214,7 +3214,7 @@ void primPolyG4(unsigned char * baseAddr)
|
|||
lx3 = sgpuData[14];
|
||||
ly3 = sgpuData[15];
|
||||
|
||||
if(offset4()) return;
|
||||
if(offset4(baseAddr)) return;
|
||||
|
||||
bDrawTextured = FALSE;
|
||||
bDrawSmoothShaded = TRUE;
|
||||
|
@ -3430,7 +3430,7 @@ void primPolyFT3(unsigned char * baseAddr)
|
|||
lx2 = sgpuData[10];
|
||||
ly2 = sgpuData[11];
|
||||
|
||||
if(offset3()) return;
|
||||
if(offset3(baseAddr)) return;
|
||||
|
||||
// do texture UV coordinates stuff
|
||||
gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
|
||||
|
@ -3868,7 +3868,7 @@ void primPolyFT4(unsigned char * baseAddr)
|
|||
lx3 = sgpuData[14];
|
||||
ly3 = sgpuData[15];
|
||||
|
||||
if(offset4()) return;
|
||||
if(offset4(baseAddr)) return;
|
||||
|
||||
gl_vy[0]=baseAddr[9];//((gpuData[2]>>8)&0xff);
|
||||
gl_vy[1]=baseAddr[17];//((gpuData[4]>>8)&0xff);
|
||||
|
@ -3953,7 +3953,7 @@ void primPolyGT3(unsigned char *baseAddr)
|
|||
lx2 = sgpuData[14];
|
||||
ly2 = sgpuData[15];
|
||||
|
||||
if(offset3()) return;
|
||||
if(offset3(baseAddr)) return;
|
||||
|
||||
// do texture stuff
|
||||
gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
|
||||
|
@ -4062,7 +4062,7 @@ void primPolyG3(unsigned char *baseAddr)
|
|||
lx2 = sgpuData[10];
|
||||
ly2 = sgpuData[11];
|
||||
|
||||
if(offset3()) return;
|
||||
if(offset3(baseAddr)) return;
|
||||
|
||||
bDrawTextured = FALSE;
|
||||
bDrawSmoothShaded = TRUE;
|
||||
|
@ -4109,7 +4109,7 @@ void primPolyGT4(unsigned char *baseAddr)
|
|||
lx3 = sgpuData[20];
|
||||
ly3 = sgpuData[21];
|
||||
|
||||
if(offset4()) return;
|
||||
if(offset4(baseAddr)) return;
|
||||
|
||||
// do texture stuff
|
||||
gl_ux[0]=baseAddr[8];//gpuData[2]&0xff;
|
||||
|
@ -4227,7 +4227,7 @@ void primPolyF3(unsigned char *baseAddr)
|
|||
lx2 = sgpuData[6];
|
||||
ly2 = sgpuData[7];
|
||||
|
||||
if(offset3()) return;
|
||||
if(offset3(baseAddr)) return;
|
||||
|
||||
bDrawTextured = FALSE;
|
||||
bDrawSmoothShaded = FALSE;
|
||||
|
@ -4318,7 +4318,7 @@ void primLineGEx(unsigned char *baseAddr)
|
|||
ly1 = (short)((gpuData[i]>>16) & 0xffff);
|
||||
lx1 = (short)(gpuData[i] & 0xffff);
|
||||
|
||||
if(offsetline()) bDraw=FALSE; else bDraw=TRUE;
|
||||
if(offsetline(baseAddr)) bDraw=FALSE; else bDraw=TRUE;
|
||||
|
||||
if (bDraw && ((lx0 != lx1) || (ly0 != ly1)))
|
||||
{
|
||||
|
@ -4367,7 +4367,7 @@ void primLineG2(unsigned char *baseAddr)
|
|||
|
||||
if((lx0 == lx1) && (ly0 == ly1)) return;
|
||||
|
||||
if(offsetline()) return;
|
||||
if(offsetline(baseAddr)) return;
|
||||
|
||||
SetRenderState(gpuData[0]);
|
||||
SetRenderMode(gpuData[0], FALSE);
|
||||
|
@ -4445,7 +4445,7 @@ void primLineFEx(unsigned char *baseAddr)
|
|||
ly1 = (short)((gpuData[i]>>16) & 0xffff);
|
||||
lx1 = (short)(gpuData[i] & 0xffff);
|
||||
|
||||
if(!offsetline())
|
||||
if(!offsetline(baseAddr))
|
||||
{
|
||||
if(iOffscreenDrawing)
|
||||
{
|
||||
|
@ -4481,7 +4481,7 @@ void primLineF2(unsigned char *baseAddr)
|
|||
lx1 = sgpuData[4];
|
||||
ly1 = sgpuData[5];
|
||||
|
||||
if(offsetline()) return;
|
||||
if(offsetline(baseAddr)) return;
|
||||
|
||||
bDrawTextured = FALSE;
|
||||
bDrawSmoothShaded = FALSE;
|
||||
|
|
|
@ -199,6 +199,7 @@
|
|||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libpcsxcore\pgxp_gte.c" />
|
||||
<ClCompile Include="..\libpcsxcore\plugins.c">
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -418,6 +419,7 @@
|
|||
<ClInclude Include="..\libpcsxcore\gte_divider.h" />
|
||||
<ClInclude Include="..\libpcsxcore\mdec.h" />
|
||||
<ClInclude Include="..\libpcsxcore\misc.h" />
|
||||
<ClInclude Include="..\libpcsxcore\pgxp_gte.h" />
|
||||
<ClInclude Include="..\libpcsxcore\plugins.h" />
|
||||
<ClInclude Include="..\libpcsxcore\ppf.h" />
|
||||
<ClInclude Include="..\libpcsxcore\psemu_plugin_defs.h" />
|
||||
|
|
|
@ -192,6 +192,9 @@
|
|||
<ClCompile Include="zlib\zutil.c">
|
||||
<Filter>zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libpcsxcore\pgxp_gte.c">
|
||||
<Filter>libpcsxcore</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\libpcsxcore\cdriso.h">
|
||||
|
@ -355,6 +358,9 @@
|
|||
<ClInclude Include="zlib\zutil.h">
|
||||
<Filter>zlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libpcsxcore\pgxp_gte.h">
|
||||
<Filter>libpcsxcore</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="gui\about.bmp">
|
||||
|
|
|
@ -34,3 +34,4 @@ EXPORTS
|
|||
GPUsetframelimit @27
|
||||
GPUvisualVibration @28
|
||||
GPUaddVertex @29
|
||||
GPUpgxpMemory @30
|
||||
|
|
|
@ -152,6 +152,7 @@
|
|||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pgxp_gpu.c" />
|
||||
<ClCompile Include="winsrc\cfg.c">
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -221,6 +222,7 @@
|
|||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pgxp_gpu.h" />
|
||||
<ClInclude Include="winsrc\ssave.h" />
|
||||
<ClInclude Include="..\..\..\plugins\peopsxgl\cfg.h" />
|
||||
<ClInclude Include="..\..\..\plugins\peopsxgl\draw.h" />
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
<ClCompile Include="..\..\..\plugins\peopsxgl\texture.c">
|
||||
<Filter>peopsxgl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pgxp_gpu.c">
|
||||
<Filter>peopsxgl</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="winsrc\ssave.h">
|
||||
|
@ -90,6 +93,9 @@
|
|||
<Filter>peopsxgl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="pgxp_gpu.h">
|
||||
<Filter>peopsxgl</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="res\gpu.bmp" />
|
||||
|
|
90
win32/plugins/peopsxgl/pgxp_gpu.c
Normal file
90
win32/plugins/peopsxgl/pgxp_gpu.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2016 by iCatButler *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
|
||||
***************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* pgxp_gpu.c
|
||||
* PGXP - Parallel/Precision Geometry Xform Pipeline
|
||||
*
|
||||
* Created on: 25 Mar 2016
|
||||
* Author: iCatButler
|
||||
***************************************************************************/
|
||||
|
||||
#include "pgxp_gpu.h"
|
||||
#include "stdafx.h"
|
||||
#include "externals.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
unsigned int valid;
|
||||
unsigned int count;
|
||||
} PGXP_vertex;
|
||||
|
||||
const unsigned int primStrideTable[] = { 1, 2, 1, 2, 2, 3, 2, 3, 0 };
|
||||
const unsigned int primCountTable[] = { 3, 3, 4, 4, 3, 3, 4, 4, 0 };
|
||||
|
||||
PGXP_vertex* PGXP_Mem = NULL; // pointer to parallel memory
|
||||
unsigned int currentAddr = 0; // address of current DMA
|
||||
|
||||
// Set current DMA address and pointer to parallel memory
|
||||
void CALLBACK GPUpgxpMemory(unsigned int addr, unsigned char* pVRAM)
|
||||
{
|
||||
if (pVRAM)
|
||||
PGXP_Mem = (PGXP_vertex*)(pVRAM);
|
||||
currentAddr = addr;
|
||||
}
|
||||
|
||||
// Set current DMA address
|
||||
void PGXP_SetAddress(unsigned int addr)
|
||||
{
|
||||
currentAddr = addr;
|
||||
}
|
||||
|
||||
// Get parallel vertex values
|
||||
int PGXP_GetVertices(unsigned int* addr, void* pOutput)
|
||||
{
|
||||
unsigned int primCmd = ((*addr >> 24) & 0xff); // primitive command
|
||||
unsigned int primIdx = (primCmd - 0x20) >> 2; // index to primitive lookup
|
||||
OGLVertex* pVertex = (OGLVertex*)pOutput; // pointer to output vertices
|
||||
unsigned int stride = primStrideTable[primIdx]; // stride between vertices
|
||||
unsigned int count = primCountTable[primIdx]; // number of vertices
|
||||
PGXP_vertex* primStart = NULL; // pointer to first vertex
|
||||
|
||||
if (PGXP_Mem == NULL)
|
||||
return 0;
|
||||
|
||||
// Offset to start of primitive
|
||||
primStart = &PGXP_Mem[currentAddr + 1];
|
||||
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
{
|
||||
if (primStart[stride * i].valid)
|
||||
{
|
||||
pVertex[i].x = primStart[stride * i].x;
|
||||
pVertex[i].y = primStart[stride * i].y;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
34
win32/plugins/peopsxgl/pgxp_gpu.h
Normal file
34
win32/plugins/peopsxgl/pgxp_gpu.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2016 by iCatButler *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
|
||||
***************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* pgxp_gpu.h
|
||||
* PGXP - Parallel/Precision Geometry Xform Pipeline
|
||||
*
|
||||
* Created on: 25 Mar 2016
|
||||
* Author: iCatButler
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _PGXP_GPU_H_
|
||||
#define _PGXP_GPU_H_
|
||||
|
||||
void PGXP_SetAddress(unsigned int addr);
|
||||
int PGXP_GetVertices(unsigned int* addr, void* pOutput);
|
||||
|
||||
#endif // _PGXP_GPU_H_
|
Loading…
Reference in a new issue