Various CPU updates

- Sign extend values read using LH

- Add conversion functions to represent Signed/Unsigned 16-bit ranges
- Add overflow and truncation functions for 16-bit ranges

- Sign extend imm value in ADD(U)
- Add component overflow and truncation to ADD/SUB functions
- Construct new value in logic operators where result using inputs is undefined

- Return a valid W component from logic operators (if either input has one)

- Compare against high value (y), then low value (x) in less than operators

- Use doubles and implement overflow for Multiply operations to try to increase accuracy

- Use unsigned values in both MUL and DIV operations to make output as accurate as possible

- Implement several variants of shift operators. Trying both arithmetically correct and more analytical approaches with varying success.

Debug updates
- Added ability to force all values to be equal to low precision values before operating on them
- Added feature to test output of operations against a tolerance and print only those which fail

GPU updates
- Colour vertices with valid XY coordinates but no W as cyan to make them easier to spot
- Remove cyan colouring for stale vertices (wasn't useful)
- Added ability to skip debug rendering when needed (like seeing the output of offscreen rendering applied to a sprite).
- Added new mode which shows primitive type
This commit is contained in:
iCatButler 2016-07-30 17:43:12 +01:00
parent d5b40fbbe0
commit 69f33a4782
10 changed files with 1018 additions and 195 deletions

File diff suppressed because it is too large Load Diff

View File

@ -119,14 +119,14 @@ static PGXP_CPU_OpData PGXP_BSC_LUT[64] = {
#define PGXP_Data_DIVU { DBG_E_DIVU, fOp_CPU_Hi | fOp_CPU_Lo, fOp_CPU_Rs | fOp_CPU_Rt, 4, 4, "/", "DIVU", (void(*)())PGXP_CPU_DIVU }
// Shift operations (sa)
#define PGXP_Data_SLL { DBG_E_SLL, fOp_CPU_Rd, fOp_CPU_Rt | fOp_Sa, 2, 2, ">>", "SLL", (void(*)())PGXP_CPU_SLL }
#define PGXP_Data_SRL { DBG_E_SRL, fOp_CPU_Rd, fOp_CPU_Rt | fOp_Sa, 2, 2, "<<", "SRL", (void(*)())PGXP_CPU_SRL }
#define PGXP_Data_SRA { DBG_E_SRA, fOp_CPU_Rd, fOp_CPU_Rt | fOp_Sa, 2, 2, "<<", "SRA", (void(*)())PGXP_CPU_SRA }
#define PGXP_Data_SLL { DBG_E_SLL, fOp_CPU_Rd, fOp_CPU_Rt | fOp_Sa, 2, 2, "<<", "SLL", (void(*)())PGXP_CPU_SLL }
#define PGXP_Data_SRL { DBG_E_SRL, fOp_CPU_Rd, fOp_CPU_Rt | fOp_Sa, 2, 2, ">>", "SRL", (void(*)())PGXP_CPU_SRL }
#define PGXP_Data_SRA { DBG_E_SRA, fOp_CPU_Rd, fOp_CPU_Rt | fOp_Sa, 2, 2, ">>", "SRA", (void(*)())PGXP_CPU_SRA }
// Shift operations variable
#define PGXP_Data_SLLV { DBG_E_SLLV, fOp_CPU_Rd, fOp_CPU_Rt | fOp_CPU_Rs, 3, 3, ">>", "SLLV", (void(*)())PGXP_CPU_SLLV }
#define PGXP_Data_SRLV { DBG_E_SRLV, fOp_CPU_Rd, fOp_CPU_Rt | fOp_CPU_Rs, 3, 3, "<<", "SRLV", (void(*)())PGXP_CPU_SRLV }
#define PGXP_Data_SRAV { DBG_E_SRAV, fOp_CPU_Rd, fOp_CPU_Rt | fOp_CPU_Rs, 3, 3, "<<", "SRAV", (void(*)())PGXP_CPU_SRAV }
#define PGXP_Data_SLLV { DBG_E_SLLV, fOp_CPU_Rd, fOp_CPU_Rt | fOp_CPU_Rs, 3, 3, "<<", "SLLV", (void(*)())PGXP_CPU_SLLV }
#define PGXP_Data_SRLV { DBG_E_SRLV, fOp_CPU_Rd, fOp_CPU_Rt | fOp_CPU_Rs, 3, 3, ">>", "SRLV", (void(*)())PGXP_CPU_SRLV }
#define PGXP_Data_SRAV { DBG_E_SRAV, fOp_CPU_Rd, fOp_CPU_Rt | fOp_CPU_Rs, 3, 3, ">>", "SRAV", (void(*)())PGXP_CPU_SRAV }
// Move registers
#define PGXP_Data_MFHI { DBG_E_MFHI, fOp_CPU_Rd, fOp_CPU_Hi, 2, 2, "<-", "MFHI", (void(*)())PGXP_CPU_MFHI }
@ -203,11 +203,96 @@ PGXP_CPU_OpData GetOpData(u32 instr)
return pOpData;
}
void PrintOperands(char* szBuffer, u32 instr, u32 flags, const char* szDelim, psx_value* psx_regs, u32* regIdx)
PGXP_value* GetReg(u32 instr, u32 flag, u32 psxValue)
{
// iCB Hack: reorder Rs and Rt for SLLV SRLV and SRAV
if ((op(instr) == 0) && (func(instr) > 3) && (func(instr) < 8))
flag = (flag == fOp_CPU_Rs) ? fOp_CPU_Rt : ((flag == fOp_CPU_Rt) ? fOp_CPU_Rs : flag);
// /iCB Hack
switch (flag)
{
case fOp_CPU_Hi:
return &CPU_Hi;
case fOp_CPU_Lo:
return &CPU_Lo;
case fOp_CPU_Rd:
return &CPU_reg[rd(instr)];
case fOp_CPU_Rs:
return &CPU_reg[rs(instr)];
case fOp_CPU_Rt:
return &CPU_reg[rt(instr)];
case fOp_GTE_Dd:
return &GTE_data_reg[rd(instr)];
case fOp_GTE_Dt:
return &GTE_data_reg[rt(instr)];
case fOp_GTE_Cd:
return &GTE_ctrl_reg[rd(instr)];
case fOp_GTE_Ct:
return &GTE_ctrl_reg[rt(instr)];
case fOp_CP0_Dd:
return &CP0_reg[rd(instr)];
case fOp_CP0_Cd:
return &CP0_reg[rd(instr)];
case fOp_Ad:
return GetPtr(psxValue);
default:
return NULL;
}
}
void ForceValues(u32 instr, u32 flags, psx_value* psx_regs, u32 startIdx)
{
PGXP_value* pReg = NULL;
u32 regIdx = startIdx;
for (u32 opdIdx = 0; opdIdx < 14; opdIdx++)
{
u32 flag = 1 << opdIdx;
// iCB: Skip Load operations as data at address is unknown
if ((flags & flag) && (flag != fOp_Ad))
{
pReg = GetReg(instr, flag, psx_regs[regIdx].d);
if (pReg)
{
SetValue(pReg, psx_regs[regIdx].d);
regIdx++;
}
}
}
}
void TestValues(u32 instr, u32 flags, psx_value* psx_regs, u32 *test_flags, u32 startIdx)
{
PGXP_value* pReg = NULL;
u32 regIdx = startIdx;
for (u32 opdIdx = 0; opdIdx < 14; opdIdx++)
{
u32 flag = 1 << opdIdx;
// iCB: Skip Store operations as data at address is unknown
if ((flags & flag) && (flag != fOp_Ad))
{
pReg = GetReg(instr, flag, psx_regs[regIdx].d);
if (pReg)
{
test_flags[regIdx] = ValueToTolerance(pReg, psx_regs[regIdx].d, PGXP_DEBUG_TOLERANCE);
regIdx++;
}
}
}
}
void PrintOperands(char* szBuffer, u32 instr, u32 flags, const char* szDelim, psx_value* psx_regs, u32 startIdx)
{
char szTempBuffer[256];
PGXP_value* pReg = NULL;
psx_value psx_reg;
u32 regIdx = startIdx;
char szOpdName[16];
const char* szPre = "";
@ -217,7 +302,7 @@ void PrintOperands(char* szBuffer, u32 instr, u32 flags, const char* szDelim, ps
u32 flag = 1 << opdIdx;
// iCB Hack: reorder Rs and Rt for SLLV SRLV and SRAV
if ((op(instr) < 8) && (op(instr) > 3))
if ((op(instr) == 0) && (func(instr) > 3) && (func(instr) < 8))
flag = (flag == fOp_CPU_Rs) ? fOp_CPU_Rt : ((flag == fOp_CPU_Rt) ? fOp_CPU_Rs : flag);
// /iCB Hack
@ -228,62 +313,62 @@ void PrintOperands(char* szBuffer, u32 instr, u32 flags, const char* szDelim, ps
case fOp_CPU_Hi:
pReg = &CPU_Hi;
sprintf(szOpdName, "Hi");
psx_reg = psx_regs[(*regIdx)++];
psx_reg = psx_regs[regIdx++];
break;
case fOp_CPU_Lo:
pReg = &CPU_Lo;
sprintf(szOpdName, "Lo");
psx_reg = psx_regs[(*regIdx)++];
psx_reg = psx_regs[regIdx++];
break;
case fOp_CPU_Rd:
pReg = &CPU_reg[rd(instr)];
sprintf(szOpdName, "Rd[%d]", rd(instr));
psx_reg = psx_regs[(*regIdx)++];
psx_reg = psx_regs[regIdx++];
break;
case fOp_CPU_Rs:
pReg = &CPU_reg[rs(instr)];
sprintf(szOpdName, "Rs[%d]", rs(instr));
psx_reg = psx_regs[(*regIdx)++];
psx_reg = psx_regs[regIdx++];
break;
case fOp_CPU_Rt:
pReg = &CPU_reg[rt(instr)];
sprintf(szOpdName, "Rt[%d]", rt(instr));
psx_reg = psx_regs[(*regIdx)++];
psx_reg = psx_regs[regIdx++];
break;
case fOp_GTE_Dd:
pReg = &GTE_data_reg[rd(instr)];
sprintf(szOpdName, "GTE_Dd[%d]", rd(instr));
psx_reg = psx_regs[(*regIdx)++];
psx_reg = psx_regs[regIdx++];
break;
case fOp_GTE_Dt:
pReg = &GTE_data_reg[rt(instr)];
sprintf(szOpdName, "GTE_Dt[%d]", rt(instr));
psx_reg = psx_regs[(*regIdx)++];
psx_reg = psx_regs[regIdx++];
break;
case fOp_GTE_Cd:
pReg = &GTE_ctrl_reg[rd(instr)];
sprintf(szOpdName, "GTE_Cd[%d]", rd(instr));
psx_reg = psx_regs[(*regIdx)++];
psx_reg = psx_regs[regIdx++];
break;
case fOp_GTE_Ct:
pReg = &GTE_ctrl_reg[rt(instr)];
sprintf(szOpdName, "GTE_Ct[%d]", rt(instr));
psx_reg = psx_regs[(*regIdx)++];
psx_reg = psx_regs[regIdx++];
break;
case fOp_CP0_Dd:
pReg = &CP0_reg[rd(instr)];
sprintf(szOpdName, "CP0_Dd[%d]", rd(instr));
psx_reg = psx_regs[(*regIdx)++];
psx_reg = psx_regs[regIdx++];
break;
case fOp_CP0_Cd:
pReg = &CP0_reg[rd(instr)];
sprintf(szOpdName, "CP0_Cd[%d]", rd(instr));
psx_reg = psx_regs[(*regIdx)++];
psx_reg = psx_regs[regIdx++];
break;
case fOp_Ad:
pReg = NULL;
sprintf(szOpdName, "Addr");
psx_reg = psx_regs[(*regIdx)++];
psx_reg = psx_regs[regIdx++];
break;
case fOp_Sa:
pReg = NULL;
@ -333,8 +418,9 @@ void PGXP_CPU_DebugOutput(u32 eOp, u32 instr, u32 numOps, u32 op1, u32 op2, u32
char szOutputBuffer[256];
char szInputBuffer[512];
PGXP_CPU_OpData opData = GetOpData(instr);
psx_value psx_regs[4];
u32 regIdx = 0;
u32 test_flags[4] = { VALID_ALL, VALID_ALL, VALID_ALL, VALID_ALL };
psx_value psx_regs[4];
u32 inIdx = 0;
psx_regs[0].d = op1;
psx_regs[1].d = op2;
psx_regs[2].d = op3;
@ -353,22 +439,29 @@ void PGXP_CPU_DebugOutput(u32 eOp, u32 instr, u32 numOps, u32 op1, u32 op2, u32
// /iCB Hack
// skip output arguments to find first input
for (u32 opdIdx = 0; opdIdx < 12; opdIdx++)
{
if (opData.OutputFlags & (1 << opdIdx))
inIdx++;
}
#ifdef PGXP_FORCE_INPUT_VALUES
ForceValues(instr, opData.InputFlags, psx_regs, inIdx);
#endif
#ifdef PGXP_OUTPUT_ALL
// reset buffers
if (pgxp_debug)
{
memset(szInputBuffer, 0, sizeof(szInputBuffer));
memset(szOutputBuffer, 0, sizeof(szOutputBuffer));
// skip output arguments
for (u32 opdIdx = 0; opdIdx < 12; opdIdx++)
{
if (opData.OutputFlags & (1 << opdIdx))
regIdx++;
}
// Print inputs
PrintOperands(szInputBuffer, instr, opData.InputFlags, opData.szOpString, psx_regs, &regIdx);
PrintOperands(szInputBuffer, instr, opData.InputFlags, opData.szOpString, psx_regs, inIdx);
}
#endif
// Call function
if (numOps != opData.numArgs)
@ -396,19 +489,28 @@ void PGXP_CPU_DebugOutput(u32 eOp, u32 instr, u32 numOps, u32 op1, u32 op2, u32
break;
}
#ifdef PGXP_TEST_OUTPUT_VALUES
TestValues(instr, opData.OutputFlags, psx_regs, test_flags, 0);
#endif//PGXP_TEST_OUTPUT_VALUES
#ifdef PGXP_OUTPUT_ALL
// Print operation details
if (pgxp_debug)
{
sprintf(szOutputBuffer, "%s %x %x: ", opData.szOpName, op(instr), func(instr));
// Print outputs
regIdx = 0;
PrintOperands(szOutputBuffer, instr, opData.OutputFlags, "/", psx_regs, &regIdx);
PrintOperands(szOutputBuffer, instr, opData.OutputFlags, "/", psx_regs, 0);
strcat(szOutputBuffer, "=");
#ifdef GTE_LOG
GTE_LOG("PGXP_Trace: %s %s|", szOutputBuffer, szInputBuffer);
#endif
#ifdef PGXP_TEST_OUTPUT_VALUES
if((test_flags[0] & test_flags[1] & VALID_01) != VALID_01)
#endif//PGXP_TEST_OUTPUT_VALUES
GTE_LOG("PGXP_Trace: %s %s|", szOutputBuffer, szInputBuffer);
#endif//GTE_LOG
}
#endif//PGXP_OUTPUT_ALL
}
void PGXP_psxTraceOp(u32 eOp, u32 instr)

View File

@ -30,7 +30,13 @@
#include "psxcommon.h"
#define PGXP_CPU_DEBUG
//#define PGXP_CPU_DEBUG
//#define PGXP_OUTPUT_ALL
//#define PGXP_FORCE_INPUT_VALUES
//#define PGXP_TEST_OUTPUT_VALUES
#define PGXP_DEBUG_TOLERANCE 2.f
// Debug wrappers
void PGXP_psxTraceOp(u32 eOp, u32 code);

View File

@ -139,7 +139,7 @@ void ValidateAndCopyMem(PGXP_value* dest, u32 addr, u32 value)
*dest = PGXP_value_invalid_address;
}
void ValidateAndCopyMem16(PGXP_value* dest, u32 addr, u32 value)
void ValidateAndCopyMem16(PGXP_value* dest, u32 addr, u32 value, int sign)
{
u32 validMask = 0;
psx_value val, mask;
@ -174,7 +174,7 @@ void ValidateAndCopyMem16(PGXP_value* dest, u32 addr, u32 value)
}
// truncate value
dest->y = 0.f;
dest->y = (dest->x < 0) ? -1.f * sign : 0.f;// 0.f;
dest->hFlags = 0;
dest->value = value;
dest->compFlags[1] = VALID; // iCB: High word is valid, just 0
@ -216,6 +216,14 @@ void WriteMem16(PGXP_value* src, u32 addr)
pVal->w.l = (u16)src->value;
}
// overwrite z/w if valid
if (src->compFlags[2] == VALID)
{
dest->z = src->z;
dest->compFlags[2] = src->compFlags[2];
}
//dest->valid = dest->valid && src->valid;
dest->gFlags |= src->gFlags; // inherit flags from both values (?)
}

View File

@ -41,7 +41,7 @@ PGXP_value* GetPtr(u32 addr);
PGXP_value* ReadMem(u32 addr);
void ValidateAndCopyMem(PGXP_value* dest, u32 addr, u32 value);
void ValidateAndCopyMem16(PGXP_value* dest, u32 addr, u32 value);
void ValidateAndCopyMem16(PGXP_value* dest, u32 addr, u32 value, int sign);
void WriteMem(PGXP_value* value, u32 addr);
void WriteMem16(PGXP_value* src, u32 addr);

View File

@ -1,5 +1,17 @@
#include "pgxp_value.h"
#include "limits.h"
void SetValue(PGXP_value *pV, u32 psxV)
{
psx_value psx;
psx.d = psxV;
pV->x = psx.sw.l;
pV->y = psx.sw.h;
pV->z = 0.f;
pV->flags = VALID_01;
pV->value = psx.d;
}
void MakeValid(PGXP_value *pV, u32 psxV)
{
@ -9,8 +21,8 @@ void MakeValid(PGXP_value *pV, u32 psxV)
{
pV->x = psx.sw.l;
pV->y = psx.sw.h;
pV->z = 1.f;
pV->flags |= VALID_ALL;
pV->z = 0.f;
pV->flags |= VALID_01;
pV->value = psx.d;
}
}
@ -18,11 +30,39 @@ void MakeValid(PGXP_value *pV, u32 psxV)
void Validate(PGXP_value *pV, u32 psxV)
{
// assume pV is not NULL
pV->flags &= pV->value == psxV ? ALL : INV_VALID_ALL;
pV->flags &= (pV->value == psxV) ? ALL : INV_VALID_ALL;
}
void MaskValidate(PGXP_value *pV, u32 psxV, u32 mask, u32 validMask)
{
// assume pV is not NULL
pV->flags &= ((pV->value & mask) == (psxV & mask)) ? ALL : (ALL ^ (validMask));
}
u32 ValueToTolerance(PGXP_value *pV, u32 psxV, float tolerance)
{
psx_value psx;
psx.d = psxV;
u32 retFlags = VALID_ALL;
if (fabs(pV->x - psx.sw.l) >= tolerance)
retFlags = retFlags & (VALID_1 | VALID_2 | VALID_3);
if (fabs(pV->y - psx.sw.h) >= tolerance)
retFlags = retFlags & (VALID_0 | VALID_2 | VALID_3);
return retFlags;
}
/// float logical arithmetic ///
double f16Sign(double in) { u32 s = in * (double)((u32)1 << 16); return ((double)*((s32*)&s)) / (double)((s32)1 << 16); }
double f16Unsign(double in) { return (in >= 0) ? in : ((double)in + (double)USHRT_MAX + 1); }
double fu16Trunc(double in) { u32 u = in * (double)((u32)1 << 16); return (double)u / (double)((u32)1 << 16); }
double f16Overflow(double in)
{
double out = 0;
s64 v = ((s64)in) >> 16;
out = v;
return out;
}

View File

@ -98,10 +98,16 @@ typedef enum
static const PGXP_value PGXP_value_invalid_address = { 0.f, 0.f, 0.f, 0, 0, 0, INVALID_ADDRESS, 0, 0 };
static const PGXP_value PGXP_value_zero = { 0.f, 0.f, 0.f, 0, 0, VALID_ALL, 0, 0, 0 };
void MakeValid(PGXP_value *pV, u32 psxV);
void Validate(PGXP_value *pV, u32 psxV);
void MaskValidate(PGXP_value *pV, u32 psxV, u32 mask, u32 validMask);
void SetValue(PGXP_value *pV, u32 psxV);
void MakeValid(PGXP_value *pV, u32 psxV);
void Validate(PGXP_value *pV, u32 psxV);
void MaskValidate(PGXP_value *pV, u32 psxV, u32 mask, u32 validMask);
u32 ValueToTolerance(PGXP_value *pV, u32 psxV, float tolerance);
double f16Sign(double in);
double f16Unsign(double in);
double fu16Trunc(double in);
double f16Overflow(double in);
typedef union
{

View File

@ -305,20 +305,23 @@ int PGXP_GetVertices(unsigned int* addr, void* pOutput, int xOffs, int yOffs)
pVertex[i].PGXP_flag = 1;
if ((primStart[stride * i].flags & VALID_2) != VALID_2)
{
pVertex[i].PGXP_flag = 6;
// __Log("GPPV No W: v:%x (%d, %d) pgxp(%f, %f)|\n", (currentAddr + 1 + (i * stride)) * 4, pPrimData[stride * i * 2], pPrimData[(stride * i * 2) + 1], primStart[stride * i].x, primStart[stride * i].y);
}
// Log incorrect vertices
//if (PGXP_tDebug &&
// (fabs((float)pPrimData[stride * i * 2] - pVertex[i].x) > debug_tolerance) ||
// (fabs((float)pPrimData[(stride * i * 2) + 1] - pVertex[i].y) > debug_tolerance))
// __Log("GPPV: v:%x (%d, %d) pgxp(%f, %f)|\n", (currentAddr + 1 + (i * stride)) * 4, pPrimData[stride * i * 2], pPrimData[(stride * i * 2) + 1], pVertex[i].x, pVertex[i].y);
// (fabs((float)pPrimData[stride * i * 2] - primStart[stride * i].x) > debug_tolerance) ||
// (fabs((float)pPrimData[(stride * i * 2) + 1] - primStart[stride * i].y) > debug_tolerance))
// __Log("GPPV: v:%x (%d, %d) pgxp(%f, %f)|\n", (currentAddr + 1 + (i * stride)) * 4, pPrimData[stride * i * 2], pPrimData[(stride * i * 2) + 1], primStart[stride * i].x, primStart[stride * i].y);
}
else
{
// Default to low precision vertex data
if (primStart && ((primStart[stride * i].flags & VALID_01) == VALID_01) && primStart[stride * i].value != *(unsigned int*)(&pPrimData[stride * i * 2]))
pVertex[i].PGXP_flag = 6;
else
//if (primStart && ((primStart[stride * i].flags & VALID_01) == VALID_01) && primStart[stride * i].value != *(unsigned int*)(&pPrimData[stride * i * 2]))
// pVertex[i].PGXP_flag = 6;
//else
pVertex[i].PGXP_flag = 2;
// Look in cache for valid vertex
@ -354,6 +357,10 @@ int PGXP_GetVertices(unsigned int* addr, void* pOutput, int xOffs, int yOffs)
for (unsigned i = 0; i < count; ++i)
pVertex[i].w = 1;
if(PGXP_vDebug == 3)
for (unsigned i = 0; i < count; ++i)
pVertex[i].PGXP_flag = primIdx;
return 1;
}
@ -361,7 +368,7 @@ int PGXP_GetVertices(unsigned int* addr, void* pOutput, int xOffs, int yOffs)
//// Visual Debugging Functions
/////////////////////////////////
unsigned int PGXP_vDebug = 0;
const unsigned int PGXP_maxDebug = 3;
const unsigned int PGXP_maxDebug = 4;
const char red[4] = { 255, 0, 0, 255 };
const char blue[4] = { 0, 0, 255, 255 };
@ -370,6 +377,9 @@ const char green[4] = { 0, 255, 0, 255 };
const char yellow[4] = { 255, 255, 0, 255 };
const char magenta[4] = { 255, 0, 255, 255 };
const char cyan[4] = { 0, 255, 255, 255 };
const char orange[4] = { 255, 128 ,0 ,255 };
const char black[4] = { 0, 0, 0, 255 };
@ -426,21 +436,57 @@ void PGXP_colour(OGLVertex* vertex)
fDepth = vertex->w / (float)(0xFFFF);
glColor4f(fDepth, fDepth, fDepth, 1.f);
break;
case 3:
// Primitive type
switch (vertex->PGXP_flag)
{
case 0:
pColour = yellow;
break;
case 1:
pColour = blue;
break;
case 2:
pColour = red;
break;
case 3:
pColour = green;
break;
case 4:
pColour = magenta;
break;
case 6:
pColour = cyan;
break;
case 7:
pColour = orange;
default:
pColour = black;
break;
}
glColor4ubv(pColour);
break;
}
}
void PGXP_DrawDebugTriQuad(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3, OGLVertex* vertex4)
int PGXP_DrawDebugTriQuad(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3, OGLVertex* vertex4)
{
GLboolean bTexture = glIsEnabled(GL_TEXTURE_2D);
GLfloat fColour[4];
GLint iShadeModel;
//if ((vertex1->PGXP_flag == 0) ||
// (vertex2->PGXP_flag == 0) ||
// (vertex3->PGXP_flag == 0) ||
// (vertex4->PGXP_flag == 0))
// return 0;
// Quit if PGXP_flag == ignore
if ((vertex1->PGXP_flag == 5) ||
(vertex2->PGXP_flag == 5) ||
(vertex3->PGXP_flag == 5) ||
(vertex4->PGXP_flag == 5))
return;
return 1;
glGetIntegerv(GL_SHADE_MODEL, &iShadeModel);
glGetFloatv(GL_CURRENT_COLOR, fColour);
@ -486,19 +532,28 @@ void PGXP_DrawDebugTriQuad(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* ve
glEnable(GL_TEXTURE_2D);
glShadeModel(iShadeModel);
return 1;
}
void PGXP_DrawDebugTri(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3)
int PGXP_DrawDebugTri(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3)
{
GLboolean bTexture = glIsEnabled(GL_TEXTURE_2D);
GLfloat fColour[4];
GLint iShadeModel;
//if ((vertex1->PGXP_flag == 0) ||
// (vertex2->PGXP_flag == 0) ||
// (vertex3->PGXP_flag == 0))
// return 0;
// Quit if PGXP_flag == ignore
if ((vertex1->PGXP_flag == 5) ||
(vertex2->PGXP_flag == 5) ||
(vertex3->PGXP_flag == 5))
return;
return 1;
glGetIntegerv(GL_SHADE_MODEL, &iShadeModel);
glGetFloatv(GL_CURRENT_COLOR, fColour);
@ -540,20 +595,30 @@ void PGXP_DrawDebugTri(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex
glEnable(GL_TEXTURE_2D);
glShadeModel(iShadeModel);
return 1;
}
void PGXP_DrawDebugQuad(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3, OGLVertex* vertex4)
int PGXP_DrawDebugQuad(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3, OGLVertex* vertex4)
{
GLboolean bTexture = glIsEnabled(GL_TEXTURE_2D);
GLfloat fColour[4];
GLint iShadeModel;
//if ((vertex1->PGXP_flag == 0) ||
// (vertex2->PGXP_flag == 0) ||
// (vertex3->PGXP_flag == 0) ||
// (vertex4->PGXP_flag == 0))
// return 0;
// Quit if PGXP_flag == ignore
if ((vertex1->PGXP_flag == 5) ||
(vertex2->PGXP_flag == 5) ||
(vertex3->PGXP_flag == 5) ||
(vertex4->PGXP_flag == 5))
return;
return 1;
glGetIntegerv(GL_SHADE_MODEL, &iShadeModel);
glGetFloatv(GL_CURRENT_COLOR, fColour);
@ -599,4 +664,6 @@ void PGXP_DrawDebugQuad(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* verte
glEnable(GL_TEXTURE_2D);
glShadeModel(iShadeModel);
return 1;
}

View File

@ -42,8 +42,8 @@ void PGXP_glVertexfv(GLfloat* pVertex);
extern unsigned int PGXP_vDebug;
extern unsigned int PGXP_debugFlags[4];
void PGXP_DrawDebugTriQuad(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3, OGLVertex* vertex4);
void PGXP_DrawDebugTri(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3);
void PGXP_DrawDebugQuad(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3, OGLVertex* vertex4);
int PGXP_DrawDebugTriQuad(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3, OGLVertex* vertex4);
int PGXP_DrawDebugTri(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3);
int PGXP_DrawDebugQuad(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3, OGLVertex* vertex4);
#endif // _PGXP_GPU_H_

View File

@ -152,7 +152,7 @@ static __inline void PRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2
{
if (PGXP_vDebug)
{
PGXP_DrawDebugTriQuad(vertex1, vertex2, vertex4, vertex3);
if(PGXP_DrawDebugTriQuad(vertex1, vertex2, vertex4, vertex3))
return;
}
@ -179,7 +179,7 @@ static __inline void PRIMdrawTexturedTri(OGLVertex* vertex1, OGLVertex* vertex2,
{
if (PGXP_vDebug)
{
PGXP_DrawDebugTri(vertex1, vertex2, vertex3);
if(PGXP_DrawDebugTri(vertex1, vertex2, vertex3))
return;
}
@ -202,7 +202,7 @@ static __inline void PRIMdrawTexGouraudTriColor(OGLVertex* vertex1, OGLVertex* v
{
if (PGXP_vDebug)
{
PGXP_DrawDebugTri(vertex1, vertex2, vertex3);
if(PGXP_DrawDebugTri(vertex1, vertex2, vertex3))
return;
}
@ -229,7 +229,7 @@ static __inline void PRIMdrawTexGouraudTriColorQuad(OGLVertex* vertex1, OGLVerte
{
if (PGXP_vDebug)
{
PGXP_DrawDebugTriQuad(vertex1, vertex2, vertex4, vertex3);
if(PGXP_DrawDebugTriQuad(vertex1, vertex2, vertex4, vertex3))
return;
}
@ -258,7 +258,7 @@ static __inline void PRIMdrawTri(OGLVertex* vertex1, OGLVertex* vertex2, OGLVert
{
if (PGXP_vDebug)
{
PGXP_DrawDebugTri(vertex1, vertex2, vertex3);
if(PGXP_DrawDebugTri(vertex1, vertex2, vertex3))
return;
}
@ -276,7 +276,7 @@ static __inline void PRIMdrawTri2(OGLVertex* vertex1, OGLVertex* vertex2,
{
if (PGXP_vDebug)
{
PGXP_DrawDebugTriQuad(vertex1, vertex3, vertex2, vertex4);
if(PGXP_DrawDebugTriQuad(vertex1, vertex3, vertex2, vertex4))
return;
}
@ -295,7 +295,7 @@ static __inline void PRIMdrawGouraudTriColor(OGLVertex* vertex1, OGLVertex* vert
{
if (PGXP_vDebug)
{
PGXP_DrawDebugTri(vertex1, vertex2, vertex3);
if(PGXP_DrawDebugTri(vertex1, vertex2, vertex3))
return;
}
@ -318,7 +318,7 @@ static __inline void PRIMdrawGouraudTri2Color(OGLVertex* vertex1, OGLVertex* ver
{
if (PGXP_vDebug)
{
PGXP_DrawDebugTriQuad(vertex1, vertex3, vertex2, vertex4);
if(PGXP_DrawDebugTriQuad(vertex1, vertex3, vertex2, vertex4))
return;
}
@ -343,7 +343,7 @@ static __inline void PRIMdrawFlatLine(OGLVertex* vertex1, OGLVertex* vertex2,OGL
{
if (PGXP_vDebug)
{
PGXP_DrawDebugQuad(vertex1, vertex2, vertex3, vertex4);
if(PGXP_DrawDebugQuad(vertex1, vertex2, vertex3, vertex4))
return;
}
@ -364,7 +364,7 @@ static __inline void PRIMdrawGouraudLine(OGLVertex* vertex1, OGLVertex* vertex2,
{
if (PGXP_vDebug)
{
PGXP_DrawDebugQuad(vertex1, vertex2, vertex3, vertex4);
if(PGXP_DrawDebugQuad(vertex1, vertex2, vertex3, vertex4))
return;
}
@ -391,7 +391,7 @@ static __inline void PRIMdrawQuad(OGLVertex* vertex1, OGLVertex* vertex2,
{
if (PGXP_vDebug)
{
PGXP_DrawDebugQuad(vertex1, vertex2, vertex3, vertex4);
if(PGXP_DrawDebugQuad(vertex1, vertex2, vertex3, vertex4))
return;
}