1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-06-25 22:09:35 +00:00

Initial project version. Based on glN64-0.4.1-rc2

This commit is contained in:
Sergey Lipskiy 2013-04-05 13:13:26 +07:00
parent 8073ec3306
commit 69f27a5d8a
79 changed files with 35356 additions and 0 deletions

647
2xSAI.cpp Normal file
View File

@ -0,0 +1,647 @@
#include "Types.h"
#include "GBI.h"
static inline s16 GetResult1( u32 A, u32 B, u32 C, u32 D, u32 E )
{
s16 x = 0;
s16 y = 0;
s16 r = 0;
if (A == C) x += 1; else if (B == C) y += 1;
if (A == D) x += 1; else if (B == D) y += 1;
if (x <= 1) r += 1;
if (y <= 1) r -= 1;
return r;
}
static inline s16 GetResult2( u32 A, u32 B, u32 C, u32 D, u32 E)
{
s16 x = 0;
s16 y = 0;
s16 r = 0;
if (A == C) x += 1; else if (B == C) y += 1;
if (A == D) x += 1; else if (B == D) y += 1;
if (x <= 1) r -= 1;
if (y <= 1) r += 1;
return r;
}
static inline s16 GetResult( u32 A, u32 B, u32 C, u32 D )
{
s16 x = 0;
s16 y = 0;
s16 r = 0;
if (A == C) x += 1; else if (B == C) y += 1;
if (A == D) x += 1; else if (B == D) y += 1;
if (x <= 1) r += 1;
if (y <= 1) r -= 1;
return r;
}
static inline u16 INTERPOLATE4444( u16 A, u16 B)
{
if (A != B)
return ((A & 0xEEEE) >> 1) +
((B & 0xEEEE) >> 1) |
(A & B & 0x1111);
else
return A;
}
static inline u16 INTERPOLATE5551( u16 A, u16 B)
{
if (A != B)
return ((A & 0xF7BC) >> 1) +
((B & 0xF7BC) >> 1) |
(A & B & 0x0843);
else
return A;
}
static inline u32 INTERPOLATE8888( u32 A, u32 B)
{
if (A != B)
return ((A & 0xFEFEFEFE) >> 1) +
((B & 0xFEFEFEFE) >> 1) |
(A & B & 0x01010101);
else
return A;
}
static inline u16 Q_INTERPOLATE4444( u16 A, u16 B, u16 C, u16 D)
{
u16 x = ((A & 0xCCCC) >> 2) +
((B & 0xCCCC) >> 2) +
((C & 0xCCCC) >> 2) +
((D & 0xCCCC) >> 2);
u16 y = (((A & 0x3333) +
(B & 0x3333) +
(C & 0x3333) +
(D & 0x3333)) >> 2) & 0x3333;
return x | y;
}
static inline u16 Q_INTERPOLATE5551( u16 A, u16 B, u16 C, u16 D)
{
u16 x = ((A & 0xE738) >> 2) +
((B & 0xE738) >> 2) +
((C & 0xE738) >> 2) +
((D & 0xE738) >> 2);
u16 y = (((A & 0x18C6) +
(B & 0x18C6) +
(C & 0x18C6) +
(D & 0x18C6)) >> 2) & 0x18C6;
u16 z = ((A & 0x0001) +
(B & 0x0001) +
(C & 0x0001) +
(D & 0x0001)) > 2 ? 1 : 0;
return x | y | z;
}
static inline u32 Q_INTERPOLATE8888( u32 A, u32 B, u32 C, u32 D)
{
u32 x = ((A & 0xFCFCFCFC) >> 2) +
((B & 0xFCFCFCFC) >> 2) +
((C & 0xFCFCFCFC) >> 2) +
((D & 0xFCFCFCFC) >> 2);
u32 y = (((A & 0x03030303) +
(B & 0x03030303) +
(C & 0x03030303) +
(D & 0x03030303)) >> 2) & 0x03030303;
return x | y;
}
void _2xSaI4444( u16 *srcPtr, u16 *destPtr, u16 width, u16 height, s32 clampS, s32 clampT )
{
u16 destWidth = width << 1;
u16 destHeight = height << 1;
u32 colorA, colorB, colorC, colorD,
colorE, colorF, colorG, colorH,
colorI, colorJ, colorK, colorL,
colorM, colorN, colorO, colorP;
u32 product, product1, product2;
s16 row0, row1, row2, row3;
s16 col0, col1, col2, col3;
for (u16 y = 0; y < height; y++)
{
if (y > 0)
row0 = -width;
else
row0 = clampT ? 0 : (height - 1) * width;
row1 = 0;
if (y < height - 1)
{
row2 = width;
if (y < height - 2)
row3 = width << 1;
else
row3 = clampT ? width : -y * width;
}
else
{
row2 = clampT ? 0 : -y * width;
row3 = clampT ? 0 : (1 - y) * width;
}
for (u16 x = 0; x < width; x++)
{
if (x > 0)
col0 = -1;
else
col0 = clampS ? 0 : width - 1;
col1 = 0;
if (x < width - 1)
{
col2 = 1;
if (x < width - 2)
col3 = 2;
else
col3 = clampS ? 1 : -x;
}
else
{
col2 = clampS ? 0 : -x;
col3 = clampS ? 0 : 1 - x;
}
//---------------------------------------
// Map of the pixels: I|E F|J
// G|A B|K
// H|C D|L
// M|N O|P
colorI = *(srcPtr + col0 + row0);
colorE = *(srcPtr + col1 + row0);
colorF = *(srcPtr + col2 + row0);
colorJ = *(srcPtr + col3 + row0);
colorG = *(srcPtr + col0 + row1);
colorA = *(srcPtr + col1 + row1);
colorB = *(srcPtr + col2 + row1);
colorK = *(srcPtr + col3 + row1);
colorH = *(srcPtr + col0 + row2);
colorC = *(srcPtr + col1 + row2);
colorD = *(srcPtr + col2 + row2);
colorL = *(srcPtr + col3 + row2);
colorM = *(srcPtr + col0 + row3);
colorN = *(srcPtr + col1 + row3);
colorO = *(srcPtr + col2 + row3);
colorP = *(srcPtr + col3 + row3);
if ((colorA == colorD) && (colorB != colorC))
{
if ( ((colorA == colorE) && (colorB == colorL)) ||
((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)) )
product = colorA;
else
product = INTERPOLATE4444(colorA, colorB);
if (((colorA == colorG) && (colorC == colorO)) ||
((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)) )
product1 = colorA;
else
product1 = INTERPOLATE4444(colorA, colorC);
product2 = colorA;
}
else if ((colorB == colorC) && (colorA != colorD))
{
if (((colorB == colorF) && (colorA == colorH)) ||
((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI)) )
product = colorB;
else
product = INTERPOLATE4444(colorA, colorB);
if (((colorC == colorH) && (colorA == colorF)) ||
((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)) )
product1 = colorC;
else
product1 = INTERPOLATE4444(colorA, colorC);
product2 = colorB;
}
else if ((colorA == colorD) && (colorB == colorC))
{
if (colorA == colorB)
{
product = colorA;
product1 = colorA;
product2 = colorA;
}
else
{
s16 r = 0;
product1 = INTERPOLATE4444(colorA, colorC);
product = INTERPOLATE4444(colorA, colorB);
r += GetResult1 (colorA, colorB, colorG, colorE, colorI);
r += GetResult2 (colorB, colorA, colorK, colorF, colorJ);
r += GetResult2 (colorB, colorA, colorH, colorN, colorM);
r += GetResult1 (colorA, colorB, colorL, colorO, colorP);
if (r > 0)
product2 = colorA;
else if (r < 0)
product2 = colorB;
else
product2 = Q_INTERPOLATE4444(colorA, colorB, colorC, colorD);
}
}
else
{
product2 = Q_INTERPOLATE4444(colorA, colorB, colorC, colorD);
if ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ))
product = colorA;
else if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
product = colorB;
else
product = INTERPOLATE4444(colorA, colorB);
if ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM))
product1 = colorA;
else if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI))
product1 = colorC;
else
product1 = INTERPOLATE4444(colorA, colorC);
}
destPtr[0] = colorA;
destPtr[1] = product;
destPtr[destWidth] = product1;
destPtr[destWidth + 1] = product2;
srcPtr++;
destPtr += 2;
}
destPtr += destWidth;
}
}
void _2xSaI5551( u16 *srcPtr, u16 *destPtr, u16 width, u16 height, s32 clampS, s32 clampT )
{
u16 destWidth = width << 1;
u16 destHeight = height << 1;
u32 colorA, colorB, colorC, colorD,
colorE, colorF, colorG, colorH,
colorI, colorJ, colorK, colorL,
colorM, colorN, colorO, colorP;
u32 product, product1, product2;
s16 row0, row1, row2, row3;
s16 col0, col1, col2, col3;
for (u16 y = 0; y < height; y++)
{
if (y > 0)
row0 = -width;
else
row0 = clampT ? 0 : (height - 1) * width;
row1 = 0;
if (y < height - 1)
{
row2 = width;
if (y < height - 2)
row3 = width << 1;
else
row3 = clampT ? width : -y * width;
}
else
{
row2 = clampT ? 0 : -y * width;
row3 = clampT ? 0 : (1 - y) * width;
}
for (u16 x = 0; x < width; x++)
{
if (x > 0)
col0 = -1;
else
col0 = clampS ? 0 : width - 1;
col1 = 0;
if (x < width - 1)
{
col2 = 1;
if (x < width - 2)
col3 = 2;
else
col3 = clampS ? 1 : -x;
}
else
{
col2 = clampS ? 0 : -x;
col3 = clampS ? 0 : 1 - x;
}
//---------------------------------------
// Map of the pixels: I|E F|J
// G|A B|K
// H|C D|L
// M|N O|P
colorI = *(srcPtr + col0 + row0);
colorE = *(srcPtr + col1 + row0);
colorF = *(srcPtr + col2 + row0);
colorJ = *(srcPtr + col3 + row0);
colorG = *(srcPtr + col0 + row1);
colorA = *(srcPtr + col1 + row1);
colorB = *(srcPtr + col2 + row1);
colorK = *(srcPtr + col3 + row1);
colorH = *(srcPtr + col0 + row2);
colorC = *(srcPtr + col1 + row2);
colorD = *(srcPtr + col2 + row2);
colorL = *(srcPtr + col3 + row2);
colorM = *(srcPtr + col0 + row3);
colorN = *(srcPtr + col1 + row3);
colorO = *(srcPtr + col2 + row3);
colorP = *(srcPtr + col3 + row3);
if ((colorA == colorD) && (colorB != colorC))
{
if ( ((colorA == colorE) && (colorB == colorL)) ||
((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)) )
product = colorA;
else
product = INTERPOLATE5551(colorA, colorB);
if (((colorA == colorG) && (colorC == colorO)) ||
((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)) )
product1 = colorA;
else
product1 = INTERPOLATE5551(colorA, colorC);
product2 = colorA;
}
else if ((colorB == colorC) && (colorA != colorD))
{
if (((colorB == colorF) && (colorA == colorH)) ||
((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI)) )
product = colorB;
else
product = INTERPOLATE5551(colorA, colorB);
if (((colorC == colorH) && (colorA == colorF)) ||
((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)) )
product1 = colorC;
else
product1 = INTERPOLATE5551(colorA, colorC);
product2 = colorB;
}
else if ((colorA == colorD) && (colorB == colorC))
{
if (colorA == colorB)
{
product = colorA;
product1 = colorA;
product2 = colorA;
}
else
{
s16 r = 0;
product1 = INTERPOLATE5551(colorA, colorC);
product = INTERPOLATE5551(colorA, colorB);
r += GetResult1 (colorA, colorB, colorG, colorE, colorI);
r += GetResult2 (colorB, colorA, colorK, colorF, colorJ);
r += GetResult2 (colorB, colorA, colorH, colorN, colorM);
r += GetResult1 (colorA, colorB, colorL, colorO, colorP);
if (r > 0)
product2 = colorA;
else if (r < 0)
product2 = colorB;
else
product2 = Q_INTERPOLATE5551(colorA, colorB, colorC, colorD);
}
}
else
{
product2 = Q_INTERPOLATE5551(colorA, colorB, colorC, colorD);
if ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ))
product = colorA;
else if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
product = colorB;
else
product = INTERPOLATE5551(colorA, colorB);
if ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM))
product1 = colorA;
else if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI))
product1 = colorC;
else
product1 = INTERPOLATE5551(colorA, colorC);
}
destPtr[0] = colorA;
destPtr[1] = product;
destPtr[destWidth] = product1;
destPtr[destWidth + 1] = product2;
srcPtr++;
destPtr += 2;
}
destPtr += destWidth;
}
}
void _2xSaI8888( u32 *srcPtr, u32 *destPtr, u16 width, u16 height, s32 clampS, s32 clampT )
{
u16 destWidth = width << 1;
u16 destHeight = height << 1;
u32 colorA, colorB, colorC, colorD,
colorE, colorF, colorG, colorH,
colorI, colorJ, colorK, colorL,
colorM, colorN, colorO, colorP;
u32 product, product1, product2;
s16 row0, row1, row2, row3;
s16 col0, col1, col2, col3;
for (u16 y = 0; y < height; y++)
{
if (y > 0)
row0 = -width;
else
row0 = clampT ? 0 : (height - 1) * width;
row1 = 0;
if (y < height - 1)
{
row2 = width;
if (y < height - 2)
row3 = width << 1;
else
row3 = clampT ? width : -y * width;
}
else
{
row2 = clampT ? 0 : -y * width;
row3 = clampT ? 0 : (1 - y) * width;
}
for (u16 x = 0; x < width; x++)
{
if (x > 0)
col0 = -1;
else
col0 = clampS ? 0 : width - 1;
col1 = 0;
if (x < width - 1)
{
col2 = 1;
if (x < width - 2)
col3 = 2;
else
col3 = clampS ? 1 : -x;
}
else
{
col2 = clampS ? 0 : -x;
col3 = clampS ? 0 : 1 - x;
}
//---------------------------------------
// Map of the pixels: I|E F|J
// G|A B|K
// H|C D|L
// M|N O|P
colorI = *(srcPtr + col0 + row0);
colorE = *(srcPtr + col1 + row0);
colorF = *(srcPtr + col2 + row0);
colorJ = *(srcPtr + col3 + row0);
colorG = *(srcPtr + col0 + row1);
colorA = *(srcPtr + col1 + row1);
colorB = *(srcPtr + col2 + row1);
colorK = *(srcPtr + col3 + row1);
colorH = *(srcPtr + col0 + row2);
colorC = *(srcPtr + col1 + row2);
colorD = *(srcPtr + col2 + row2);
colorL = *(srcPtr + col3 + row2);
colorM = *(srcPtr + col0 + row3);
colorN = *(srcPtr + col1 + row3);
colorO = *(srcPtr + col2 + row3);
colorP = *(srcPtr + col3 + row3);
if ((colorA == colorD) && (colorB != colorC))
{
if ( ((colorA == colorE) && (colorB == colorL)) ||
((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)) )
product = colorA;
else
product = INTERPOLATE8888(colorA, colorB);
if (((colorA == colorG) && (colorC == colorO)) ||
((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)) )
product1 = colorA;
else
product1 = INTERPOLATE8888(colorA, colorC);
product2 = colorA;
}
else if ((colorB == colorC) && (colorA != colorD))
{
if (((colorB == colorF) && (colorA == colorH)) ||
((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI)) )
product = colorB;
else
product = INTERPOLATE8888(colorA, colorB);
if (((colorC == colorH) && (colorA == colorF)) ||
((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)) )
product1 = colorC;
else
product1 = INTERPOLATE8888(colorA, colorC);
product2 = colorB;
}
else if ((colorA == colorD) && (colorB == colorC))
{
if (colorA == colorB)
{
product = colorA;
product1 = colorA;
product2 = colorA;
}
else
{
s16 r = 0;
product1 = INTERPOLATE8888(colorA, colorC);
product = INTERPOLATE8888(colorA, colorB);
r += GetResult1 (colorA, colorB, colorG, colorE, colorI);
r += GetResult2 (colorB, colorA, colorK, colorF, colorJ);
r += GetResult2 (colorB, colorA, colorH, colorN, colorM);
r += GetResult1 (colorA, colorB, colorL, colorO, colorP);
if (r > 0)
product2 = colorA;
else if (r < 0)
product2 = colorB;
else
product2 = Q_INTERPOLATE8888(colorA, colorB, colorC, colorD);
}
}
else
{
product2 = Q_INTERPOLATE8888(colorA, colorB, colorC, colorD);
if ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ))
product = colorA;
else if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
product = colorB;
else
product = INTERPOLATE8888(colorA, colorB);
if ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM))
product1 = colorA;
else if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI))
product1 = colorC;
else
product1 = INTERPOLATE8888(colorA, colorC);
}
destPtr[0] = colorA;
destPtr[1] = product;
destPtr[destWidth] = product1;
destPtr[destWidth + 1] = product2;
srcPtr++;
destPtr += 2;
}
destPtr += destWidth;
}
}

9
2xSAI.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef _2XSAI_H
#define _2XSAI_H
#include "Types.h"
void _2xSaI8888( u32 *srcPtr, u32 *destPtr, u16 width, u16 height, s32 clampS, s32 clampT );
void _2xSaI4444( u16 *srcPtr, u16 *destPtr, u16 width, u16 height, s32 clampS, s32 clampT );
void _2xSaI5551( u16 *srcPtr, u16 *destPtr, u16 width, u16 height, s32 clampS, s32 clampT );
#endif

849
3DMath.h Normal file
View File

@ -0,0 +1,849 @@
#ifndef _3DMATH_H
#define _3DMATH_H
#undef X86_ASM
inline void CopyMatrix( float m0[4][4], float m1[4][4] )
{
#ifndef __LINUX__
__asm {
mov esi, [m1]
mov edi, [m0]
mov eax, dword ptr [esi+00h]
mov dword ptr [edi+00h], eax
mov eax, dword ptr [esi+04h]
mov dword ptr [edi+04h], eax
mov eax, dword ptr [esi+08h]
mov dword ptr [edi+08h], eax
mov eax, dword ptr [esi+0Ch]
mov dword ptr [edi+0Ch], eax
mov eax, dword ptr [esi+10h]
mov dword ptr [edi+10h], eax
mov eax, dword ptr [esi+14h]
mov dword ptr [edi+14h], eax
mov eax, dword ptr [esi+18h]
mov dword ptr [edi+18h], eax
mov eax, dword ptr [esi+1Ch]
mov dword ptr [edi+1Ch], eax
mov eax, dword ptr [esi+20h]
mov dword ptr [edi+20h], eax
mov eax, dword ptr [esi+24h]
mov dword ptr [edi+24h], eax
mov eax, dword ptr [esi+28h]
mov dword ptr [edi+28h], eax
mov eax, dword ptr [esi+2Ch]
mov dword ptr [edi+2Ch], eax
mov eax, dword ptr [esi+30h]
mov dword ptr [edi+30h], eax
mov eax, dword ptr [esi+34h]
mov dword ptr [edi+34h], eax
mov eax, dword ptr [esi+38h]
mov dword ptr [edi+38h], eax
mov eax, dword ptr [esi+3Ch]
mov dword ptr [edi+3Ch], eax
}
#else
# ifdef X86_ASM
__asm__ __volatile__(
".intel_syntax noprefix" "\n\t"
" mov eax, dword ptr [esi+0x00]" "\n\t"
" mov dword ptr [edi+0x00], eax" "\n\t"
" mov eax, dword ptr [esi+0x04]" "\n\t"
" mov dword ptr [edi+0x04], eax" "\n\t"
" mov eax, dword ptr [esi+0x08]" "\n\t"
" mov dword ptr [edi+0x08], eax" "\n\t"
" mov eax, dword ptr [esi+0x0C]" "\n\t"
" mov dword ptr [edi+0x0C], eax" "\n\t"
" mov eax, dword ptr [esi+0x10]" "\n\t"
" mov dword ptr [edi+0x10], eax" "\n\t"
" mov eax, dword ptr [esi+0x14]" "\n\t"
" mov dword ptr [edi+0x14], eax" "\n\t"
" mov eax, dword ptr [esi+0x18]" "\n\t"
" mov dword ptr [edi+0x18], eax" "\n\t"
" mov eax, dword ptr [esi+0x1C]" "\n\t"
" mov dword ptr [edi+0x1C], eax" "\n\t"
" mov eax, dword ptr [esi+0x20]" "\n\t"
" mov dword ptr [edi+0x20], eax" "\n\t"
" mov eax, dword ptr [esi+0x24]" "\n\t"
" mov dword ptr [edi+0x24], eax" "\n\t"
" mov eax, dword ptr [esi+0x28]" "\n\t"
" mov dword ptr [edi+0x28], eax" "\n\t"
" mov eax, dword ptr [esi+0x2C]" "\n\t"
" mov dword ptr [edi+0x2C], eax" "\n\t"
" mov eax, dword ptr [esi+0x30]" "\n\t"
" mov dword ptr [edi+0x30], eax" "\n\t"
" mov eax, dword ptr [esi+0x34]" "\n\t"
" mov dword ptr [edi+0x34], eax" "\n\t"
" mov eax, dword ptr [esi+0x38]" "\n\t"
" mov dword ptr [edi+0x38], eax" "\n\t"
" mov eax, dword ptr [esi+0x3C]" "\n\t"
" mov dword ptr [edi+0x3C], eax" "\n\t"
".att_syntax prefix" "\n\t"
: /* no output */
: "S"(m1), "D"(m0)
: "%eax", "memory" );
# else // X86_ASM
memcpy( m0, m1, 16 * sizeof( float ) );
# endif // !X86_ASM
#endif
}
inline void MultMatrix( float m0[4][4], float m1[4][4] )
{
#ifndef __LINUX__
__asm {
mov esi, dword ptr [m0]
mov edi, dword ptr [m1]
mov cx, 4
MultMatrix_Loop:
// ST(5) ST(4) ST(3) ST(2) ST(1) ST
fld dword ptr [esi+30h] // m030
fld dword ptr [esi+20h] // m030 m020
fld dword ptr [esi+10h] // m030 m020 m010
fld dword ptr [esi] // m030 m020 m010 m000
fld dword ptr [edi] // m030 m020 m010 m000 m100
fmul ST, ST(1) // m030 m020 m010 m000 m000*m100
fld dword ptr [edi+04h] // m030 m020 m010 m000 m000*m100 m101
fmul ST, ST(3) // m030 m020 m010 m000 m000*m100 m010*m101
fadd // m030 m020 m010 m000 m000*m100+m010*m101
fld dword ptr [edi+08h] // m030 m020 m010 m000 m000*m100+m010*m101 m102
fmul ST, ST(4) // m030 m020 m010 m000 m000*m100+m010*m101 m020*m102
fadd // m030 m020 m010 m000 m000*m100+m010*m101+m020*m102
fld dword ptr [edi+0Ch] // m030 m020 m010 m000 m000*m100+m010*m101+m020*m102 m103
fmul ST, ST(5) // m030 m020 m010 m000 m000*m100+m010*m101+m020*m102 m030*m103
fadd // m030 m020 m010 m000 m000*m100+m010*m101+m020*m102+m030*m103
fstp dword ptr [esi] // m030 m020 m010 m000
fld dword ptr [edi+10h] // m030 m020 m010 m000 m110
fmul ST, ST(1) // m030 m020 m010 m000 m000*m110
fld dword ptr [edi+14h] // m030 m020 m010 m000 m000*m110 m111
fmul ST, ST(3) // m030 m020 m010 m000 m000*m110 m010*m111
fadd // m030 m020 m010 m000 m000*m110+m010*m111
fld dword ptr [edi+18h] // m030 m020 m010 m000 m000*m110+m010*m111 m112
fmul ST, ST(4) // m030 m020 m010 m000 m000*m110+m010*m111 m020*m112
fadd // m030 m020 m010 m000 m000*m110+m010*m111+m020*m112
fld dword ptr [edi+1Ch] // m030 m020 m010 m000 m000*m110+m010*m111+m020*m112 m113
fmul ST, ST(5) // m030 m020 m010 m000 m000*m110+m010*m111+m020*m112 m030*m113
fadd // m030 m020 m010 m000 m000*m110+m010*m111+m020*m112+m030*m113
fstp dword ptr [esi+10h] // m030 m020 m010 m000
fld dword ptr [edi+20h] // m030 m020 m010 m000 m120
fmul ST, ST(1) // m030 m020 m010 m000 m000*m120
fld dword ptr [edi+24h] // m030 m020 m010 m000 m000*m120 m121
fmul ST, ST(3) // m030 m020 m010 m000 m000*m120 m010*m121
fadd // m030 m020 m010 m000 m000*m120+m010*m121
fld dword ptr [edi+28h] // m030 m020 m010 m000 m000*m120+m010*m121 m122
fmul ST, ST(4) // m030 m020 m010 m000 m000*m120+m010*m121 m020*m122
fadd // m030 m020 m010 m000 m000*m120+m010*m121+m020*m122
fld dword ptr [edi+2Ch] // m030 m020 m010 m000 m000*m120+m010*m121+m020*m122 m123
fmul ST, ST(5) // m030 m020 m010 m000 m000*m120+m010*m121+m020*m122 m030*m123
fadd // m030 m020 m010 m000 m000*m120+m010*m121+m020*m122+m030*m123
fstp dword ptr [esi+20h] // m030 m020 m010 m000
fld dword ptr [edi+30h] // m030 m020 m010 m000 m130
fmulp ST(1), ST // m030 m020 m010 m000*m130
fld dword ptr [edi+34h] // m030 m020 m010 m000*m130 m131
fmulp ST(2), ST // m030 m020 m010*m131 m000*m130
fadd // m030 m020 m010*m131+m000*m130
fld dword ptr [edi+38h] // m030 m020 m010*m131+m000*m130 m132
fmulp ST(2), ST // m030 m020*m132 m010*m131+m000*m130
fadd // m030 m020*m132+m010*m131+m000*m130
fld dword ptr [edi+3Ch] // m030 m020*m132+m010*m131+m000*m130 m133
fmulp ST(2), ST // m030*m133 m020*m132+m010*m131+m000*m130
fadd // m030*m133+m020*m132+m010*m131+m000*m130
fstp dword ptr [esi+30h] //
add esi, 4
dec cx
cmp cx, 0
ja MultMatrix_Loop
}
#else // !__LINUX__
# ifdef X86_ASM
__asm__ __volatile__(
".intel_syntax noprefix" "\n\t"
"MultMatrix_Loop:" "\n\t"
" fld dword ptr [esi+0x30]" "\n\t"
" fld dword ptr [esi+0x20]" "\n\t"
" fld dword ptr [esi+0x10]" "\n\t"
" fld dword ptr [esi]" "\n\t"
" fld dword ptr [edi]" "\n\t"
" fmul ST, ST(1)" "\n\t"
" fld dword ptr [edi+0x04]" "\n\t"
" fmul ST, ST(3)" "\n\t"
" fadd" "\n\t"
" fld dword ptr [edi+0x08]" "\n\t"
" fmul ST, ST(4)" "\n\t"
" fadd" "\n\t"
" fld dword ptr [edi+0x0C]" "\n\t"
" fmul ST, ST(5)" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [esi]" "\n\t"
" fld dword ptr [edi+0x10]" "\n\t"
" fmul ST, ST(1)" "\n\t"
" fld dword ptr [edi+0x14]" "\n\t"
" fmul ST, ST(3)" "\n\t"
" fadd" "\n\t"
" fld dword ptr [edi+0x18]" "\n\t"
" fmul ST, ST(4)" "\n\t"
" fadd" "\n\t"
" fld dword ptr [edi+0x1C]" "\n\t"
" fmul ST, ST(5)" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [esi+0x10]" "\n\t"
" fld dword ptr [edi+0x20]" "\n\t"
" fmul ST, ST(1)" "\n\t"
" fld dword ptr [edi+0x24]" "\n\t"
" fmul ST, ST(3)" "\n\t"
" fadd" "\n\t"
" fld dword ptr [edi+0x28]" "\n\t"
" fmul ST, ST(4)" "\n\t"
" fadd" "\n\t"
" fld dword ptr [edi+0x2C]" "\n\t"
" fmul ST, ST(5)" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [esi+0x20]" "\n\t"
" fld dword ptr [edi+0x30]" "\n\t"
" fmulp ST(1), ST" "\n\t"
" fld dword ptr [edi+0x34]" "\n\t"
" fmulp ST(2), ST" "\n\t"
" fadd" "\n\t"
" fld dword ptr [edi+0x38]" "\n\t"
" fmulp ST(2), ST" "\n\t"
" fadd" "\n\t"
" fld dword ptr [edi+0x3C]" "\n\t"
" fmulp ST(2), ST" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [esi+0x30]" "\n\t"
" add esi, 4" "\n\t"
" dec cx" "\n\t"
" cmp cx, 0" "\n\t"
" ja MultMatrix_Loop" "\n\t"
".att_syntax prefix" "\n\t"
: /* no output */
: "S"(m0), "D"(m1), "c"(4)
: "memory" );
# else // X86_ASM
int i;
float dst[4][4];
for (i = 0; i < 4; i++)
{
dst[0][i] = m0[0][i]*m1[0][0] + m0[1][i]*m1[0][1] + m0[2][i]*m1[0][2] + m0[3][i]*m1[0][3];
dst[1][i] = m0[0][i]*m1[1][0] + m0[1][i]*m1[1][1] + m0[2][i]*m1[1][2] + m0[3][i]*m1[1][3];
dst[2][i] = m0[0][i]*m1[2][0] + m0[1][i]*m1[2][1] + m0[2][i]*m1[2][2] + m0[3][i]*m1[2][3];
dst[3][i] = m0[3][i]*m1[3][3] + m0[2][i]*m1[3][2] + m0[1][i]*m1[3][1] + m0[0][i]*m1[3][0];
}
memcpy( m0, dst, sizeof(float) * 16 );
# endif // !X86_ASM
#endif // __LINUX__
}
inline void Transpose3x3Matrix( float mtx[4][4] )
{
#ifndef __LINUX__
__asm
{
mov esi, [mtx]
mov eax, dword ptr [esi+04h]
mov ebx, dword ptr [esi+10h]
mov dword ptr [esi+04h], ebx
mov dword ptr [esi+10h], eax
mov eax, dword ptr [esi+08h]
mov ebx, dword ptr [esi+20h]
mov dword ptr [esi+08h], ebx
mov dword ptr [esi+20h], eax
mov eax, dword ptr [esi+18h]
mov ebx, dword ptr [esi+24h]
mov dword ptr [esi+18h], ebx
mov dword ptr [esi+24h], eax
}
#else // !__LINUX__
# ifdef X86_ASM
__asm__ __volatile__(
".intel_syntax noprefix" "\n\t"
" mov eax, dword ptr [esi+0x04]" "\n\t"
" mov ebx, dword ptr [esi+0x10]" "\n\t"
" mov dword ptr [esi+0x04], ebx" "\n\t"
" mov dword ptr [esi+0x10], eax" "\n\t"
" mov eax, dword ptr [esi+0x08]" "\n\t"
" mov ebx, dword ptr [esi+0x20]" "\n\t"
" mov dword ptr [esi+0x08], ebx" "\n\t"
" mov dword ptr [esi+0x20], eax" "\n\t"
" mov eax, dword ptr [esi+0x18]" "\n\t"
" mov ebx, dword ptr [esi+0x24]" "\n\t"
" mov dword ptr [esi+0x18], ebx" "\n\t"
" mov dword ptr [esi+0x24], eax" "\n\t"
".att_syntax prefix" "\n\t"
: /* no output */
: "S"(mtx)
: "%eax", "%ebx", "memory" );
# else // X86_ASM
float tmp;
tmp = mtx[0][1];
mtx[0][1] = mtx[1][0];
mtx[1][0] = tmp;
tmp = mtx[0][2];
mtx[0][2] = mtx[2][0];
mtx[2][0] = tmp;
tmp = mtx[1][2];
mtx[1][2] = mtx[2][1];
mtx[2][1] = tmp;
# endif // !X86_ASM
#endif // __LINUX__
}
inline void TransformVertex( float vtx[4], float mtx[4][4] )//, float perspNorm )
{
#ifndef __LINUX__
__asm {
mov esi, dword ptr [vtx]
mov ebx, dword ptr [mtx]
// ST(4) ST(3) ST(2) ST(1) ST
fld dword ptr [esi+8] // vtx2
fld dword ptr [esi+4] // vtx2 vtx1
fld dword ptr [esi] // vtx2 vtx1 vtx0
fld dword ptr [ebx] // vtx2 vtx1 vtx0 mtx00
fmul ST, ST(1) // vtx2 vtx1 vtx0 vtx0*mtx00
fld dword ptr [ebx+10h] // vtx2 vtx1 vtx0 vtx0*mtx00 mtx10
fmul ST, ST(3) // vtx2 vtx1 vtx0 vtx0*mtx00 vtx1*mtx10
fadd // vtx2 vtx1 vtx0 vtx0*mtx00+vtx1*mtx10
fld dword ptr [ebx+20h] // vtx2 vtx1 vtx0 vtx0*mtx00+vtx1*mtx10 mtx20
fmul ST, ST(4) // vtx2 vtx1 vtx0 vtx0*mtx00+vtx1*mtx10 vtx2*mtx20
fadd // vtx2 vtx1 vtx0 vtx0*mtx00+vtx1*mtx10+vtx2*mtx20
fadd dword ptr [ebx+30h] // vtx2 vtx1 vtx0 vtx0*mtx00+vtx1*mtx10+vtx2*mtx20+mtx30
// fmul dword ptr [perspNorm] // (vtx2*mtx23+vtx1*mtx13+vtx0*mtx03+mtx33)*perspNorm
fstp dword ptr [esi] // vtx2 vtx1 vtx[0]
fld dword ptr [ebx+04h] // vtx2 vtx1 vtx0 mtx01
fmul ST, ST(1) // vtx2 vtx1 vtx0 vtx0*mtx01
fld dword ptr [ebx+14h] // vtx2 vtx1 vtx0 vtx0*mtx01 mtx11
fmul ST, ST(3) // vtx2 vtx1 vtx0 vtx0*mtx01 vtx1*mtx11
fadd // vtx2 vtx1 vtx0 vtx0*mtx01+vtx1*mtx11
fld dword ptr [ebx+24h] // vtx2 vtx1 vtx0 vtx0*mtx01+vtx1*mtx11 mtx21
fmul ST, ST(4) // vtx2 vtx1 vtx0 vtx0*mtx01+vtx1*mtx11 vtx2*mtx21
fadd // vtx2 vtx1 vtx0 vtx0*mtx01+vtx1*mtx11+vtx2*mtx21
fadd dword ptr [ebx+34h] // vtx2 vtx1 vtx0 vtx0*mtx01+vtx1*mtx11+vtx2*mtx21+mtx31
// fmul dword ptr [perspNorm] // (vtx2*mtx23+vtx1*mtx13+vtx0*mtx03+mtx33)*perspNorm
fstp dword ptr [esi+04h] // vtx2 vtx1 vtx[0]
fld dword ptr [ebx+08h] // vtx2 vtx1 vtx0 mtx02
fmul ST, ST(1) // vtx2 vtx1 vtx0 vtx0*mtx02
fld dword ptr [ebx+18h] // vtx2 vtx1 vtx0 vtx0*mtx02 mtx12
fmul ST, ST(3) // vtx2 vtx1 vtx0 vtx0*mtx02 vtx1*mtx12
fadd // vtx2 vtx1 vtx0 vtx0*mtx02+vtx1*mtx12
fld dword ptr [ebx+28h] // vtx2 vtx1 vtx0 vtx0*mtx02+vtx1*mtx12 mtx22
fmul ST, ST(4) // vtx2 vtx1 vtx0 vtx0*mtx02+vtx1*mtx12 vtx2*mtx22
fadd // vtx2 vtx1 vtx0 vtx0*mtx02+vtx1*mtx12+vtx2*mtx22
fadd dword ptr [ebx+38h] // vtx2 vtx1 vtx0 vtx0*mtx02+vtx1*mtx12+vtx2*mtx22+mtx32
// fmul dword ptr [perspNorm] // (vtx2*mtx23+vtx1*mtx13+vtx0*mtx03+mtx33)*perspNorm
fstp dword ptr [esi+08h] // vtx2 vtx1 vtx0
fld dword ptr [ebx+0Ch] // vtx2 vtx1 vtx0 mtx03
fmulp ST(1), ST // vtx2 vtx1 vtx0*mtx03
fld dword ptr [ebx+1Ch] // vtx2 vtx1 vtx0*mtx03 mtx13
fmulp ST(2), ST // vtx2 vtx1*mtx13 vtx0*mtx03
fadd // vtx2 vtx1*mtx13+vtx0*mtx03
fld dword ptr [ebx+2Ch] // vtx2 vtx1*mtx13+vtx0*mtx03 mtx23
fmulp ST(2), ST // vtx2*mtx23 vtx1*mtx13+vtx0*mtx03
fadd // vtx2*mtx23+vtx1*mtx13+vtx0*mtx03
fadd dword ptr [ebx+3Ch] // vtx2*mtx23+vtx1*mtx13+vtx0*mtx03+mtx33
// fmul dword ptr [perspNorm] // (vtx2*mtx23+vtx1*mtx13+vtx0*mtx03+mtx33)*perspNorm
fstp dword ptr [esi+0Ch] //
}
#else // !__LINUX__
# ifdef X86_ASM
__asm__ __volatile__(
".intel_syntax noprefix" "\n\t"
" fld dword ptr [esi+8]" "\n\t"
" fld dword ptr [esi+4]" "\n\t"
" fld dword ptr [esi]" "\n\t"
" fld dword ptr [ebx]" "\n\t"
" fmul ST, ST(1)" "\n\t"
" fld dword ptr [ebx+0x10]" "\n\t"
" fmul ST, ST(3)" "\n\t"
" fadd" "\n\t"
" fld dword ptr [ebx+0x20]" "\n\t"
" fmul ST, ST(4)" "\n\t"
" fadd" "\n\t"
" fadd dword ptr [ebx+0x30]" "\n\t"
// " fmul dword ptr [perspNorm]" "\n\t"
" fstp dword ptr [esi]" "\n\t"
" fld dword ptr [ebx+0x04]" "\n\t"
" fmul ST, ST(1)" "\n\t"
" fld dword ptr [ebx+0x14]" "\n\t"
" fmul ST, ST(3)" "\n\t"
" fadd" "\n\t"
" fld dword ptr [ebx+0x24]" "\n\t"
" fmul ST, ST(4)" "\n\t"
" fadd" "\n\t"
" fadd dword ptr [ebx+0x34]" "\n\t"
// " fmul dword ptr [perspNorm]" "\n\t"
" fstp dword ptr [esi+0x04]" "\n\t"
" fld dword ptr [ebx+0x08]" "\n\t"
" fmul ST, ST(1)" "\n\t"
" fld dword ptr [ebx+0x18]" "\n\t"
" fmul ST, ST(3)" "\n\t"
" fadd" "\n\t"
" fld dword ptr [ebx+0x28]" "\n\t"
" fmul ST, ST(4)" "\n\t"
" fadd" "\n\t"
" fadd dword ptr [ebx+0x38]" "\n\t"
// " fmul dword ptr [perspNorm]" "\n\t"
" fstp dword ptr [esi+0x08]" "\n\t"
" fld dword ptr [ebx+0x0C]" "\n\t"
" fmulp ST(1), ST" "\n\t"
" fld dword ptr [ebx+0x1C]" "\n\t"
" fmulp ST(2), ST" "\n\t"
" fadd" "\n\t"
" fld dword ptr [ebx+0x2C]" "\n\t"
" fmulp ST(2), ST" "\n\t"
" fadd" "\n\t"
" fadd dword ptr [ebx+0x3C]" "\n\t"
// " fmul dword ptr [perspNorm]" "\n\t"
" fstp dword ptr [esi+0x0C]" "\n\t"
".att_syntax prefix" "\n\t"
: /* no output */
: "S"(vtx), "b"(mtx)
: "memory" );
# else // X86_ASM
float x, y, z, w;
x = vtx[0];
y = vtx[1];
z = vtx[2];
w = vtx[3];
vtx[0] = x * mtx[0][0] +
y * mtx[1][0] +
z * mtx[2][0];
vtx[1] = x * mtx[0][1] +
y * mtx[1][1] +
z * mtx[2][1];
vtx[2] = x * mtx[0][2] +
y * mtx[1][2] +
z * mtx[2][2];
vtx[3] = x * mtx[0][3] +
y * mtx[1][3] +
z * mtx[2][3];
vtx[0] += mtx[3][0];
vtx[1] += mtx[3][1];
vtx[2] += mtx[3][2];
vtx[3] += mtx[3][3];
# endif // X86_ASM
#endif // __LINUX__
}
inline void TransformVector( float vec[3], float mtx[4][4] )
{
#ifndef __LINUX__
__asm {
mov esi, dword ptr [vec]
mov ebx, dword ptr [mtx]
// ST(4) ST(3) ST(2) ST(1) ST
fld dword ptr [esi+8] // vec2
fld dword ptr [esi+4] // vec2 vtx1
fld dword ptr [esi] // vec2 vec1 vec0
fld dword ptr [ebx] // vec2 vec1 vec0 mtx00
fmul ST, ST(1) // vec2 vec1 vec0 vec0*mtx00
fld dword ptr [ebx+10h] // vec2 vec1 vec0 vec0*mtx00 mtx10
fmul ST, ST(3) // vec2 vec1 vec0 vec0*mtx00 vec1*mtx10
fadd // vec2 vec1 vec0 vec0*mtx00+vec1*mtx10
fld dword ptr [ebx+20h] // vec2 vec1 vec0 vec0*mtx00+vec1*mtx10 mtx20
fmul ST, ST(4) // vec2 vec1 vec0 vec0*mtx00+vec1*mtx10 vec2*mtx20
fadd // vec2 vec1 vec0 vec0*mtx00+vec1*mtx10+vec2*mtx20
fstp dword ptr [esi] // vec2 vec1 vec[0]
fld dword ptr [ebx+04h] // vec2 vec1 vec0 mtx01
fmul ST, ST(1) // vec2 vec1 vec0 vec0*mtx01
fld dword ptr [ebx+14h] // vec2 vec1 vec0 vec0*mtx01 mtx11
fmul ST, ST(3) // vec2 vec1 vec0 vec0*mtx01 vec1*mtx11
fadd // vec2 vec1 vec0 vec0*mtx01+vec1*mtx11
fld dword ptr [ebx+24h] // vec2 vec1 vec0 vec0*mtx01+vec1*mtx11 mtx21
fmul ST, ST(4) // vec2 vec1 vec0 vec0*mtx01+vec1*mtx11 vec2*mtx21
fadd // vec2 vec1 vec0 vec0*mtx01+vec1*mtx11+vec2*mtx21
fstp dword ptr [esi+04h] // vec2 vec1 vec[0]
fld dword ptr [ebx+08h] // vec2 vec1 vec0 mtx02
fmulp ST(1), ST // vec2 vec1 vec0*mtx02
fld dword ptr [ebx+18h] // vec2 vec1 vec0*mtx02 mtx12
fmulp ST(2), ST // vec2 vec1*mtx12 vec0*mtx02
fadd // vec2 vec1*mtx12+vec0*mtx02
fld dword ptr [ebx+28h] // vec2 vec1*mtx12+vec0*mtx03 mtx22
fmulp ST(2), ST // vec2*mtx22 vec1*mtx12+vec0*mtx02
fadd // vec2*mtx22+vec1*mtx12+vec0*mtx02
fstp dword ptr [esi+08h] //
}
#else // !__LINUX__
# ifdef X86_ASM
__asm__ __volatile__(
".intel_syntax noprefix" "\n\t"
" fld dword ptr [esi+8]" "\n\t"
" fld dword ptr [esi+4]" "\n\t"
" fld dword ptr [esi]" "\n\t"
" fld dword ptr [ebx]" "\n\t"
" fmul ST, ST(1)" "\n\t"
" fld dword ptr [ebx+0x10]" "\n\t"
" fmul ST, ST(3)" "\n\t"
" fadd" "\n\t"
" fld dword ptr [ebx+0x20]" "\n\t"
" fmul ST, ST(4)" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [esi]" "\n\t"
" fld dword ptr [ebx+0x04]" "\n\t"
" fmul ST, ST(1)" "\n\t"
" fld dword ptr [ebx+0x14]" "\n\t"
" fmul ST, ST(3)" "\n\t"
" fadd" "\n\t"
" fld dword ptr [ebx+0x24]" "\n\t"
" fmul ST, ST(4)" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [esi+0x04]" "\n\t"
" fld dword ptr [ebx+0x08]" "\n\t"
" fmulp ST(1), ST" "\n\t"
" fld dword ptr [ebx+0x18]" "\n\t"
" fmulp ST(2), ST" "\n\t"
" fadd" "\n\t"
" fld dword ptr [ebx+0x28]" "\n\t"
" fmulp ST(2), ST" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [esi+0x08]" "\n\t"
".att_syntax prefix" "\n\t"
: /* no output */
: "S"(vec), "b"(mtx)
: "memory" );
# else // X86_ASM
vec[0] = mtx[0][0] * vec[0]
+ mtx[1][0] * vec[1]
+ mtx[2][0] * vec[2];
vec[1] = mtx[0][1] * vec[0]
+ mtx[1][1] * vec[1]
+ mtx[2][1] * vec[2];
vec[2] = mtx[0][2] * vec[0]
+ mtx[1][2] * vec[1]
+ mtx[2][2] * vec[2];
# endif // !X86_ASM
#endif // __LINUX__
}
inline void Normalize( float v[3] )
{
#ifndef __LINUX__
__asm {
mov esi, dword ptr [v]
// ST(6) ST(5) ST(4) ST(3) ST(2) ST(1) ST
fld dword ptr [esi+08h] // v2
fld dword ptr [esi+04h] // v2 v1
fld dword ptr [esi] // v2 v1 v0
fld1 // v2 v1 v0 1.0
fld ST(3) // v2 v1 v0 1.0 v2
fmul ST, ST // v2 v1 v0 1.0 v2*v2
fld ST(3) // v2 v1 v0 1.0 v2*v2 v1
fmul ST, ST // v2 v1 v0 1.0 v2*v2 v1*v1
fld ST(3) // v2 v1 v0 1.0 v2*v2 v1*v1 v0
fmul ST, ST // v2 v1 v0 1.0 v2*v2 v1*v1 v0*v0
fadd // v2 v1 v0 1.0 v2*v2 v1*v1+v0*v0
fadd // v2 v1 v0 1.0 v2*v2+v1*v1+v0*v0
ftst // Compare ST to 0
fstsw ax // Store FPU status word in ax
sahf // Transfer ax to flags register
jz End // Skip if length is zero
fsqrt // v2 v1 v0 1.0 len
fdiv // v2 v1 v0 1.0/len
fmul ST(3), ST // v2*(1.0/len) v1 v0 1.0/len
fmul ST(2), ST // v2*(1.0/len) v1*(1.0/len) v0 1.0/len
fmul // v2*(1.0/len) v1*(1.0/len) v0*(1.0/len)
fstp dword ptr [esi] // v2*(1.0/len) v1*(1.0/len)
fstp dword ptr [esi+04h] // v2*(1.0/len)
fstp dword ptr [esi+08h] //
End:
finit
}
#else // !__LINUX__
# ifdef X86_ASM
__asm__ __volatile__(
".intel_syntax noprefix" "\n\t"
" fld dword ptr [esi+0x08]" "\n\t"
" fld dword ptr [esi+0x04]" "\n\t"
" fld dword ptr [esi]" "\n\t"
" fld1" "\n\t"
" fld ST(3)" "\n\t"
" fmul ST, ST" "\n\t"
" fld ST(3)" "\n\t"
" fmul ST, ST" "\n\t"
" fld ST(3)" "\n\t"
" fmul ST, ST" "\n\t"
" fadd" "\n\t"
" fadd" "\n\t"
" ftst" "\n\t"
" fstsw ax" "\n\t"
" sahf" "\n\t"
" jz End" "\n\t"
" fsqrt" "\n\t"
" fdiv" "\n\t"
" fmul ST(3), ST" "\n\t"
" fmul ST(2), ST" "\n\t"
" fmul" "\n\t"
" fstp dword ptr [esi]" "\n\t"
" fstp dword ptr [esi+0x04]" "\n\t"
" fstp dword ptr [esi+0x08]" "\n\t"
"End:" "\n\t"
" finit" "\n\t"
".att_syntax prefix" "\n\t"
: /* no output */
: "S"(v)
: "memory", "cc" );
# else // X86_ASM
float len;
len = (float)(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
if (len != 0.0)
{
len = (float)sqrt( len );
v[0] /= (float)len;
v[1] /= (float)len;
v[2] /= (float)len;
}
# endif // X86_ASM
#endif // __LINUX__
}
inline void Normalize2D( float v[2] )
{
#ifndef __LINUX__
__asm {
mov esi, dword ptr [v]
// ST(6) ST(5) ST(4) ST(3) ST(2) ST(1) ST
fld dword ptr [esi+04h] // v1
fld dword ptr [esi] // v1 v0
fld1 // v1 v0 1.0
fld ST(2) // v1 v0 1.0 v1
fmul ST, ST // v1 v0 1.0 v1*v1
fld ST(2) // v1 v0 1.0 v1*v1 v0
fmul ST, ST // v1 v0 1.0 v1*v1 v0*v0
fadd // v1 v0 1.0 v1*v1+v0*v0
fsqrt // v1 v0 1.0 len
fdiv // v1 v0 1.0/len
fmul ST(2), ST // v1*(1.0/len) v0 1.0/len
fmul // v1*(1.0/len) v0*(1.0/len)
fstp dword ptr [esi] // v1*(1.0/len)
fstp dword ptr [esi+04h] //
}
#else // !__LINUX__
# ifdef X86_ASM
__asm__ __volatile__(
".intel_syntax noprefix" "\n\t"
" fld dword ptr [esi+0x04]" "\n\t"
" fld dword ptr [esi]" "\n\t"
" fld1" "\n\t"
" fld ST(2)" "\n\t"
" fmul ST, ST" "\n\t"
" fld ST(2)" "\n\t"
" fmul ST, ST" "\n\t"
" fadd" "\n\t"
" fsqrt" "\n\t"
" fdiv" "\n\t"
" fmul ST(2), ST" "\n\t"
" fmul" "\n\t"
" fstp dword ptr [esi]" "\n\t"
" fstp dword ptr [esi+0x04]" "\n\t"
".att_syntax prefix" "\n\t"
: /* no output */
: "S"(v)
: "memory" );
# else // X86_ASM
float len;
len = (float)sqrt( v[0]*v[0] + v[1]*v[1] );
/* if (len != 0.0)
{*/
v[0] /= len;
v[1] /= len;
/* }
else
{
v[0] = 0.0;
v[1] = 0.0;
}*/
# endif // !X86_ASM
#endif // __LINUX__
}
/*inline float Determinate4x4( float m[4][4] )
{
float m_2233_3223;
float m_2133_3123;
float m_2132_3122;
float m_2033_3023;
float m_2032_3022;
float m_2031_3021;
float det, ret;
__asm {
mov esi, dword ptr [m]
// ST(7) ST(6) ST(5) ST(4) ST(3) ST(2) ST(1) ST
fld dword ptr [esi+20h] // m20
fld dword ptr [esi+30h] // m20 m30
fld dword ptr [esi+34h] // m20 m30 m31
fmul ST, ST(2) // m20 m30 m20*m31
fld dword ptr [esi+24h] // m20 m30 m20*m31 m21
fmul ST, ST(2) // m20 m30 m20*m31 m30*m21
fsub // m20 m30 m20*m31-m30*m21
fstp dword ptr [m_2031_3021] // m20 m30
fld dword ptr [esi+38h] // m20 m30 m32
fmul ST, ST(2) // m20 m30 m20*m32
fld dword ptr [esi+28h] // m20 m30 m20*m32 m22
fmul ST, ST(2) // m20 m30 m20*m32 m30*m22
fsub // m20 m30 m20*m32-m30*m22
fstp dword ptr [m_2032_3022] // m20 m30
fld dword ptr [esi+3Ch] // m20 m30 m33
fmulp ST(2), ST // m20*m33 m30
fld dword ptr [esi+2Ch] // m20*m33 m30 m23
fmul // m20*m33 m30*m23
fsub // m20*m33-m30*m23
fstp dword ptr [m_2033_3023] //
fld dword ptr [esi+24h] // m21
fld dword ptr [esi+34h] // m21 m31
fld dword ptr [esi+38h] // m21 m31 m32
fld dword ptr [esi+28h] // m21 m31 m32 m22
fld ST(1) // m21 m31 m32 m22 m32
fmul ST, ST(4) // m21 m31 m32 m22 m21*m32
fld ST(1) // m21 m31 m32 m22 m21*m32 m22
fmul ST, ST(4) // m21 m31 m32 m22 m21*m32 m31*m22
fsub // m21 m31 m32 m22 m21*m32-m31*m22
fstp dword ptr [m_2132_3122] // m21 m31 m32 m22
fld dword ptr [esi+3Ch] // m21 m31 m32 m22 m33
fxch ST(1), ST // m21 m31 m32 m33 m22
fmul ST, ST(1) // m21 m31 m32 m33 m22*m33
fld dword ptr [esi+2Ch] // m21 m31 m32 m33 m22*m33 m23
fxch ST(3), ST // m21 m31 m23 m33 m22*m33 m32
fmul ST, ST(3) // m21 m31 m23 m33 m22*m33 m32*m23
fsub // m21 m31 m23 m33 m22*m33-m32*m23
fstp dword ptr [m_2233_3223] // m21 m31 m23 m33
fmulp ST(3), ST // m21*m33 m31 m23
fmul // m21*m33 m31*m23
fsub // m21*m33-m31*m23
tstp dword ptr [m_2133_3123] //
fld0 // 0.0
fld dword ptr [esi+1Ch] // 0.0 m13
fld dword ptr [esi+18h] // 0.0 m13 m12
fld dword ptr [m_2233_3223] // 0.0 m13 m12 m_2233_3223
fld dword ptr [esi+14h] // 0.0 m13 m12 m_2233_3223 m11
fmul ST, ST(1) // 0.0 m13 m12 m_2233_3223 m11*m_2233_3223
fld dword ptr [m_2133_3123] // 0.0 m13 m12 m_2233_3223 m11*m_2233_3223 m_2133_3123
fmul ST, ST(3) // 0.0 m13 m12 m_2233_3223 m11*m_2233_3223 m12*m_2133_3123
fsub // 0.0 m13 m12 m_2233_3223 m11*m_2233_3223-m12*m_2133_3123
fld dword ptr [m_2132_3122] // 0.0 m13 m12 m_2233_3223 m11*m_2233_3223-m12*m_2133_3123 m_2132_3122
fmul ST, ST(4) // 0.0 m13 m12 m_2233_3223 m11*m_2233_3223-m12*m_2133_3123 m13*m_2132_3122
fadd // 0.0 m13 m12 m_2233_3223 m11*m_2233_3223-m12*m_2133_3123+m13*m_2132_3122=det1
fmul dword ptr [esi] // 0.0 m13 m12 m_2233_3223 det1*m00=res
faddp ST(4), ST // res m13 m12 m_2233_3223
// needs work from here on
fmul dword ptr [esi+10h] // res m13 m12 m10*m_2233_3223
fld dword ptr [m_2033_3023] // res m13 m12 m10*m_2233_3223 m_2033_3023
fxch ST(2), ST // res m13 m_2033_3023 m10*m_2233_3223 m12
fmul ST, ST(2) // res m13 m_2033_3023 m10*m_2233_3223 m12*m_2033_3023
fsub // res m13 m_2033_3023 m10*m_2233_3223-m12*m_2033_3023
fld dword ptr [m_2032_3022] // res m13 m_2033_3023 m10*m_2233_3223-m12*m_2033_3023 m_2032_3022
fmul ST, ST(3) // res m13 m_2033_3023 m10*m_2233_3223-m12*m_2033_3023 m13*m_2032_3022
fadd // res m13 m_2033_3023 m10*m_2233_3223-m12*m_2033_3023+m13*m_2032_3022=det
fmul dword ptr [esi+04h] // res m13 m_2033_3023 det*m01
fsubp ST(3), ST // res m13 m_2033_3023
fld dword ptr [esi+10h]
det = mr._21 * mr_3244_4234 - mr._22 * mr_3144_4134 + mr._24 * mr_3142_4132;
res += mr._13 * det;
}
}*/
inline float DotProduct( float v0[3], float v1[3] )
{
float dot;
#ifndef __LINUX__
__asm {
mov esi, dword ptr [v0]
mov edi, dword ptr [v1]
lea ebx, [dot]
fld dword ptr [esi]
fmul dword ptr [edi]
fld dword ptr [esi+04h]
fmul dword ptr [edi+04h]
fld dword ptr [esi+08h]
fmul dword ptr [edi+08h]
fadd
fadd
fstp dword ptr [ebx]
}
#else // !__LINUX__
# ifdef X86_ASM
__asm__ __volatile__(
".intel_syntax noprefix" "\n\t"
" fld dword ptr [esi]" "\n\t"
" fmul dword ptr [edi]" "\n\t"
" fld dword ptr [esi+0x04]" "\n\t"
" fmul dword ptr [edi+0x04]" "\n\t"
" fld dword ptr [esi+0x08]" "\n\t"
" fmul dword ptr [edi+0x08]" "\n\t"
" fadd" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [ebx]" "\n\t"
".att_syntax prefix" "\n\t"
: /* no output */
: "S"(v0), "D"(v1), "b"(&dot)
: "memory" );
# else // X86_ASM
dot = v0[0]*v1[0] + v0[1]*v1[1] + v0[2]*v1[2];
# endif // !X86_ASM
#endif // __LINUX__
return dot;
}
#endif

67
CRC.cpp Normal file
View File

@ -0,0 +1,67 @@
#ifndef __LINUX__
# include <windows.h>
#else
# include "winlnxdefs.h"
#endif // __LINUX__
#define CRC32_POLYNOMIAL 0x04C11DB7
unsigned long CRCTable[ 256 ];
DWORD Reflect( DWORD ref, char ch )
{
DWORD value = 0;
// Swap bit 0 for bit 7
// bit 1 for bit 6, etc.
for (int i = 1; i < (ch + 1); i++)
{
if(ref & 1)
value |= 1 << (ch - i);
ref >>= 1;
}
return value;
}
void CRC_BuildTable()
{
DWORD crc;
for (int i = 0; i <= 255; i++)
{
crc = Reflect( i, 8 ) << 24;
for (int j = 0; j < 8; j++)
crc = (crc << 1) ^ (crc & (1 << 31) ? CRC32_POLYNOMIAL : 0);
CRCTable[i] = Reflect( crc, 32 );
}
}
DWORD CRC_Calculate( DWORD crc, void *buffer, DWORD count )
{
BYTE *p;
DWORD orig = crc;
p = (BYTE*) buffer;
while (count--)
crc = (crc >> 8) ^ CRCTable[(crc & 0xFF) ^ *p++];
return crc ^ orig;
}
DWORD CRC_CalculatePalette( DWORD crc, void *buffer, DWORD count )
{
BYTE *p;
DWORD orig = crc;
p = (BYTE*) buffer;
while (count--)
{
crc = (crc >> 8) ^ CRCTable[(crc & 0xFF) ^ *p++];
crc = (crc >> 8) ^ CRCTable[(crc & 0xFF) ^ *p++];
p += 6;
}
return crc ^ orig;
}

10
CRC.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef __LINUX__
# include <windows.h>
#else
# include "winlnxdefs.h"
#endif // __LINUX__
void CRC_BuildTable();
DWORD CRC_Calculate( DWORD crc, void *buffer, DWORD count );
DWORD CRC_CalculatePalette( DWORD crc, void *buffer, DWORD count );

411
Combiner.cpp Normal file
View File

@ -0,0 +1,411 @@
#ifndef __LINUX__
# include <windows.h>
#else
# include "winlnxdefs.h"
#endif // __LINUX__
#include "OpenGL.h"
#include "Combiner.h"
#include "NV_register_combiners.h"
#include "texture_env_combine.h"
#include "texture_env.h"
#include "Debug.h"
#include "gDP.h"
CombinerInfo combiner;
void Combiner_Init()
{
if (OGL.NV_register_combiners)
combiner.compiler = NV_REGISTER_COMBINERS;
else if (OGL.EXT_texture_env_combine || OGL.ARB_texture_env_combine)
combiner.compiler = TEXTURE_ENV_COMBINE;
else
combiner.compiler = TEXTURE_ENV;
switch (combiner.compiler)
{
case TEXTURE_ENV:
Init_texture_env();
break;
case TEXTURE_ENV_COMBINE:
Init_texture_env_combine();
break;
case NV_REGISTER_COMBINERS:
Init_NV_register_combiners();
break;
}
combiner.root = NULL;
}
void Combiner_UpdateCombineColors()
{
switch (combiner.compiler)
{
case TEXTURE_ENV_COMBINE:
Update_texture_env_combine_Colors( (TexEnvCombiner*)combiner.current->compiled );
break;
case NV_REGISTER_COMBINERS:
Update_NV_register_combiners_Colors( (RegisterCombiners*)combiner.current->compiled );
break;
}
gDP.changed &= ~CHANGED_COMBINE_COLORS;
}
void Combiner_SimplifyCycle( CombineCycle *cc, CombinerStage *stage )
{
// Load the first operand
stage->op[0].op = LOAD;
stage->op[0].param1 = cc->sa;
stage->numOps = 1;
// If we're just subtracting zero, skip it
if (cc->sb != ZERO)
{
// Subtracting a number from itself is zero
if (cc->sb == stage->op[0].param1)
stage->op[0].param1 = ZERO;
else
{
stage->op[1].op = SUB;
stage->op[1].param1 = cc->sb;
stage->numOps++;
}
}
// If we either subtracted, or didn't load a zero
if ((stage->numOps > 1) || (stage->op[0].param1 != ZERO))
{
// Multiplying by zero is zero
if (cc->m == ZERO)
{
stage->numOps = 1;
stage->op[0].op = LOAD;
stage->op[0].param1 = ZERO;
}
else
{
// Multiplying by one, so just do a load
if ((stage->numOps == 1) && (stage->op[0].param1 == ONE))
stage->op[0].param1 = cc->m;
else
{
stage->op[stage->numOps].op = MUL;
stage->op[stage->numOps].param1 = cc->m;
stage->numOps++;
}
}
}
// Don't bother adding zero
if (cc->a != ZERO)
{
// If all we have so far is zero, then load this instead
if ((stage->numOps == 1) && (stage->op[0].param1 == ZERO))
stage->op[0].param1 = cc->a;
else
{
stage->op[stage->numOps].op = ADD;
stage->op[stage->numOps].param1 = cc->a;
stage->numOps++;
}
}
// Handle interpolation
if ((stage->numOps == 4) && (stage->op[1].param1 == stage->op[3].param1))
{
stage->numOps = 1;
stage->op[0].op = INTER;
stage->op[0].param2 = stage->op[1].param1;
stage->op[0].param3 = stage->op[2].param1;
}
}
void Combiner_MergeStages( Combiner *c )
{
// If all we have is a load in the first stage we can just replace
// each occurance of COMBINED in the second stage with it
if ((c->stage[0].numOps == 1) && (c->stage[0].op[0].op == LOAD))
{
int combined = c->stage[0].op[0].param1;
for (int i = 0; i < c->stage[1].numOps; i++)
{
c->stage[0].op[i].op = c->stage[1].op[i].op;
c->stage[0].op[i].param1 = (c->stage[1].op[i].param1 == COMBINED) ? combined : c->stage[1].op[i].param1;
c->stage[0].op[i].param2 = (c->stage[1].op[i].param2 == COMBINED) ? combined : c->stage[1].op[i].param2;
c->stage[0].op[i].param3 = (c->stage[1].op[i].param3 == COMBINED) ? combined : c->stage[1].op[i].param3;
}
c->stage[0].numOps = c->stage[1].numOps;
c->numStages = 1;
}
// We can't do any merging on an interpolation
else if (c->stage[1].op[0].op != INTER)
{
int numCombined = 0;
// See how many times the first stage is used in the second one
for (int i = 0; i < c->stage[1].numOps; i++)
if (c->stage[1].op[i].param1 == COMBINED)
numCombined++;
// If it's not used, just replace the first stage with the second
if (numCombined == 0)
{
for (int i = 0; i < c->stage[1].numOps; i++)
{
c->stage[0].op[i].op = c->stage[1].op[i].op;
c->stage[0].op[i].param1 = c->stage[1].op[i].param1;
c->stage[0].op[i].param2 = c->stage[1].op[i].param2;
c->stage[0].op[i].param3 = c->stage[1].op[i].param3;
}
c->stage[0].numOps = c->stage[1].numOps;
c->numStages = 1;
}
// If it's only used once
else if (numCombined == 1)
{
// It's only used in the load, so tack on the ops from stage 2 on stage 1
if (c->stage[1].op[0].param1 == COMBINED)
{
for (int i = 1; i < c->stage[1].numOps; i++)
{
c->stage[0].op[c->stage[0].numOps].op = c->stage[1].op[i].op;
c->stage[0].op[c->stage[0].numOps].param1 = c->stage[1].op[i].param1;
c->stage[0].numOps++;
}
c->numStages = 1;
}
// Otherwise, if it's used in the second op, and that op isn't SUB
// we can switch the parameters so it works out to tack the ops onto stage 1
else if ((c->stage[1].op[1].param1 == COMBINED) && (c->stage[1].op[1].op != SUB))
{
c->stage[0].op[c->stage[0].numOps].op = c->stage[1].op[1].op;
c->stage[0].op[c->stage[0].numOps].param1 = c->stage[1].op[0].param1;
c->stage[0].numOps++;
// If there's another op, tack it onto stage 1 too
if (c->stage[1].numOps > 2)
{
c->stage[0].op[c->stage[0].numOps].op = c->stage[1].op[2].op;
c->stage[0].op[c->stage[0].numOps].param1 = c->stage[1].op[2].param1;
c->stage[0].numOps++;
}
c->numStages = 1;
}
}
}
}
CachedCombiner *Combiner_Compile( u64 mux )
{
gDPCombine combine;
combine.mux = mux;
int numCycles;
Combiner color, alpha;
if (gDP.otherMode.cycleType == G_CYC_2CYCLE)
{
numCycles = 2;
color.numStages = 2;
alpha.numStages = 2;
}
else
{
numCycles = 1;
color.numStages = 1;
alpha.numStages = 1;
}
CombineCycle cc[2];
CombineCycle ac[2];
// Decode and expand the combine mode into a more general form
cc[0].sa = saRGBExpanded[combine.saRGB0];
cc[0].sb = sbRGBExpanded[combine.sbRGB0];
cc[0].m = mRGBExpanded[combine.mRGB0];
cc[0].a = aRGBExpanded[combine.aRGB0];
ac[0].sa = saAExpanded[combine.saA0];
ac[0].sb = sbAExpanded[combine.sbA0];
ac[0].m = mAExpanded[combine.mA0];
ac[0].a = aAExpanded[combine.aA0];
cc[1].sa = saRGBExpanded[combine.saRGB1];
cc[1].sb = sbRGBExpanded[combine.sbRGB1];
cc[1].m = mRGBExpanded[combine.mRGB1];
cc[1].a = aRGBExpanded[combine.aRGB1];
ac[1].sa = saAExpanded[combine.saA1];
ac[1].sb = sbAExpanded[combine.sbA1];
ac[1].m = mAExpanded[combine.mA1];
ac[1].a = aAExpanded[combine.aA1];
for (int i = 0; i < numCycles; i++)
{
// Simplify each RDP combiner cycle into a combiner stage
Combiner_SimplifyCycle( &cc[i], &color.stage[i] );
Combiner_SimplifyCycle( &ac[i], &alpha.stage[i] );
}
if (numCycles == 2)
{
// Attempt to merge the two stages into one
Combiner_MergeStages( &color );
Combiner_MergeStages( &alpha );
}
CachedCombiner *cached = (CachedCombiner*)malloc( sizeof( CachedCombiner ) );
cached->combine.mux = combine.mux;
cached->left = NULL;
cached->right = NULL;
// Send the simplified combiner to the hardware-specific compiler
switch (combiner.compiler)
{
case TEXTURE_ENV:
cached->compiled = (void*)Compile_texture_env( &color, &alpha );
break;
case TEXTURE_ENV_COMBINE:
cached->compiled = (void*)Compile_texture_env_combine( &color, &alpha );
break;
case NV_REGISTER_COMBINERS:
cached->compiled = (void*)Compile_NV_register_combiners( &color, &alpha );
break;
}
return cached;
}
void Combiner_DeleteCombiner( CachedCombiner *combiner )
{
if (combiner->left) Combiner_DeleteCombiner( combiner->left );
if (combiner->right) Combiner_DeleteCombiner( combiner->right );
free( combiner->compiled );
free( combiner );
}
void Combiner_Destroy()
{
if (combiner.root)
{
Combiner_DeleteCombiner( combiner.root );
combiner.root = NULL;
}
for (int i = 0; i < OGL.maxTextureUnits; i++)
{
glActiveTextureARB( GL_TEXTURE0_ARB + i );
glDisable( GL_TEXTURE_2D );
}
}
void Combiner_BeginTextureUpdate()
{
switch (combiner.compiler)
{
case TEXTURE_ENV_COMBINE:
BeginTextureUpdate_texture_env_combine();
break;
}
}
void Combiner_EndTextureUpdate()
{
switch (combiner.compiler)
{
case TEXTURE_ENV_COMBINE:
//EndTextureUpdate_texture_env_combine();
Set_texture_env_combine( (TexEnvCombiner*)combiner.current->compiled );
break;
}
}
DWORD64 Combiner_EncodeCombineMode( WORD saRGB0, WORD sbRGB0, WORD mRGB0, WORD aRGB0,
WORD saA0, WORD sbA0, WORD mA0, WORD aA0,
WORD saRGB1, WORD sbRGB1, WORD mRGB1, WORD aRGB1,
WORD saA1, WORD sbA1, WORD mA1, WORD aA1 )
{
return (((DWORD64)CCEncodeA[saRGB0] << 52) | ((DWORD64)CCEncodeB[sbRGB0] << 28) | ((DWORD64)CCEncodeC[mRGB0] << 47) | ((DWORD64)CCEncodeD[aRGB0] << 15) |
((DWORD64)ACEncodeA[saA0] << 44) | ((DWORD64)ACEncodeB[sbA0] << 12) | ((DWORD64)ACEncodeC[mA0] << 41) | ((DWORD64)ACEncodeD[aA0] << 9) |
((DWORD64)CCEncodeA[saRGB1] << 37) | ((DWORD64)CCEncodeB[sbRGB1] << 24) | ((DWORD64)CCEncodeC[mRGB1] ) | ((DWORD64)CCEncodeD[aRGB1] << 6) |
((DWORD64)ACEncodeA[saA1] << 18) | ((DWORD64)ACEncodeB[sbA1] << 3) | ((DWORD64)ACEncodeC[mA1] << 18) | ((DWORD64)ACEncodeD[aA1] ));
}
void Combiner_SelectCombine( u64 mux )
{
// Hack for the Banjo-Tooie shadow (framebuffer textures must be enabled too)
if ((gDP.otherMode.cycleType == G_CYC_1CYCLE) && (mux == 0x00ffe7ffffcf9fcf) && (cache.current[0]->frameBufferTexture))
{
mux = EncodeCombineMode( 0, 0, 0, 0, TEXEL0, 0, PRIMITIVE, 0,
0, 0, 0, 0, TEXEL0, 0, PRIMITIVE, 0 );
}
CachedCombiner *current = combiner.root;
CachedCombiner *parent = current;
while (current)
{
parent = current;
if (mux == current->combine.mux)
break;
else if (mux < current->combine.mux)
current = current->left;
else
current = current->right;
}
if (current == NULL)
{
current = Combiner_Compile( mux );
if (parent == NULL)
combiner.root = current;
else if (parent->combine.mux > current->combine.mux)
parent->left = current;
else
parent->right = current;
}
combiner.current = current;
gDP.changed |= CHANGED_COMBINE_COLORS;
}
void Combiner_SetCombineStates()
{
switch (combiner.compiler)
{
case TEXTURE_ENV:
Set_texture_env( (TexEnv*)combiner.current->compiled );
break;
case TEXTURE_ENV_COMBINE:
Set_texture_env_combine( (TexEnvCombiner*)combiner.current->compiled );
break;
case NV_REGISTER_COMBINERS:
Set_NV_register_combiners( (RegisterCombiners*)combiner.current->compiled );
break;
}
}
void Combiner_SetCombine( u64 mux )
{
Combiner_SelectCombine( mux );
Combiner_SetCombineStates();
}

365
Combiner.h Normal file
View File

@ -0,0 +1,365 @@
#ifndef COMBINER_H
#define COMBINER_H
#include "glN64.h"
#include "OpenGL.h"
#include "gDP.h"
#include "Types.h"
#define TEXTURE_ENV 0
#define TEXTURE_ENV_COMBINE 1
#define NV_REGISTER_COMBINERS 2
#define NV_TEXTURE_ENV_COMBINE4 3
/*
* G_SETCOMBINE: color combine modes
*/
/* Color combiner constants: */
#define G_CCMUX_COMBINED 0
#define G_CCMUX_TEXEL0 1
#define G_CCMUX_TEXEL1 2
#define G_CCMUX_PRIMITIVE 3
#define G_CCMUX_SHADE 4
#define G_CCMUX_ENVIRONMENT 5
#define G_CCMUX_CENTER 6
#define G_CCMUX_SCALE 6
#define G_CCMUX_COMBINED_ALPHA 7
#define G_CCMUX_TEXEL0_ALPHA 8
#define G_CCMUX_TEXEL1_ALPHA 9
#define G_CCMUX_PRIMITIVE_ALPHA 10
#define G_CCMUX_SHADE_ALPHA 11
#define G_CCMUX_ENV_ALPHA 12
#define G_CCMUX_LOD_FRACTION 13
#define G_CCMUX_PRIM_LOD_FRAC 14
#define G_CCMUX_NOISE 7
#define G_CCMUX_K4 7
#define G_CCMUX_K5 15
#define G_CCMUX_1 6
#define G_CCMUX_0 31
/* Alpha combiner constants: */
#define G_ACMUX_COMBINED 0
#define G_ACMUX_TEXEL0 1
#define G_ACMUX_TEXEL1 2
#define G_ACMUX_PRIMITIVE 3
#define G_ACMUX_SHADE 4
#define G_ACMUX_ENVIRONMENT 5
#define G_ACMUX_LOD_FRACTION 0
#define G_ACMUX_PRIM_LOD_FRAC 6
#define G_ACMUX_1 6
#define G_ACMUX_0 7
#define EncodeCombineMode( a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \
a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1 ) \
(u64)(((u64)(_SHIFTL( G_CCMUX_##a0, 20, 4 ) | _SHIFTL( G_CCMUX_##c0, 15, 5 ) | \
_SHIFTL( G_ACMUX_##Aa0, 12, 3 ) | _SHIFTL( G_ACMUX_##Ac0, 9, 3 ) | \
_SHIFTL( G_CCMUX_##a1, 5, 4 ) | _SHIFTL( G_CCMUX_##c1, 0, 5 )) << 32) | \
(u64)(_SHIFTL( G_CCMUX_##b0, 28, 4 ) | _SHIFTL( G_CCMUX_##d0, 15, 3 ) | \
_SHIFTL( G_ACMUX_##Ab0, 12, 3 ) | _SHIFTL( G_ACMUX_##Ad0, 9, 3 ) | \
_SHIFTL( G_CCMUX_##b1, 24, 4 ) | _SHIFTL( G_ACMUX_##Aa1, 21, 3 ) | \
_SHIFTL( G_ACMUX_##Ac1, 18, 3 ) | _SHIFTL( G_CCMUX_##d1, 6, 3 ) | \
_SHIFTL( G_ACMUX_##Ab1, 3, 3 ) | _SHIFTL( G_ACMUX_##Ad1, 0, 3 )))
#define G_CC_PRIMITIVE 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE
#define G_CC_SHADE 0, 0, 0, SHADE, 0, 0, 0, SHADE
#define G_CC_MODULATEI TEXEL0, 0, SHADE, 0, 0, 0, 0, SHADE
#define G_CC_MODULATEIA TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0
#define G_CC_MODULATEIDECALA TEXEL0, 0, SHADE, 0, 0, 0, 0, TEXEL0
#define G_CC_MODULATERGB G_CC_MODULATEI
#define G_CC_MODULATERGBA G_CC_MODULATEIA
#define G_CC_MODULATERGBDECALA G_CC_MODULATEIDECALA
#define G_CC_MODULATEI_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE
#define G_CC_MODULATEIA_PRIM TEXEL0, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0
#define G_CC_MODULATEIDECALA_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, TEXEL0
#define G_CC_MODULATERGB_PRIM G_CC_MODULATEI_PRIM
#define G_CC_MODULATERGBA_PRIM G_CC_MODULATEIA_PRIM
#define G_CC_MODULATERGBDECALA_PRIM G_CC_MODULATEIDECALA_PRIM
#define G_CC_DECALRGB 0, 0, 0, TEXEL0, 0, 0, 0, SHADE
#define G_CC_DECALRGBA 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0
#define G_CC_BLENDI ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE
#define G_CC_BLENDIA ENVIRONMENT, SHADE, TEXEL0, SHADE, TEXEL0, 0, SHADE, 0
#define G_CC_BLENDIDECALA ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0
#define G_CC_BLENDRGBA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, SHADE
#define G_CC_BLENDRGBDECALA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, TEXEL0
#define G_CC_ADDRGB 1, 0, TEXEL0, SHADE, 0, 0, 0, SHADE
#define G_CC_ADDRGBDECALA 1, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0
#define G_CC_REFLECTRGB ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, SHADE
#define G_CC_REFLECTRGBDECALA ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0
#define G_CC_HILITERGB PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE
#define G_CC_HILITERGBA PRIMITIVE, SHADE, TEXEL0, SHADE, PRIMITIVE, SHADE, TEXEL0, SHADE
#define G_CC_HILITERGBDECALA PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0
#define G_CC_SHADEDECALA 0, 0, 0, SHADE, 0, 0, 0, TEXEL0
#define G_CC_BLENDPE PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, SHADE, 0
#define G_CC_BLENDPEDECALA PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, TEXEL0
#define _G_CC_BLENDPE ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, SHADE, 0
#define _G_CC_BLENDPEDECALA ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, 0, 0, 0, TEXEL0
#define _G_CC_TWOCOLORTEX PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE
#define _G_CC_SPARSEST PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0, PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0
#define G_CC_TEMPLERP TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0
#define G_CC_TRILERP TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0, TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0
#define G_CC_INTERFERENCE TEXEL0, 0, TEXEL1, 0, TEXEL0, 0, TEXEL1, 0
#define G_CC_1CYUV2RGB TEXEL0, K4, K5, TEXEL0, 0, 0, 0, SHADE
#define G_CC_YUV2RGB TEXEL1, K4, K5, TEXEL1, 0, 0, 0, 0
#define G_CC_PASS2 0, 0, 0, COMBINED, 0, 0, 0, COMBINED
#define G_CC_MODULATEI2 COMBINED, 0, SHADE, 0, 0, 0, 0, SHADE
#define G_CC_MODULATEIA2 COMBINED, 0, SHADE, 0, COMBINED, 0, SHADE, 0
#define G_CC_MODULATERGB2 G_CC_MODULATEI2
#define G_CC_MODULATERGBA2 G_CC_MODULATEIA2
#define G_CC_MODULATEI_PRIM2 COMBINED, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE
#define G_CC_MODULATEIA_PRIM2 COMBINED, 0, PRIMITIVE, 0, COMBINED, 0, PRIMITIVE, 0
#define G_CC_MODULATERGB_PRIM2 G_CC_MODULATEI_PRIM2
#define G_CC_MODULATERGBA_PRIM2 G_CC_MODULATEIA_PRIM2
#define G_CC_DECALRGB2 0, 0, 0, COMBINED, 0, 0, 0, SHADE
#define G_CC_BLENDI2 ENVIRONMENT, SHADE, COMBINED, SHADE, 0, 0, 0, SHADE
#define G_CC_BLENDIA2 ENVIRONMENT, SHADE, COMBINED, SHADE, COMBINED, 0, SHADE, 0
#define G_CC_CHROMA_KEY2 TEXEL0, CENTER, SCALE, 0, 0, 0, 0, 0
#define G_CC_HILITERGB2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, SHADE
#define G_CC_HILITERGBA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, ENVIRONMENT, COMBINED, TEXEL0, COMBINED
#define G_CC_HILITERGBDECALA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, TEXEL0
#define G_CC_HILITERGBPASSA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, COMBINED
// Internal combiner commands
#define LOAD 0
#define SUB 1
#define MUL 2
#define ADD 3
#define INTER 4
// Internal generalized combiner inputs
#define COMBINED 0
#define TEXEL0 1
#define TEXEL1 2
#define PRIMITIVE 3
#define SHADE 4
#define ENVIRONMENT 5
#define CENTER 6
#define SCALE 7
#define COMBINED_ALPHA 8
#define TEXEL0_ALPHA 9
#define TEXEL1_ALPHA 10
#define PRIMITIVE_ALPHA 11
#define SHADE_ALPHA 12
#define ENV_ALPHA 13
#define LOD_FRACTION 14
#define PRIM_LOD_FRAC 15
#define NOISE 16
#define K4 17
#define K5 18
#define ONE 19
#define ZERO 20
struct CombinerOp
{
int op;
int param1;
int param2;
int param3;
};
struct CombinerStage
{
int numOps;
CombinerOp op[6];
};
struct Combiner
{
int numStages;
CombinerStage stage[2];
};
struct CombineCycle
{
int sa, sb, m, a;
};
static int saRGBExpanded[] =
{
COMBINED, TEXEL0, TEXEL1, PRIMITIVE,
SHADE, ENVIRONMENT, ONE, NOISE,
ZERO, ZERO, ZERO, ZERO,
ZERO, ZERO, ZERO, ZERO
};
static int sbRGBExpanded[] =
{
COMBINED, TEXEL0, TEXEL1, PRIMITIVE,
SHADE, ENVIRONMENT, CENTER, K4,
ZERO, ZERO, ZERO, ZERO,
ZERO, ZERO, ZERO, ZERO
};
static int mRGBExpanded[] =
{
COMBINED, TEXEL0, TEXEL1, PRIMITIVE,
SHADE, ENVIRONMENT, SCALE, COMBINED_ALPHA,
TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA,
ENV_ALPHA, LOD_FRACTION, PRIM_LOD_FRAC, K5,
ZERO, ZERO, ZERO, ZERO,
ZERO, ZERO, ZERO, ZERO,
ZERO, ZERO, ZERO, ZERO,
ZERO, ZERO, ZERO, ZERO
};
static int aRGBExpanded[] =
{
COMBINED, TEXEL0, TEXEL1, PRIMITIVE,
SHADE, ENVIRONMENT, ONE, ZERO
};
static int saAExpanded[] =
{
COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA,
SHADE_ALPHA, ENV_ALPHA, ONE, ZERO
};
static int sbAExpanded[] =
{
COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA,
SHADE_ALPHA, ENV_ALPHA, ONE, ZERO
};
static int mAExpanded[] =
{
LOD_FRACTION, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA,
SHADE_ALPHA, ENV_ALPHA, PRIM_LOD_FRAC, ZERO,
};
static int aAExpanded[] =
{
COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA,
SHADE_ALPHA, ENV_ALPHA, ONE, ZERO
};
static int CCEncodeA[] =
{
0, 1, 2, 3, 4, 5, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 15, 15, 6, 15
};
static int CCEncodeB[] =
{
0, 1, 2, 3, 4, 5, 6, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 15, 15, 15
};
static int CCEncodeC[] =
{
0, 1, 2, 3, 4, 5, 31, 6, 7, 8, 9, 10, 11, 12, 13, 14, 31, 31, 15, 31, 31
};
static int CCEncodeD[] =
{
0, 1, 2, 3, 4, 5, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 6, 15
};
static DWORD64 ACEncodeA[] =
{
7, 7, 7, 7, 7, 7, 7, 7, 0, 1, 2, 3, 4, 5, 7, 7, 7, 7, 7, 6, 7
};
static DWORD64 ACEncodeB[] =
{
7, 7, 7, 7, 7, 7, 7, 7, 0, 1, 2, 3, 4, 5, 7, 7, 7, 7, 7, 6, 7
};
static DWORD64 ACEncodeC[] =
{
7, 7, 7, 7, 7, 7, 7, 7, 0, 1, 2, 3, 4, 5, 7, 6, 7, 7, 7, 7, 7
};
static DWORD64 ACEncodeD[] =
{
7, 7, 7, 7, 7, 7, 7, 7, 0, 1, 2, 3, 4, 5, 7, 7, 7, 7, 7, 6, 7
};
struct CachedCombiner
{
gDPCombine combine;
void *compiled;
CachedCombiner *left, *right;
};
extern struct CombinerInfo
{
struct
{
WORD color, secondaryColor, alpha;
} vertex;
CachedCombiner *root, *current;
int compiler;
BOOL usesT0, usesT1, usesNoise;
} combiner;
#define SetConstant( constant, color, alpha ) \
switch (color) \
{ \
case PRIMITIVE: \
constant.r = gDP.primColor.r; \
constant.g = gDP.primColor.g; \
constant.b = gDP.primColor.b; \
break; \
case ENVIRONMENT: \
constant.r = gDP.envColor.r; \
constant.g = gDP.envColor.g; \
constant.b = gDP.envColor.b; \
break; \
case PRIMITIVE_ALPHA: \
constant.r = gDP.primColor.a; \
constant.g = gDP.primColor.a; \
constant.b = gDP.primColor.a; \
break; \
case ENV_ALPHA: \
constant.r = gDP.envColor.a; \
constant.g = gDP.envColor.a; \
constant.b = gDP.envColor.a; \
break; \
case PRIM_LOD_FRAC: \
constant.r = gDP.primColor.l; \
constant.g = gDP.primColor.l; \
constant.b = gDP.primColor.l; \
break; \
case ONE: \
constant.r = 1.0f; \
constant.g = 1.0f; \
constant.b = 1.0f; \
break; \
case ZERO: \
constant.r = 0.0f; \
constant.g = 0.0f; \
constant.b = 0.0f; \
break; \
} \
\
switch (alpha) \
{ \
case PRIMITIVE_ALPHA: \
constant.a = gDP.primColor.a; \
break; \
case ENV_ALPHA: \
constant.a = gDP.envColor.a; \
break; \
case PRIM_LOD_FRAC: \
constant.a = gDP.primColor.l; \
break; \
case ONE: \
constant.a = 1.0f; \
break; \
case ZERO: \
constant.a = 0.0f; \
break; \
}
void Combiner_Init();
void Combiner_UpdateCombineColors();
void Combiner_UpdateCombineMode();
void Combiner_SetCombine( u64 mux );
void Combiner_SelectCombine( u64 mux );
void Combiner_SetCombineStates();
void Combiner_Destroy();
void Combiner_BeginTextureUpdate();
void Combiner_EndTextureUpdate();
#endif

389
Config.cpp Normal file
View File

@ -0,0 +1,389 @@
#include <windows.h>
#include <stdio.h>
#include "Config.h"
#include "glN64.h"
#include "Resource.h"
#include "RSP.h"
#include "Textures.h"
#include "OpenGL.h"
#include <commctrl.h>
HWND hConfigDlg;
struct
{
struct
{
DWORD width, height, bitDepth, refreshRate;
} selected;
DWORD bitDepth[4];
struct
{
DWORD width, height;
} resolution[32];
DWORD refreshRate[32];
DWORD numBitDepths;
DWORD numResolutions;
DWORD numRefreshRates;
} fullscreen;
#define numWindowedModes 12
struct
{
WORD width, height;
char *description;
} windowedModes[12] = {
{ 320, 240, "320 x 240" },
{ 400, 300, "400 x 300" },
{ 480, 360, "480 x 360" },
{ 640, 480, "640 x 480" },
{ 800, 600, "800 x 600" },
{ 960, 720, "960 x 720" },
{ 1024, 768, "1024 x 768" },
{ 1152, 864, "1152 x 864" },
{ 1280, 960, "1280 x 960" },
{ 1280, 1024, "1280 x 1024" },
{ 1440, 1080, "1440 x 1080" },
{ 1600, 1200, "1600 x 1200" }
};
void Config_LoadConfig()
{
DWORD value, size;
HKEY hKey;
RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\N64 Emulation\\DLL\\glN64", 0, KEY_READ, &hKey );
if (hKey)
{
RegQueryValueEx( hKey, "Fullscreen Bit Depth", 0, NULL, (BYTE*)&OGL.fullscreenBits, &size );
RegQueryValueEx( hKey, "Fullscreen Width", 0, NULL, (BYTE*)&OGL.fullscreenWidth, &size );
RegQueryValueEx( hKey, "Fullscreen Height", 0, NULL, (BYTE*)&OGL.fullscreenHeight, &size );
RegQueryValueEx( hKey, "Fullscreen Refresh", 0, NULL, (BYTE*)&OGL.fullscreenRefresh, &size );
RegQueryValueEx( hKey, "Windowed Width", 0, NULL, (BYTE*)&OGL.windowedWidth, &size );
RegQueryValueEx( hKey, "Windowed Height", 0, NULL, (BYTE*)&OGL.windowedHeight, &size );
RegQueryValueEx( hKey, "Windowed Width", 0, NULL, (BYTE*)&OGL.windowedWidth, &size );
RegQueryValueEx( hKey, "Force Bilinear", 0, NULL, (BYTE*)&value, &size );
OGL.forceBilinear = value ? TRUE : FALSE;
RegQueryValueEx( hKey, "Enable 2xSaI", 0, NULL, (BYTE*)&value, &size );
OGL.enable2xSaI = value ? TRUE : FALSE;
RegQueryValueEx( hKey, "Enable Fog", 0, NULL, (BYTE*)&value, &size );
OGL.fog = value ? TRUE : FALSE;
RegQueryValueEx( hKey, "Texture Cache Size", 0, NULL, (BYTE*)&value, &size );
cache.maxBytes = value * 1048576;
RegQueryValueEx( hKey, "Hardware Frame Buffer Textures", 0, NULL, (BYTE*)&value, &size );
OGL.frameBufferTextures = value ? TRUE : FALSE;
RegQueryValueEx( hKey, "Dithered Alpha Testing", 0, NULL, (BYTE*)&value, &size );
OGL.usePolygonStipple = value ? TRUE : FALSE;
RegQueryValueEx( hKey, "Texture Bit Depth", 0, NULL, (BYTE*)&value, &size );
OGL.textureBitDepth = value;
RegCloseKey( hKey );
}
else
{
OGL.fog = TRUE;
OGL.windowedWidth = 640;
OGL.windowedHeight = 480;
OGL.fullscreenWidth = 640;
OGL.fullscreenHeight = 480;
OGL.fullscreenBits = 16;
OGL.fullscreenRefresh = 60;
OGL.forceBilinear = FALSE;
cache.maxBytes = 32 * 1048576;
OGL.frameBufferTextures = FALSE;
OGL.enable2xSaI = FALSE;
OGL.textureBitDepth = 1;
OGL.usePolygonStipple = FALSE;
}
}
void Config_SaveConfig()
{
DWORD value;
HKEY hKey;
RegCreateKeyEx( HKEY_CURRENT_USER, "Software\\N64 Emulation\\DLL\\glN64", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL );
RegSetValueEx( hKey, "Fullscreen Bit Depth", 0, REG_DWORD, (BYTE*)&OGL.fullscreenBits, 4 );
RegSetValueEx( hKey, "Fullscreen Width", 0, REG_DWORD, (BYTE*)&OGL.fullscreenWidth, 4 );
RegSetValueEx( hKey, "Fullscreen Height", 0, REG_DWORD, (BYTE*)&OGL.fullscreenHeight, 4 );
RegSetValueEx( hKey, "Fullscreen Refresh", 0, REG_DWORD, (BYTE*)&OGL.fullscreenRefresh, 4 );
RegSetValueEx( hKey, "Windowed Width", 0, REG_DWORD, (BYTE*)&OGL.windowedWidth, 4 );
RegSetValueEx( hKey, "Windowed Height", 0, REG_DWORD, (BYTE*)&OGL.windowedHeight, 4 );
value = OGL.forceBilinear ? 1 : 0;
RegSetValueEx( hKey, "Force Bilinear", 0, REG_DWORD, (BYTE*)&value, 4 );
value = OGL.enable2xSaI ? 1 : 0;
RegSetValueEx( hKey, "Enable 2xSaI", 0, REG_DWORD, (BYTE*)&value, 4 );
value = OGL.fog ? 1 : 0;
RegSetValueEx( hKey, "Enable Fog", 0, REG_DWORD, (BYTE*)&value, 4 );
value = cache.maxBytes / 1048576;
RegSetValueEx( hKey, "Texture Cache Size", 0, REG_DWORD, (BYTE*)&value, 4 );
value = OGL.frameBufferTextures ? 1 : 0;
RegSetValueEx( hKey, "Hardware Frame Buffer Textures", 0, REG_DWORD, (BYTE*)&value, 4 );
value = OGL.usePolygonStipple ? 1 : 0;
RegSetValueEx( hKey, "Dithered Alpha Testing", 0, REG_DWORD, (BYTE*)&value, 4 );
value = OGL.textureBitDepth;
RegSetValueEx( hKey, "Texture Bit Depth", 0, REG_DWORD, (BYTE*)&value, 4 );
RegCloseKey( hKey );
}
void Config_ApplyDlgConfig( HWND hWndDlg )
{
char text[256];
int i;
SendDlgItemMessage( hWndDlg, IDC_CACHEMEGS, WM_GETTEXT, 4, (LPARAM)text );
cache.maxBytes = atol( text ) * 1048576;
OGL.forceBilinear = (SendDlgItemMessage( hWndDlg, IDC_FORCEBILINEAR, BM_GETCHECK, NULL, NULL ) == BST_CHECKED);
OGL.enable2xSaI = (SendDlgItemMessage( hWndDlg, IDC_ENABLE2XSAI, BM_GETCHECK, NULL, NULL ) == BST_CHECKED);
OGL.fog = (SendDlgItemMessage( hWndDlg, IDC_FOG, BM_GETCHECK, NULL, NULL ) == BST_CHECKED);
OGL.originAdjust = (OGL.enable2xSaI ? 0.25 : 0.50);
OGL.fullscreenBits = fullscreen.bitDepth[SendDlgItemMessage( hWndDlg, IDC_FULLSCREENBITDEPTH, CB_GETCURSEL, 0, 0 )];
i = SendDlgItemMessage( hWndDlg, IDC_FULLSCREENRES, CB_GETCURSEL, 0, 0 );
OGL.fullscreenWidth = fullscreen.resolution[i].width;
OGL.fullscreenHeight = fullscreen.resolution[i].height;
OGL.fullscreenRefresh = fullscreen.refreshRate[SendDlgItemMessage( hWndDlg, IDC_FULLSCREENREFRESH, CB_GETCURSEL, 0, 0 )];
i = SendDlgItemMessage( hWndDlg, IDC_TEXTUREBPP, CB_GETCURSEL, 0, 0 );
OGL.textureBitDepth = i;
i = SendDlgItemMessage( hWndDlg, IDC_WINDOWEDRES, CB_GETCURSEL, 0, 0 );
OGL.windowedWidth = windowedModes[i].width;
OGL.windowedHeight = windowedModes[i].height;
OGL.frameBufferTextures = (SendDlgItemMessage( hWndDlg, IDC_FRAMEBUFFER, BM_GETCHECK, NULL, NULL ) == BST_CHECKED);
OGL.usePolygonStipple = (SendDlgItemMessage( hWndDlg, IDC_DITHEREDALPHATEST, BM_GETCHECK, NULL, NULL ) == BST_CHECKED);
if (!OGL.fullscreen)
OGL_ResizeWindow();
Config_SaveConfig();
}
void UpdateFullscreenConfig( HWND hWndDlg )
{
DEVMODE deviceMode;
int i;
char text[256];
memset( &fullscreen.bitDepth, 0, sizeof( fullscreen.bitDepth ) );
memset( &fullscreen.resolution, 0, sizeof( fullscreen.resolution ) );
memset( &fullscreen.refreshRate, 0, sizeof( fullscreen.refreshRate ) );
fullscreen.numBitDepths = 0;
fullscreen.numResolutions = 0;
fullscreen.numRefreshRates = 0;
i = 0;
SendDlgItemMessage( hWndDlg, IDC_FULLSCREENBITDEPTH, CB_RESETCONTENT, 0, 0 );
while (EnumDisplaySettings( NULL, i, &deviceMode ) != 0)
{
int j = 0;
for (; j < fullscreen.numBitDepths; j++)
{
if (deviceMode.dmBitsPerPel == fullscreen.bitDepth[j])
break;
}
if ((deviceMode.dmBitsPerPel != fullscreen.bitDepth[j]) && (deviceMode.dmBitsPerPel > 8))
{
fullscreen.bitDepth[fullscreen.numBitDepths] = deviceMode.dmBitsPerPel;
sprintf( text, "%i bit", deviceMode.dmBitsPerPel );
SendDlgItemMessage( hWndDlg, IDC_FULLSCREENBITDEPTH, CB_ADDSTRING, 0, (LPARAM)text );
if (fullscreen.selected.bitDepth == deviceMode.dmBitsPerPel)
SendDlgItemMessage( hWndDlg, IDC_FULLSCREENBITDEPTH, CB_SETCURSEL, fullscreen.numBitDepths, 0 );
fullscreen.numBitDepths++;
}
i++;
}
if (SendDlgItemMessage( hWndDlg, IDC_FULLSCREENBITDEPTH, CB_GETCURSEL, 0, 0 ) == CB_ERR)
SendDlgItemMessage( hWndDlg, IDC_FULLSCREENBITDEPTH, CB_SETCURSEL, SendDlgItemMessage( hWndDlg, IDC_FULLSCREENBITDEPTH, CB_GETCOUNT, 0, 0 ) - 1, 0 );
i = 0;
SendDlgItemMessage( hWndDlg, IDC_FULLSCREENRES, CB_RESETCONTENT, 0, 0 );
while (EnumDisplaySettings( NULL, i, &deviceMode ) != 0)
{
int j = 0;
for (; j < fullscreen.numResolutions; j++)
{
if ((deviceMode.dmPelsWidth == fullscreen.resolution[j].width) &&
(deviceMode.dmPelsHeight == fullscreen.resolution[j].height))
{
break;
}
}
if (((deviceMode.dmPelsWidth != fullscreen.resolution[j].width) ||
(deviceMode.dmPelsHeight != fullscreen.resolution[j].height)) &&
(deviceMode.dmBitsPerPel != fullscreen.selected.bitDepth))
{
fullscreen.resolution[fullscreen.numResolutions].width = deviceMode.dmPelsWidth;
fullscreen.resolution[fullscreen.numResolutions].height = deviceMode.dmPelsHeight;
sprintf( text, "%i x %i", deviceMode.dmPelsWidth, deviceMode.dmPelsHeight );
SendDlgItemMessage( hWndDlg, IDC_FULLSCREENRES, CB_ADDSTRING, 0, (LPARAM)text );
if ((fullscreen.selected.width == deviceMode.dmPelsWidth) &&
(fullscreen.selected.height == deviceMode.dmPelsHeight))
SendDlgItemMessage( hWndDlg, IDC_FULLSCREENRES, CB_SETCURSEL, fullscreen.numResolutions, 0 );
fullscreen.numResolutions++;
}
i++;
}
if (SendDlgItemMessage( hWndDlg, IDC_FULLSCREENRES, CB_GETCURSEL, 0, 0 ) == CB_ERR)
SendDlgItemMessage( hWndDlg, IDC_FULLSCREENRES, CB_SETCURSEL, SendDlgItemMessage( hWndDlg, IDC_FULLSCREENRES, CB_GETCOUNT, 0, 0 ) - 1, 0 );
i = 0;
SendDlgItemMessage( hWndDlg, IDC_FULLSCREENREFRESH, CB_RESETCONTENT, 0, 0 );
while (EnumDisplaySettings( NULL, i, &deviceMode ) != 0)
{
int j = 0;
for (; j < fullscreen.numRefreshRates; j++)
{
if ((deviceMode.dmDisplayFrequency == fullscreen.refreshRate[j]))
break;
}
if ((deviceMode.dmDisplayFrequency != fullscreen.refreshRate[j]) &&
(deviceMode.dmPelsWidth == fullscreen.selected.width) &&
(deviceMode.dmPelsHeight == fullscreen.selected.height) &&
(deviceMode.dmBitsPerPel == fullscreen.selected.bitDepth))
{
fullscreen.refreshRate[j] = deviceMode.dmDisplayFrequency;
sprintf( text, "%i Hz", deviceMode.dmDisplayFrequency );
SendDlgItemMessage( hWndDlg, IDC_FULLSCREENREFRESH, CB_ADDSTRING, 0, (LPARAM)text );
if (fullscreen.selected.refreshRate == deviceMode.dmDisplayFrequency)
SendDlgItemMessage( hWndDlg, IDC_FULLSCREENREFRESH, CB_SETCURSEL, fullscreen.numRefreshRates, 0 );
fullscreen.numRefreshRates++;
}
i++;
}
if (SendDlgItemMessage( hWndDlg, IDC_FULLSCREENREFRESH, CB_GETCURSEL, 0, 0 ) == CB_ERR)
SendDlgItemMessage( hWndDlg, IDC_FULLSCREENREFRESH, CB_SETCURSEL, SendDlgItemMessage( hWndDlg, IDC_FULLSCREENREFRESH, CB_GETCOUNT, 0, 0 ) - 1, 0 );
}
BOOL CALLBACK ConfigDlgProc( HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
char text[256];
int i;
DEVMODE deviceMode;
switch (message)
{
case WM_INITDIALOG:
hConfigDlg = hWndDlg;
fullscreen.selected.width = OGL.fullscreenWidth;
fullscreen.selected.height = OGL.fullscreenHeight;
fullscreen.selected.bitDepth = OGL.fullscreenBits;
fullscreen.selected.refreshRate = OGL.fullscreenRefresh;
UpdateFullscreenConfig( hWndDlg );
EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &deviceMode );
// Fill windowed mode resolution
for (i = 0; i < numWindowedModes; i++)
{
if ((deviceMode.dmPelsWidth > windowedModes[i].width) &&
(deviceMode.dmPelsHeight > windowedModes[i].height))
{
SendDlgItemMessage( hWndDlg, IDC_WINDOWEDRES, CB_ADDSTRING, 0, (LPARAM)windowedModes[i].description );
if ((OGL.windowedWidth == windowedModes[i].width) &&
(OGL.windowedHeight == windowedModes[i].height))
SendDlgItemMessage( hWndDlg, IDC_WINDOWEDRES, CB_SETCURSEL, i, 0 );
}
}
SendDlgItemMessage( hWndDlg, IDC_ENABLE2XSAI, BM_SETCHECK, OGL.enable2xSaI ? (LPARAM)BST_CHECKED : (LPARAM)BST_UNCHECKED, NULL );
// Set forced bilinear check box
SendDlgItemMessage( hWndDlg, IDC_FORCEBILINEAR, BM_SETCHECK, OGL.forceBilinear ? (LPARAM)BST_CHECKED : (LPARAM)BST_UNCHECKED, NULL );
SendDlgItemMessage( hWndDlg, IDC_TEXTUREBPP, CB_ADDSTRING, 0, (LPARAM)"16-bit only (faster)" );
SendDlgItemMessage( hWndDlg, IDC_TEXTUREBPP, CB_ADDSTRING, 0, (LPARAM)"16-bit and 32-bit (normal)" );
SendDlgItemMessage( hWndDlg, IDC_TEXTUREBPP, CB_ADDSTRING, 0, (LPARAM)"32-bit only (best for 2xSaI)" );
SendDlgItemMessage( hWndDlg, IDC_TEXTUREBPP, CB_SETCURSEL, OGL.textureBitDepth, 0 );
// Enable/disable fog
SendDlgItemMessage( hWndDlg, IDC_FOG, BM_SETCHECK, OGL.fog ? (LPARAM)BST_CHECKED : (LPARAM)BST_UNCHECKED, NULL );
SendDlgItemMessage( hWndDlg, IDC_FRAMEBUFFER, BM_SETCHECK, OGL.frameBufferTextures ? (LPARAM)BST_CHECKED : (LPARAM)BST_UNCHECKED, NULL );
SendDlgItemMessage( hWndDlg, IDC_DITHEREDALPHATEST, BM_SETCHECK, OGL.usePolygonStipple ? (LPARAM)BST_CHECKED : (LPARAM)BST_UNCHECKED, NULL );
_ltoa( cache.maxBytes / 1048576, text, 10 );
SendDlgItemMessage( hWndDlg, IDC_CACHEMEGS, WM_SETTEXT, NULL, (LPARAM)text );
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
Config_ApplyDlgConfig( hWndDlg );
EndDialog( hWndDlg, wParam );
hConfigDlg = NULL;
return TRUE;
case IDCANCEL:
EndDialog( hWndDlg, wParam );
hConfigDlg = NULL;
return TRUE;
case IDC_FULLSCREENBITDEPTH:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
fullscreen.selected.bitDepth = fullscreen.bitDepth[SendDlgItemMessage( hWndDlg, IDC_FULLSCREENBITDEPTH, CB_GETCURSEL, 0, 0 )];
UpdateFullscreenConfig( hWndDlg );
}
break;
case IDC_FULLSCREENRES:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
i = SendDlgItemMessage( hWndDlg, IDC_FULLSCREENRES, CB_GETCURSEL, 0, 0 );
fullscreen.selected.width = fullscreen.resolution[i].width;
fullscreen.selected.height = fullscreen.resolution[i].height;
UpdateFullscreenConfig( hWndDlg );
}
break;
case IDC_FULLSCREENREFRESH:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
fullscreen.selected.refreshRate = fullscreen.refreshRate[SendDlgItemMessage( hWndDlg, IDC_FULLSCREENREFRESH, CB_GETCURSEL, 0, 0 )];
UpdateFullscreenConfig( hWndDlg );
}
break;
}
}
return FALSE;
}
void Config_DoConfig()
{
if (!hConfigDlg)
DialogBox( hInstance, MAKEINTRESOURCE(IDD_CONFIGDLG), hWnd, (DLGPROC)ConfigDlgProc );
}

6
Config.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef CONFIG_H
#define CONFIG_H
void Config_LoadConfig();
void Config_DoConfig();
#endif

478
Config_linux.cpp Normal file
View File

@ -0,0 +1,478 @@
#include "winlnxdefs.h"
#include "SDL.h"
#include <errno.h>
#include <gtk/gtk.h>
#include <string.h>
#include "Config.h"
#include "glN64.h"
#include "RSP.h"
#include "Textures.h"
#include "OpenGL.h"
static GtkWidget *configWindow = NULL;
//static GtkWidget *bitdepthCombo[2], *resolutionCombo[2];
static GtkWidget *resolutionCombo;
static GtkWidget *enable2xSAICheck, *forceBilinearCheck, *enableFogCheck;
static GtkWidget *enableHardwareFBCheck, *enablePolygonStippleCheck;
static GtkWidget *textureDepthCombo;
static GtkWidget *textureCacheEntry;
static const char *pluginDir = 0;
static const char *textureBitDepth[] =
{
"16-bit only (faster)",
"16-bit and 32-bit (normal)",
"32-bit only (best for 2xSaI)",
0
};
static void okButton_clicked( GtkWidget *widget, void *data )
{
const char *text;
int i, i1, i2;
FILE *f;
gtk_widget_hide( configWindow );
// apply configuration
/* text = gtk_entry_get_text( GTK_ENTRY(GTK_COMBO(resolutionCombo[0])->entry) );
if (sscanf( text, "%d x %d", &i1, &i2 ) != 2)
{
i1 = 640;
i2 = 480;
}
OGL.fullscreenWidth = i1;
OGL.fullscreenHeight = i2;
text = gtk_entry_get_text( GTK_ENTRY(GTK_COMBO(bitdepthCombo[0])->entry) );
if (sscanf( text, "%d Bit", &i1 ) != 1)
i1 = 0;
OGL.fullscreenBits = i1;
text = gtk_entry_get_text( GTK_ENTRY(GTK_COMBO(resolutionCombo[1])->entry) );
if (sscanf( text, "%d x %d", &i1, &i2 ) != 2)
{
i1 = 640;
i2 = 480;
}
OGL.windowedWidth = i1;
OGL.windowedHeight = i2;
text = gtk_entry_get_text( GTK_ENTRY(GTK_COMBO(bitdepthCombo[1])->entry) );
if (sscanf( text, "%d Bit", &i1 ) != 1)
i1 = 0;
OGL.windowedBits = i1;*/
text = gtk_entry_get_text( GTK_ENTRY(GTK_COMBO(resolutionCombo)->entry) );
if (sscanf( text, "%d x %d", &i1, &i2 ) != 2)
{
i1 = 640;
i2 = 480;
}
OGL.fullscreenWidth = OGL.windowedWidth = i1;
OGL.fullscreenHeight = OGL.windowedHeight = i2;
OGL.forceBilinear = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(forceBilinearCheck) );
OGL.enable2xSaI = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(enable2xSAICheck) );
OGL.fog = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(enableFogCheck) );
OGL.frameBufferTextures = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(enableHardwareFBCheck) );
OGL.usePolygonStipple = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(enablePolygonStippleCheck) );
const char *depth = gtk_entry_get_text( GTK_ENTRY(GTK_COMBO(textureDepthCombo)->entry) );
OGL.textureBitDepth = 1;
for (i = 0; textureBitDepth[i] != 0; i++)
{
if (!strcmp( depth, textureBitDepth[i] ))
OGL.textureBitDepth = i;
}
cache.maxBytes = atoi( gtk_entry_get_text( GTK_ENTRY(textureCacheEntry) ) ) * 1048576;
// write configuration
if (pluginDir == 0)
pluginDir = GetPluginDir();
char filename[PATH_MAX];
snprintf( filename, PATH_MAX, "%s/glN64.conf", pluginDir );
f = fopen( filename, "w" );
if (!f)
{
fprintf( stderr, "[glN64]: (EE) Couldn't save config file '%s': %s\n", filename, strerror( errno ) );
return;
}
/* fprintf( f, "fullscreen width=%d\n", OGL.fullscreenWidth );
fprintf( f, "fullscreen height=%d\n", OGL.fullscreenHeight );
fprintf( f, "fullscreen depth=%d\n", OGL.fullscreenBits );*/
fprintf( f, "width=%d\n", OGL.windowedWidth );
fprintf( f, "height=%d\n", OGL.windowedHeight );
// fprintf( f, "windowed depth=%d\n", OGL.windowedBits );*/
/* fprintf( f, "width=%d\n", OGL.width );
fprintf( f, "height=%d\n", OGL.height );*/
fprintf( f, "force bilinear=%d\n", OGL.forceBilinear );
fprintf( f, "enable 2xSAI=%d\n", OGL.enable2xSaI );
fprintf( f, "enable fog=%d\n", OGL.fog );
fprintf( f, "enable HardwareFB=%d\n", OGL.frameBufferTextures );
fprintf( f, "enable dithered alpha=%d\n", OGL.usePolygonStipple );
fprintf( f, "texture depth=%d\n", OGL.textureBitDepth );
fprintf( f, "cache size=%d\n", cache.maxBytes / 1048576 );
fclose( f );
}
static void cancelButton_clicked( GtkWidget *widget, void *data )
{
gtk_widget_hide( configWindow );
}
static void configWindow_show( GtkWidget *widget, void *data )
{
static char text[300];
// display
/* gtk_entry_set_text( GTK_ENTRY(GTK_COMBO(bitdepthCombo[0])->entry),
(OGL.fullscreenBits == 32) ? "32 Bit" :
((OGL.fullscreenBits == 16) ? "16 Bit" :
"Desktop") );
sprintf( text, "%d x %d", OGL.fullscreenWidth, OGL.fullscreenHeight );
gtk_entry_set_text( GTK_ENTRY(GTK_COMBO(resolutionCombo[0])->entry), text );
gtk_entry_set_text( GTK_ENTRY(GTK_COMBO(bitdepthCombo[1])->entry),
(OGL.windowedBits == 32) ? "32 Bit" :
((OGL.windowedBits == 16) ? "16 Bit" :
"Desktop") );
sprintf( text, "%d x %d", OGL.windowedWidth, OGL.windowedHeight );
gtk_entry_set_text( GTK_ENTRY(GTK_COMBO(resolutionCombo[1])->entry), text );*/
sprintf( text, "%d x %d", OGL.windowedWidth, OGL.windowedHeight );
gtk_entry_set_text( GTK_ENTRY(GTK_COMBO(resolutionCombo)->entry), text );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(enable2xSAICheck), (OGL.enable2xSaI) );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(forceBilinearCheck), (OGL.forceBilinear) );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(enableFogCheck), (OGL.fog) );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(enablePolygonStippleCheck), (OGL.usePolygonStipple) );
// textures
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(enableHardwareFBCheck), (OGL.frameBufferTextures) );
gtk_entry_set_text( GTK_ENTRY(GTK_COMBO(textureDepthCombo)->entry), textureBitDepth[OGL.textureBitDepth] );
sprintf( text, "%d", cache.maxBytes / 1048576 );
gtk_entry_set_text( GTK_ENTRY(textureCacheEntry), text );
}
static int Config_CreateWindow()
{
GtkWidget *okButton, *cancelButton;
GtkWidget *displayFrame, *texturesFrame;
GtkWidget *displayTable, *texturesTable;
// GtkWidget *fullscreenModeLabel, *windowedModeLabel;
GtkWidget *videoModeLabel;
// GtkWidget *bitdepthLabel, *resolutionLabel;
GtkWidget *resolutionLabel;
GtkWidget *textureDepthLabel;
GtkWidget *textureCacheLabel;
GList *resolutionList = NULL, *textureDepthList = NULL;
SDL_Rect **modes;
static char modeBuf[20][20];
int i;
// create dialog
configWindow = gtk_dialog_new();
gtk_signal_connect_object( GTK_OBJECT(configWindow), "delete-event",
GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete), GTK_OBJECT(configWindow) );
gtk_signal_connect_object( GTK_OBJECT(configWindow), "show",
GTK_SIGNAL_FUNC(configWindow_show), NULL );
gtk_window_set_title( GTK_WINDOW(configWindow), pluginName );
// ok button
okButton = gtk_button_new_with_label( "Ok" );
gtk_signal_connect_object( GTK_OBJECT(okButton), "clicked",
GTK_SIGNAL_FUNC(okButton_clicked), NULL );
gtk_container_add( GTK_CONTAINER(GTK_DIALOG(configWindow)->action_area), okButton );
// cancel button
cancelButton = gtk_button_new_with_label( "Cancel" );
gtk_signal_connect_object( GTK_OBJECT(cancelButton), "clicked",
GTK_SIGNAL_FUNC(cancelButton_clicked), NULL );
gtk_container_add( GTK_CONTAINER(GTK_DIALOG(configWindow)->action_area), cancelButton );
// display frame
displayFrame = gtk_frame_new( "Display" );
gtk_container_set_border_width( GTK_CONTAINER(displayFrame), 7 );
gtk_container_add( GTK_CONTAINER(GTK_DIALOG(configWindow)->vbox), displayFrame );
displayTable = gtk_table_new( 5, 3, FALSE );
gtk_container_set_border_width( GTK_CONTAINER(displayTable), 7 );
gtk_table_set_col_spacings( GTK_TABLE(displayTable), 3 );
gtk_table_set_row_spacings( GTK_TABLE(displayTable), 3 );
gtk_container_add( GTK_CONTAINER(displayFrame), displayTable );
/* fullscreenModeLabel = gtk_label_new( "Fullscreen mode" );
windowedModeLabel = gtk_label_new( "Windowed mode" );
bitdepthLabel = gtk_label_new( "Bit depth" );*/
videoModeLabel = gtk_label_new( "Video mode" );
resolutionLabel = gtk_label_new( "Resolution" );
/* for (i = 0; i < 2; i++)
{
static GList *bitdepthList = NULL;
if (!bitdepthList)
{
bitdepthList = g_list_append( bitdepthList, "Desktop" );
bitdepthList = g_list_append( bitdepthList, "16 bit" );
bitdepthList = g_list_append( bitdepthList, "32 bit" );
}
bitdepthCombo[i] = gtk_combo_new();
gtk_combo_set_value_in_list( GTK_COMBO(bitdepthCombo[i]), TRUE, FALSE );
gtk_combo_set_popdown_strings( GTK_COMBO(bitdepthCombo[i]), bitdepthList );
resolutionCombo[i] = gtk_combo_new();
gtk_combo_set_value_in_list( GTK_COMBO(resolutionCombo[i]), TRUE, FALSE );
}*/
// get video mode list
/* modes = SDL_ListModes( NULL, SDL_HWSURFACE );//SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE | SDL_HWSURFACE | SDL_HWACCEL );
if (modes == (SDL_Rect **)0)
{
printf( "glNintendo64: No modes available!\n" );
}
else if (modes == (SDL_Rect **)-1)
{
printf( "glNintendo64: All resolutions available.\n" );
}
else
{
char buf[200];
for (i = 0; modes[i]; i++)// ++i)
{
sprintf( modeBuf[i], "%d x %d", modes[i]->w, modes[i]->h );
resolutionList = g_list_append( resolutionList, modeBuf[i] );
}
}*/
resolutionList = g_list_append( resolutionList, (void *)"320 x 240" );
resolutionList = g_list_append( resolutionList, (void *)"400 x 300" );
resolutionList = g_list_append( resolutionList, (void *)"480 x 360" );
resolutionList = g_list_append( resolutionList, (void *)"640 x 480" );
resolutionList = g_list_append( resolutionList, (void *)"800 x 600" );
resolutionList = g_list_append( resolutionList, (void *)"960 x 720" );
resolutionList = g_list_append( resolutionList, (void *)"1024 x 768" );
resolutionList = g_list_append( resolutionList, (void *)"1152 x 864" );
resolutionList = g_list_append( resolutionList, (void *)"1280 x 960" );
resolutionList = g_list_append( resolutionList, (void *)"1280 x 1024" );
resolutionList = g_list_append( resolutionList, (void *)"1440 x 1080" );
resolutionList = g_list_append( resolutionList, (void *)"1600 x 1200" );
resolutionCombo = gtk_combo_new();
gtk_combo_set_value_in_list( GTK_COMBO(resolutionCombo), TRUE, FALSE );
gtk_combo_set_popdown_strings( GTK_COMBO(resolutionCombo), resolutionList );
enable2xSAICheck = gtk_check_button_new_with_label( "Enable 2xSAI texture scaling" );
forceBilinearCheck = gtk_check_button_new_with_label( "Force bilinear filtering" );
enableFogCheck = gtk_check_button_new_with_label( "Enable fog" );
enablePolygonStippleCheck = gtk_check_button_new_with_label( "Enable dithered alpha testing" );
/* // row 0
gtk_table_attach_defaults( GTK_TABLE(displayTable), bitdepthLabel, 1, 2, 0, 1 );
gtk_table_attach_defaults( GTK_TABLE(displayTable), resolutionLabel, 2, 3, 0, 1 );
// row 1
gtk_table_attach_defaults( GTK_TABLE(displayTable), fullscreenModeLabel, 0, 1, 1, 2 );
gtk_table_attach_defaults( GTK_TABLE(displayTable), bitdepthCombo[0], 1, 2, 1, 2 );
gtk_table_attach_defaults( GTK_TABLE(displayTable), resolutionCombo[0], 2, 3, 1, 2 );
// row 2
gtk_table_attach_defaults( GTK_TABLE(displayTable), windowedModeLabel, 0, 1, 2, 3 );
gtk_table_attach_defaults( GTK_TABLE(displayTable), bitdepthCombo[1], 1, 2, 2, 3 );
gtk_table_attach_defaults( GTK_TABLE(displayTable), resolutionCombo[1], 2, 3, 2, 3 );
*/
// row 0
gtk_table_attach_defaults( GTK_TABLE(displayTable), resolutionLabel, 2, 3, 0, 1 );
// row 1
gtk_table_attach_defaults( GTK_TABLE(displayTable), videoModeLabel, 0, 1, 1, 2 );
gtk_table_attach_defaults( GTK_TABLE(displayTable), resolutionCombo, 2, 3, 1, 2 );
// row 3
gtk_table_attach_defaults( GTK_TABLE(displayTable), enableFogCheck, 0, 1, 3, 4 );
gtk_table_attach_defaults( GTK_TABLE(displayTable), forceBilinearCheck, 1, 2, 3, 4 );
// row 4
gtk_table_attach_defaults( GTK_TABLE(displayTable), enable2xSAICheck, 0, 1, 4, 5 );
gtk_table_attach_defaults( GTK_TABLE(displayTable), enablePolygonStippleCheck, 1, 2, 4, 5 );
// textures frame
texturesFrame = gtk_frame_new( "Textures" );
gtk_container_set_border_width( GTK_CONTAINER(texturesFrame), 7 );
gtk_container_add( GTK_CONTAINER(GTK_DIALOG(configWindow)->vbox), texturesFrame );
texturesTable = gtk_table_new( 3, 2, FALSE );
gtk_container_set_border_width( GTK_CONTAINER(texturesTable), 7 );
gtk_table_set_col_spacings( GTK_TABLE(texturesTable), 3 );
gtk_table_set_row_spacings( GTK_TABLE(texturesTable), 3 );
gtk_container_add( GTK_CONTAINER(texturesFrame), texturesTable );
textureDepthLabel = gtk_label_new( "Texture bit depth" );
textureDepthCombo = gtk_combo_new();
if (!textureDepthList)
{
i = 0;
while (textureBitDepth[i] != 0)
{
textureDepthList = g_list_append( textureDepthList, (void *)textureBitDepth[i] );
i++;
}
}
gtk_combo_set_popdown_strings( GTK_COMBO(textureDepthCombo), textureDepthList );
gtk_combo_set_value_in_list( GTK_COMBO(textureDepthCombo), TRUE, FALSE );
textureCacheLabel = gtk_label_new( "Texture cache size (MB)" );
textureCacheEntry = gtk_entry_new();
gtk_entry_set_text( GTK_ENTRY(textureCacheEntry), "0" );
enableHardwareFBCheck = gtk_check_button_new_with_label( "HW framebuffer textures (experimental)" );
// row 0
gtk_table_attach_defaults( GTK_TABLE(texturesTable), textureDepthLabel, 0, 1, 0, 1 );
gtk_table_attach_defaults( GTK_TABLE(texturesTable), textureDepthCombo, 1, 2, 0, 1 );
// row 1
gtk_table_attach_defaults( GTK_TABLE(texturesTable), textureCacheLabel, 0, 1, 1, 2 );
gtk_table_attach_defaults( GTK_TABLE(texturesTable), textureCacheEntry, 1, 2, 1, 2 );
// row 2
gtk_table_attach_defaults( GTK_TABLE(texturesTable), enableHardwareFBCheck, 0, 2, 2, 3 );
return 0;
}
void Config_LoadConfig()
{
static int loaded = 0;
FILE *f;
char line[2000];
if (loaded)
return;
loaded = 1;
if (pluginDir == 0)
pluginDir = GetPluginDir();
// default configuration
OGL.fullscreenWidth = 640;
OGL.fullscreenHeight = 480;
// OGL.fullscreenBits = 0;
OGL.windowedWidth = 640;
OGL.windowedHeight = 480;
// OGL.windowedBits = 0;
OGL.forceBilinear = 0;
OGL.enable2xSaI = 0;
OGL.fog = 1;
OGL.textureBitDepth = 1; // normal (16 & 32 bits)
OGL.frameBufferTextures = 0;
OGL.usePolygonStipple = 0;
cache.maxBytes = 32 * 1048576;
// read configuration
char filename[PATH_MAX];
snprintf( filename, PATH_MAX, "%s/glN64.conf", pluginDir );
f = fopen( filename, "r" );
if (!f)
{
fprintf( stderr, "[glN64]: (WW) Couldn't open config file '%s' for reading: %s\n", filename, strerror( errno ) );
return;
}
while (!feof( f ))
{
char *val;
fgets( line, 2000, f );
val = strchr( line, '=' );
if (!val)
continue;
*val++ = '\0';
/* if (!strcasecmp( line, "fullscreen width" ))
{
OGL.fullscreenWidth = atoi( val );
}
else if (!strcasecmp( line, "fullscreen height" ))
{
OGL.fullscreenHeight = atoi( val );
}
else if (!strcasecmp( line, "fullscreen depth" ))
{
OGL.fullscreenBits = atoi( val );
}
else if (!strcasecmp( line, "windowed width" ))
{
OGL.windowedWidth = atoi( val );
}
else if (!strcasecmp( line, "windowed height" ))
{
OGL.windowedHeight = atoi( val );
}
else if (!strcasecmp( line, "windowed depth" ))
{
OGL.windowedBits = atoi( val );
}*/
if (!strcasecmp( line, "width" ))
{
int w = atoi( val );
OGL.fullscreenWidth = OGL.windowedWidth = (w == 0) ? (640) : (w);
}
else if (!strcasecmp( line, "height" ))
{
int h = atoi( val );
OGL.fullscreenHeight = OGL.windowedHeight = (h == 0) ? (480) : (h);
}
else if (!strcasecmp( line, "force bilinear" ))
{
OGL.forceBilinear = atoi( val );
}
else if (!strcasecmp( line, "enable 2xSAI" ))
{
OGL.enable2xSaI = atoi( val );
}
else if (!strcasecmp( line, "enable fog" ))
{
OGL.fog = atoi( val );
}
else if (!strcasecmp( line, "cache size" ))
{
cache.maxBytes = atoi( val ) * 1048576;
}
else if (!strcasecmp( line, "enable HardwareFB" ))
{
OGL.frameBufferTextures = atoi( val );
}
else if (!strcasecmp( line, "enable dithered alpha" ))
{
OGL.usePolygonStipple = atoi( val );
}
else if (!strcasecmp( line, "texture depth" ))
{
OGL.textureBitDepth = atoi( val );
}
else
{
printf( "Unknown config option: %s\n", line );
}
}
fclose( f );
}
void Config_DoConfig()
{
Config_LoadConfig();
if (!configWindow)
Config_CreateWindow();
gtk_widget_show_all( configWindow );
}

303
Debug.cpp Normal file
View File

@ -0,0 +1,303 @@
#include <windows.h>
#include <stdio.h>
#include <process.h>
#include "glN64.h"
#include "Debug.h"
#include "resource.h"
#include "RDP.h"
#include "RSP.h"
#include "RichEdit.h"
DebugInfo Debug;
CHARFORMAT handledFormat =
{
sizeof( CHARFORMAT ),
CFM_BOLD | CFM_COLOR | CFM_FACE | CFM_ITALIC | CFM_SIZE,
NULL,
200,
0,
RGB( 0, 0, 0 ),
NULL,
NULL,
(TCHAR*)"Courier New"
};
CHARFORMAT unknownFormat =
{
sizeof( CHARFORMAT ),
CFM_BOLD | CFM_COLOR | CFM_FACE | CFM_ITALIC | CFM_SIZE,
NULL,
200,
0,
RGB( 128, 128, 0 ),
NULL,
NULL,
(TCHAR*)"Courier New"
};
CHARFORMAT errorFormat =
{
sizeof( CHARFORMAT ),
CFM_BOLD | CFM_COLOR | CFM_FACE | CFM_ITALIC | CFM_SIZE,
NULL,
200,
0,
RGB( 128, 0, 0 ),
NULL,
NULL,
(TCHAR*)"Courier New"
};
CHARFORMAT detailFormat =
{
sizeof( CHARFORMAT ),
CFM_BOLD | CFM_COLOR | CFM_FACE | CFM_ITALIC | CFM_SIZE,
NULL,
200,
0,
RGB( 0, 128, 0 ),
NULL,
NULL,
(TCHAR*)"Courier New"
};
HWND hDebugDlg;
BOOL DumpMessages;
FILE *dumpFile;
char dumpFilename[256];
BOOL CALLBACK DebugDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch (uMsg)
{
case WM_INITDIALOG:
SendDlgItemMessage( hDlg, IDC_DEBUGEDIT, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&handledFormat );
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
/* case IDC_DUMP:
RSP.dumpNextDL = TRUE;
return TRUE;
case IDC_VERIFYCACHE:
if (!TextureCache_Verify())
MessageBox( NULL, "Texture cache chain is currupted!", "glNintendo64()", MB_OK );
else
MessageBox( NULL, "Texture cache chain verified", "glNintendo64()", MB_OK );
return TRUE;*/
case IDC_DEBUGDETAIL:
Debug.detail = (SendDlgItemMessage( hDlg, IDC_DEBUGDETAIL, BM_GETCHECK, NULL, NULL ) == BST_CHECKED);
break;
case IDC_DEBUGHIGH:
if (SendDlgItemMessage( hDlg, IDC_DEBUGHIGH, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.level = DEBUG_HIGH;
break;
case IDC_DEBUGMEDIUM:
if (SendDlgItemMessage( hDlg, IDC_DEBUGMEDIUM, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.level = DEBUG_MEDIUM;
break;
case IDC_DEBUGLOW:
if (SendDlgItemMessage( hDlg, IDC_DEBUGLOW, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.level = DEBUG_LOW;
break;
case IDC_SHOWHANDLED:
if (SendDlgItemMessage( hDlg, IDC_SHOWHANDLED, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.show |= DEBUG_HANDLED;
else
Debug.show &= ~DEBUG_HANDLED;
break;
case IDC_SHOWUNHANDLED:
if (SendDlgItemMessage( hDlg, IDC_SHOWUNHANDLED, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.show |= DEBUG_UNHANDLED;
else
Debug.show &= ~DEBUG_UNHANDLED;
break;
case IDC_SHOWUNKNOWN:
if (SendDlgItemMessage( hDlg, IDC_SHOWUNKNOWN, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.show |= DEBUG_UNKNOWN;
else
Debug.show &= ~DEBUG_UNKNOWN;
break;
case IDC_SHOWIGNORED:
if (SendDlgItemMessage( hDlg, IDC_SHOWIGNORED, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.show |= DEBUG_IGNORED;
else
Debug.show &= ~DEBUG_IGNORED;
break;
case IDC_SHOWERRORS:
if (SendDlgItemMessage( hDlg, IDC_SHOWERRORS, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.show |= DEBUG_ERROR;
else
Debug.show &= ~DEBUG_ERROR;
break;
case IDC_SHOWCOMBINE:
if (SendDlgItemMessage( hDlg, IDC_SHOWCOMBINE, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.show |= DEBUG_COMBINE;
else
Debug.show &= ~DEBUG_COMBINE;
break;
case IDC_SHOWTEXTURE:
if (SendDlgItemMessage( hDlg, IDC_SHOWTEXTURE, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.show |= DEBUG_TEXTURE;
else
Debug.show &= ~DEBUG_TEXTURE;
break;
case IDC_SHOWVERTEX:
if (SendDlgItemMessage( hDlg, IDC_SHOWVERTEX, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.show |= DEBUG_VERTEX;
else
Debug.show &= ~DEBUG_VERTEX;
break;
case IDC_SHOWTRIANGLE:
if (SendDlgItemMessage( hDlg, IDC_SHOWTRIANGLE, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.show |= DEBUG_TRIANGLE;
else
Debug.show &= ~DEBUG_TRIANGLE;
break;
case IDC_SHOWMATRIX:
if (SendDlgItemMessage( hDlg, IDC_SHOWMATRIX, BM_GETCHECK, NULL, NULL ) == BST_CHECKED)
Debug.show |= DEBUG_MATRIX;
else
Debug.show &= ~DEBUG_MATRIX;
break;
case IDC_PAUSE:
Debug.paused = TRUE;
break;
case IDC_RUN:
Debug.paused = FALSE;
break;
case IDC_STEP:
Debug.step = TRUE;
break;
}
break;
case WM_DESTROY:
PostQuitMessage( 0 );
break;
}
return FALSE;
}
void DebugDlgThreadFunc( void* )
{
LoadLibrary( "RichEd20.dll" );
hDebugDlg = CreateDialog( hInstance, MAKEINTRESOURCE(IDD_DEBUGDLG), hWnd, DebugDlgProc );
MSG msg;
while (GetMessage( &msg, hDebugDlg, 0, 0 ) != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
void OpenDebugDlg()
{
DumpMessages = FALSE;
/* hDebugDlg = CreateDialog( hInstance, MAKEINTRESOURCE(IDD_DEBUGDLG), NULL, DebugDlgProc );
MSG msg;
while (GetMessage( &msg, NULL, 0, 0)
{
if (IsWindow(hwndGoto)
IsDialogMessage( hwndGoto, &msg );
}
_endthread();*/
_beginthread( DebugDlgThreadFunc, 255, NULL );
}
void CloseDebugDlg()
{
DestroyWindow( hDebugDlg );
}
void StartDump( char *filename )
{
DumpMessages = TRUE;
strcpy( dumpFilename, filename );
dumpFile = fopen( filename, "w" );
fclose( dumpFile );
}
void EndDump()
{
DumpMessages = FALSE;
fclose( dumpFile );
}
void DebugRSPState( DWORD pci, DWORD pc, DWORD cmd, DWORD w0, DWORD w1 )
{
Debug.rsp.pci = pci;
Debug.rsp.pc = pc;
Debug.rsp.cmd = cmd;
Debug.rsp.w0 = w0;
Debug.rsp.w1 = w1;
}
void DebugMsg( WORD type, LPCSTR format, ... )
{
char text[256];
va_list va;
va_start( va, format );
if (DumpMessages)
{
dumpFile = fopen( dumpFilename, "a+" );
vfprintf( dumpFile, format, va );
fclose( dumpFile );
}
if ((((type & DEBUG_DETAIL) && Debug.detail) || ((type & 0xF000) == Debug.level)) && (type & 0x0FFF & Debug.show))
{
for (int i = 0; i < 4 * RSP.PCi; i++)
text[i] = ' ';
vsprintf( text + 4 * RSP.PCi, format, va );
INT length = SendDlgItemMessage( hDebugDlg, IDC_DEBUGEDIT, WM_GETTEXTLENGTH, 0, 0 );
INT lengthLimit = SendDlgItemMessage( hDebugDlg, IDC_DEBUGEDIT, EM_GETLIMITTEXT, 0, 0 );
if ((length + strlen( text )) > lengthLimit)
{
INT lineLength = SendDlgItemMessage( hDebugDlg, IDC_DEBUGEDIT, EM_LINELENGTH, 0, 0 );
SendDlgItemMessage( hDebugDlg, IDC_DEBUGEDIT, EM_SETSEL, 0, lineLength + 1 );
SendDlgItemMessage( hDebugDlg, IDC_DEBUGEDIT, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)"" );
}
SendDlgItemMessage( hDebugDlg, IDC_DEBUGEDIT, EM_SETSEL, length, length );
if (type & DEBUG_DETAIL)
SendDlgItemMessage( hDebugDlg, IDC_DEBUGEDIT, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&detailFormat );
else if (type & DEBUG_ERROR)
SendDlgItemMessage( hDebugDlg, IDC_DEBUGEDIT, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&errorFormat );
else if (type & DEBUG_UNKNOWN)
SendDlgItemMessage( hDebugDlg, IDC_DEBUGEDIT, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&unknownFormat );
else
SendDlgItemMessage( hDebugDlg, IDC_DEBUGEDIT, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&handledFormat );
SendDlgItemMessage( hDebugDlg, IDC_DEBUGEDIT, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)text );
SendDlgItemMessage( hDebugDlg, IDC_DEBUGEDIT, EM_LINESCROLL, 0, 1 );
sprintf( text, "%02X", Debug.rsp.pci );
SendDlgItemMessage( hDebugDlg, IDC_PCI, WM_SETTEXT, NULL, (LPARAM)text );
sprintf( text, "%08X", Debug.rsp.pc );
SendDlgItemMessage( hDebugDlg, IDC_PC, WM_SETTEXT, NULL, (LPARAM)text );
sprintf( text, "%02X", Debug.rsp.cmd );
SendDlgItemMessage( hDebugDlg, IDC_CMD, WM_SETTEXT, NULL, (LPARAM)text );
sprintf( text, "%08X", Debug.rsp.w0 );
SendDlgItemMessage( hDebugDlg, IDC_W0, WM_SETTEXT, NULL, (LPARAM)text );
sprintf( text, "%08X", Debug.rsp.w1 );
SendDlgItemMessage( hDebugDlg, IDC_W1, WM_SETTEXT, NULL, (LPARAM)text );
}
va_end( va );
}

46
Debug.h Normal file
View File

@ -0,0 +1,46 @@
#if !defined( DEBUG_H ) && defined( _DEBUG )
#define DEBUG_H
#ifndef __LINUX__
# include <windows.h>
#else
# include "winlnxdefs.h"
#endif
#include <stdio.h>
#define DEBUG_LOW 0x1000
#define DEBUG_MEDIUM 0x2000
#define DEBUG_HIGH 0x4000
#define DEBUG_DETAIL 0x8000
#define DEBUG_HANDLED 0x0001
#define DEBUG_UNHANDLED 0x0002
#define DEBUG_IGNORED 0x0004
#define DEBUG_UNKNOWN 0x0008
#define DEBUG_ERROR 0x0010
#define DEBUG_COMBINE 0x0020
#define DEBUG_TEXTURE 0x0040
#define DEBUG_VERTEX 0x0080
#define DEBUG_TRIANGLE 0x0100
#define DEBUG_MATRIX 0x0200
struct DebugInfo
{
WORD show, level;
BOOL detail, paused, step;
struct
{
DWORD pci, pc, cmd, w0, w1;
} rsp;
};
extern DebugInfo Debug;
void OpenDebugDlg();
void CloseDebugDlg();
void DebugRSPState( DWORD pci, DWORD pc, DWORD cmd, DWORD w0, DWORD w1 );
void DebugMsg( WORD type, LPCSTR format, ... );
void StartDump( char *filename );
void EndDump();
#endif // DEBUG_H

70
Debug_linux.cpp Normal file
View File

@ -0,0 +1,70 @@
#include "Debug.h"
#ifdef DEBUG
#include <stdarg.h>
#include <stdio.h>
DebugInfo Debug;
static bool dumpMessages = FALSE;
static char dumpFilename[1024];
void
OpenDebugDlg()
{
}
void
CloseDebugDlg()
{
}
void
DebugRSPState( DWORD pci, DWORD pc, DWORD cmd, DWORD w0, DWORD w1 )
{
}
void
DebugMsg( WORD type, LPCSTR format, ... )
{
char text[1024];
va_list va;
va_start( va, format );
vsprintf( text, format, va );
va_end( va );
if (dumpMessages)
{
FILE *f = fopen( dumpFilename, "a" );
if (f != 0)
{
fprintf( f, text );
fclose( f );
}
}
fprintf( stderr, "glN64 Debug: %s", text );
}
void
StartDump( char *filename )
{
dumpMessages = TRUE;
strcpy( dumpFilename, filename );
FILE *f = fopen( dumpFilename, "w" );
if (f != 0)
fclose( f );
}
void EndDump()
{
dumpMessages = FALSE;
}
#endif // DEBUG

166
DepthBuffer.cpp Normal file
View File

@ -0,0 +1,166 @@
#include <malloc.h>
#include "DepthBuffer.h"
#include "Types.h"
DepthBufferInfo depthBuffer;
void DepthBuffer_Init()
{
depthBuffer.current = NULL;
depthBuffer.top = NULL;
depthBuffer.bottom = NULL;
depthBuffer.numBuffers = 0;
}
void DepthBuffer_RemoveBottom()
{
DepthBuffer *newBottom = depthBuffer.bottom->higher;
if (depthBuffer.bottom == depthBuffer.top)
depthBuffer.top == NULL;
free( depthBuffer.bottom );
depthBuffer.bottom = newBottom;
if (depthBuffer.bottom != NULL)
depthBuffer.bottom->lower = NULL;
depthBuffer.numBuffers--;
}
void DepthBuffer_Remove( DepthBuffer *buffer )
{
if ((buffer == depthBuffer.bottom) &&
(buffer == depthBuffer.top))
{
depthBuffer.top = NULL;
depthBuffer.bottom = NULL;
}
else if (buffer == depthBuffer.bottom)
{
depthBuffer.bottom = buffer->higher;
if (depthBuffer.bottom)
depthBuffer.bottom->lower = NULL;
}
else if (buffer == depthBuffer.top)
{
depthBuffer.top = buffer->lower;
if (depthBuffer.top)
depthBuffer.top->higher = NULL;
}
else
{
buffer->higher->lower = buffer->lower;
buffer->lower->higher = buffer->higher;
}
free( buffer );
depthBuffer.numBuffers--;
}
void DepthBuffer_RemoveBuffer( u32 address )
{
DepthBuffer *current = depthBuffer.bottom;
while (current != NULL)
{
if (current->address == address)
{
DepthBuffer_Remove( current );
return;
}
current = current->higher;
}
}
DepthBuffer *DepthBuffer_AddTop()
{
DepthBuffer *newtop = (DepthBuffer*)malloc( sizeof( DepthBuffer ) );
newtop->lower = depthBuffer.top;
newtop->higher = NULL;
if (depthBuffer.top)
depthBuffer.top->higher = newtop;
if (!depthBuffer.bottom)
depthBuffer.bottom = newtop;
depthBuffer.top = newtop;
depthBuffer.numBuffers++;
return newtop;
}
void DepthBuffer_MoveToTop( DepthBuffer *newtop )
{
if (newtop == depthBuffer.top)
return;
if (newtop == depthBuffer.bottom)
{
depthBuffer.bottom = newtop->higher;
depthBuffer.bottom->lower = NULL;
}
else
{
newtop->higher->lower = newtop->lower;
newtop->lower->higher = newtop->higher;
}
newtop->higher = NULL;
newtop->lower = depthBuffer.top;
depthBuffer.top->higher = newtop;
depthBuffer.top = newtop;
}
void DepthBuffer_Destroy()
{
while (depthBuffer.bottom)
DepthBuffer_RemoveBottom();
depthBuffer.top = NULL;
}
void DepthBuffer_SetBuffer( u32 address )
{
DepthBuffer *current = depthBuffer.top;
// Search through saved depth buffers
while (current != NULL)
{
if (current->address == address)
{
DepthBuffer_MoveToTop( current );
depthBuffer.current = current;
return;
}
current = current->lower;
}
current = DepthBuffer_AddTop();
current->address = address;
current->cleared = TRUE;
depthBuffer.current = current;
}
DepthBuffer *DepthBuffer_FindBuffer( u32 address )
{
DepthBuffer *current = depthBuffer.top;
while (current)
{
if (current->address == address)
return current;
current = current->lower;
}
return NULL;
}

27
DepthBuffer.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef DEPTHBUFFER_H
#define DEPTHBUFFER_H
#include "Types.h"
struct DepthBuffer
{
DepthBuffer *higher, *lower;
u32 address, cleared;
};
struct DepthBufferInfo
{
DepthBuffer *top, *bottom, *current;
int numBuffers;
};
extern DepthBufferInfo depthBuffer;
void DepthBuffer_Init();
void DepthBuffer_Destroy();
void DepthBuffer_SetBuffer( u32 address );
void DepthBuffer_RemoveBuffer( u32 address );
DepthBuffer *DepthBuffer_FindBuffer( u32 address );
#endif

382
F3D.cpp Normal file
View File

@ -0,0 +1,382 @@
#include "glN64.h"
#include "Debug.h"
#include "F3D.h"
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "gSP.h"
#include "gDP.h"
#include "GBI.h"
void F3D_SPNoOp( u32 w0, u32 w1 )
{
gSPNoOp();
}
void F3D_Mtx( u32 w0, u32 w1 )
{
if (_SHIFTR( w0, 0, 16 ) != 64)
{
// GBI_DetectUCode(); // Something's wrong
#ifdef DEBUG
DebugMsg( DEBUG_MEDIUM | DEBUG_HIGH | DEBUG_ERROR, "G_MTX: address = 0x%08X length = %i params = 0x%02X\n", w1, _SHIFTR( w0, 0, 16 ), _SHIFTR( w0, 16, 8 ) );
#endif
return;
}
gSPMatrix( w1, _SHIFTR( w0, 16, 8 ) );
}
void F3D_Reserved0( u32 w0, u32 w1 )
{
#ifdef DEBUG
DebugMsg( DEBUG_MEDIUM | DEBUG_IGNORED | DEBUG_UNKNOWN, "G_RESERVED0: w0=0x%08lX w1=0x%08lX\n", w0, w1 );
#endif
}
void F3D_MoveMem( u32 w0, u32 w1 )
{
switch (_SHIFTR( w0, 16, 8 ))
{
case F3D_MV_VIEWPORT://G_MV_VIEWPORT:
gSPViewport( w1 );
break;
case G_MV_MATRIX_1:
gSPForceMatrix( w1 );
// force matrix takes four commands
RSP.PC[RSP.PCi] += 24;
break;
case G_MV_L0:
gSPLight( w1, LIGHT_1 );
break;
case G_MV_L1:
gSPLight( w1, LIGHT_2 );
break;
case G_MV_L2:
gSPLight( w1, LIGHT_3 );
break;
case G_MV_L3:
gSPLight( w1, LIGHT_4 );
break;
case G_MV_L4:
gSPLight( w1, LIGHT_5 );
break;
case G_MV_L5:
gSPLight( w1, LIGHT_6 );
break;
case G_MV_L6:
gSPLight( w1, LIGHT_7 );
break;
case G_MV_L7:
gSPLight( w1, LIGHT_8 );
break;
case G_MV_LOOKATX:
break;
case G_MV_LOOKATY:
break;
}
}
void F3D_Vtx( u32 w0, u32 w1 )
{
gSPVertex( w1, _SHIFTR( w0, 20, 4 ) + 1, _SHIFTR( w0, 16, 4 ) );
}
void F3D_Reserved1( u32 w0, u32 w1 )
{
}
void F3D_DList( u32 w0, u32 w1 )
{
switch (_SHIFTR( w0, 16, 8 ))
{
case G_DL_PUSH:
gSPDisplayList( w1 );
break;
case G_DL_NOPUSH:
gSPBranchList( w1 );
break;
}
}
void F3D_Reserved2( u32 w0, u32 w1 )
{
}
void F3D_Reserved3( u32 w0, u32 w1 )
{
}
void F3D_Sprite2D_Base( u32 w0, u32 w1 )
{
//gSPSprite2DBase( w1 );
RSP.PC[RSP.PCi] += 8;
}
void F3D_Tri1( u32 w0, u32 w1 )
{
gSP1Triangle( _SHIFTR( w1, 16, 8 ) / 10,
_SHIFTR( w1, 8, 8 ) / 10,
_SHIFTR( w1, 0, 8 ) / 10,
_SHIFTR( w1, 24, 8 ) );
}
void F3D_CullDL( u32 w0, u32 w1 )
{
gSPCullDisplayList( _SHIFTR( w0, 0, 24 ) / 40, (w1 / 40) - 1 );
}
void F3D_PopMtx( u32 w0, u32 w1 )
{
gSPPopMatrix( w1 );
}
void F3D_MoveWord( u32 w0, u32 w1 )
{
switch (_SHIFTR( w0, 0, 8 ))
{
case G_MW_MATRIX:
gSPInsertMatrix( _SHIFTR( w0, 8, 16 ), w1 );
break;
case G_MW_NUMLIGHT:
gSPNumLights( ((w1 - 0x80000000) >> 5) - 1 );
break;
case G_MW_CLIP:
gSPClipRatio( w1 );
break;
case G_MW_SEGMENT:
gSPSegment( _SHIFTR( w0, 8, 16 ) >> 2, w1 & 0x00FFFFFF );
break;
case G_MW_FOG:
/* u32 fm, fo, min, max;
fm = _SHIFTR( w1, 16, 16 );
fo = _SHIFTR( w1, 0, 16 );
min = 500 - (fo * (128000 / fm)) / 256;
max = (128000 / fm) + min;*/
gSPFogFactor( (s16)_SHIFTR( w1, 16, 16 ), (s16)_SHIFTR( w1, 0, 16 ) );
break;
case G_MW_LIGHTCOL:
switch (_SHIFTR( w0, 8, 16 ))
{
case F3D_MWO_aLIGHT_1:
gSPLightColor( LIGHT_1, w1 );
break;
case F3D_MWO_aLIGHT_2:
gSPLightColor( LIGHT_2, w1 );
break;
case F3D_MWO_aLIGHT_3:
gSPLightColor( LIGHT_3, w1 );
break;
case F3D_MWO_aLIGHT_4:
gSPLightColor( LIGHT_4, w1 );
break;
case F3D_MWO_aLIGHT_5:
gSPLightColor( LIGHT_5, w1 );
break;
case F3D_MWO_aLIGHT_6:
gSPLightColor( LIGHT_6, w1 );
break;
case F3D_MWO_aLIGHT_7:
gSPLightColor( LIGHT_7, w1 );
break;
case F3D_MWO_aLIGHT_8:
gSPLightColor( LIGHT_8, w1 );
break;
}
break;
case G_MW_POINTS:
gSPModifyVertex( _SHIFTR( w0, 8, 16 ) / 40, _SHIFTR( w0, 0, 8 ) % 40, w1 );
break;
case G_MW_PERSPNORM:
gSPPerspNormalize( w1 );
break;
}
}
void F3D_Texture( u32 w0, u32 w1 )
{
gSPTexture( _FIXED2FLOAT( _SHIFTR( w1, 16, 16 ), 16 ),
_FIXED2FLOAT( _SHIFTR( w1, 0, 16 ), 16 ),
_SHIFTR( w0, 11, 3 ),
_SHIFTR( w0, 8, 3 ),
_SHIFTR( w0, 0, 8 ) );
}
void F3D_SetOtherMode_H( u32 w0, u32 w1 )
{
switch (_SHIFTR( w0, 8, 8 ))
{
case G_MDSFT_PIPELINE:
gDPPipelineMode( w1 >> G_MDSFT_PIPELINE );
break;
case G_MDSFT_CYCLETYPE:
gDPSetCycleType( w1 >> G_MDSFT_CYCLETYPE );
break;
case G_MDSFT_TEXTPERSP:
gDPSetTexturePersp( w1 >> G_MDSFT_TEXTPERSP );
break;
case G_MDSFT_TEXTDETAIL:
gDPSetTextureDetail( w1 >> G_MDSFT_TEXTDETAIL );
break;
case G_MDSFT_TEXTLOD:
gDPSetTextureLOD( w1 >> G_MDSFT_TEXTLOD );
break;
case G_MDSFT_TEXTLUT:
gDPSetTextureLUT( w1 >> G_MDSFT_TEXTLUT );
break;
case G_MDSFT_TEXTFILT:
gDPSetTextureFilter( w1 >> G_MDSFT_TEXTFILT );
break;
case G_MDSFT_TEXTCONV:
gDPSetTextureConvert( w1 >> G_MDSFT_TEXTCONV );
break;
case G_MDSFT_COMBKEY:
gDPSetCombineKey( w1 >> G_MDSFT_COMBKEY );
break;
case G_MDSFT_RGBDITHER:
gDPSetColorDither( w1 >> G_MDSFT_RGBDITHER );
break;
case G_MDSFT_ALPHADITHER:
gDPSetAlphaDither( w1 >> G_MDSFT_ALPHADITHER );
break;
default:
u32 shift = _SHIFTR( w0, 8, 8 );
u32 length = _SHIFTR( w0, 0, 8 );
u32 mask = ((1 << length) - 1) << shift;
gDP.otherMode.h &= ~mask;
gDP.otherMode.h |= w1 & mask;
gDP.changed |= CHANGED_CYCLETYPE;
break;
}
}
void F3D_SetOtherMode_L( u32 w0, u32 w1 )
{
switch (_SHIFTR( w0, 8, 8 ))
{
case G_MDSFT_ALPHACOMPARE:
gDPSetAlphaCompare( w1 >> G_MDSFT_ALPHACOMPARE );
break;
case G_MDSFT_ZSRCSEL:
gDPSetDepthSource( w1 >> G_MDSFT_ZSRCSEL );
break;
case G_MDSFT_RENDERMODE:
gDPSetRenderMode( w1 & 0xCCCCFFFF, w1 & 0x3333FFFF );
break;
default:
u32 shift = _SHIFTR( w0, 8, 8 );
u32 length = _SHIFTR( w0, 0, 8 );
u32 mask = ((1 << length) - 1) << shift;
gDP.otherMode.l &= ~mask;
gDP.otherMode.l |= w1 & mask;
gDP.changed |= CHANGED_RENDERMODE | CHANGED_ALPHACOMPARE;
break;
}
}
void F3D_EndDL( u32 w0, u32 w1 )
{
gSPEndDisplayList();
}
void F3D_SetGeometryMode( u32 w0, u32 w1 )
{
gSPSetGeometryMode( w1 );
}
void F3D_ClearGeometryMode( u32 w0, u32 w1 )
{
gSPClearGeometryMode( w1 );
}
void F3D_Line3D( u32 w0, u32 w1 )
{
// Hmmm...
}
void F3D_Quad( u32 w0, u32 w1 )
{
gSP1Quadrangle( _SHIFTR( w1, 24, 8 ) / 10, _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, _SHIFTR( w1, 0, 8 ) / 10 );
}
void F3D_RDPHalf_1( u32 w0, u32 w1 )
{
/* if (_SHIFTR( w1, 24, 8 ) == 0xCE)
{
u32 w2 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
gDPTextureRectangle( gDP.scissor.ulx, // ulx
_FIXED2FLOAT( _SHIFTR( w2, 0, 16 ), 2 ), // uly
gDP.scissor.lrx, // lrx
_FIXED2FLOAT( _SHIFTR( w2, 16, 16 ), 2 ), // lry
0, // tile
0, // s
0, // t
1, // dsdx
1 ); // dsdy
}*/
gDP.half_1 = w1;
}
void F3D_RDPHalf_2( u32 w0, u32 w1 )
{
gDP.half_2 = w1;
}
void F3D_RDPHalf_Cont( u32 w0, u32 w1 )
{
}
void F3D_Tri4( u32 w0, u32 w1 )
{
gSP4Triangles( _SHIFTR( w0, 0, 4 ), _SHIFTR( w1, 0, 4 ), _SHIFTR( w1, 4, 4 ),
_SHIFTR( w0, 4, 4 ), _SHIFTR( w1, 8, 4 ), _SHIFTR( w1, 12, 4 ),
_SHIFTR( w0, 8, 4 ), _SHIFTR( w1, 16, 4 ), _SHIFTR( w1, 20, 4 ),
_SHIFTR( w0, 12, 4 ), _SHIFTR( w1, 24, 4 ), _SHIFTR( w1, 28, 4 ) );
}
void F3D_Init()
{
// Set GeometryMode flags
GBI_InitFlags( F3D );
GBI.PCStackSize = 10;
// GBI Command Command Value Command Function
GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp );
GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx );
GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 );
GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem );
GBI_SetGBI( G_VTX, F3D_VTX, F3D_Vtx );
GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 );
GBI_SetGBI( G_DL, F3D_DL, F3D_DList );
GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 );
GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 );
GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base );
GBI_SetGBI( G_TRI1, F3D_TRI1, F3D_Tri1 );
GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL );
GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx );
GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord );
GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture );
GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H );
GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L );
GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL );
GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode );
GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode );
GBI_SetGBI( G_QUAD, F3D_QUAD, F3D_Quad );
GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 );
GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 );
GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont );
GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 );
}

97
F3D.h Normal file
View File

@ -0,0 +1,97 @@
#ifndef F3D_H
#define F3D_H
#include "Types.h"
#define F3D_MTX_STACKSIZE 10
#define F3D_MTX_MODELVIEW 0x00
#define F3D_MTX_PROJECTION 0x01
#define F3D_MTX_MUL 0x00
#define F3D_MTX_LOAD 0x02
#define F3D_MTX_NOPUSH 0x00
#define F3D_MTX_PUSH 0x04
#define F3D_TEXTURE_ENABLE 0x00000002
#define F3D_SHADING_SMOOTH 0x00000200
#define F3D_CULL_FRONT 0x00001000
#define F3D_CULL_BACK 0x00002000
#define F3D_CULL_BOTH 0x00003000
#define F3D_CLIPPING 0x00000000
#define F3D_MV_VIEWPORT 0x80
#define F3D_MWO_aLIGHT_1 0x00
#define F3D_MWO_bLIGHT_1 0x04
#define F3D_MWO_aLIGHT_2 0x20
#define F3D_MWO_bLIGHT_2 0x24
#define F3D_MWO_aLIGHT_3 0x40
#define F3D_MWO_bLIGHT_3 0x44
#define F3D_MWO_aLIGHT_4 0x60
#define F3D_MWO_bLIGHT_4 0x64
#define F3D_MWO_aLIGHT_5 0x80
#define F3D_MWO_bLIGHT_5 0x84
#define F3D_MWO_aLIGHT_6 0xa0
#define F3D_MWO_bLIGHT_6 0xa4
#define F3D_MWO_aLIGHT_7 0xc0
#define F3D_MWO_bLIGHT_7 0xc4
#define F3D_MWO_aLIGHT_8 0xe0
#define F3D_MWO_bLIGHT_8 0xe4
// FAST3D commands
#define F3D_SPNOOP 0x00
#define F3D_MTX 0x01
#define F3D_RESERVED0 0x02
#define F3D_MOVEMEM 0x03
#define F3D_VTX 0x04
#define F3D_RESERVED1 0x05
#define F3D_DL 0x06
#define F3D_RESERVED2 0x07
#define F3D_RESERVED3 0x08
#define F3D_SPRITE2D_BASE 0x09
#define F3D_TRI1 0xBF
#define F3D_CULLDL 0xBE
#define F3D_POPMTX 0xBD
#define F3D_MOVEWORD 0xBC
#define F3D_TEXTURE 0xBB
#define F3D_SETOTHERMODE_H 0xBA
#define F3D_SETOTHERMODE_L 0xB9
#define F3D_ENDDL 0xB8
#define F3D_SETGEOMETRYMODE 0xB7
#define F3D_CLEARGEOMETRYMODE 0xB6
//#define F3D_LINE3D 0xB5 // Only used in Line3D
#define F3D_QUAD 0xB5
#define F3D_RDPHALF_1 0xB4
#define F3D_RDPHALF_2 0xB3
#define F3D_RDPHALF_CONT 0xB2
#define F3D_TRI4 0xB1
void F3D_SPNoOp( u32 w0, u32 w1 );
void F3D_Mtx( u32 w0, u32 w1 );
void F3D_Reserved0( u32 w0, u32 w1 );
void F3D_MoveMem( u32 w0, u32 w1 );
void F3D_Vtx( u32 w0, u32 w1 );
void F3D_Reserved1( u32 w0, u32 w1 );
void F3D_DList( u32 w0, u32 w1 );
void F3D_Reserved2( u32 w0, u32 w1 );
void F3D_Reserved3( u32 w0, u32 w1 );
void F3D_Sprite2D_Base( u32 w0, u32 w1 );
void F3D_Tri1( u32 w0, u32 w1 );
void F3D_CullDL( u32 w0, u32 w1 );
void F3D_PopMtx( u32 w0, u32 w1 );
void F3D_MoveWord( u32 w0, u32 w1 );
void F3D_Texture( u32 w0, u32 w1 );
void F3D_SetOtherMode_H( u32 w0, u32 w1 );
void F3D_SetOtherMode_L( u32 w0, u32 w1 );
void F3D_EndDL( u32 w0, u32 w1 );
void F3D_SetGeometryMode( u32 w0, u32 w1 );
void F3D_ClearGeometryMode( u32 w0, u32 w1 );
//void F3D_Line3D( u32 w0, u32 w1 );
void F3D_Quad( u32 w0, u32 w1 );
void F3D_RDPHalf_1( u32 w0, u32 w1 );
void F3D_RDPHalf_2( u32 w0, u32 w1 );
void F3D_RDPHalf_Cont( u32 w0, u32 w1 );
void F3D_Tri4( u32 w0, u32 w1 );
void F3D_Init();
#endif

122
F3DDKR.cpp Normal file
View File

@ -0,0 +1,122 @@
#include "glN64.h"
#include "Debug.h"
#include "F3D.h"
#include "F3DDKR.h"
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "gSP.h"
#include "gDP.h"
#include "GBI.h"
void F3DDKR_DMA_Mtx( u32 w0, u32 w1 )
{
if (_SHIFTR( w0, 0, 16 ) != 64)
{
// GBI_DetectUCode(); // Something's wrong
#ifdef DEBUG
DebugMsg( DEBUG_MEDIUM | DEBUG_HIGH | DEBUG_ERROR, "G_MTX: address = 0x%08X length = %i params = 0x%02X\n", w1, _SHIFTR( w0, 0, 16 ), _SHIFTR( w0, 16, 8 ) );
#endif
return;
}
u32 index = _SHIFTR( w0, 16, 4 );
u32 multiply;
if (index == 0) // DKR
{
index = _SHIFTR( w0, 22, 2 );
multiply = 0;
}
else // Gemini
{
multiply = _SHIFTR( w0, 23, 1 );
}
gSPDMAMatrix( w1, index, multiply );
}
void F3DDKR_DMA_Vtx( u32 w0, u32 w1 )
{
if ((w0 & F3DDKR_VTX_APPEND))
{
if (gSP.matrix.billboard)
gSP.vertexi = 1;
}
else
gSP.vertexi = 0;
u32 n = _SHIFTR( w0, 19, 5 ) + 1;
gSPDMAVertex( w1, n, gSP.vertexi + _SHIFTR( w0, 9, 5 ) );
gSP.vertexi += n;
}
void F3DDKR_DMA_Tri( u32 w0, u32 w1 )
{
gSPDMATriangles( w1, _SHIFTR( w0, 4, 12 ) );
gSP.vertexi = 0;
}
void F3DDKR_DMA_DList( u32 w0, u32 w1 )
{
gSPDMADisplayList( w1, _SHIFTR( w0, 16, 8 ) );
}
void F3DDKR_DMA_Offsets( u32 w0, u32 w1 )
{
gSPSetDMAOffsets( _SHIFTR( w0, 0, 24 ), _SHIFTR( w1, 0, 24 ) );
}
void F3DDKR_MoveWord( u32 w0, u32 w1 )
{
switch (_SHIFTR( w0, 0, 8 ))
{
case 0x02:
gSP.matrix.billboard = w1 & 1;
break;
case 0x0A:
gSP.matrix.modelViewi = _SHIFTR( w1, 6, 2 );
gSP.changed |= CHANGED_MATRIX;
break;
default:
F3D_MoveWord( w0, w1 );
break;
}
}
void F3DDKR_Init()
{
// Set GeometryMode flags
GBI_InitFlags( F3D );
GBI.PCStackSize = 10;
// GBI Command Command Value Command Function
GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp );
GBI_SetGBI( G_DMA_MTX, F3DDKR_DMA_MTX, F3DDKR_DMA_Mtx );
GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem );
GBI_SetGBI( G_DMA_VTX, F3DDKR_DMA_VTX, F3DDKR_DMA_Vtx );
GBI_SetGBI( G_DL, F3D_DL, F3D_DList );
GBI_SetGBI( G_DMA_DL, F3DDKR_DMA_DL, F3DDKR_DMA_DList );
GBI_SetGBI( G_DMA_TRI, F3DDKR_DMA_TRI, F3DDKR_DMA_Tri );
GBI_SetGBI( G_DMA_OFFSETS, F3DDKR_DMA_OFFSETS, F3DDKR_DMA_Offsets );
GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL );
GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3DDKR_MoveWord );
GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture );
GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H );
GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L );
GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL );
GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode );
GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode );
GBI_SetGBI( G_QUAD, F3D_QUAD, F3D_Quad );
GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 );
GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 );
GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont );
GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 );
gSPSetDMAOffsets( 0, 0 );
}

14
F3DDKR.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef F3DDKR_H
#define F3DDKR_H
#define F3DDKR_VTX_APPEND 0x00010000
#define F3DDKR_DMA_MTX 0x01
#define F3DDKR_DMA_VTX 0x04
#define F3DDKR_DMA_TRI 0x05
#define F3DDKR_DMA_DL 0x07
#define F3DDKR_DMA_OFFSETS 0xBF
void F3DDKR_Init();
#endif

90
F3DEX.cpp Normal file
View File

@ -0,0 +1,90 @@
#include "glN64.h"
#include "Debug.h"
#include "F3D.h"
#include "F3DEX.h"
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "gSP.h"
#include "gDP.h"
#include "GBI.h"
void F3DEX_Vtx( u32 w0, u32 w1 )
{
gSPVertex( w1, _SHIFTR( w0, 10, 6 ), _SHIFTR( w0, 17, 7 ) );
}
void F3DEX_Tri1( u32 w0, u32 w1 )
{
gSP1Triangle( _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), _SHIFTR( w1, 1, 7 ), 0 );
}
void F3DEX_CullDL( u32 w0, u32 w1 )
{
gSPCullDisplayList( _SHIFTR( w0, 1, 15 ), _SHIFTR( w1, 1, 15 ) );
}
void F3DEX_ModifyVtx( u32 w0, u32 w1 )
{
gSPModifyVertex( _SHIFTR( w0, 1, 15 ), _SHIFTR( w0, 16, 8 ), w1 );
}
void F3DEX_Tri2( u32 w0, u32 w1 )
{
gSP2Triangles( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), _SHIFTR( w0, 1, 7 ), 0,
_SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), _SHIFTR( w1, 1, 7 ), 0);
}
void F3DEX_Quad( u32 w0, u32 w1 )
{
gSP1Quadrangle( _SHIFTR( w1, 25, 7 ), _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), _SHIFTR( w1, 1, 7 ) );
}
void F3DEX_Branch_Z( u32 w0, u32 w1 )
{
gSPBranchLessZ( gDP.half_1, _SHIFTR( w0, 1, 11 ), (s32)w1 );
}
void F3DEX_Load_uCode( u32 w0, u32 w1 )
{
gSPLoadUcodeEx( w1, gDP.half_1, _SHIFTR( w0, 0, 16 ) + 1 );
}
void F3DEX_Init()
{
// Set GeometryMode flags
GBI_InitFlags( F3DEX );
GBI.PCStackSize = 18;
// GBI Command Command Value Command Function
GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp );
GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx );
GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 );
GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem );
GBI_SetGBI( G_VTX, F3D_VTX, F3DEX_Vtx );
GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 );
GBI_SetGBI( G_DL, F3D_DL, F3D_DList );
GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 );
GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 );
GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base );
GBI_SetGBI( G_TRI1, F3D_TRI1, F3DEX_Tri1 );
GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3DEX_CullDL );
GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx );
GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord );
GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture );
GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H );
GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L );
GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL );
GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode );
GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode );
GBI_SetGBI( G_QUAD, F3D_QUAD, F3DEX_Quad );
GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 );
GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 );
GBI_SetGBI( G_MODIFYVTX, F3DEX_MODIFYVTX, F3DEX_ModifyVtx );
GBI_SetGBI( G_TRI2, F3DEX_TRI2, F3DEX_Tri2 );
GBI_SetGBI( G_BRANCH_Z, F3DEX_BRANCH_Z, F3DEX_Branch_Z );
GBI_SetGBI( G_LOAD_UCODE, F3DEX_LOAD_UCODE, F3DEX_Load_uCode );
}

54
F3DEX.h Normal file
View File

@ -0,0 +1,54 @@
#ifndef F3DEX_H
#define F3DEX_H
#define F3DEX_MTX_STACKSIZE 18
#define F3DEX_MTX_MODELVIEW 0x00
#define F3DEX_MTX_PROJECTION 0x01
#define F3DEX_MTX_MUL 0x00
#define F3DEX_MTX_LOAD 0x02
#define F3DEX_MTX_NOPUSH 0x00
#define F3DEX_MTX_PUSH 0x04
#define F3DEX_TEXTURE_ENABLE 0x00000002
#define F3DEX_SHADING_SMOOTH 0x00000200
#define F3DEX_CULL_FRONT 0x00001000
#define F3DEX_CULL_BACK 0x00002000
#define F3DEX_CULL_BOTH 0x00003000
#define F3DEX_CLIPPING 0x00800000
#define F3DEX_MV_VIEWPORT 0x80
#define F3DEX_MWO_aLIGHT_1 0x00
#define F3DEX_MWO_bLIGHT_1 0x04
#define F3DEX_MWO_aLIGHT_2 0x20
#define F3DEX_MWO_bLIGHT_2 0x24
#define F3DEX_MWO_aLIGHT_3 0x40
#define F3DEX_MWO_bLIGHT_3 0x44
#define F3DEX_MWO_aLIGHT_4 0x60
#define F3DEX_MWO_bLIGHT_4 0x64
#define F3DEX_MWO_aLIGHT_5 0x80
#define F3DEX_MWO_bLIGHT_5 0x84
#define F3DEX_MWO_aLIGHT_6 0xa0
#define F3DEX_MWO_bLIGHT_6 0xa4
#define F3DEX_MWO_aLIGHT_7 0xc0
#define F3DEX_MWO_bLIGHT_7 0xc4
#define F3DEX_MWO_aLIGHT_8 0xe0
#define F3DEX_MWO_bLIGHT_8 0xe4
// F3DEX commands
#define F3DEX_MODIFYVTX 0xB2
#define F3DEX_TRI2 0xB1
#define F3DEX_BRANCH_Z 0xB0
#define F3DEX_LOAD_UCODE 0xAF // 0xCF
void F3DEX_Vtx( u32 w0, u32 w1 );
void F3DEX_Tri1( u32 w0, u32 w1 );
void F3DEX_CullDL( u32 w0, u32 w1 );
void F3DEX_ModifyVtx( u32 w0, u32 w1 );
void F3DEX_Tri2( u32 w0, u32 w1 );
void F3DEX_Branch_Z( u32 w0, u32 w1 );
void F3DEX_Load_uCode( u32 w0, u32 w1 );
void F3DEX_Init();
#endif

289
F3DEX2.cpp Normal file
View File

@ -0,0 +1,289 @@
#include "glN64.h"
#include "Debug.h"
#include "F3D.h"
#include "F3DEX.h"
#include "F3DEX2.h"
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "gSP.h"
#include "gDP.h"
#include "GBI.h"
void F3DEX2_Mtx( u32 w0, u32 w1 )
{
gSPMatrix( w1, _SHIFTR( w0, 0, 8 ) ^ G_MTX_PUSH );
}
void F3DEX2_MoveMem( u32 w0, u32 w1 )
{
switch (_SHIFTR( w0, 0, 8 ))
{
case F3DEX2_MV_VIEWPORT:
gSPViewport( w1 );
break;
case G_MV_MATRIX:
gSPForceMatrix( w1 );
// force matrix takes two commands
RSP.PC[RSP.PCi] += 8;
break;
case G_MV_LIGHT:
u32 offset = _SHIFTR( w0, 8, 8 ) << 3;
if (offset >= 48)
{
gSPLight( w1, (offset - 24) / 24);
}
/* else
{
// Do lookat stuff
}*/
break;
}
}
void F3DEX2_Vtx( u32 w0, u32 w1 )
{
u32 n = _SHIFTR( w0, 12, 8 );
gSPVertex( w1, n, _SHIFTR( w0, 1, 7 ) - n );
}
void F3DEX2_Reserved1( u32 w0, u32 w1 )
{
}
void F3DEX2_Tri1( u32 w0, u32 w1 )
{
gSP1Triangle( _SHIFTR( w0, 17, 7 ),
_SHIFTR( w0, 9, 7 ),
_SHIFTR( w0, 1, 7 ),
0 );
}
void F3DEX2_PopMtx( u32 w0, u32 w1 )
{
gSPPopMatrixN( 0, w1 >> 6 );
}
void F3DEX2_MoveWord( u32 w0, u32 w1 )
{
switch (_SHIFTR( w0, 16, 8 ))
{
case G_MW_FORCEMTX:
// Handled in movemem
break;
case G_MW_MATRIX:
gSPInsertMatrix( _SHIFTR( w0, 0, 16 ), w1 );
break;
case G_MW_NUMLIGHT:
gSPNumLights( w1 / 24 );
break;
case G_MW_CLIP:
gSPClipRatio( w1 );
break;
case G_MW_SEGMENT:
gSPSegment( _SHIFTR( w0, 0, 16 ) >> 2, w1 & 0x00FFFFFF );
break;
case G_MW_FOG:
/* s16 fm, fo, min, max;
fm = _SHIFTR( w1, 16, 16 );
fo = _SHIFTR( w1, 0, 16 );
min = 500 - (fo * (128000 / fm)) / 256;
max = (128000 / fm) + min;*/
gSPFogFactor( (s16)_SHIFTR( w1, 16, 16 ), (s16)_SHIFTR( w1, 0, 16 ) );
break;
case G_MW_LIGHTCOL:
switch (_SHIFTR( w0, 0, 16 ))
{
case F3DEX2_MWO_aLIGHT_1:
gSPLightColor( LIGHT_1, w1 );
break;
case F3DEX2_MWO_aLIGHT_2:
gSPLightColor( LIGHT_2, w1 );
break;
case F3DEX2_MWO_aLIGHT_3:
gSPLightColor( LIGHT_3, w1 );
break;
case F3DEX2_MWO_aLIGHT_4:
gSPLightColor( LIGHT_4, w1 );
break;
case F3DEX2_MWO_aLIGHT_5:
gSPLightColor( LIGHT_5, w1 );
break;
case F3DEX2_MWO_aLIGHT_6:
gSPLightColor( LIGHT_6, w1 );
break;
case F3DEX2_MWO_aLIGHT_7:
gSPLightColor( LIGHT_7, w1 );
break;
case F3DEX2_MWO_aLIGHT_8:
gSPLightColor( LIGHT_8, w1 );
break;
}
break;
case G_MW_PERSPNORM:
gSPPerspNormalize( w1 );
break;
}
}
void F3DEX2_Texture( u32 w0, u32 w1 )
{
gSPTexture( _FIXED2FLOAT( _SHIFTR( w1, 16, 16 ), 16 ),
_FIXED2FLOAT( _SHIFTR( w1, 0, 16 ), 16 ),
_SHIFTR( w0, 11, 3 ),
_SHIFTR( w0, 8, 3 ),
_SHIFTR( w0, 1, 7 ) );
}
void F3DEX2_SetOtherMode_H( u32 w0, u32 w1 )
{
switch (32 - _SHIFTR( w0, 8, 8 ) - (_SHIFTR( w0, 0, 8 ) + 1))
{
case G_MDSFT_PIPELINE:
gDPPipelineMode( w1 >> G_MDSFT_PIPELINE );
break;
case G_MDSFT_CYCLETYPE:
gDPSetCycleType( w1 >> G_MDSFT_CYCLETYPE );
break;
case G_MDSFT_TEXTPERSP:
gDPSetTexturePersp( w1 >> G_MDSFT_TEXTPERSP );
break;
case G_MDSFT_TEXTDETAIL:
gDPSetTextureDetail( w1 >> G_MDSFT_TEXTDETAIL );
break;
case G_MDSFT_TEXTLOD:
gDPSetTextureLOD( w1 >> G_MDSFT_TEXTLOD );
break;
case G_MDSFT_TEXTLUT:
gDPSetTextureLUT( w1 >> G_MDSFT_TEXTLUT );
break;
case G_MDSFT_TEXTFILT:
gDPSetTextureFilter( w1 >> G_MDSFT_TEXTFILT );
break;
case G_MDSFT_TEXTCONV:
gDPSetTextureConvert( w1 >> G_MDSFT_TEXTCONV );
break;
case G_MDSFT_COMBKEY:
gDPSetCombineKey( w1 >> G_MDSFT_COMBKEY );
break;
case G_MDSFT_RGBDITHER:
gDPSetColorDither( w1 >> G_MDSFT_RGBDITHER );
break;
case G_MDSFT_ALPHADITHER:
gDPSetAlphaDither( w1 >> G_MDSFT_ALPHADITHER );
break;
default:
u32 length = _SHIFTR( w0, 0, 8 ) + 1;
u32 shift = 32 - _SHIFTR( w0, 8, 8 ) - length;
u32 mask = ((1 << length) - 1) << shift;
gDP.otherMode.h &= ~mask;
gDP.otherMode.h |= w1 & mask;
gDP.changed |= CHANGED_CYCLETYPE;
break;
}
}
void F3DEX2_SetOtherMode_L( u32 w0, u32 w1 )
{
switch (32 - _SHIFTR( w0, 8, 8 ) - (_SHIFTR( w0, 0, 8 ) + 1))
{
case G_MDSFT_ALPHACOMPARE:
gDPSetAlphaCompare( w1 >> G_MDSFT_ALPHACOMPARE );
break;
case G_MDSFT_ZSRCSEL:
gDPSetDepthSource( w1 >> G_MDSFT_ZSRCSEL );
break;
case G_MDSFT_RENDERMODE:
gDPSetRenderMode( w1 & 0xCCCCFFFF, w1 & 0x3333FFFF );
break;
default:
u32 length = _SHIFTR( w0, 0, 8 ) + 1;
u32 shift = 32 - _SHIFTR( w0, 8, 8 ) - length;
u32 mask = ((1 << length) - 1) << shift;
gDP.otherMode.l &= ~mask;
gDP.otherMode.l |= w1 & mask;
gDP.changed |= CHANGED_RENDERMODE | CHANGED_ALPHACOMPARE;
break;
}
}
void F3DEX2_GeometryMode( u32 w0, u32 w1 )
{
gSPGeometryMode( ~_SHIFTR( w0, 0, 24 ), w1 );
}
void F3DEX2_DMAIO( u32 w0, u32 w1 )
{
}
void F3DEX2_Special_1( u32 w0, u32 w1 )
{
}
void F3DEX2_Special_2( u32 w0, u32 w1 )
{
}
void F3DEX2_Special_3( u32 w0, u32 w1 )
{
}
void F3DEX2_Quad( u32 w0, u32 w1 )
{
gSP2Triangles( _SHIFTR( w0, 17, 7 ),
_SHIFTR( w0, 9, 7 ),
_SHIFTR( w0, 1, 7 ),
0,
_SHIFTR( w1, 17, 7 ),
_SHIFTR( w1, 9, 7 ),
_SHIFTR( w1, 1, 7 ),
0 );
}
void F3DEX2_Init()
{
// Set GeometryMode flags
GBI_InitFlags( F3DEX2 );
GBI.PCStackSize = 18;
// GBI Command Command Value Command Function
GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 );
GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H );
GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L );
GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 );
GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp );
GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL );
GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList );
GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode );
GBI_SetGBI( G_MOVEMEM, F3DEX2_MOVEMEM, F3DEX2_MoveMem );
GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2_MoveWord );
GBI_SetGBI( G_MTX, F3DEX2_MTX, F3DEX2_Mtx );
GBI_SetGBI( G_GEOMETRYMODE, F3DEX2_GEOMETRYMODE, F3DEX2_GeometryMode );
GBI_SetGBI( G_POPMTX, F3DEX2_POPMTX, F3DEX2_PopMtx );
GBI_SetGBI( G_TEXTURE, F3DEX2_TEXTURE, F3DEX2_Texture );
GBI_SetGBI( G_DMA_IO, F3DEX2_DMA_IO, F3DEX2_DMAIO );
GBI_SetGBI( G_SPECIAL_1, F3DEX2_SPECIAL_1, F3DEX2_Special_1 );
GBI_SetGBI( G_SPECIAL_2, F3DEX2_SPECIAL_2, F3DEX2_Special_2 );
GBI_SetGBI( G_SPECIAL_3, F3DEX2_SPECIAL_3, F3DEX2_Special_3 );
GBI_SetGBI( G_VTX, F3DEX2_VTX, F3DEX2_Vtx );
GBI_SetGBI( G_MODIFYVTX, F3DEX2_MODIFYVTX, F3DEX_ModifyVtx );
GBI_SetGBI( G_CULLDL, F3DEX2_CULLDL, F3DEX_CullDL );
GBI_SetGBI( G_BRANCH_Z, F3DEX2_BRANCH_Z, F3DEX_Branch_Z );
GBI_SetGBI( G_TRI1, F3DEX2_TRI1, F3DEX2_Tri1 );
GBI_SetGBI( G_TRI2, F3DEX2_TRI2, F3DEX_Tri2 );
GBI_SetGBI( G_QUAD, F3DEX2_QUAD, F3DEX2_Quad );
// GBI_SetGBI( G_LINE3D, F3DEX2_LINE3D, F3DEX2_Line3D );
}

88
F3DEX2.h Normal file
View File

@ -0,0 +1,88 @@
#ifndef F3DEX2_H
#define F3DEX2_H
#define F3DEX2_MTX_STACKSIZE 18
#define F3DEX2_MTX_MODELVIEW 0x00
#define F3DEX2_MTX_PROJECTION 0x04
#define F3DEX2_MTX_MUL 0x00
#define F3DEX2_MTX_LOAD 0x02
#define F3DEX2_MTX_NOPUSH 0x00
#define F3DEX2_MTX_PUSH 0x01
#define F3DEX2_TEXTURE_ENABLE 0x00000000
#define F3DEX2_SHADING_SMOOTH 0x00200000
#define F3DEX2_CULL_FRONT 0x00000200
#define F3DEX2_CULL_BACK 0x00000400
#define F3DEX2_CULL_BOTH 0x00000600
#define F3DEX2_CLIPPING 0x00800000
#define F3DEX2_MV_VIEWPORT 8
#define F3DEX2_MWO_aLIGHT_1 0x00
#define F3DEX2_MWO_bLIGHT_1 0x04
#define F3DEX2_MWO_aLIGHT_2 0x18
#define F3DEX2_MWO_bLIGHT_2 0x1c
#define F3DEX2_MWO_aLIGHT_3 0x30
#define F3DEX2_MWO_bLIGHT_3 0x34
#define F3DEX2_MWO_aLIGHT_4 0x48
#define F3DEX2_MWO_bLIGHT_4 0x4c
#define F3DEX2_MWO_aLIGHT_5 0x60
#define F3DEX2_MWO_bLIGHT_5 0x64
#define F3DEX2_MWO_aLIGHT_6 0x78
#define F3DEX2_MWO_bLIGHT_6 0x7c
#define F3DEX2_MWO_aLIGHT_7 0x90
#define F3DEX2_MWO_bLIGHT_7 0x94
#define F3DEX2_MWO_aLIGHT_8 0xa8
#define F3DEX2_MWO_bLIGHT_8 0xac
#define F3DEX2_RDPHALF_2 0xF1
#define F3DEX2_SETOTHERMODE_H 0xE3
#define F3DEX2_SETOTHERMODE_L 0xE2
#define F3DEX2_RDPHALF_1 0xE1
#define F3DEX2_SPNOOP 0xE0
#define F3DEX2_ENDDL 0xDF
#define F3DEX2_DL 0xDE
#define F3DEX2_LOAD_UCODE 0xDD
#define F3DEX2_MOVEMEM 0xDC
#define F3DEX2_MOVEWORD 0xDB
#define F3DEX2_MTX 0xDA
#define F3DEX2_GEOMETRYMODE 0xD9
#define F3DEX2_POPMTX 0xD8
#define F3DEX2_TEXTURE 0xD7
#define F3DEX2_DMA_IO 0xD6
#define F3DEX2_SPECIAL_1 0xD5
#define F3DEX2_SPECIAL_2 0xD4
#define F3DEX2_SPECIAL_3 0xD3
#define F3DEX2_VTX 0x01
#define F3DEX2_MODIFYVTX 0x02
#define F3DEX2_CULLDL 0x03
#define F3DEX2_BRANCH_Z 0x04
#define F3DEX2_TRI1 0x05
#define F3DEX2_TRI2 0x06
#define F3DEX2_QUAD 0x07
//#define F3DEX2_LINE3D 0x08
void F3DEX2_Mtx( u32 w0, u32 w1 );
void F3DEX2_MoveMem( u32 w0, u32 w1 );
void F3DEX2_Vtx( u32 w0, u32 w1 );
void F3DEX2_Reserved1( u32 w0, u32 w1 );
void F3DEX2_Tri1( u32 w0, u32 w1 );
void F3DEX2_PopMtx( u32 w0, u32 w1 );
void F3DEX2_MoveWord( u32 w0, u32 w1 );
void F3DEX2_Texture( u32 w0, u32 w1 );
void F3DEX2_SetOtherMode_H( u32 w0, u32 w1 );
void F3DEX2_SetOtherMode_L( u32 w0, u32 w1 );
void F3DEX2_GeometryMode( u32 w0, u32 w1 );
//void F3DEX2_Line3D( u32 w0, u32 w1 );
void F3DEX2_DMAIO( u32 w0, u32 w1 );
void F3DEX2_Special_1( u32 w0, u32 w1 );
void F3DEX2_Special_2( u32 w0, u32 w1 );
void F3DEX2_Special_3( u32 w0, u32 w1 );
void F3DEX2_Quad( u32 w0, u32 w1 );
void F3DEX2_Init();
#endif

59
F3DPD.cpp Normal file
View File

@ -0,0 +1,59 @@
#include "glN64.h"
#include "Debug.h"
#include "F3D.h"
#include "F3DPD.h"
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "gSP.h"
#include "gDP.h"
#include "GBI.h"
void F3DPD_Vtx( u32 w0, u32 w1 )
{
gSPCIVertex( w1, _SHIFTR( w0, 20, 4 ) + 1, _SHIFTR( w0, 16, 4 ) );
}
void F3DPD_VtxColorBase( u32 w0, u32 w1 )
{
gSPSetVertexColorBase( w1 );
}
void F3DPD_Init()
{
// Set GeometryMode flags
GBI_InitFlags( F3D );
GBI.PCStackSize = 10;
// GBI Command Command Value Command Function
GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp );
GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx );
GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 );
GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem );
GBI_SetGBI( G_VTX, F3D_VTX, F3DPD_Vtx );
GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 );
GBI_SetGBI( G_DL, F3D_DL, F3D_DList );
GBI_SetGBI( G_VTXCOLORBASE, F3DPD_VTXCOLORBASE, F3DPD_VtxColorBase );
GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 );
GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base );
GBI_SetGBI( G_TRI1, F3D_TRI1, F3D_Tri1 );
GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL );
GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx );
GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord );
GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture );
GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H );
GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L );
GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL );
GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode );
GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode );
GBI_SetGBI( G_QUAD, F3D_QUAD, F3D_Quad );
GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 );
GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 );
GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont );
GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 );
gSPSetDMAOffsets( 0, 0 );
}

8
F3DPD.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef F3DPD_H
#define F3DPD_H
#define F3DPD_VTXCOLORBASE 0x07
void F3DPD_Init();
#endif

73
F3DWRUS.cpp Normal file
View File

@ -0,0 +1,73 @@
#include "glN64.h"
#include "Debug.h"
#include "F3D.h"
#include "F3DEX.h"
#include "F3DWRUS.h"
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "gSP.h"
#include "gDP.h"
#include "GBI.h"
void F3DWRUS_Vtx( u32 w0, u32 w1 )
{
gSPVertex( w1, _SHIFTR( w0, 9, 7 ), _SHIFTR( w0, 16, 8 ) / 5 );
}
void F3DWRUS_Tri1( u32 w0, u32 w1 )
{
gSP1Triangle( _SHIFTR( w1, 16, 8 ) / 5,
_SHIFTR( w1, 8, 8 ) / 5,
_SHIFTR( w1, 0, 8 ) / 5,
_SHIFTR( w1, 24, 8 ) );
}
void F3DWRUS_Tri2( u32 w0, u32 w1 )
{
gSP2Triangles( _SHIFTR( w0, 16, 8 ) / 5, _SHIFTR( w0, 8, 8 ) / 5, _SHIFTR( w0, 0, 8 ) / 5, 0,
_SHIFTR( w1, 16, 8 ) / 5, _SHIFTR( w1, 8, 8 ) / 5, _SHIFTR( w1, 0, 8 ) / 5, 0);
}
void F3DWRUS_Quad( u32 w0, u32 w1 )
{
gSP1Quadrangle( _SHIFTR( w1, 24, 8 ) / 5, _SHIFTR( w1, 16, 8 ) / 5, _SHIFTR( w1, 8, 8 ) / 5, _SHIFTR( w1, 0, 8 ) / 5 );
}
void F3DWRUS_Init()
{
// Set GeometryMode flags
GBI_InitFlags( F3D );
GBI.PCStackSize = 10;
// GBI Command Command Value Command Function
GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp );
GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx );
GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 );
GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem );
GBI_SetGBI( G_VTX, F3D_VTX, F3DWRUS_Vtx );
GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 );
GBI_SetGBI( G_DL, F3D_DL, F3D_DList );
GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 );
GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 );
GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base );
GBI_SetGBI( G_TRI1, F3D_TRI1, F3DWRUS_Tri1 );
GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL );
GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx );
GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord );
GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture );
GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H );
GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L );
GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL );
GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode );
GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode );
GBI_SetGBI( G_QUAD, F3D_QUAD, F3DWRUS_Quad );
GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 );
GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 );
GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont );
GBI_SetGBI( G_TRI2, F3DWRUS_TRI2, F3DWRUS_Tri2 );
}

8
F3DWRUS.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef F3DWRUS_H
#define F3DWRUS_H
#define F3DWRUS_TRI2 0xB1
void F3DWRUS_Init();
#endif

423
FrameBuffer.cpp Normal file
View File

@ -0,0 +1,423 @@
#ifndef __LINUX__
# include <windows.h>
#else
# include "winlnxdefs.h"
#endif // __LINUX__
#include "OpenGL.h"
#include "FrameBuffer.h"
#include "RSP.h"
#include "RDP.h"
#include "Textures.h"
#include "Combiner.h"
#include "Types.h"
FrameBufferInfo frameBuffer;
void FrameBuffer_Init()
{
frameBuffer.current = NULL;
frameBuffer.top = NULL;
frameBuffer.bottom = NULL;
frameBuffer.numBuffers = 0;
}
void FrameBuffer_RemoveBottom()
{
FrameBuffer *newBottom = frameBuffer.bottom->higher;
TextureCache_Remove( frameBuffer.bottom->texture );
if (frameBuffer.bottom == frameBuffer.top)
frameBuffer.top = NULL;
free( frameBuffer.bottom );
frameBuffer.bottom = newBottom;
if (frameBuffer.bottom != NULL)
frameBuffer.bottom->lower = NULL;
frameBuffer.numBuffers--;
}
void FrameBuffer_Remove( FrameBuffer *buffer )
{
if ((buffer == frameBuffer.bottom) &&
(buffer == frameBuffer.top))
{
frameBuffer.top = NULL;
frameBuffer.bottom = NULL;
}
else if (buffer == frameBuffer.bottom)
{
frameBuffer.bottom = buffer->higher;
if (frameBuffer.bottom)
frameBuffer.bottom->lower = NULL;
}
else if (buffer == frameBuffer.top)
{
frameBuffer.top = buffer->lower;
if (frameBuffer.top)
frameBuffer.top->higher = NULL;
}
else
{
buffer->higher->lower = buffer->lower;
buffer->lower->higher = buffer->higher;
}
if (buffer->texture)
TextureCache_Remove( buffer->texture );
free( buffer );
frameBuffer.numBuffers--;
}
void FrameBuffer_RemoveBuffer( u32 address )
{
FrameBuffer *current = frameBuffer.bottom;
while (current != NULL)
{
if (current->startAddress == address)
{
current->texture = NULL;
FrameBuffer_Remove( current );
return;
}
current = current->higher;
}
}
FrameBuffer *FrameBuffer_AddTop()
{
FrameBuffer *newtop = (FrameBuffer*)malloc( sizeof( FrameBuffer ) );
newtop->texture = TextureCache_AddTop();
newtop->lower = frameBuffer.top;
newtop->higher = NULL;
if (frameBuffer.top)
frameBuffer.top->higher = newtop;
if (!frameBuffer.bottom)
frameBuffer.bottom = newtop;
frameBuffer.top = newtop;
frameBuffer.numBuffers++;
return newtop;
}
void FrameBuffer_MoveToTop( FrameBuffer *newtop )
{
if (newtop == frameBuffer.top)
return;
if (newtop == frameBuffer.bottom)
{
frameBuffer.bottom = newtop->higher;
frameBuffer.bottom->lower = NULL;
}
else
{
newtop->higher->lower = newtop->lower;
newtop->lower->higher = newtop->higher;
}
newtop->higher = NULL;
newtop->lower = frameBuffer.top;
frameBuffer.top->higher = newtop;
frameBuffer.top = newtop;
TextureCache_MoveToTop( newtop->texture );
}
void FrameBuffer_Destroy()
{
while (frameBuffer.bottom)
FrameBuffer_RemoveBottom();
}
void FrameBuffer_SaveBuffer( u32 address, u16 size, u16 width, u16 height )
{
FrameBuffer *current = frameBuffer.top;
// Search through saved frame buffers
while (current != NULL)
{
if ((current->startAddress == address) &&
(current->width == width) &&
(current->height == height) &&
(current->size == size))
{
if ((current->scaleX != OGL.scaleX) ||
(current->scaleY != OGL.scaleY))
{
FrameBuffer_Remove( current );
break;
}
glBindTexture( GL_TEXTURE_2D, current->texture->glName );
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, OGL.height - current->texture->height + OGL.heightOffset, current->texture->width, current->texture->height );
*(u32*)&RDRAM[current->startAddress] = current->startAddress;
current->changed = TRUE;
FrameBuffer_MoveToTop( current );
gSP.changed |= CHANGED_TEXTURE;
return;
}
current = current->lower;
}
// Wasn't found, create a new one
current = FrameBuffer_AddTop();
current->startAddress = address;
current->endAddress = address + ((width * height << size >> 1) - 1);
current->width = width;
current->height = height;
current->size = size;
current->scaleX = OGL.scaleX;
current->scaleY = OGL.scaleY;
current->texture->width = current->width * OGL.scaleX;
current->texture->height = current->height * OGL.scaleY;
current->texture->clampS = 1;
current->texture->clampT = 1;
current->texture->address = current->startAddress;
current->texture->clampWidth = current->width;
current->texture->clampHeight = current->height;
current->texture->frameBufferTexture = TRUE;
current->texture->maskS = 0;
current->texture->maskT = 0;
current->texture->mirrorS = 0;
current->texture->mirrorT = 0;
current->texture->realWidth = pow2( current->width * OGL.scaleX );
current->texture->realHeight = pow2( current->height * OGL.scaleY );
current->texture->textureBytes = current->texture->realWidth * current->texture->realHeight * 4;
cache.cachedBytes += current->texture->textureBytes;
glBindTexture( GL_TEXTURE_2D, current->texture->glName );
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, 0, OGL.height - current->texture->height + OGL.heightOffset, current->texture->realWidth, current->texture->realHeight, 0 );
*(u32*)&RDRAM[current->startAddress] = current->startAddress;
current->changed = TRUE;
gSP.changed |= CHANGED_TEXTURE;
}
void FrameBuffer_RenderBuffer( u32 address )
{
FrameBuffer *current = frameBuffer.top;
while (current != NULL)
{
if ((current->startAddress <= address) &&
(current->endAddress >= address))
{
glPushAttrib( GL_ENABLE_BIT | GL_VIEWPORT_BIT );
Combiner_BeginTextureUpdate();
TextureCache_ActivateTexture( 0, current->texture );
Combiner_SetCombine( EncodeCombineMode( 0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1 ) );
/* if (OGL.ARB_multitexture)
{
for (int i = 0; i < OGL.maxTextureUnits; i++)
{
glActiveTextureARB( GL_TEXTURE0_ARB + i );
glDisable( GL_TEXTURE_2D );
}
glActiveTextureARB( GL_TEXTURE0_ARB );
}
TextureCache_ActivateTexture( 0, current->texture );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
glEnable( GL_TEXTURE_2D );*/
glDisable( GL_BLEND );
glDisable( GL_ALPHA_TEST );
glDisable( GL_DEPTH_TEST );
glDisable( GL_CULL_FACE );
glDisable( GL_POLYGON_OFFSET_FILL );
// glDisable( GL_REGISTER_COMBINERS_NV );
glDisable( GL_FOG );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, OGL.width, 0, OGL.height, -1.0f, 1.0f );
glViewport( 0, OGL.heightOffset, OGL.width, OGL.height );
glDisable( GL_SCISSOR_TEST );
float u1, v1;
u1 = (float)current->texture->width / (float)current->texture->realWidth;
v1 = (float)current->texture->height / (float)current->texture->realHeight;
glDrawBuffer( GL_FRONT );
glBegin(GL_QUADS);
glTexCoord2f( 0.0f, 0.0f );
glVertex2f( 0.0f, OGL.height - current->texture->height );
glTexCoord2f( 0.0f, v1 );
glVertex2f( 0.0f, OGL.height );
glTexCoord2f( u1, v1 );
glVertex2f( current->texture->width, OGL.height );
glTexCoord2f( u1, 0.0f );
glVertex2f( current->texture->width, OGL.height - current->texture->height );
glEnd();
glDrawBuffer( GL_BACK );
/* glEnable( GL_TEXTURE_2D );
glActiveTextureARB( GL_TEXTURE0_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );*/
glPopAttrib();
current->changed = FALSE;
FrameBuffer_MoveToTop( current );
gSP.changed |= CHANGED_TEXTURE | CHANGED_VIEWPORT;
gDP.changed |= CHANGED_COMBINE;
return;
}
current = current->lower;
}
}
void FrameBuffer_RestoreBuffer( u32 address, u16 size, u16 width )
{
FrameBuffer *current = frameBuffer.top;
while (current != NULL)
{
if ((current->startAddress == address) &&
(current->width == width) &&
(current->size == size))
{
glPushAttrib( GL_ENABLE_BIT | GL_VIEWPORT_BIT );
/* if (OGL.ARB_multitexture)
{
for (int i = 0; i < OGL.maxTextureUnits; i++)
{
glActiveTextureARB( GL_TEXTURE0_ARB + i );
glDisable( GL_TEXTURE_2D );
}
glActiveTextureARB( GL_TEXTURE0_ARB );
}
TextureCache_ActivateTexture( 0, current->texture );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
glEnable( GL_TEXTURE_2D );*/
Combiner_BeginTextureUpdate();
TextureCache_ActivateTexture( 0, current->texture );
Combiner_SetCombine( EncodeCombineMode( 0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1 ) );
glDisable( GL_BLEND );
glDisable( GL_ALPHA_TEST );
glDisable( GL_DEPTH_TEST );
glDisable( GL_SCISSOR_TEST );
glDisable( GL_CULL_FACE );
glDisable( GL_POLYGON_OFFSET_FILL );
//glDisable( GL_REGISTER_COMBINERS_NV );
glDisable( GL_FOG );
// glDepthMask( FALSE );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, OGL.width, 0, OGL.height, -1.0f, 1.0f );
// glOrtho( 0, RDP.width, RDP.height, 0, -1.0f, 1.0f );
glViewport( 0, OGL.heightOffset, OGL.width, OGL.height );
float u1, v1;
u1 = (float)current->texture->width / (float)current->texture->realWidth;
v1 = (float)current->texture->height / (float)current->texture->realHeight;
glBegin(GL_QUADS);
glTexCoord2f( 0.0f, 0.0f );
glVertex2f( 0.0f, OGL.height - current->texture->height );
glTexCoord2f( 0.0f, v1 );
glVertex2f( 0.0f, OGL.height );
glTexCoord2f( u1, v1 );
glVertex2f( current->texture->width, OGL.height );
glTexCoord2f( u1, 0.0f );
glVertex2f( current->texture->width, OGL.height - current->texture->height );
glEnd();
glLoadIdentity();
glPopAttrib();
FrameBuffer_MoveToTop( current );
gSP.changed |= CHANGED_TEXTURE | CHANGED_VIEWPORT;
gDP.changed |= CHANGED_COMBINE;
return;
}
current = current->lower;
}
}
FrameBuffer *FrameBuffer_FindBuffer( u32 address )
{
FrameBuffer *current = frameBuffer.top;
while (current)
{
if ((current->startAddress <= address) &&
(current->endAddress >= address))
return current;
current = current->lower;
}
return NULL;
}
void FrameBuffer_ActivateBufferTexture( s16 t, FrameBuffer *buffer )
{
buffer->texture->scaleS = OGL.scaleX / (float)buffer->texture->realWidth;
buffer->texture->scaleT = OGL.scaleY / (float)buffer->texture->realHeight;
if (gSP.textureTile[t]->shifts > 10)
buffer->texture->shiftScaleS = (float)(1 << (16 - gSP.textureTile[t]->shifts));
else if (gSP.textureTile[t]->shifts > 0)
buffer->texture->shiftScaleS = 1.0f / (float)(1 << gSP.textureTile[t]->shifts);
else
buffer->texture->shiftScaleS = 1.0f;
if (gSP.textureTile[t]->shiftt > 10)
buffer->texture->shiftScaleT = (float)(1 << (16 - gSP.textureTile[t]->shiftt));
else if (gSP.textureTile[t]->shiftt > 0)
buffer->texture->shiftScaleT = 1.0f / (float)(1 << gSP.textureTile[t]->shiftt);
else
buffer->texture->shiftScaleT = 1.0f;
if (gDP.loadType == LOADTYPE_TILE)
{
buffer->texture->offsetS = gDP.loadTile->uls;
buffer->texture->offsetT = (float)buffer->height - (gDP.loadTile->ult + (gDP.textureImage.address - buffer->startAddress) / (buffer->width << buffer->size >> 1));
}
else
{
buffer->texture->offsetS = 0.0f;
buffer->texture->offsetT = (float)buffer->height - (gDP.textureImage.address - buffer->startAddress) / (buffer->width << buffer->size >> 1);
}
FrameBuffer_MoveToTop( buffer );
TextureCache_ActivateTexture( t, buffer->texture );
}

35
FrameBuffer.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H
#include "Types.h"
#include "Textures.h"
struct FrameBuffer
{
FrameBuffer *higher, *lower;
CachedTexture *texture;
u32 startAddress, endAddress;
u32 size, width, height, changed;
float scaleX, scaleY;
};
struct FrameBufferInfo
{
FrameBuffer *top, *bottom, *current;
int numBuffers;
};
extern FrameBufferInfo frameBuffer;
void FrameBuffer_Init();
void FrameBuffer_Destroy();
void FrameBuffer_SaveBuffer( u32 address, u16 size, u16 width, u16 height );
void FrameBuffer_RenderBuffer( u32 address );
void FrameBuffer_RestoreBuffer( u32 address, u16 size, u16 width );
void FrameBuffer_RemoveBuffer( u32 address );
FrameBuffer *FrameBuffer_FindBuffer( u32 address );
void FrameBuffer_ActivateBufferTexture( s16 t, FrameBuffer *buffer );
#endif

488
GBI.cpp Normal file
View File

@ -0,0 +1,488 @@
#include <stdio.h>
#include "glN64.h"
#include "GBI.h"
#include "RDP.h"
#include "RSP.h"
#include "F3D.h"
#include "F3DEX.h"
#include "F3DEX2.h"
#include "L3D.h"
#include "L3DEX.h"
#include "L3DEX2.h"
#include "S2DEX.h"
#include "S2DEX2.h"
#include "F3DDKR.h"
#include "F3DWRUS.h"
#include "F3DPD.h"
#include "Types.h"
#ifndef __LINUX__
# include "Resource.h"
#else // !__LINUX__
# include <glib.h>
# include <gtk/gtk.h>
#endif // __LINUX__
#include "CRC.h"
#include "Debug.h"
u32 uc_crc, uc_dcrc;
char uc_str[256];
SpecialMicrocodeInfo specialMicrocodes[] =
{
{ F3DWRUS, FALSE, 0xd17906e2, "RSP SW Version: 2.0D, 04-01-96" },
{ F3DWRUS, FALSE, 0x94c4c833, "RSP SW Version: 2.0D, 04-01-96" },
{ S2DEX, FALSE, 0x9df31081, "RSP Gfx ucode S2DEX 1.06 Yoshitaka Yasumoto Nintendo." },
{ F3DDKR, FALSE, 0x8d91244f, "Diddy Kong Racing" },
{ F3DDKR, FALSE, 0x6e6fc893, "Diddy Kong Racing" },
{ F3DDKR, FALSE, 0xbde9d1fb, "Jet Force Gemini" },
{ F3DPD, FALSE, 0x1c4f7869, "Perfect Dark" }
};
u32 G_RDPHALF_1, G_RDPHALF_2, G_RDPHALF_CONT;
u32 G_SPNOOP;
u32 G_SETOTHERMODE_H, G_SETOTHERMODE_L;
u32 G_DL, G_ENDDL, G_CULLDL, G_BRANCH_Z;
u32 G_LOAD_UCODE;
u32 G_MOVEMEM, G_MOVEWORD;
u32 G_MTX, G_POPMTX;
u32 G_GEOMETRYMODE, G_SETGEOMETRYMODE, G_CLEARGEOMETRYMODE;
u32 G_TEXTURE;
u32 G_DMA_IO, G_DMA_DL, G_DMA_TRI, G_DMA_MTX, G_DMA_VTX, G_DMA_OFFSETS;
u32 G_SPECIAL_1, G_SPECIAL_2, G_SPECIAL_3;
u32 G_VTX, G_MODIFYVTX, G_VTXCOLORBASE;
u32 G_TRI1, G_TRI2, G_TRI4;
u32 G_QUAD, G_LINE3D;
u32 G_RESERVED0, G_RESERVED1, G_RESERVED2, G_RESERVED3;
u32 G_SPRITE2D_BASE;
u32 G_BG_1CYC, G_BG_COPY;
u32 G_OBJ_RECTANGLE, G_OBJ_SPRITE, G_OBJ_MOVEMEM;
u32 G_SELECT_DL, G_OBJ_RENDERMODE, G_OBJ_RECTANGLE_R;
u32 G_OBJ_LOADTXTR, G_OBJ_LDTX_SPRITE, G_OBJ_LDTX_RECT, G_OBJ_LDTX_RECT_R;
u32 G_RDPHALF_0;
u32 G_MTX_STACKSIZE;
u32 G_MTX_MODELVIEW;
u32 G_MTX_PROJECTION;
u32 G_MTX_MUL;
u32 G_MTX_LOAD;
u32 G_MTX_NOPUSH;
u32 G_MTX_PUSH;
u32 G_TEXTURE_ENABLE;
u32 G_SHADING_SMOOTH;
u32 G_CULL_FRONT;
u32 G_CULL_BACK;
u32 G_CULL_BOTH;
u32 G_CLIPPING;
u32 G_MV_VIEWPORT;
u32 G_MWO_aLIGHT_1, G_MWO_bLIGHT_1;
u32 G_MWO_aLIGHT_2, G_MWO_bLIGHT_2;
u32 G_MWO_aLIGHT_3, G_MWO_bLIGHT_3;
u32 G_MWO_aLIGHT_4, G_MWO_bLIGHT_4;
u32 G_MWO_aLIGHT_5, G_MWO_bLIGHT_5;
u32 G_MWO_aLIGHT_6, G_MWO_bLIGHT_6;
u32 G_MWO_aLIGHT_7, G_MWO_bLIGHT_7;
u32 G_MWO_aLIGHT_8, G_MWO_bLIGHT_8;
//GBIFunc GBICmd[256];
GBIInfo GBI;
void GBI_Unknown( u32 w0, u32 w1 )
{
#ifdef DEBUG
if (Debug.level == DEBUG_LOW)
DebugMsg( DEBUG_LOW | DEBUG_UNKNOWN, "UNKNOWN GBI COMMAND 0x%02X", _SHIFTR( w0, 24, 8 ) );
if (Debug.level == DEBUG_MEDIUM)
DebugMsg( DEBUG_MEDIUM | DEBUG_UNKNOWN, "Unknown GBI Command 0x%02X", _SHIFTR( w0, 24, 8 ) );
else if (Debug.level == DEBUG_HIGH)
DebugMsg( DEBUG_HIGH | DEBUG_UNKNOWN, "// Unknown GBI Command 0x%02X", _SHIFTR( w0, 24, 8 ) );
#endif
}
#ifndef __LINUX__
INT_PTR CALLBACK MicrocodeDlgProc( HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch (uMsg)
{
case WM_INITDIALOG:
for (int i = 0; i < numMicrocodeTypes; i++)
{
SendDlgItemMessage( hWndDlg, IDC_MICROCODE, CB_ADDSTRING, 0, (LPARAM)MicrocodeTypes[i] );
}
SendDlgItemMessage( hWndDlg, IDC_MICROCODE, CB_SETCURSEL, 0, 0 );
char text[1024];
sprintf( text, "Microcode CRC:\t\t0x%08x\r\nMicrocode Data CRC:\t0x%08x\r\nMicrocode Text:\t\t%s", uc_crc, uc_dcrc, uc_str );
SendDlgItemMessage( hWndDlg, IDC_TEXTBOX, WM_SETTEXT, NULL, (LPARAM)text );
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
EndDialog( hWndDlg, SendDlgItemMessage( hWndDlg, IDC_MICROCODE, CB_GETCURSEL, 0, 0 ) );
return TRUE;
case IDCANCEL:
EndDialog( hWndDlg, NONE );
return TRUE;
}
break;
}
return FALSE;
}
#else // !__LINUX__
static int selectedMicrocode = -1;
static GtkWidget *microcodeWindow = 0;
static GtkWidget *microcodeList = 0;
static void okButton_clicked( GtkWidget *widget, void *data )
{
gtk_widget_hide( microcodeWindow );
if (GTK_LIST(microcodeList)->selection != 0)
{
char *text = 0;
GtkListItem *item = GTK_LIST_ITEM(GTK_LIST(microcodeList)->selection->data);
GtkLabel *label = GTK_LABEL(GTK_BIN(item)->child);
gtk_label_get( label, &text );
if (text != 0)
for (int i = 0; i < numMicrocodeTypes; i++)
if (!strcmp( text, MicrocodeTypes[i] ))
{
selectedMicrocode = i;
return;
}
}
selectedMicrocode = NONE;
}
static void stopButton_clicked( GtkWidget *widget, void *data )
{
gtk_widget_hide( microcodeWindow );
selectedMicrocode = NONE;
}
static gint
delete_question_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
return TRUE; // undeleteable
}
static int MicrocodeDialog()
{
GtkWidget *infoLabel;
GtkWidget *infoFrame, *infoTable;
GtkWidget *crcInfoLabel, *crcDataInfoLabel, *textInfoLabel;
GtkWidget *crcLabel, *crcDataLabel, *textLabel;
GtkWidget *selectUcodeLabel;
GtkWidget *microcodeLabel;
GtkWidget *okButton, *stopButton;
GList *ucodeList = 0;
char buf[1024];
if (!g_thread_supported())
g_thread_init( NULL );
gdk_threads_enter();
// create dialog
if (microcodeWindow == 0)
{
microcodeWindow = gtk_dialog_new();
gtk_signal_connect( GTK_OBJECT(microcodeWindow), "delete_event",
GTK_SIGNAL_FUNC(delete_question_event), (gpointer)NULL );
sprintf( buf, "%s - unknown microcode", pluginName );
gtk_window_set_title( GTK_WINDOW(microcodeWindow), buf );
gtk_container_set_border_width( GTK_CONTAINER(GTK_DIALOG(microcodeWindow)->vbox), 11 );
// ok button
okButton = gtk_button_new_with_label( "Ok" );
gtk_signal_connect_object( GTK_OBJECT(okButton), "clicked",
GTK_SIGNAL_FUNC(okButton_clicked), NULL );
gtk_container_add( GTK_CONTAINER(GTK_DIALOG(microcodeWindow)->action_area), okButton );
// stop button
stopButton = gtk_button_new_with_label( "Stop" );
gtk_signal_connect_object( GTK_OBJECT(stopButton), "clicked",
GTK_SIGNAL_FUNC(stopButton_clicked), NULL );
gtk_container_add( GTK_CONTAINER(GTK_DIALOG(microcodeWindow)->action_area), stopButton );
// info label
infoLabel = gtk_label_new( "Unknown microcode. Please notify Orkin, including the following information:" );
gtk_box_pack_start_defaults( GTK_BOX(GTK_DIALOG(microcodeWindow)->vbox), infoLabel );
// info frame
infoFrame = gtk_frame_new( "Microcode info" );
gtk_container_set_border_width( GTK_CONTAINER(infoFrame), 7 );
gtk_box_pack_start_defaults( GTK_BOX(GTK_DIALOG(microcodeWindow)->vbox), infoFrame );
infoTable = gtk_table_new( 3, 2, FALSE );
gtk_container_set_border_width( GTK_CONTAINER(infoTable), 7 );
gtk_table_set_col_spacings( GTK_TABLE(infoTable), 3 );
gtk_table_set_row_spacings( GTK_TABLE(infoTable), 3 );
gtk_container_add( GTK_CONTAINER(infoFrame), infoTable );
crcInfoLabel = gtk_label_new( "Microcode CRC:" );
crcDataInfoLabel = gtk_label_new( "Microcode Data CRC:" );
textInfoLabel = gtk_label_new( "Microcode Text:" );
crcLabel = gtk_label_new( "" );
crcDataLabel = gtk_label_new( "" );
textLabel = gtk_label_new( "" );
gtk_table_attach_defaults( GTK_TABLE(infoTable), crcInfoLabel, 0, 1, 0, 1 );
gtk_table_attach_defaults( GTK_TABLE(infoTable), crcLabel, 1, 2, 0, 1 );
gtk_table_attach_defaults( GTK_TABLE(infoTable), crcDataInfoLabel, 0, 1, 1, 2 );
gtk_table_attach_defaults( GTK_TABLE(infoTable), crcDataLabel, 1, 2, 1, 2 );
gtk_table_attach_defaults( GTK_TABLE(infoTable), textInfoLabel, 0, 1, 2, 3 );
gtk_table_attach_defaults( GTK_TABLE(infoTable), textLabel, 1, 2, 2, 3 );
selectUcodeLabel = gtk_label_new( "You can manually select the closest matching microcode." );
for (int i = 0; i < numMicrocodeTypes; i++)
ucodeList = g_list_append( ucodeList, gtk_list_item_new_with_label( MicrocodeTypes[i] ) );
microcodeList = gtk_list_new();
gtk_list_set_selection_mode( GTK_LIST(microcodeList), GTK_SELECTION_SINGLE );
gtk_list_append_items( GTK_LIST(microcodeList), ucodeList );
gtk_box_pack_start_defaults( GTK_BOX(GTK_DIALOG(microcodeWindow)->vbox), selectUcodeLabel );
gtk_box_pack_start_defaults( GTK_BOX(GTK_DIALOG(microcodeWindow)->vbox), microcodeList );
}
snprintf( buf, 1024, "0x%8.8X", uc_crc );
gtk_label_set_text( GTK_LABEL(crcLabel), buf );
snprintf( buf, 1024, "0x%8.8X", uc_dcrc );
gtk_label_set_text( GTK_LABEL(crcDataLabel), buf );
gtk_label_set_text( GTK_LABEL(textLabel), uc_str );
selectedMicrocode = -1;
gtk_widget_show_all( microcodeWindow );
while (selectedMicrocode == -1)
{
// if( gtk_main_iteration() )
// break;
usleep( 10000 );
}
gdk_threads_leave();
return selectedMicrocode;
}
#endif // __LINUX__
MicrocodeInfo *GBI_AddMicrocode()
{
MicrocodeInfo *newtop = (MicrocodeInfo*)malloc( sizeof( MicrocodeInfo ) );
newtop->lower = GBI.top;
newtop->higher = NULL;
if (GBI.top)
GBI.top->higher = newtop;
if (!GBI.bottom)
GBI.bottom = newtop;
GBI.top = newtop;
GBI.numMicrocodes++;
return newtop;
}
void GBI_Init()
{
GBI.top = NULL;
GBI.bottom = NULL;
GBI.current = NULL;
GBI.numMicrocodes = 0;
for (u32 i = 0; i <= 0xFF; i++)
GBI.cmd[i] = GBI_Unknown;
}
void GBI_Destroy()
{
while (GBI.bottom)
{
MicrocodeInfo *newBottom = GBI.bottom->higher;
if (GBI.bottom == GBI.top)
GBI.top = NULL;
free( GBI.bottom );
GBI.bottom = newBottom;
if (GBI.bottom)
GBI.bottom->lower = NULL;
GBI.numMicrocodes--;
}
}
MicrocodeInfo *GBI_DetectMicrocode( u32 uc_start, u32 uc_dstart, u16 uc_dsize )
{
MicrocodeInfo *current;
for (int i = 0; i < GBI.numMicrocodes; i++)
{
current = GBI.top;
while (current)
{
if ((current->address == uc_start) && (current->dataAddress == uc_dstart) && (current->dataSize == uc_dsize))
return current;
current = current->lower;
}
}
current = GBI_AddMicrocode();
current->address = uc_start;
current->dataAddress = uc_dstart;
current->dataSize = uc_dsize;
current->NoN = FALSE;
current->type = NONE;
// See if we can identify it by CRC
uc_crc = CRC_Calculate( 0xFFFFFFFF, &RDRAM[uc_start & 0x1FFFFFFF], 4096 );
for (u32 i = 0; i < sizeof( specialMicrocodes ) / sizeof( SpecialMicrocodeInfo ); i++)
{
if (uc_crc == specialMicrocodes[i].crc)
{
current->type = specialMicrocodes[i].type;
return current;
}
}
// See if we can identify it by text
char uc_data[2048];
UnswapCopy( &RDRAM[uc_dstart & 0x1FFFFFFF], uc_data, 2048 );
strcpy( uc_str, "Not Found" );
for (u32 i = 0; i < 2048; i++)
{
if ((uc_data[i] == 'R') && (uc_data[i+1] == 'S') && (uc_data[i+2] == 'P'))
{
u32 j = 0;
while (uc_data[i+j] > 0x0A)
{
uc_str[j] = uc_data[i+j];
j++;
}
uc_str[j] = 0x00;
int type = NONE;
if (strncmp( &uc_str[4], "SW", 2 ) == 0)
{
type = F3D;
}
else if (strncmp( &uc_str[4], "Gfx", 3 ) == 0)
{
current->NoN = (strncmp( &uc_str[20], ".NoN", 4 ) == 0);
if (strncmp( &uc_str[14], "F3D", 3 ) == 0)
{
if (uc_str[28] == '1')
type = F3DEX;
else if (uc_str[31] == '2')
type = F3DEX2;
}
else if (strncmp( &uc_str[14], "L3D", 3 ) == 0)
{
if (uc_str[28] == '1')
type = L3DEX;
else if (uc_str[31] == '2')
type = L3DEX2;
}
else if (strncmp( &uc_str[14], "S2D", 3 ) == 0)
{
if (uc_str[28] == '1')
type = S2DEX;
else if (uc_str[31] == '2')
type = S2DEX2;
}
}
if (type != NONE)
{
current->type = type;
return current;
}
break;
}
}
for (u32 i = 0; i < sizeof( specialMicrocodes ) / sizeof( SpecialMicrocodeInfo ); i++)
{
if (strcmp( uc_str, specialMicrocodes[i].text ) == 0)
{
current->type = specialMicrocodes[i].type;
return current;
}
}
// Let the user choose the microcode
#ifndef __LINUX__
current->type = DialogBox( hInstance, MAKEINTRESOURCE( IDD_MICROCODEDLG ), hWnd, MicrocodeDlgProc );
#else // !__LINUX__
printf( "glN64: Warning - unknown ucode!!!\n" );
current->type = MicrocodeDialog();
#endif // __LINUX__
return current;
}
void GBI_MakeCurrent( MicrocodeInfo *current )
{
if (current != GBI.top)
{
if (current == GBI.bottom)
{
GBI.bottom = current->higher;
GBI.bottom->lower = NULL;
}
else
{
current->higher->lower = current->lower;
current->lower->higher = current->higher;
}
current->higher = NULL;
current->lower = GBI.top;
GBI.top->higher = current;
GBI.top = current;
}
if (!GBI.current || (GBI.current->type != current->type))
{
for (int i = 0; i <= 0xFF; i++)
GBI.cmd[i] = GBI_Unknown;
RDP_Init();
switch (current->type)
{
case F3D: F3D_Init(); break;
case F3DEX: F3DEX_Init(); break;
case F3DEX2: F3DEX2_Init(); break;
case L3D: L3D_Init(); break;
case L3DEX: L3DEX_Init(); break;
case L3DEX2: L3DEX2_Init(); break;
case S2DEX: S2DEX_Init(); break;
case S2DEX2: S2DEX2_Init(); break;
case F3DDKR: F3DDKR_Init(); break;
case F3DWRUS: F3DWRUS_Init(); break;
case F3DPD: F3DPD_Init(); break;
}
}
GBI.current = current;
}

783
GBI.h Normal file
View File

@ -0,0 +1,783 @@
#ifndef GBI_H
#define GBI_H
#include "Types.h"
// Microcode Types
#define F3D 0
#define F3DEX 1
#define F3DEX2 2
#define L3D 3
#define L3DEX 4
#define L3DEX2 5
#define S2DEX 6
#define S2DEX2 7
#define F3DPD 8
#define F3DDKR 9
#define F3DWRUS 10
#define NONE 11
static const char *MicrocodeTypes[] =
{
"Fast3D",
"F3DEX",
"F3DEX2",
"Line3D",
"L3DEX",
"L3DEX2",
"S2DEX",
"S2DEX2",
"Perfect Dark",
"DKR/JFG",
"Waverace US",
"None"
};
static const int numMicrocodeTypes = 11;
// Fixed point conversion factors
#define FIXED2FLOATRECIP1 0.5f
#define FIXED2FLOATRECIP2 0.25f
#define FIXED2FLOATRECIP3 0.125f
#define FIXED2FLOATRECIP4 0.0625f
#define FIXED2FLOATRECIP5 0.03125f
#define FIXED2FLOATRECIP6 0.015625f
#define FIXED2FLOATRECIP7 0.0078125f
#define FIXED2FLOATRECIP8 0.00390625f
#define FIXED2FLOATRECIP9 0.001953125f
#define FIXED2FLOATRECIP10 0.0009765625f
#define FIXED2FLOATRECIP11 0.00048828125f
#define FIXED2FLOATRECIP12 0.00024414063f
#define FIXED2FLOATRECIP13 0.00012207031f
#define FIXED2FLOATRECIP14 6.1035156e-05f
#define FIXED2FLOATRECIP15 3.0517578e-05f
#define FIXED2FLOATRECIP16 1.5258789e-05f
#define _FIXED2FLOAT( v, b ) \
((f32)v * FIXED2FLOATRECIP##b)
// Useful macros for decoding GBI command's parameters
#define _SHIFTL( v, s, w ) \
(((u32)v & ((0x01 << w) - 1)) << s)
#define _SHIFTR( v, s, w ) \
(((u32)v >> s) & ((0x01 << w) - 1))
// BG flags
#define G_BGLT_LOADBLOCK 0x0033
#define G_BGLT_LOADTILE 0xfff4
#define G_BG_FLAG_FLIPS 0x01
#define G_BG_FLAG_FLIPT 0x10
// Sprite object render modes
#define G_OBJRM_NOTXCLAMP 0x01
#define G_OBJRM_XLU 0x02 /* Ignored */
#define G_OBJRM_ANTIALIAS 0x04 /* Ignored */
#define G_OBJRM_BILERP 0x08
#define G_OBJRM_SHRINKSIZE_1 0x10
#define G_OBJRM_SHRINKSIZE_2 0x20
#define G_OBJRM_WIDEN 0x40
// Sprite texture loading types
#define G_OBJLT_TXTRBLOCK 0x00001033
#define G_OBJLT_TXTRTILE 0x00fc1034
#define G_OBJLT_TLUT 0x00000030
// These are all the constant flags
#define G_ZBUFFER 0x00000001
#define G_SHADE 0x00000004
#define G_FOG 0x00010000
#define G_LIGHTING 0x00020000
#define G_TEXTURE_GEN 0x00040000
#define G_TEXTURE_GEN_LINEAR 0x00080000
#define G_LOD 0x00100000
#define G_MV_MMTX 2
#define G_MV_PMTX 6
#define G_MV_LIGHT 10
#define G_MV_POINT 12
#define G_MV_MATRIX 14
#define G_MVO_LOOKATX 0
#define G_MVO_LOOKATY 24
#define G_MVO_L0 48
#define G_MVO_L1 72
#define G_MVO_L2 96
#define G_MVO_L3 120
#define G_MVO_L4 144
#define G_MVO_L5 168
#define G_MVO_L6 192
#define G_MVO_L7 216
#define G_MV_LOOKATY 0x82
#define G_MV_LOOKATX 0x84
#define G_MV_L0 0x86
#define G_MV_L1 0x88
#define G_MV_L2 0x8a
#define G_MV_L3 0x8c
#define G_MV_L4 0x8e
#define G_MV_L5 0x90
#define G_MV_L6 0x92
#define G_MV_L7 0x94
#define G_MV_TXTATT 0x96
#define G_MV_MATRIX_1 0x9E
#define G_MV_MATRIX_2 0x98
#define G_MV_MATRIX_3 0x9A
#define G_MV_MATRIX_4 0x9C
#define G_MW_MATRIX 0x00
#define G_MW_NUMLIGHT 0x02
#define G_MW_CLIP 0x04
#define G_MW_SEGMENT 0x06
#define G_MW_FOG 0x08
#define G_MW_LIGHTCOL 0x0A
#define G_MW_FORCEMTX 0x0C
#define G_MW_POINTS 0x0C
#define G_MW_PERSPNORM 0x0E
#define G_MWO_NUMLIGHT 0x00
#define G_MWO_CLIP_RNX 0x04
#define G_MWO_CLIP_RNY 0x0c
#define G_MWO_CLIP_RPX 0x14
#define G_MWO_CLIP_RPY 0x1c
#define G_MWO_SEGMENT_0 0x00
#define G_MWO_SEGMENT_1 0x01
#define G_MWO_SEGMENT_2 0x02
#define G_MWO_SEGMENT_3 0x03
#define G_MWO_SEGMENT_4 0x04
#define G_MWO_SEGMENT_5 0x05
#define G_MWO_SEGMENT_6 0x06
#define G_MWO_SEGMENT_7 0x07
#define G_MWO_SEGMENT_8 0x08
#define G_MWO_SEGMENT_9 0x09
#define G_MWO_SEGMENT_A 0x0a
#define G_MWO_SEGMENT_B 0x0b
#define G_MWO_SEGMENT_C 0x0c
#define G_MWO_SEGMENT_D 0x0d
#define G_MWO_SEGMENT_E 0x0e
#define G_MWO_SEGMENT_F 0x0f
#define G_MWO_FOG 0x00
#define G_MWO_MATRIX_XX_XY_I 0x00
#define G_MWO_MATRIX_XZ_XW_I 0x04
#define G_MWO_MATRIX_YX_YY_I 0x08
#define G_MWO_MATRIX_YZ_YW_I 0x0C
#define G_MWO_MATRIX_ZX_ZY_I 0x10
#define G_MWO_MATRIX_ZZ_ZW_I 0x14
#define G_MWO_MATRIX_WX_WY_I 0x18
#define G_MWO_MATRIX_WZ_WW_I 0x1C
#define G_MWO_MATRIX_XX_XY_F 0x20
#define G_MWO_MATRIX_XZ_XW_F 0x24
#define G_MWO_MATRIX_YX_YY_F 0x28
#define G_MWO_MATRIX_YZ_YW_F 0x2C
#define G_MWO_MATRIX_ZX_ZY_F 0x30
#define G_MWO_MATRIX_ZZ_ZW_F 0x34
#define G_MWO_MATRIX_WX_WY_F 0x38
#define G_MWO_MATRIX_WZ_WW_F 0x3C
#define G_MWO_POINT_RGBA 0x10
#define G_MWO_POINT_ST 0x14
#define G_MWO_POINT_XYSCREEN 0x18
#define G_MWO_POINT_ZSCREEN 0x1C
#ifdef DEBUG
static const char *MWOPointText[] =
{
"G_MWO_POINT_RGBA",
"G_MWO_POINT_ST",
"G_MWO_POINT_XYSCREEN",
"G_MWO_POINT_ZSCREEN"
};
static const char *MWOMatrixText[] =
{
"G_MWO_MATRIX_XX_XY_I", "G_MWO_MATRIX_XZ_XW_I", "G_MWO_MATRIX_YX_YY_I", "G_MWO_MATRIX_YZ_YW_I",
"G_MWO_MATRIX_ZX_ZY_I", "G_MWO_MATRIX_ZZ_ZW_I", "G_MWO_MATRIX_WX_WY_I", "G_MWO_MATRIX_WZ_WW_I",
"G_MWO_MATRIX_XX_XY_F", "G_MWO_MATRIX_XZ_XW_F", "G_MWO_MATRIX_YX_YY_F", "G_MWO_MATRIX_YZ_YW_F",
"G_MWO_MATRIX_ZX_ZY_F", "G_MWO_MATRIX_ZZ_ZW_F", "G_MWO_MATRIX_WX_WY_F", "G_MWO_MATRIX_WZ_WW_F"
};
#endif
// These flags change between ucodes
extern u32 G_MTX_STACKSIZE;
extern u32 G_MTX_MODELVIEW;
extern u32 G_MTX_PROJECTION;
extern u32 G_MTX_MUL;
extern u32 G_MTX_LOAD;
extern u32 G_MTX_NOPUSH;
extern u32 G_MTX_PUSH;
extern u32 G_TEXTURE_ENABLE;
extern u32 G_SHADING_SMOOTH;
extern u32 G_CULL_FRONT;
extern u32 G_CULL_BACK;
extern u32 G_CULL_BOTH;
extern u32 G_CLIPPING;
extern u32 G_MV_VIEWPORT;
extern u32 G_MWO_aLIGHT_1, G_MWO_bLIGHT_1;
extern u32 G_MWO_aLIGHT_2, G_MWO_bLIGHT_2;
extern u32 G_MWO_aLIGHT_3, G_MWO_bLIGHT_3;
extern u32 G_MWO_aLIGHT_4, G_MWO_bLIGHT_4;
extern u32 G_MWO_aLIGHT_5, G_MWO_bLIGHT_5;
extern u32 G_MWO_aLIGHT_6, G_MWO_bLIGHT_6;
extern u32 G_MWO_aLIGHT_7, G_MWO_bLIGHT_7;
extern u32 G_MWO_aLIGHT_8, G_MWO_bLIGHT_8;
// Image formats
#define G_IM_FMT_RGBA 0
#define G_IM_FMT_YUV 1
#define G_IM_FMT_CI 2
#define G_IM_FMT_IA 3
#define G_IM_FMT_I 4
// Image sizes
#define G_IM_SIZ_4b 0
#define G_IM_SIZ_8b 1
#define G_IM_SIZ_16b 2
#define G_IM_SIZ_32b 3
#define G_IM_SIZ_DD 5
#define G_TX_MIRROR 0x1
#define G_TX_CLAMP 0x2
#ifdef DEBUG
static const char *ImageFormatText[] =
{
"G_IM_FMT_RGBA",
"G_IM_FMT_YUV",
"G_IM_FMT_CI",
"G_IM_FMT_IA",
"G_IM_FMT_I",
"G_IM_FMT_INVALID",
"G_IM_FMT_INVALID",
"G_IM_FMT_INVALID"
};
static const char *ImageSizeText[] =
{
"G_IM_SIZ_4b",
"G_IM_SIZ_8b",
"G_IM_SIZ_16b",
"G_IM_SIZ_32b"
};
static const char *SegmentText[] =
{
"G_MWO_SEGMENT_0", "G_MWO_SEGMENT_1", "G_MWO_SEGMENT_2", "G_MWO_SEGMENT_3",
"G_MWO_SEGMENT_4", "G_MWO_SEGMENT_5", "G_MWO_SEGMENT_6", "G_MWO_SEGMENT_7",
"G_MWO_SEGMENT_8", "G_MWO_SEGMENT_9", "G_MWO_SEGMENT_A", "G_MWO_SEGMENT_B",
"G_MWO_SEGMENT_C", "G_MWO_SEGMENT_D", "G_MWO_SEGMENT_E", "G_MWO_SEGMENT_F"
};
#endif
#define G_NOOP 0x00
#define G_IMMFIRST -65
// These GBI commands are common to all ucodes
#define G_SETCIMG 0xFF /* -1 */
#define G_SETZIMG 0xFE /* -2 */
#define G_SETTIMG 0xFD /* -3 */
#define G_SETCOMBINE 0xFC /* -4 */
#define G_SETENVCOLOR 0xFB /* -5 */
#define G_SETPRIMCOLOR 0xFA /* -6 */
#define G_SETBLENDCOLOR 0xF9 /* -7 */
#define G_SETFOGCOLOR 0xF8 /* -8 */
#define G_SETFILLCOLOR 0xF7 /* -9 */
#define G_FILLRECT 0xF6 /* -10 */
#define G_SETTILE 0xF5 /* -11 */
#define G_LOADTILE 0xF4 /* -12 */
#define G_LOADBLOCK 0xF3 /* -13 */
#define G_SETTILESIZE 0xF2 /* -14 */
#define G_LOADTLUT 0xF0 /* -16 */
#define G_RDPSETOTHERMODE 0xEF /* -17 */
#define G_SETPRIMDEPTH 0xEE /* -18 */
#define G_SETSCISSOR 0xED /* -19 */
#define G_SETCONVERT 0xEC /* -20 */
#define G_SETKEYR 0xEB /* -21 */
#define G_SETKEYGB 0xEA /* -22 */
#define G_RDPFULLSYNC 0xE9 /* -23 */
#define G_RDPTILESYNC 0xE8 /* -24 */
#define G_RDPPIPESYNC 0xE7 /* -25 */
#define G_RDPLOADSYNC 0xE6 /* -26 */
#define G_TEXRECTFLIP 0xE5 /* -27 */
#define G_TEXRECT 0xE4 /* -28 */
#define G_TRI_FILL 0xC8 /* fill triangle: 11001000 */
#define G_TRI_SHADE 0xCC /* shade triangle: 11001100 */
#define G_TRI_TXTR 0xCA /* texture triangle: 11001010 */
#define G_TRI_SHADE_TXTR 0xCE /* shade, texture triangle: 11001110 */
#define G_TRI_FILL_ZBUFF 0xC9 /* fill, zbuff triangle: 11001001 */
#define G_TRI_SHADE_ZBUFF 0xCD /* shade, zbuff triangle: 11001101 */
#define G_TRI_TXTR_ZBUFF 0xCB /* texture, zbuff triangle: 11001011 */
#define G_TRI_SHADE_TXTR_ZBUFF 0xCF /* shade, txtr, zbuff trngl: 11001111 */
/*
* G_SETOTHERMODE_L sft: shift count
*/
#define G_MDSFT_ALPHACOMPARE 0
#define G_MDSFT_ZSRCSEL 2
#define G_MDSFT_RENDERMODE 3
#define G_MDSFT_BLENDER 16
/*
* G_SETOTHERMODE_H sft: shift count
*/
#define G_MDSFT_BLENDMASK 0 /* unsupported */
#define G_MDSFT_ALPHADITHER 4
#define G_MDSFT_RGBDITHER 6
#define G_MDSFT_COMBKEY 8
#define G_MDSFT_TEXTCONV 9
#define G_MDSFT_TEXTFILT 12
#define G_MDSFT_TEXTLUT 14
#define G_MDSFT_TEXTLOD 16
#define G_MDSFT_TEXTDETAIL 17
#define G_MDSFT_TEXTPERSP 19
#define G_MDSFT_CYCLETYPE 20
#define G_MDSFT_COLORDITHER 22 /* unsupported in HW 2.0 */
#define G_MDSFT_PIPELINE 23
/* G_SETOTHERMODE_H gPipelineMode */
#define G_PM_1PRIMITIVE 1
#define G_PM_NPRIMITIVE 0
/* G_SETOTHERMODE_H gSetCycleType */
#define G_CYC_1CYCLE 0
#define G_CYC_2CYCLE 1
#define G_CYC_COPY 2
#define G_CYC_FILL 3
/* G_SETOTHERMODE_H gSetTexturePersp */
#define G_TP_NONE 0
#define G_TP_PERSP 1
/* G_SETOTHERMODE_H gSetTextureDetail */
#define G_TD_CLAMP 0
#define G_TD_SHARPEN 1
#define G_TD_DETAIL 2
/* G_SETOTHERMODE_H gSetTextureLOD */
#define G_TL_TILE 0
#define G_TL_LOD 1
/* G_SETOTHERMODE_H gSetTextureLUT */
#define G_TT_NONE 0
#define G_TT_RGBA16 2
#define G_TT_IA16 3
/* G_SETOTHERMODE_H gSetTextureFilter */
#define G_TF_POINT 0
#define G_TF_AVERAGE 3
#define G_TF_BILERP 2
/* G_SETOTHERMODE_H gSetTextureConvert */
#define G_TC_CONV 0
#define G_TC_FILTCONV 5
#define G_TC_FILT 6
/* G_SETOTHERMODE_H gSetCombineKey */
#define G_CK_NONE 0
#define G_CK_KEY 1
/* G_SETOTHERMODE_H gSetColorDither */
#define G_CD_MAGICSQ 0
#define G_CD_BAYER 1
#define G_CD_NOISE 2
#define G_CD_DISABLE 3
#define G_CD_ENABLE G_CD_NOISE /* HW 1.0 compatibility mode */
/* G_SETOTHERMODE_H gSetAlphaDither */
#define G_AD_PATTERN 0
#define G_AD_NOTPATTERN 1
#define G_AD_NOISE 2
#define G_AD_DISABLE 3
/* G_SETOTHERMODE_L gSetAlphaCompare */
#define G_AC_NONE 0
#define G_AC_THRESHOLD 1
#define G_AC_DITHER 3
/* G_SETOTHERMODE_L gSetDepthSource */
#define G_ZS_PIXEL 0
#define G_ZS_PRIM 1
/* G_SETOTHERMODE_L gSetRenderMode */
#define AA_EN 1
#define Z_CMP 1
#define Z_UPD 1
#define IM_RD 1
#define CLR_ON_CVG 1
#define CVG_DST_CLAMP 0
#define CVG_DST_WRAP 1
#define CVG_DST_FULL 2
#define CVG_DST_SAVE 3
#define ZMODE_OPA 0
#define ZMODE_INTER 1
#define ZMODE_XLU 2
#define ZMODE_DEC 3
#define CVG_X_ALPHA 1
#define ALPHA_CVG_SEL 1
#define FORCE_BL 1
#define TEX_EDGE 0 // not used
#define G_SC_NON_INTERLACE 0
#define G_SC_EVEN_INTERLACE 2
#define G_SC_ODD_INTERLACE 3
#ifdef DEBUG
static const char *AAEnableText = "AA_EN";
static const char *DepthCompareText = "Z_CMP";
static const char *DepthUpdateText = "Z_UPD";
static const char *ClearOnCvgText = "CLR_ON_CVG";
static const char *CvgXAlphaText = "CVG_X_ALPHA";
static const char *AlphaCvgSelText = "ALPHA_CVG_SEL";
static const char *ForceBlenderText = "FORCE_BL";
static const char *AlphaCompareText[] =
{
"G_AC_NONE", "G_AC_THRESHOLD", "G_AC_INVALID", "G_AC_DITHER"
};
static const char *DepthSourceText[] =
{
"G_ZS_PIXEL", "G_ZS_PRIM"
};
static const char *AlphaDitherText[] =
{
"G_AD_PATTERN", "G_AD_NOTPATTERN", "G_AD_NOISE", "G_AD_DISABLE"
};
static const char *ColorDitherText[] =
{
"G_CD_MAGICSQ", "G_CD_BAYER", "G_CD_NOISE", "G_CD_DISABLE"
};
static const char *CombineKeyText[] =
{
"G_CK_NONE", "G_CK_KEY"
};
static const char *TextureConvertText[] =
{
"G_TC_CONV", "G_TC_INVALID", "G_TC_INVALID", "G_TC_INVALID", "G_TC_INVALID", "G_TC_FILTCONV", "G_TC_FILT", "G_TC_INVALID"
};
static const char *TextureFilterText[] =
{
"G_TF_POINT", "G_TF_INVALID", "G_TF_BILERP", "G_TF_AVERAGE"
};
static const char *TextureLUTText[] =
{
"G_TT_NONE", "G_TT_INVALID", "G_TT_RGBA16", "G_TT_IA16"
};
static const char *TextureLODText[] =
{
"G_TL_TILE", "G_TL_LOD"
};
static const char *TextureDetailText[] =
{
"G_TD_CLAMP", "G_TD_SHARPEN", "G_TD_DETAIL"
};
static const char *TexturePerspText[] =
{
"G_TP_NONE", "G_TP_PERSP"
};
static const char *CycleTypeText[] =
{
"G_CYC_1CYCLE", "G_CYC_2CYCLE", "G_CYC_COPY", "G_CYC_FILL"
};
static const char *PipelineModeText[] =
{
"G_PM_NPRIMITIVE", "G_PM_1PRIMITIVE"
};
static const char *CvgDestText[] =
{
"CVG_DST_CLAMP", "CVG_DST_WRAP", "CVG_DST_FULL", "CVG_DST_SAVE"
};
static const char *DepthModeText[] =
{
"ZMODE_OPA", "ZMODE_INTER", "ZMODE_XLU", "ZMODE_DEC"
};
static const char *ScissorModeText[] =
{
"G_SC_NON_INTERLACE", "G_SC_INVALID", "G_SC_EVEN_INTERLACE", "G_SC_ODD_INTERLACE"
};
#endif
/* Color combiner constants: */
#define G_CCMUX_COMBINED 0
#define G_CCMUX_TEXEL0 1
#define G_CCMUX_TEXEL1 2
#define G_CCMUX_PRIMITIVE 3
#define G_CCMUX_SHADE 4
#define G_CCMUX_ENVIRONMENT 5
#define G_CCMUX_CENTER 6
#define G_CCMUX_SCALE 6
#define G_CCMUX_COMBINED_ALPHA 7
#define G_CCMUX_TEXEL0_ALPHA 8
#define G_CCMUX_TEXEL1_ALPHA 9
#define G_CCMUX_PRIMITIVE_ALPHA 10
#define G_CCMUX_SHADE_ALPHA 11
#define G_CCMUX_ENV_ALPHA 12
#define G_CCMUX_LOD_FRACTION 13
#define G_CCMUX_PRIM_LOD_FRAC 14
#define G_CCMUX_NOISE 7
#define G_CCMUX_K4 7
#define G_CCMUX_K5 15
#define G_CCMUX_1 6
#define G_CCMUX_0 31
/* Alpha combiner constants: */
#define G_ACMUX_COMBINED 0
#define G_ACMUX_TEXEL0 1
#define G_ACMUX_TEXEL1 2
#define G_ACMUX_PRIMITIVE 3
#define G_ACMUX_SHADE 4
#define G_ACMUX_ENVIRONMENT 5
#define G_ACMUX_LOD_FRACTION 0
#define G_ACMUX_PRIM_LOD_FRAC 6
#define G_ACMUX_1 6
#define G_ACMUX_0 7
#ifdef DEBUG
static const char *saRGBText[] =
{
"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE",
"SHADE", "ENVIRONMENT", "NOISE", "1",
"0", "0", "0", "0",
"0", "0", "0", "0"
};
static const char *sbRGBText[] =
{
"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE",
"SHADE", "ENVIRONMENT", "CENTER", "K4",
"0", "0", "0", "0",
"0", "0", "0", "0"
};
static const char *mRGBText[] =
{
"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE",
"SHADE", "ENVIRONMENT", "SCALE", "COMBINED_ALPHA",
"TEXEL0_ALPHA", "TEXEL1_ALPHA", "PRIMITIVE_ALPHA", "SHADE_ALPHA",
"ENV_ALPHA", "LOD_FRACTION", "PRIM_LOD_FRAC", "K5",
"0", "0", "0", "0",
"0", "0", "0", "0",
"0", "0", "0", "0",
"0", "0", "0", "0"
};
static const char *aRGBText[] =
{
"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE",
"SHADE", "ENVIRONMENT", "1", "0",
};
static const char *saAText[] =
{
"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE",
"SHADE", "ENVIRONMENT", "1", "0",
};
static const char *sbAText[] =
{
"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE",
"SHADE", "ENVIRONMENT", "1", "0",
};
static const char *mAText[] =
{
"LOD_FRACTION", "TEXEL0", "TEXEL1", "PRIMITIVE",
"SHADE", "ENVIRONMENT", "PRIM_LOD_FRAC", "0",
};
static const char *aAText[] =
{
"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE",
"SHADE", "ENVIRONMENT", "1", "0",
};
#endif
extern u32 G_RDPHALF_1, G_RDPHALF_2, G_RDPHALF_CONT;
extern u32 G_SPNOOP;
extern u32 G_SETOTHERMODE_H, G_SETOTHERMODE_L;
extern u32 G_DL, G_ENDDL, G_CULLDL, G_BRANCH_Z;
extern u32 G_LOAD_UCODE;
extern u32 G_MOVEMEM, G_MOVEWORD;
extern u32 G_MTX, G_POPMTX;
extern u32 G_GEOMETRYMODE, G_SETGEOMETRYMODE, G_CLEARGEOMETRYMODE;
extern u32 G_TEXTURE;
extern u32 G_DMA_IO, G_DMA_DL, G_DMA_TRI, G_DMA_MTX, G_DMA_VTX, G_DMA_OFFSETS;
extern u32 G_SPECIAL_1, G_SPECIAL_2, G_SPECIAL_3;
extern u32 G_VTX, G_MODIFYVTX, G_VTXCOLORBASE;
extern u32 G_TRI1, G_TRI2, G_TRI4;
extern u32 G_QUAD, G_LINE3D;
extern u32 G_RESERVED0, G_RESERVED1, G_RESERVED2, G_RESERVED3;
extern u32 G_SPRITE2D_BASE;
extern u32 G_BG_1CYC, G_BG_COPY;
extern u32 G_OBJ_RECTANGLE, G_OBJ_SPRITE, G_OBJ_MOVEMEM;
extern u32 G_SELECT_DL, G_OBJ_RENDERMODE, G_OBJ_RECTANGLE_R;
extern u32 G_OBJ_LOADTXTR, G_OBJ_LDTX_SPRITE, G_OBJ_LDTX_RECT, G_OBJ_LDTX_RECT_R;
extern u32 G_RDPHALF_0;
#define LIGHT_1 1
#define LIGHT_2 2
#define LIGHT_3 3
#define LIGHT_4 4
#define LIGHT_5 5
#define LIGHT_6 6
#define LIGHT_7 7
#define LIGHT_8 8
#define G_DL_PUSH 0x00
#define G_DL_NOPUSH 0x01
typedef struct
{
s16 y;
s16 x;
u16 flag;
s16 z;
s16 t;
s16 s;
union {
struct
{
u8 a;
u8 b;
u8 g;
u8 r;
} color;
struct
{
s8 a;
s8 z; // b
s8 y; //g
s8 x; //r
} normal;
};
} Vertex;
typedef struct
{
s16 y, x;
u16 ci;
s16 z;
s16 t, s;
} PDVertex;
typedef struct
{
u8 v2, v1, v0, flag;
s16 t0, s0;
s16 t1, s1;
s16 t2, s2;
} DKRTriangle;
struct Light
{
u8 pad0, b, g, r;
u8 pad1, b2, g2, r2;
s8 pad2, z, y, x;
};
// GBI commands
typedef void (*GBIFunc)( u32 w0, u32 w1 );
//extern GBIFunc GBICmd[256];
struct SpecialMicrocodeInfo
{
u32 type;
u32 NoN;
u32 crc;
char *text;
};
struct MicrocodeInfo
{
u32 address, dataAddress;
u16 dataSize;
u32 type;
u32 NoN;
u32 crc;
u32 *text;
MicrocodeInfo *higher, *lower;
};
struct GBIInfo
{
GBIFunc cmd[256];
u32 PCStackSize, numMicrocodes;
MicrocodeInfo *current, *top, *bottom;
};
extern GBIInfo GBI;
void GBI_MakeCurrent( MicrocodeInfo *current );
MicrocodeInfo *GBI_DetectMicrocode( u32 uc_start, u32 uc_dstart, u16 uc_dsize );
void GBI_Init();
void GBI_Destroy();
// Allows easier setting of GBI commands
#define GBI_SetGBI( command, value, function ) \
command = value; \
GBI.cmd[command] = function
#define GBI_InitFlags( ucode ) \
G_MTX_STACKSIZE = ucode##_MTX_STACKSIZE; \
G_MTX_MODELVIEW = ucode##_MTX_MODELVIEW; \
G_MTX_PROJECTION = ucode##_MTX_PROJECTION; \
G_MTX_MUL = ucode##_MTX_MUL; \
G_MTX_LOAD = ucode##_MTX_LOAD; \
G_MTX_NOPUSH = ucode##_MTX_NOPUSH; \
G_MTX_PUSH = ucode##_MTX_PUSH; \
\
G_TEXTURE_ENABLE = ucode##_TEXTURE_ENABLE; \
G_SHADING_SMOOTH = ucode##_SHADING_SMOOTH; \
G_CULL_FRONT = ucode##_CULL_FRONT; \
G_CULL_BACK = ucode##_CULL_BACK; \
G_CULL_BOTH = ucode##_CULL_BOTH; \
G_CLIPPING = ucode##_CLIPPING; \
\
G_MV_VIEWPORT = ucode##_MV_VIEWPORT; \
\
G_MWO_aLIGHT_1 = ucode##_MWO_aLIGHT_1; \
G_MWO_bLIGHT_1 = ucode##_MWO_bLIGHT_1; \
G_MWO_aLIGHT_2 = ucode##_MWO_aLIGHT_2; \
G_MWO_bLIGHT_2 = ucode##_MWO_bLIGHT_2; \
G_MWO_aLIGHT_3 = ucode##_MWO_aLIGHT_3; \
G_MWO_bLIGHT_3 = ucode##_MWO_bLIGHT_3; \
G_MWO_aLIGHT_4 = ucode##_MWO_aLIGHT_4; \
G_MWO_bLIGHT_4 = ucode##_MWO_bLIGHT_4; \
G_MWO_aLIGHT_5 = ucode##_MWO_aLIGHT_5; \
G_MWO_bLIGHT_5 = ucode##_MWO_bLIGHT_5; \
G_MWO_aLIGHT_6 = ucode##_MWO_aLIGHT_6; \
G_MWO_bLIGHT_6 = ucode##_MWO_bLIGHT_6; \
G_MWO_aLIGHT_7 = ucode##_MWO_aLIGHT_7; \
G_MWO_bLIGHT_7 = ucode##_MWO_bLIGHT_7; \
G_MWO_aLIGHT_8 = ucode##_MWO_aLIGHT_8; \
G_MWO_bLIGHT_8 = ucode##_MWO_bLIGHT_8;
#endif

57
L3D.cpp Normal file
View File

@ -0,0 +1,57 @@
#include "glN64.h"
#include "Debug.h"
#include "F3D.h"
#include "L3D.h"
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "gSP.h"
#include "gDP.h"
#include "GBI.h"
void L3D_Line3D( u32 w0, u32 w1 )
{
u32 wd = _SHIFTR( w1, 0, 8 );
if (wd == 0)
gSPLine3D( _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, _SHIFTR( w1, 24, 8 ) );
else
gSPLineW3D( _SHIFTR( w1, 16, 8 ) / 10, _SHIFTR( w1, 8, 8 ) / 10, wd, _SHIFTR( w1, 24, 8 ) );
}
void L3D_Init()
{
// Set GeometryMode flags
GBI_InitFlags( F3D );
GBI.PCStackSize = 10;
// GBI Command Command Value Command Function
GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp );
GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx );
GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 );
GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem );
GBI_SetGBI( G_VTX, F3D_VTX, F3D_Vtx );
GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 );
GBI_SetGBI( G_DL, F3D_DL, F3D_DList );
GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 );
GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 );
GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base );
// GBI_SetGBI( G_TRI1, F3D_TRI1, F3D_Tri1 );
GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3D_CullDL );
GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx );
GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord );
GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture );
GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H );
GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L );
GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL );
GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode );
GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode );
GBI_SetGBI( G_LINE3D, L3D_LINE3D, L3D_Line3D );
GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 );
GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 );
GBI_SetGBI( G_RDPHALF_CONT, F3D_RDPHALF_CONT, F3D_RDPHalf_Cont );
// GBI_SetGBI( G_TRI4, F3D_TRI4, F3D_Tri4 );
}

10
L3D.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef L3D_H
#define L3D_H
#include "Types.h"
#define L3D_LINE3D 0xB5
void L3D_Line3D( u32 w0, u32 w1 );
void L3D_Init();
#endif

61
L3DEX.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "glN64.h"
#include "Debug.h"
#include "F3D.h"
#include "F3DEX.h"
#include "L3D.h"
#include "L3DEX.h"
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "gSP.h"
#include "gDP.h"
#include "GBI.h"
void L3DEX_Line3D( u32 w0, u32 w1 )
{
u32 wd = _SHIFTR( w1, 0, 8 );
if (wd == 0)
gSPLine3D( _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), 0 );
else
gSPLineW3D( _SHIFTR( w1, 17, 7 ), _SHIFTR( w1, 9, 7 ), wd, 0 );
}
void L3DEX_Init()
{
// Set GeometryMode flags
GBI_InitFlags( F3DEX );
GBI.PCStackSize = 18;
// GBI Command Command Value Command Function
GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp );
GBI_SetGBI( G_MTX, F3D_MTX, F3D_Mtx );
GBI_SetGBI( G_RESERVED0, F3D_RESERVED0, F3D_Reserved0 );
GBI_SetGBI( G_MOVEMEM, F3D_MOVEMEM, F3D_MoveMem );
GBI_SetGBI( G_VTX, F3D_VTX, F3DEX_Vtx );
GBI_SetGBI( G_RESERVED1, F3D_RESERVED1, F3D_Reserved1 );
GBI_SetGBI( G_DL, F3D_DL, F3D_DList );
GBI_SetGBI( G_RESERVED2, F3D_RESERVED2, F3D_Reserved2 );
GBI_SetGBI( G_RESERVED3, F3D_RESERVED3, F3D_Reserved3 );
GBI_SetGBI( G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, F3D_Sprite2D_Base );
// GBI_SetGBI( G_TRI1, F3D_TRI1, F3DEX_Tri1 );
GBI_SetGBI( G_CULLDL, F3D_CULLDL, F3DEX_CullDL );
GBI_SetGBI( G_POPMTX, F3D_POPMTX, F3D_PopMtx );
GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord );
GBI_SetGBI( G_TEXTURE, F3D_TEXTURE, F3D_Texture );
GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H );
GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L );
GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL );
GBI_SetGBI( G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, F3D_SetGeometryMode );
GBI_SetGBI( G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE, F3D_ClearGeometryMode );
GBI_SetGBI( G_LINE3D, L3D_LINE3D, L3DEX_Line3D );
GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 );
GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 );
GBI_SetGBI( G_MODIFYVTX, F3DEX_MODIFYVTX, F3DEX_ModifyVtx );
// GBI_SetGBI( G_TRI2, F3DEX_TRI2, F3DEX_Tri2 );
GBI_SetGBI( G_BRANCH_Z, F3DEX_BRANCH_Z, F3DEX_Branch_Z );
GBI_SetGBI( G_LOAD_UCODE, F3DEX_LOAD_UCODE, F3DEX_Load_uCode );
}

8
L3DEX.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef L3DEX_H
#define L3DEX_H
#include "Types.h"
void L3DEX_Line3D( u32 w0, u32 w1 );
void L3DEX_Init();
#endif

61
L3DEX2.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "glN64.h"
#include "Debug.h"
#include "F3D.h"
#include "F3DEX.h"
#include "F3DEX2.h"
#include "L3DEX2.h"
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "gSP.h"
#include "gDP.h"
#include "GBI.h"
void L3DEX2_Line3D( u32 w0, u32 w1 )
{
u32 wd = _SHIFTR( w0, 0, 8 );
if (wd == 0)
gSPLine3D( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), 0 );
else
gSPLineW3D( _SHIFTR( w0, 17, 7 ), _SHIFTR( w0, 9, 7 ), wd, 0 );
}
void L3DEX2_Init()
{
// Set GeometryMode flags
GBI_InitFlags( F3DEX2 );
GBI.PCStackSize = 18;
// GBI Command Command Value Command Function
// GBI_SetGBI( G_BG_COPY, 0x0A, S2DEX_BG_Copy );
GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 );
GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H );
GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L );
GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 );
GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp );
GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL );
GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList );
GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode );
GBI_SetGBI( G_MOVEMEM, F3DEX2_MOVEMEM, F3DEX2_MoveMem );
GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2_MoveWord );
GBI_SetGBI( G_MTX, F3DEX2_MTX, F3DEX2_Mtx );
GBI_SetGBI( G_GEOMETRYMODE, F3DEX2_GEOMETRYMODE, F3DEX2_GeometryMode );
GBI_SetGBI( G_POPMTX, F3DEX2_POPMTX, F3DEX2_PopMtx );
GBI_SetGBI( G_TEXTURE, F3DEX2_TEXTURE, F3DEX2_Texture );
GBI_SetGBI( G_DMA_IO, F3DEX2_DMA_IO, F3DEX2_DMAIO );
GBI_SetGBI( G_SPECIAL_1, F3DEX2_SPECIAL_1, F3DEX2_Special_1 );
GBI_SetGBI( G_SPECIAL_2, F3DEX2_SPECIAL_2, F3DEX2_Special_2 );
GBI_SetGBI( G_SPECIAL_3, F3DEX2_SPECIAL_3, F3DEX2_Special_3 );
GBI_SetGBI( G_VTX, F3DEX2_VTX, F3DEX2_Vtx );
GBI_SetGBI( G_MODIFYVTX, F3DEX2_MODIFYVTX, F3DEX_ModifyVtx );
GBI_SetGBI( G_CULLDL, F3DEX2_CULLDL, F3DEX_CullDL );
GBI_SetGBI( G_BRANCH_Z, F3DEX2_BRANCH_Z, F3DEX_Branch_Z );
// GBI_SetGBI( G_TRI1, F3DEX2_TRI1, F3DEX2_Tri1 );
// GBI_SetGBI( G_TRI2, F3DEX2_TRI2, F3DEX_Tri2 );
// GBI_SetGBI( G_QUAD, F3DEX2_QUAD, F3DEX2_Quad );
GBI_SetGBI( G_LINE3D, L3DEX2_LINE3D, L3DEX2_Line3D );
}

10
L3DEX2.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef L3DEX2_H
#define L3DEX2_H
#include "Types.h"
#define L3DEX2_LINE3D 0x08
void L3DEX2_Line3D( u32 w0, u32 w1 );
void L3DEX2_Init();
#endif

339
LICENCE Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

48
Makefile Normal file
View File

@ -0,0 +1,48 @@
DEFINES = -D__LINUX__ -DX86_ASM
CXX = g++
CXXFLAGS = -I. $(DEFINES) `sdl-config --cflags` `gtk-config --cflags gtk gthread` \
`glib-config --cflags` -fPIC -finline-functions -funroll-loops \
-ffast-math -mcpu=`uname -m` -O2
#CXXFLAGS = -I. $(DEFINES) `sdl-config --cflags` `gtk-config --cflags gtk gthread` \
# `glib-config --cflags` -g3 #-DDEBUG
LD = g++
LDFLAGS = -shared -fPIC
LIBS = `sdl-config --libs` `gtk-config --libs gtk gthread` `glib-config --libs` -lGL -lGLU
TARGET = glN64-0.4.1.so
OBJECTS = 2xSAI.o \
CRC.o \
Combiner.o \
Config_linux.o \
Debug_linux.o \
DepthBuffer.o \
F3D.o \
F3DEX.o \
F3DEX2.o \
F3DDKR.o \
F3DPD.o \
F3DWRUS.o \
FrameBuffer.o \
glN64.o \
GBI.o \
gDP.o \
gSP.o \
L3D.o \
L3DEX.o \
L3DEX2.o \
N64.o \
NV_register_combiners.o \
OpenGL.o \
RDP.o \
RSP.o \
S2DEX.o \
S2DEX2.o \
texture_env.o \
texture_env_combine.o \
Textures.o \
VI.o
$(TARGET): $(OBJECTS)
$(LD) $(LDFLAGS) $(LIBS) -o $@ $(OBJECTS)
clean:
rm -f $(TARGET) $(OBJECTS)

15
N64.cpp Normal file
View File

@ -0,0 +1,15 @@
#ifndef __LINUX__
# include <windows.h>
#else
# include "winlnxdefs.h"
#endif // __LINUX__
#include "N64.h"
#include "Types.h"
u8 *DMEM;
u8 *IMEM;
u64 TMEM[512];
u8 *RDRAM;
u32 RDRAMSize;
N64Regs REG;

45
N64.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef N64_H
#define N64_H
#include "Types.h"
#define MI_INTR_DP 0x20 // Bit 5: DP intr
struct N64Regs
{
u32 *MI_INTR;
u32 *DPC_START;
u32 *DPC_END;
u32 *DPC_CURRENT;
u32 *DPC_STATUS;
u32 *DPC_CLOCK;
u32 *DPC_BUFBUSY;
u32 *DPC_PIPEBUSY;
u32 *DPC_TMEM;
u32 *VI_STATUS;
u32 *VI_ORIGIN;
u32 *VI_WIDTH;
u32 *VI_INTR;
u32 *VI_V_CURRENT_LINE;
u32 *VI_TIMING;
u32 *VI_V_SYNC;
u32 *VI_H_SYNC;
u32 *VI_LEAP;
u32 *VI_H_START;
u32 *VI_V_START;
u32 *VI_V_BURST;
u32 *VI_X_SCALE;
u32 *VI_Y_SCALE;
};
extern N64Regs REG;
extern u8 *DMEM;
extern u8 *IMEM;
extern u8 *RDRAM;
extern u64 TMEM[512];
extern u32 RDRAMSize;
#endif

548
NV_register_combiners.cpp Normal file
View File

@ -0,0 +1,548 @@
#ifndef __LINUX__
# include <windows.h>
#else
# include "winlnxdefs.h"
#endif // __LINUX__
#include "OpenGL.h"
#include "Combiner.h"
#include "NV_register_combiners.h"
#include "Debug.h"
#include "gDP.h"
#include "gSP.h"
#define SetColorCombinerInput( n, v, p, s ) \
if (CombinerInputs[p].input == GL_CONSTANT_COLOR0_NV) \
{ \
if ((p > 5) && ((regCombiners->constant[0].alpha == COMBINED) || (regCombiners->constant[0].alpha == p))) \
{ \
regCombiners->constant[0].alpha = p; \
regCombiners->color[n].v.input = GL_CONSTANT_COLOR0_NV; \
regCombiners->color[n].v.usage = GL_ALPHA; \
} \
else if ((p > 5) && ((regCombiners->constant[1].alpha == COMBINED) || (regCombiners->constant[1].alpha == p))) \
{ \
regCombiners->constant[1].alpha = p; \
regCombiners->color[n].v.input = GL_CONSTANT_COLOR1_NV; \
regCombiners->color[n].v.usage = GL_ALPHA; \
} \
else if ((p > 5) && ((regCombiners->vertex.alpha == COMBINED) || (regCombiners->vertex.alpha == p))) \
{ \
regCombiners->vertex.alpha = p; \
regCombiners->color[n].v.input = GL_PRIMARY_COLOR_NV; \
regCombiners->color[n].v.usage = GL_ALPHA; \
} \
else if ((regCombiners->constant[0].color == COMBINED) || (regCombiners->constant[0].color == p)) \
{ \
regCombiners->constant[0].color = p; \
regCombiners->color[n].v.input = GL_CONSTANT_COLOR0_NV; \
regCombiners->color[n].v.usage = GL_RGB; \
} \
else if ((regCombiners->constant[1].color == COMBINED) || (regCombiners->constant[1].color == p)) \
{ \
regCombiners->constant[1].color = p; \
regCombiners->color[n].v.input = GL_CONSTANT_COLOR1_NV; \
regCombiners->color[n].v.usage = GL_RGB; \
} \
else if ((regCombiners->vertex.secondaryColor == COMBINED) || (regCombiners->vertex.secondaryColor == p)) \
{ \
regCombiners->vertex.secondaryColor = p; \
regCombiners->color[n].v.input = GL_SECONDARY_COLOR_NV; \
regCombiners->color[n].v.usage = GL_RGB; \
} \
else if ((regCombiners->vertex.color == COMBINED) || (regCombiners->vertex.color == p)) \
{ \
regCombiners->vertex.color = p; \
regCombiners->color[n].v.input = GL_PRIMARY_COLOR_NV; \
regCombiners->color[n].v.usage = GL_RGB; \
} \
} \
else \
{ \
regCombiners->color[n].v.input = CombinerInputs[p].input; \
regCombiners->color[n].v.usage = CombinerInputs[p].usage; \
} \
regCombiners->color[n].v.mapping = CombinerInputs[p].mapping; \
regCombiners->color[n].v.used = s
#define SetColorCombinerVariable( n, v, i, m, u, s ) \
regCombiners->color[n].v.input = i; \
regCombiners->color[n].v.mapping = m; \
regCombiners->color[n].v.usage = u; \
regCombiners->color[n].v.used = s
#define SetAlphaCombinerInput( n, v, p, use ) \
if (CombinerInputs[p].input == GL_CONSTANT_COLOR0_NV) \
{ \
if ((regCombiners->constant[0].alpha == COMBINED) || (regCombiners->constant[0].alpha == p)) \
{ \
regCombiners->constant[0].alpha = p; \
regCombiners->alpha[n].v.input = GL_CONSTANT_COLOR0_NV; \
regCombiners->alpha[n].v.usage = GL_ALPHA; \
} \
else if ((regCombiners->constant[1].alpha == COMBINED) || (regCombiners->constant[1].alpha == p)) \
{ \
regCombiners->constant[1].alpha = p; \
regCombiners->alpha[n].v.input = GL_CONSTANT_COLOR1_NV; \
regCombiners->alpha[n].v.usage = GL_ALPHA; \
} \
else if ((regCombiners->vertex.alpha == COMBINED) || (regCombiners->vertex.alpha == p)) \
{ \
regCombiners->vertex.alpha = p; \
regCombiners->alpha[n].v.input = GL_PRIMARY_COLOR_NV; \
regCombiners->alpha[n].v.usage = GL_ALPHA; \
} \
} \
else \
{ \
regCombiners->alpha[n].v.input = CombinerInputs[p].input; \
regCombiners->alpha[n].v.usage = CombinerInputs[p].usage; \
} \
regCombiners->alpha[n].v.mapping = CombinerInputs[p].mapping; \
regCombiners->alpha[n].v.used = use
#define SetAlphaCombinerVariable( n, v, i, m, u, use ) \
regCombiners->alpha[n].v.input = i; \
regCombiners->alpha[n].v.mapping = m; \
regCombiners->alpha[n].v.usage = u; \
regCombiners->alpha[n].v.used = use
#define SetFinalCombinerInput( v, p, use ) \
if (CombinerInputs[p].input == GL_CONSTANT_COLOR0_NV) \
{ \
if ((p > 5) && ((regCombiners->constant[0].alpha == COMBINED) || (regCombiners->constant[0].alpha == p))) \
{ \
regCombiners->constant[0].alpha = p; \
regCombiners->final.v.input = GL_CONSTANT_COLOR0_NV; \
regCombiners->final.v.usage = GL_ALPHA; \
} \
else if ((p > 5) && ((regCombiners->constant[1].alpha == COMBINED) || (regCombiners->constant[1].alpha == p))) \
{ \
regCombiners->constant[1].alpha = p; \
regCombiners->final.v.input = GL_CONSTANT_COLOR1_NV; \
regCombiners->final.v.usage = GL_ALPHA; \
} \
else if ((p > 5) && ((regCombiners->vertex.alpha == COMBINED) || (regCombiners->vertex.alpha == p))) \
{ \
regCombiners->vertex.alpha = p; \
regCombiners->final.v.input = GL_PRIMARY_COLOR_NV; \
regCombiners->final.v.usage = GL_ALPHA; \
} \
else if ((regCombiners->constant[0].color == COMBINED) || (regCombiners->constant[0].color == p)) \
{ \
regCombiners->constant[0].color = p; \
regCombiners->final.v.input = GL_CONSTANT_COLOR0_NV; \
regCombiners->final.v.usage = GL_RGB; \
} \
else if ((regCombiners->constant[1].color == COMBINED) || (regCombiners->constant[1].color == p)) \
{ \
regCombiners->constant[1].color = p; \
regCombiners->final.v.input = GL_CONSTANT_COLOR1_NV; \
regCombiners->final.v.usage = GL_RGB; \
} \
else if ((regCombiners->vertex.secondaryColor == COMBINED) || (regCombiners->vertex.secondaryColor == p)) \
{ \
regCombiners->vertex.secondaryColor = p; \
regCombiners->final.v.input = GL_SECONDARY_COLOR_NV; \
regCombiners->final.v.usage = GL_RGB; \
} \
else if ((regCombiners->vertex.color == COMBINED) || (regCombiners->vertex.color == p)) \
{ \
regCombiners->vertex.color = p; \
regCombiners->final.v.input = GL_PRIMARY_COLOR_NV; \
regCombiners->final.v.usage = GL_RGB; \
} \
} \
else \
{ \
regCombiners->final.v.input = CombinerInputs[p].input; \
regCombiners->final.v.usage = CombinerInputs[p].usage; \
} \
regCombiners->final.v.mapping = CombinerInputs[p].mapping; \
regCombiners->final.v.used = use
#define SetFinalCombinerVariable( v, i, m, u, use ) \
regCombiners->final.v.input = i; \
regCombiners->final.v.mapping = m; \
regCombiners->final.v.usage = u; \
regCombiners->final.v.used = use
void Init_NV_register_combiners()
{
glCombinerParameteriNV( GL_COLOR_SUM_CLAMP_NV, GL_TRUE );
glEnable( GL_REGISTER_COMBINERS_NV );
for (int i = 0; i < OGL.maxTextureUnits; i++)
{
glActiveTextureARB( GL_TEXTURE0_ARB + i );
glDisable( GL_TEXTURE_2D );
}
}
void Uninit_NV_register_combiners()
{
glDisable( GL_REGISTER_COMBINERS_NV );
}
void Update_NV_register_combiners_Colors( RegisterCombiners *regCombiners)
{
GLcolor color;
for (int i = 0; i < 2; i++)
{
SetConstant( color, regCombiners->constant[i].color, regCombiners->constant[i].alpha );
glCombinerParameterfvNV( GL_CONSTANT_COLOR0_NV + i, (GLfloat*)&color );
}
SetConstant( color, regCombiners->vertex.secondaryColor, ZERO );
glSecondaryColor3fvEXT( (GLfloat*)&color );
}
RegisterCombiners *Compile_NV_register_combiners( Combiner *color, Combiner *alpha )
{
int curCombiner, numCombiners;
RegisterCombiners *regCombiners = (RegisterCombiners*)malloc( sizeof( RegisterCombiners ) );
for (int i = 0; i < OGL.maxGeneralCombiners; i++)
{
SetColorCombinerInput( i, A, ZERO, FALSE );
SetColorCombinerInput( i, B, ZERO, FALSE );
SetColorCombinerInput( i, C, ZERO, FALSE );
SetColorCombinerInput( i, D, ZERO, FALSE );
regCombiners->color[i].output.ab = GL_DISCARD_NV;
regCombiners->color[i].output.cd = GL_DISCARD_NV;
regCombiners->color[i].output.sum = GL_DISCARD_NV;
SetAlphaCombinerInput( i, A, ZERO, FALSE );
SetAlphaCombinerInput( i, B, ZERO, FALSE );
SetAlphaCombinerInput( i, C, ZERO, FALSE );
SetAlphaCombinerInput( i, D, ZERO, FALSE );
regCombiners->alpha[i].output.ab = GL_DISCARD_NV;
regCombiners->alpha[i].output.cd = GL_DISCARD_NV;
regCombiners->alpha[i].output.sum = GL_DISCARD_NV;
}
SetFinalCombinerInput( A, ONE, FALSE );
SetFinalCombinerInput( B, COMBINED, FALSE );
SetFinalCombinerInput( C, ZERO, FALSE );
SetFinalCombinerInput( D, ZERO, FALSE );
SetFinalCombinerInput( E, ZERO, FALSE );
SetFinalCombinerInput( F, ZERO, FALSE );
SetFinalCombinerInput( G, COMBINED, FALSE );
if ((gSP.geometryMode & G_FOG) &&
((gDP.otherMode.cycleType == G_CYC_1CYCLE) ||
(gDP.otherMode.cycleType == G_CYC_2CYCLE)) && OGL.fog)
{
SetFinalCombinerVariable( A, GL_FOG, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA, FALSE );
SetFinalCombinerVariable( C, GL_FOG, GL_UNSIGNED_IDENTITY_NV, GL_RGB, FALSE );
}
regCombiners->usesT0 = FALSE;
regCombiners->usesT1 = FALSE;
regCombiners->usesNoise = FALSE;
regCombiners->constant[0].color = COMBINED;
regCombiners->constant[0].alpha = COMBINED;
regCombiners->constant[1].color = COMBINED;
regCombiners->constant[1].alpha = COMBINED;
regCombiners->vertex.color = COMBINED;
regCombiners->vertex.secondaryColor = COMBINED;
regCombiners->vertex.alpha = COMBINED;
curCombiner = 0;
for (int i = 0; i < alpha->numStages; i++)
{
for (int j = 0; j < alpha->stage[i].numOps; j++)
{
regCombiners->usesT0 |= (alpha->stage[i].op[j].param1 == TEXEL0_ALPHA);
regCombiners->usesT1 |= (alpha->stage[i].op[j].param1 == TEXEL1_ALPHA);
regCombiners->usesNoise |= (alpha->stage[i].op[j].param1 == NOISE);
switch (alpha->stage[i].op[j].op)
{
case LOAD:
if (regCombiners->alpha[curCombiner].A.used)
{
curCombiner++;
if (curCombiner == OGL.maxGeneralCombiners)
break;
}
SetAlphaCombinerInput( curCombiner, A, alpha->stage[i].op[j].param1, TRUE );
SetAlphaCombinerInput( curCombiner, B, ONE, FALSE );
regCombiners->alpha[curCombiner].output.sum = GL_SPARE0_NV;
break;
case SUB:
if (regCombiners->alpha[curCombiner].C.used || regCombiners->alpha[curCombiner].D.used)
{
curCombiner++;
if (curCombiner == OGL.maxGeneralCombiners)
break;
SetAlphaCombinerVariable( curCombiner, A, GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_ALPHA, TRUE );
SetAlphaCombinerInput( curCombiner, B, ONE, FALSE );
regCombiners->alpha[curCombiner].output.sum = GL_SPARE0_NV;
}
SetAlphaCombinerInput( curCombiner, C, alpha->stage[i].op[j].param1, TRUE );
if (regCombiners->alpha[curCombiner].C.mapping == GL_UNSIGNED_INVERT_NV)
regCombiners->alpha[curCombiner].C.mapping = GL_EXPAND_NORMAL_NV;
else
regCombiners->alpha[curCombiner].C.mapping = GL_SIGNED_NEGATE_NV;
SetAlphaCombinerInput( curCombiner, D, ONE, FALSE );
break;
case MUL:
if (regCombiners->alpha[curCombiner].B.used || regCombiners->alpha[curCombiner].D.used)
{
curCombiner++;
if (curCombiner == OGL.maxGeneralCombiners)
break;
SetAlphaCombinerVariable( curCombiner, A, GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_ALPHA, TRUE );
regCombiners->alpha[curCombiner].output.sum = GL_SPARE0_NV;
}
SetAlphaCombinerInput( curCombiner, B, alpha->stage[i].op[j].param1, TRUE );
if (regCombiners->alpha[curCombiner].C.used)
{
SetAlphaCombinerInput( curCombiner, D, alpha->stage[i].op[j].param1, TRUE );
}
break;
case ADD:
if (regCombiners->alpha[curCombiner].C.used || regCombiners->alpha[curCombiner].D.used)
{
curCombiner++;
if (curCombiner == OGL.maxGeneralCombiners)
break;
SetAlphaCombinerVariable( curCombiner, A, GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_ALPHA, TRUE );
SetAlphaCombinerInput( curCombiner, B, ONE, FALSE );
regCombiners->alpha[curCombiner].output.sum = GL_SPARE0_NV;
}
SetAlphaCombinerInput( curCombiner, C, alpha->stage[i].op[j].param1, TRUE );
SetAlphaCombinerInput( curCombiner, D, ONE, FALSE );
break;
case INTER:
if (regCombiners->alpha[curCombiner].A.used ||
regCombiners->alpha[curCombiner].B.used ||
regCombiners->alpha[curCombiner].C.used ||
regCombiners->alpha[curCombiner].D.used)
{
curCombiner++;
if (curCombiner == OGL.maxGeneralCombiners)
break;
}
regCombiners->usesT0 |= (alpha->stage[i].op[j].param2 == TEXEL0_ALPHA) || (alpha->stage[i].op[j].param3 == TEXEL0_ALPHA);
regCombiners->usesT1 |= (alpha->stage[i].op[j].param2 == TEXEL1_ALPHA) || (alpha->stage[i].op[j].param3 == TEXEL1_ALPHA);
regCombiners->usesNoise |= (alpha->stage[i].op[j].param2 == NOISE) || (alpha->stage[i].op[j].param3 == NOISE);
SetAlphaCombinerInput( curCombiner, A, alpha->stage[i].op[j].param1, TRUE );
SetAlphaCombinerInput( curCombiner, B, alpha->stage[i].op[j].param3, TRUE );
SetAlphaCombinerInput( curCombiner, C, alpha->stage[i].op[j].param2, TRUE );
SetAlphaCombinerVariable( curCombiner, D, regCombiners->alpha[curCombiner].B.input, GL_UNSIGNED_INVERT_NV, GL_ALPHA, TRUE );
regCombiners->alpha[curCombiner].output.sum = GL_SPARE0_NV;
break;
}
if (curCombiner == OGL.maxGeneralCombiners)
break; // Get out if the combiners are full
}
if (curCombiner == OGL.maxGeneralCombiners)
break; // Get out if the combiners are full
}
numCombiners = min( curCombiner + 1, OGL.maxGeneralCombiners );
curCombiner = 0;
for (int i = 0; i < (color->numStages) && (curCombiner < OGL.maxGeneralCombiners); i++)
{
for (int j = 0; (j < color->stage[i].numOps) && (curCombiner < OGL.maxGeneralCombiners); j++)
{
regCombiners->usesT0 |= (color->stage[i].op[j].param1 == TEXEL0) || (color->stage[i].op[j].param1 == TEXEL0_ALPHA);
regCombiners->usesT1 |= (color->stage[i].op[j].param1 == TEXEL1) || (color->stage[i].op[j].param1 == TEXEL1_ALPHA);
regCombiners->usesNoise |= (color->stage[i].op[j].param1 == NOISE);
switch (color->stage[i].op[j].op)
{
case LOAD:
if (regCombiners->color[curCombiner].A.used)
{
curCombiner++;
if (curCombiner == OGL.maxGeneralCombiners)
break;
}
SetColorCombinerInput( curCombiner, A, color->stage[i].op[j].param1, TRUE );
SetColorCombinerInput( curCombiner, B, ONE, FALSE );
regCombiners->color[curCombiner].output.sum = GL_SPARE0_NV;
break;
case SUB:
if (regCombiners->color[curCombiner].C.used || regCombiners->color[curCombiner].D.used)
{
curCombiner++;
if (curCombiner == OGL.maxGeneralCombiners)
break;
SetColorCombinerVariable( curCombiner, A, GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_RGB, TRUE );
SetColorCombinerInput( curCombiner, B, ONE, FALSE );
regCombiners->color[curCombiner].output.sum = GL_SPARE0_NV;
}
SetColorCombinerInput( curCombiner, C, color->stage[i].op[j].param1, TRUE );
regCombiners->color[curCombiner].C.mapping = GL_SIGNED_NEGATE_NV;
SetColorCombinerInput( curCombiner, D, ONE, FALSE );
break;
case MUL:
if (regCombiners->color[curCombiner].B.used || regCombiners->color[curCombiner].D.used)
{
curCombiner++;
if (curCombiner == OGL.maxGeneralCombiners)
{
if ((!regCombiners->final.B.used) &&
(!regCombiners->final.E.used) &&
(!regCombiners->final.F.used))
{
SetFinalCombinerVariable( B, GL_E_TIMES_F_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB, TRUE );
SetFinalCombinerInput( E, COMBINED, TRUE );
SetFinalCombinerInput( F, color->stage[i].op[j].param1, TRUE );
}
break;
}
SetColorCombinerVariable( curCombiner, A, GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_RGB, TRUE );
regCombiners->color[curCombiner].output.sum = GL_SPARE0_NV;
}
SetColorCombinerInput( curCombiner, B, color->stage[i].op[j].param1, TRUE );
if (regCombiners->color[curCombiner].C.used)
{
SetColorCombinerInput( curCombiner, D, color->stage[i].op[j].param1, TRUE );
}
break;
case ADD:
if (regCombiners->color[curCombiner].C.used || regCombiners->color[curCombiner].D.used)
{
curCombiner++;
if (curCombiner == OGL.maxGeneralCombiners)
{
if (!regCombiners->final.D.used)
{
SetFinalCombinerInput( D, color->stage[i].op[j].param1, TRUE );
}
break;
}
SetColorCombinerVariable( curCombiner, A, GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_RGB, TRUE );
SetColorCombinerInput( curCombiner, B, ONE, FALSE );
regCombiners->color[curCombiner].output.sum = GL_SPARE0_NV;
}
SetColorCombinerInput( curCombiner, C, color->stage[i].op[j].param1, TRUE );
SetColorCombinerInput( curCombiner, D, ONE, FALSE );
break;
case INTER:
regCombiners->usesT0 |= (color->stage[i].op[j].param2 == TEXEL0) || (color->stage[i].op[j].param3 == TEXEL0) || (color->stage[i].op[j].param2 == TEXEL0_ALPHA) || (color->stage[i].op[j].param3 == TEXEL0_ALPHA);
regCombiners->usesT1 |= (color->stage[i].op[j].param2 == TEXEL1) || (color->stage[i].op[j].param3 == TEXEL1) || (color->stage[i].op[j].param2 == TEXEL1_ALPHA) || (color->stage[i].op[j].param3 == TEXEL1_ALPHA);
regCombiners->usesNoise |= (color->stage[i].op[j].param2 == NOISE) || (color->stage[i].op[j].param3 == NOISE);
if (regCombiners->color[curCombiner].A.used ||
regCombiners->color[curCombiner].B.used ||
regCombiners->color[curCombiner].C.used ||
regCombiners->color[curCombiner].D.used)
{
curCombiner++;
if (curCombiner == OGL.maxGeneralCombiners)
{
if (!regCombiners->final.A.used &&
!regCombiners->final.B.used &&
!regCombiners->final.C.used)
{
SetFinalCombinerInput( A, color->stage[i].op[j].param3, TRUE );
SetFinalCombinerInput( B, color->stage[i].op[j].param1, TRUE );
SetFinalCombinerInput( C, color->stage[i].op[j].param2, TRUE );
}
break;
}
}
SetColorCombinerInput( curCombiner, A, color->stage[i].op[j].param1, TRUE );
SetColorCombinerInput( curCombiner, B, color->stage[i].op[j].param3, TRUE );
SetColorCombinerInput( curCombiner, C, color->stage[i].op[j].param2, TRUE );
SetColorCombinerVariable( curCombiner, D, regCombiners->color[curCombiner].B.input, GL_UNSIGNED_INVERT_NV, regCombiners->color[curCombiner].B.usage, TRUE );
regCombiners->color[curCombiner].output.sum = GL_SPARE0_NV;
break;
}
}
}
regCombiners->numCombiners = max( min( curCombiner + 1, OGL.maxGeneralCombiners ), numCombiners );
return regCombiners;
}
void Set_NV_register_combiners( RegisterCombiners *regCombiners )
{
combiner.usesT0 = regCombiners->usesT0;
combiner.usesT1 = regCombiners->usesT1;
combiner.usesNoise = FALSE;
combiner.vertex.color = regCombiners->vertex.color;
combiner.vertex.secondaryColor = regCombiners->vertex.secondaryColor;
combiner.vertex.alpha = regCombiners->vertex.alpha;
glActiveTextureARB( GL_TEXTURE0_ARB );
if (combiner.usesT0) glEnable( GL_TEXTURE_2D ); else glDisable( GL_TEXTURE_2D );
glActiveTextureARB( GL_TEXTURE1_ARB );
if (combiner.usesT1) glEnable( GL_TEXTURE_2D ); else glDisable( GL_TEXTURE_2D );
glCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, regCombiners->numCombiners );
for (int i = 0; i < regCombiners->numCombiners; i++)
{
glCombinerInputNV( GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_A_NV, regCombiners->color[i].A.input, regCombiners->color[i].A.mapping, regCombiners->color[i].A.usage );
glCombinerInputNV( GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_B_NV, regCombiners->color[i].B.input, regCombiners->color[i].B.mapping, regCombiners->color[i].B.usage );
glCombinerInputNV( GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_C_NV, regCombiners->color[i].C.input, regCombiners->color[i].C.mapping, regCombiners->color[i].C.usage );
glCombinerInputNV( GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_D_NV, regCombiners->color[i].D.input, regCombiners->color[i].D.mapping, regCombiners->color[i].D.usage );
glCombinerOutputNV( GL_COMBINER0_NV + i, GL_RGB, regCombiners->color[i].output.ab, regCombiners->color[i].output.cd, regCombiners->color[i].output.sum, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
glCombinerInputNV( GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_A_NV, regCombiners->alpha[i].A.input, regCombiners->alpha[i].A.mapping, GL_ALPHA );
glCombinerInputNV( GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_B_NV, regCombiners->alpha[i].B.input, regCombiners->alpha[i].B.mapping, GL_ALPHA );
glCombinerInputNV( GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_C_NV, regCombiners->alpha[i].C.input, regCombiners->alpha[i].C.mapping, GL_ALPHA );
glCombinerInputNV( GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_D_NV, regCombiners->alpha[i].D.input, regCombiners->alpha[i].D.mapping, GL_ALPHA );
glCombinerOutputNV( GL_COMBINER0_NV + i, GL_ALPHA, regCombiners->alpha[i].output.ab, regCombiners->alpha[i].output.cd, regCombiners->alpha[i].output.sum, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
}
glFinalCombinerInputNV( GL_VARIABLE_A_NV, regCombiners->final.A.input, regCombiners->final.A.mapping, regCombiners->final.A.usage );
glFinalCombinerInputNV( GL_VARIABLE_B_NV, regCombiners->final.B.input, regCombiners->final.B.mapping, regCombiners->final.B.usage );
glFinalCombinerInputNV( GL_VARIABLE_C_NV, regCombiners->final.C.input, regCombiners->final.C.mapping, regCombiners->final.C.usage );
glFinalCombinerInputNV( GL_VARIABLE_D_NV, regCombiners->final.D.input, regCombiners->final.D.mapping, regCombiners->final.D.usage );
glFinalCombinerInputNV( GL_VARIABLE_E_NV, regCombiners->final.E.input, regCombiners->final.E.mapping, regCombiners->final.E.usage );
glFinalCombinerInputNV( GL_VARIABLE_F_NV, regCombiners->final.F.input, regCombiners->final.F.mapping, regCombiners->final.F.usage );
glFinalCombinerInputNV( GL_VARIABLE_G_NV, regCombiners->final.G.input, regCombiners->final.G.mapping, GL_ALPHA );
}

104
NV_register_combiners.h Normal file
View File

@ -0,0 +1,104 @@
#include <GL/gl.h>
struct CombinerInput
{
GLenum input;
GLenum mapping;
GLenum usage;
};
struct CombinerVariable
{
GLenum input;
GLenum mapping;
GLenum usage;
BOOL used;
};
struct GeneralCombiner
{
CombinerVariable A, B, C, D;
struct
{
GLenum ab;
GLenum cd;
GLenum sum;
} output;
};
struct RegisterCombiners
{
GeneralCombiner color[8];
GeneralCombiner alpha[8];
struct
{
CombinerVariable A, B, C, D, E, F, G;
} final;
struct
{
WORD color, alpha;
} constant[2];
struct
{
WORD color, secondaryColor, alpha;
} vertex;
WORD numCombiners;
BOOL usesT0, usesT1, usesNoise;
};
static CombinerInput CombinerInputs[] =
{
// CMB
{ GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// T0
{ GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// T1
{ GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// PRIM
{ GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// SHADE
{ GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// ENV
{ GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// CENTER
{ GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// SCALE
{ GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// CMBALPHA
{ GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA },
// T0ALPHA
{ GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA },
// T1ALPHA
{ GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA },
// PRIMALPHA
{ GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA },
// SHADEALPHA
{ GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA },
// ENVALPHA
{ GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA },
// LODFRAC
{ GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// PRIMLODFRAC
{ GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// NOISE
{ GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// K4
{ GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// K5
{ GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB },
// ONE
{ GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB },
// ZERO
{ GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB }
};
void Init_NV_register_combiners();
void Uninit_NV_register_combiners();
RegisterCombiners *Compile_NV_register_combiners( Combiner *color, Combiner *alpha );
void Update_NV_register_combiners_Colors( RegisterCombiners *regCombiners );
void Set_NV_register_combiners( RegisterCombiners *regCombiners );

1126
OpenGL.cpp Normal file

File diff suppressed because it is too large Load Diff

167
OpenGL.h Normal file
View File

@ -0,0 +1,167 @@
#ifndef OPENGL_H
#define OPENGL_H
#ifndef __LINUX__
# include <windows.h>
# include <GL/gl.h>
# include "wglext.h"
# include "glext.h"
#else
# include "winlnxdefs.h"
# include <GL/gl.h>
# include <GL/glext.h>
# include "SDL.h"
#endif // __LINUX__
#include "glATI.h"
#include "gSP.h"
struct GLVertex
{
float x, y, z, w;
struct
{
float r, g, b, a;
} color, secondaryColor;
float s0, t0, s1, t1;
float fog;
};
struct GLInfo
{
#ifndef __LINUX__
HGLRC hRC, hPbufferRC;
HDC hDC, hPbufferDC;
HWND hWnd;
HPBUFFERARB hPbuffer;
#else
SDL_Surface *hScreen;
#endif // __LINUX__
DWORD fullscreenWidth, fullscreenHeight, fullscreenBits, fullscreenRefresh;
DWORD width, height, windowedWidth, windowedHeight, heightOffset;
BOOL fullscreen, forceBilinear, fog;
float scaleX, scaleY;
BOOL ATI_texture_env_combine3; // Radeon
BOOL ATIX_texture_env_route; // Radeon
BOOL ARB_multitexture; // TNT, GeForce, Rage 128, Radeon
BOOL ARB_texture_env_combine; // GeForce, Rage 128, Radeon
BOOL ARB_texture_env_crossbar; // Radeon (GeForce supports it, but doesn't report it)
BOOL EXT_fog_coord; // TNT, GeForce, Rage 128, Radeon
BOOL EXT_texture_env_combine; // TNT, GeForce, Rage 128, Radeon
BOOL EXT_secondary_color; // GeForce, Radeon
BOOL NV_texture_env_combine4; // TNT, GeForce
BOOL NV_register_combiners; // GeForce
BOOL ARB_buffer_region;
BOOL ARB_pbuffer;
BOOL ARB_render_texture;
BOOL ARB_pixel_format;
int maxTextureUnits; // TNT = 2, GeForce = 2-4, Rage 128 = 2, Radeon = 3-6
int maxGeneralCombiners;
BOOL enable2xSaI;
BOOL frameBufferTextures;
int textureBitDepth;
float originAdjust;
GLVertex vertices[256];
BYTE triangles[80][3];
BYTE numTriangles;
BYTE numVertices;
#ifndef __LINUX__
HWND hFullscreenWnd;
#endif
BOOL usePolygonStipple;
GLubyte stipplePattern[32][8][128];
BYTE lastStipple;
BYTE combiner;
};
extern GLInfo OGL;
struct GLcolor
{
float r, g, b, a;
};
#ifndef __LINUX__
extern PFNGLCOMBINERPARAMETERFVNVPROC glCombinerParameterfvNV;
extern PFNGLCOMBINERPARAMETERFNVPROC glCombinerParameterfNV;
extern PFNGLCOMBINERPARAMETERIVNVPROC glCombinerParameterivNV;
extern PFNGLCOMBINERPARAMETERINVPROC glCombinerParameteriNV;
extern PFNGLCOMBINERINPUTNVPROC glCombinerInputNV;
extern PFNGLCOMBINEROUTPUTNVPROC glCombinerOutputNV;
extern PFNGLFINALCOMBINERINPUTNVPROC glFinalCombinerInputNV;
extern PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC glGetCombinerInputParameterfvNV;
extern PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC glGetCombinerInputParameterivNV;
extern PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC glGetCombinerOutputParameterfvNV;
extern PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC glGetCombinerOutputParameterivNV;
extern PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC glGetFinalCombinerInputParameterfvNV;
extern PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC glGetFinalCombinerInputParameterivNV;
extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;
extern PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;
extern PFNGLSECONDARYCOLOR3FVEXTPROC glSecondaryColor3fvEXT;
extern PFNGLSECONDARYCOLOR3BEXTPROC glSecondaryColor3bEXT;
extern PFNGLSECONDARYCOLOR3BVEXTPROC glSecondaryColor3bvEXT;
extern PFNGLSECONDARYCOLOR3DEXTPROC glSecondaryColor3dEXT;
extern PFNGLSECONDARYCOLOR3DVEXTPROC glSecondaryColor3dvEXT;
extern PFNGLSECONDARYCOLOR3FEXTPROC glSecondaryColor3fEXT;
extern PFNGLSECONDARYCOLOR3FVEXTPROC glSecondaryColor3fvEXT;
extern PFNGLSECONDARYCOLOR3IEXTPROC glSecondaryColor3iEXT;
extern PFNGLSECONDARYCOLOR3IVEXTPROC glSecondaryColor3ivEXT;
extern PFNGLSECONDARYCOLOR3SEXTPROC glSecondaryColor3sEXT;
extern PFNGLSECONDARYCOLOR3SVEXTPROC glSecondaryColor3svEXT;
extern PFNGLSECONDARYCOLOR3UBEXTPROC glSecondaryColor3ubEXT;
extern PFNGLSECONDARYCOLOR3UBVEXTPROC glSecondaryColor3ubvEXT;
extern PFNGLSECONDARYCOLOR3UIEXTPROC glSecondaryColor3uiEXT;
extern PFNGLSECONDARYCOLOR3UIVEXTPROC glSecondaryColor3uivEXT;
extern PFNGLSECONDARYCOLOR3USEXTPROC glSecondaryColor3usEXT;
extern PFNGLSECONDARYCOLOR3USVEXTPROC glSecondaryColor3usvEXT;
extern PFNGLSECONDARYCOLORPOINTEREXTPROC glSecondaryColorPointerEXT;
extern PFNWGLCREATEBUFFERREGIONARBPROC wglCreateBufferRegionARB;
extern PFNWGLDELETEBUFFERREGIONARBPROC wglDeleteBufferRegionARB;
extern PFNWGLSAVEBUFFERREGIONARBPROC wglSaveBufferRegionARB;
extern PFNWGLRESTOREBUFFERREGIONARBPROC wglRestoreBufferRegionARB;
extern PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB;
extern PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB;
extern PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB;
extern PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB;
extern PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB;
extern PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB;
extern PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB;
extern PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
#endif // !__LINUX__
bool OGL_Start();
void OGL_Stop();
void OGL_AddTriangle( SPVertex *vertices, int v0, int v1, int v2 );
void OGL_DrawTriangles();
void OGL_DrawLine( SPVertex *vertices, int v0, int v1, float width );
void OGL_DrawRect( int ulx, int uly, int lrx, int lry, float *color );
void OGL_DrawTexturedRect( float ulx, float uly, float lrx, float lry, float uls, float ult, float lrs, float lrt, bool flip );
void OGL_UpdateScale();
void OGL_ClearDepthBuffer();
void OGL_ClearColorBuffer( float *color );
void OGL_ResizeWindow();
void OGL_SaveScreenshot();
#ifdef __LINUX__
void OGL_SwapBuffers();
#endif // __LINUX__
void OGL_ReadScreen( void **dest, long *width, long *height );
#endif

294
RDP.cpp Normal file
View File

@ -0,0 +1,294 @@
#include "N64.h"
#include "RSP.h"
#include "GBI.h"
#include "gDP.h"
#include "Types.h"
#include "Debug.h"
void RDP_Unknown( u32 w0, u32 w1 )
{
#ifdef DEBUG
DebugMsg( DEBUG_UNKNOWN, "RDP_Unknown\r\n" );
DebugMsg( DEBUG_UNKNOWN, "\tUnknown RDP opcode %02X\r\n", _SHIFTR( w0, 24, 8 ) );
#endif
}
void RDP_NoOp( u32 w0, u32 w1 )
{
gDPNoOp();
}
void RDP_SetCImg( u32 w0, u32 w1 )
{
gDPSetColorImage( _SHIFTR( w0, 21, 3 ), // fmt
_SHIFTR( w0, 19, 2 ), // siz
_SHIFTR( w0, 0, 12 ) + 1, // width
w1 ); // img
}
void RDP_SetZImg( u32 w0, u32 w1 )
{
gDPSetDepthImage( w1 ); // img
}
void RDP_SetTImg( u32 w0, u32 w1 )
{
gDPSetTextureImage( _SHIFTR( w0, 21, 3), // fmt
_SHIFTR( w0, 19, 2 ), // siz
_SHIFTR( w0, 0, 12 ) + 1, // width
w1 ); // img
}
void RDP_SetCombine( u32 w0, u32 w1 )
{
gDPSetCombine( _SHIFTR( w0, 0, 24 ), // muxs0
w1 ); // muxs1
}
void RDP_SetEnvColor( u32 w0, u32 w1 )
{
gDPSetEnvColor( _SHIFTR( w1, 24, 8 ), // r
_SHIFTR( w1, 16, 8 ), // g
_SHIFTR( w1, 8, 8 ), // b
_SHIFTR( w1, 0, 8 ) ); // a
}
void RDP_SetPrimColor( u32 w0, u32 w1 )
{
gDPSetPrimColor( _SHIFTL( w0, 8, 8 ), // m
_SHIFTL( w0, 0, 8 ), // l
_SHIFTR( w1, 24, 8 ), // r
_SHIFTR( w1, 16, 8 ), // g
_SHIFTR( w1, 8, 8 ), // b
_SHIFTR( w1, 0, 8 ) ); // a
}
void RDP_SetBlendColor( u32 w0, u32 w1 )
{
gDPSetBlendColor( _SHIFTR( w1, 24, 8 ), // r
_SHIFTR( w1, 16, 8 ), // g
_SHIFTR( w1, 8, 8 ), // b
_SHIFTR( w1, 0, 8 ) ); // a
}
void RDP_SetFogColor( u32 w0, u32 w1 )
{
gDPSetFogColor( _SHIFTR( w1, 24, 8 ), // r
_SHIFTR( w1, 16, 8 ), // g
_SHIFTR( w1, 8, 8 ), // b
_SHIFTR( w1, 0, 8 ) ); // a
}
void RDP_SetFillColor( u32 w0, u32 w1 )
{
gDPSetFillColor( w1 );
}
void RDP_FillRect( u32 w0, u32 w1 )
{
gDPFillRectangle( _SHIFTR( w1, 14, 10 ), // ulx
_SHIFTR( w1, 2, 10 ), // uly
_SHIFTR( w0, 14, 10 ), // lrx
_SHIFTR( w0, 2, 10 ) ); // lry
}
void RDP_SetTile( u32 w0, u32 w1 )
{
gDPSetTile( _SHIFTR( w0, 21, 3 ), // fmt
_SHIFTR( w0, 19, 2 ), // siz
_SHIFTR( w0, 9, 9 ), // line
_SHIFTR( w0, 0, 9 ), // tmem
_SHIFTR( w1, 24, 3 ), // tile
_SHIFTR( w1, 20, 4 ), // palette
_SHIFTR( w1, 18, 2 ), // cmt
_SHIFTR( w1, 8, 2 ), // cms
_SHIFTR( w1, 14, 4 ), // maskt
_SHIFTR( w1, 4, 4 ), // masks
_SHIFTR( w1, 10, 4 ), // shiftt
_SHIFTR( w1, 0, 4 ) ); // shifts
}
void RDP_LoadTile( u32 w0, u32 w1 )
{
gDPLoadTile( _SHIFTR( w1, 24, 3 ), // tile
_SHIFTR( w0, 12, 12 ), // uls
_SHIFTR( w0, 0, 12 ), // ult
_SHIFTR( w1, 12, 12 ), // lrs
_SHIFTR( w1, 0, 12 ) ); // lrt
}
void RDP_LoadBlock( u32 w0, u32 w1 )
{
gDPLoadBlock( _SHIFTR( w1, 24, 3 ), // tile
_SHIFTR( w0, 12, 12 ), // uls
_SHIFTR( w0, 0, 12 ), // ult
_SHIFTR( w1, 12, 12 ), // lrs
_SHIFTR( w1, 0, 12 ) ); // dxt
}
void RDP_SetTileSize( u32 w0, u32 w1 )
{
gDPSetTileSize( _SHIFTR( w1, 24, 3 ), // tile
_SHIFTR( w0, 12, 12 ), // uls
_SHIFTR( w0, 0, 12 ), // ult
_SHIFTR( w1, 12, 12 ), // lrs
_SHIFTR( w1, 0, 12 ) ); // lrt
}
void RDP_LoadTLUT( u32 w0, u32 w1 )
{
gDPLoadTLUT( _SHIFTR( w1, 24, 3 ), // tile
_SHIFTR( w0, 12, 12 ), // uls
_SHIFTR( w0, 0, 12 ), // ult
_SHIFTR( w1, 12, 12 ), // lrs
_SHIFTR( w1, 0, 12 ) ); // lrt
}
void RDP_SetOtherMode( u32 w0, u32 w1 )
{
gDPSetOtherMode( _SHIFTR( w0, 0, 24 ), // mode0
w1 ); // mode1
}
void RDP_SetPrimDepth( u32 w0, u32 w1 )
{
gDPSetPrimDepth( _SHIFTR( w1, 16, 16 ), // z
_SHIFTR( w1, 0, 16 ) ); // dz
}
void RDP_SetScissor( u32 w0, u32 w1 )
{
gDPSetScissor( _SHIFTR( w1, 24, 2 ), // mode
_FIXED2FLOAT( _SHIFTR( w0, 12, 12 ), 2 ), // ulx
_FIXED2FLOAT( _SHIFTR( w0, 0, 12 ), 2 ), // uly
_FIXED2FLOAT( _SHIFTR( w1, 12, 12 ), 2 ), // lrx
_FIXED2FLOAT( _SHIFTR( w1, 0, 12 ), 2 ) ); // lry
}
void RDP_SetConvert( u32 w0, u32 w1 )
{
gDPSetConvert( _SHIFTR( w0, 13, 9 ), // k0
_SHIFTR( w0, 4, 9 ), // k1
_SHIFTL( w0, 5, 4 ) | _SHIFTR( w1, 25, 5 ), // k2
_SHIFTR( w1, 18, 9 ), // k3
_SHIFTR( w1, 9, 9 ), // k4
_SHIFTR( w1, 0, 9 ) ); // k5
}
void RDP_SetKeyR( u32 w0, u32 w1 )
{
gDPSetKeyR( _SHIFTR( w1, 8, 8 ), // cR
_SHIFTR( w1, 0, 8 ), // sR
_SHIFTR( w1, 16, 12 ) ); // wR
}
void RDP_SetKeyGB( u32 w0, u32 w1 )
{
gDPSetKeyGB( _SHIFTR( w1, 24, 8 ), // cG
_SHIFTR( w1, 16, 8 ), // sG
_SHIFTR( w0, 12, 12 ), // wG
_SHIFTR( w1, 8, 8 ), // cB
_SHIFTR( w1, 0, 8 ), // SB
_SHIFTR( w0, 0, 12 ) ); // wB
}
void RDP_FullSync( u32 w0, u32 w1 )
{
gDPFullSync();
}
void RDP_TileSync( u32 w0, u32 w1 )
{
gDPTileSync();
}
void RDP_PipeSync( u32 w0, u32 w1 )
{
gDPPipeSync();
}
void RDP_LoadSync( u32 w0, u32 w1 )
{
gDPLoadSync();
}
void RDP_TexRectFlip( u32 w0, u32 w1 )
{
u32 w2 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
u32 w3 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
gDPTextureRectangleFlip( _FIXED2FLOAT( _SHIFTR( w1, 12, 12 ), 2 ), // ulx
_FIXED2FLOAT( _SHIFTR( w1, 0, 12 ), 2 ), // uly
_FIXED2FLOAT( _SHIFTR( w0, 12, 12 ), 2 ), // lrx
_FIXED2FLOAT( _SHIFTR( w0, 0, 12 ), 2 ), // lry
_SHIFTR( w1, 24, 3 ), // tile
_FIXED2FLOAT( (s16)_SHIFTR( w2, 16, 16 ), 5 ), // s
_FIXED2FLOAT( (s16)_SHIFTR( w2, 0, 16 ), 5 ), // t
_FIXED2FLOAT( (s16)_SHIFTR( w3, 16, 16 ), 10 ), // dsdx
_FIXED2FLOAT( (s16)_SHIFTR( w3, 0, 16 ), 10 ) ); // dsdy
}
void RDP_TexRect( u32 w0, u32 w1 )
{
u32 w2 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
u32 w3 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
gDPTextureRectangle( _FIXED2FLOAT( _SHIFTR( w1, 12, 12 ), 2 ), // ulx
_FIXED2FLOAT( _SHIFTR( w1, 0, 12 ), 2 ), // uly
_FIXED2FLOAT( _SHIFTR( w0, 12, 12 ), 2 ), // lrx
_FIXED2FLOAT( _SHIFTR( w0, 0, 12 ), 2 ), // lry
_SHIFTR( w1, 24, 3 ), // tile
_FIXED2FLOAT( (s16)_SHIFTR( w2, 16, 16 ), 5 ), // s
_FIXED2FLOAT( (s16)_SHIFTR( w2, 0, 16 ), 5 ), // t
_FIXED2FLOAT( (s16)_SHIFTR( w3, 16, 16 ), 10 ), // dsdx
_FIXED2FLOAT( (s16)_SHIFTR( w3, 0, 16 ), 10 ) ); // dsdy
}
void RDP_Init()
{
// Initialize RDP commands to RDP_UNKNOWN
for (int i = 0xC8; i <= 0xCF; i++)
GBI.cmd[i] = RDP_Unknown;
// Initialize RDP commands to RDP_UNKNOWN
for (int i = 0xE4; i <= 0xFF; i++)
GBI.cmd[i] = RDP_Unknown;
// Set known GBI commands
GBI.cmd[G_NOOP] = RDP_NoOp;
GBI.cmd[G_SETCIMG] = RDP_SetCImg;
GBI.cmd[G_SETZIMG] = RDP_SetZImg;
GBI.cmd[G_SETTIMG] = RDP_SetTImg;
GBI.cmd[G_SETCOMBINE] = RDP_SetCombine;
GBI.cmd[G_SETENVCOLOR] = RDP_SetEnvColor;
GBI.cmd[G_SETPRIMCOLOR] = RDP_SetPrimColor;
GBI.cmd[G_SETBLENDCOLOR] = RDP_SetBlendColor;
GBI.cmd[G_SETFOGCOLOR] = RDP_SetFogColor;
GBI.cmd[G_SETFILLCOLOR] = RDP_SetFillColor;
GBI.cmd[G_FILLRECT] = RDP_FillRect;
GBI.cmd[G_SETTILE] = RDP_SetTile;
GBI.cmd[G_LOADTILE] = RDP_LoadTile;
GBI.cmd[G_LOADBLOCK] = RDP_LoadBlock;
GBI.cmd[G_SETTILESIZE] = RDP_SetTileSize;
GBI.cmd[G_LOADTLUT] = RDP_LoadTLUT;
GBI.cmd[G_RDPSETOTHERMODE] = RDP_SetOtherMode;
GBI.cmd[G_SETPRIMDEPTH] = RDP_SetPrimDepth;
GBI.cmd[G_SETSCISSOR] = RDP_SetScissor;
GBI.cmd[G_SETCONVERT] = RDP_SetConvert;
GBI.cmd[G_SETKEYR] = RDP_SetKeyR;
GBI.cmd[G_SETKEYGB] = RDP_SetKeyGB;
GBI.cmd[G_RDPFULLSYNC] = RDP_FullSync;
GBI.cmd[G_RDPTILESYNC] = RDP_TileSync;
GBI.cmd[G_RDPPIPESYNC] = RDP_PipeSync;
GBI.cmd[G_RDPLOADSYNC] = RDP_LoadSync;
GBI.cmd[G_TEXRECTFLIP] = RDP_TexRectFlip;
GBI.cmd[G_TEXRECT] = RDP_TexRect;
}

7
RDP.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef RDP_H
#define RDP_H
void RDP_Init();
#endif

328
RSP.cpp Normal file
View File

@ -0,0 +1,328 @@
#ifndef __LINUX__
# include <windows.h>
#else
# include "winlnxdefs.h"
#endif
#include <math.h>
#include "glN64.h"
#include "OpenGL.h"
#include "Debug.h"
#include "RSP.h"
#include "RDP.h"
#include "N64.h"
#include "F3D.h"
#include "3DMath.h"
#include "VI.h"
#include "Combiner.h"
//#include "textures.h"
//#include "Config.h"
#include "FrameBuffer.h"
#include "DepthBuffer.h"
#include "GBI.h"
RSPInfo RSP;
void RSP_LoadMatrix( f32 mtx[4][4], u32 address )
{
f32 recip = 1.5258789e-05f;
#ifndef __LINUX__
__asm {
mov esi, dword ptr [RDRAM];
add esi, dword ptr [address];
mov edi, dword ptr [mtx];
mov ecx, 4
LoadLoop:
fild word ptr [esi+02h]
movzx eax, word ptr [esi+22h]
mov dword ptr [edi], eax
fild dword ptr [edi]
fmul dword ptr [recip]
fadd
fstp dword ptr [edi]
fild word ptr [esi+00h]
movzx eax, word ptr [esi+20h]
mov dword ptr [edi+04h], eax
fild dword ptr [edi+04h]
fmul dword ptr [recip]
fadd
fstp dword ptr [edi+04h]
fild word ptr [esi+06h]
movzx eax, word ptr [esi+26h]
mov dword ptr [edi+08h], eax
fild dword ptr [edi+08h]
fmul dword ptr [recip]
fadd
fstp dword ptr [edi+08h]
fild word ptr [esi+04h]
movzx eax, word ptr [esi+24h]
mov dword ptr [edi+0Ch], eax
fild dword ptr [edi+0Ch]
fmul dword ptr [recip]
fadd
fstp dword ptr [edi+0Ch]
add esi, 08h
add edi, 10h
loop LoadLoop
}
#else // !__LINUX__
# ifdef X86_ASM
__asm__ __volatile__(
".intel_syntax noprefix" "\n\t"
"LoadLoop:" "\n\t"
" fild word ptr [esi+0x02]" "\n\t"
" movzx eax, word ptr [esi+0x22]" "\n\t"
" mov dword ptr [edi], eax" "\n\t"
" fild dword ptr [edi]" "\n\t"
" fmul %0" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [edi]" "\n\t"
" fild word ptr [esi+0x00]" "\n\t"
" movzx eax, word ptr [esi+0x20]" "\n\t"
" mov dword ptr [edi+0x04], eax" "\n\t"
" fild dword ptr [edi+0x04]" "\n\t"
" fmul %0" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [edi+0x04]" "\n\t"
" fild word ptr [esi+0x06]" "\n\t"
" movzx eax, word ptr [esi+0x26]" "\n\t"
" mov dword ptr [edi+0x08], eax" "\n\t"
" fild dword ptr [edi+0x08]" "\n\t"
" fmul %0" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [edi+0x08]" "\n\t"
" fild word ptr [esi+0x04]" "\n\t"
" movzx eax, word ptr [esi+0x24]" "\n\t"
" mov dword ptr [edi+0x0C], eax" "\n\t"
" fild dword ptr [edi+0x0C]" "\n\t"
" fmul %0" "\n\t"
" fadd" "\n\t"
" fstp dword ptr [edi+0x0C]" "\n\t"
" add esi, 0x08" "\n\t"
" add edi, 0x10" "\n\t"
" loop LoadLoop" "\n\t"
".att_syntax prefix" "\n\t"
: /* no output */
: "f"(recip), "S"((int)RDRAM+address), "D"(mtx), "c"(4)
: "memory" );
# else // X86_ASM
struct _N64Matrix
{
SHORT integer[4][4];
WORD fraction[4][4];
} *n64Mat = (struct _N64Matrix *)&RDRAM[address];
int i, j;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
mtx[i][j] = (GLfloat)(n64Mat->integer[i][j^1]) + (GLfloat)(n64Mat->fraction[i][j^1]) * recip;
# endif // !X86_ASM
#endif // __LINUX__
}
#ifdef RSPTHREAD
DWORD WINAPI RSP_ThreadProc( LPVOID lpParameter )
{
RSP_Init();
SetEvent( RSP.threadFinished );
#ifndef _DEBUG
__try
{
#endif
while (TRUE)
{
switch (WaitForMultipleObjects( 6, RSP.threadMsg, FALSE, INFINITE ))
{
case (WAIT_OBJECT_0 + RSPMSG_PROCESSDLIST):
RSP_ProcessDList();
break;
case (WAIT_OBJECT_0 + RSPMSG_UPDATESCREEN):
VI_UpdateScreen();
break;
case (WAIT_OBJECT_0 + RSPMSG_CLOSE):
OGL_Stop();
SetEvent( RSP.threadFinished );
return 1;
case (WAIT_OBJECT_0 + RSPMSG_DESTROYTEXTURES):
Combiner_Destroy();
FrameBuffer_Destroy();
TextureCache_Destroy();
break;
case (WAIT_OBJECT_0 + RSPMSG_INITTEXTURES):
FrameBuffer_Init();
TextureCache_Init();
Combiner_Init();
gSP.changed = gDP.changed = 0xFFFFFFFF;
break;
case (WAIT_OBJECT_0 + RSPMSG_CAPTURESCREEN):
OGL_SaveScreenshot();
break;
}
SetEvent( RSP.threadFinished );
}
#ifndef _DEBUG
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
char exception[256];
sprintf( exception, "Win32 exception 0x%08X occured in glN64", GetExceptionCode() );
MessageBox( NULL, exception, pluginName, MB_OK | MB_ICONERROR );
GBI_Destroy();
DepthBuffer_Destroy();
OGL_Stop();
}
#endif
RSP.thread = NULL;
return 0;
}
#endif // RSPTHREAD
void RSP_ProcessDList()
{
VI_UpdateSize();
OGL_UpdateScale();
RSP.PC[0] = *(u32*)&DMEM[0x0FF0];
RSP.PCi = 0;
RSP.count = 0;
RSP.halt = FALSE;
RSP.busy = TRUE;
gSP.matrix.stackSize = min( 32, *(u32*)&DMEM[0x0FE4] >> 6 );
gSP.matrix.modelViewi = 0;
gSP.changed |= CHANGED_MATRIX;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
gSP.matrix.modelView[0][i][j] = 0.0f;
gSP.matrix.modelView[0][0][0] = 1.0f;
gSP.matrix.modelView[0][1][1] = 1.0f;
gSP.matrix.modelView[0][2][2] = 1.0f;
gSP.matrix.modelView[0][3][3] = 1.0f;
u32 uc_start = *(u32*)&DMEM[0x0FD0];
u32 uc_dstart = *(u32*)&DMEM[0x0FD8];
u32 uc_dsize = *(u32*)&DMEM[0x0FDC];
if ((uc_start != RSP.uc_start) || (uc_dstart != RSP.uc_dstart))
gSPLoadUcodeEx( uc_start, uc_dstart, uc_dsize );
gDPSetAlphaCompare( G_AC_NONE );
gDPSetDepthSource( G_ZS_PIXEL );
gDPSetRenderMode( 0, 0 );
gDPSetAlphaDither( G_AD_DISABLE );
gDPSetColorDither( G_CD_DISABLE );
gDPSetCombineKey( G_CK_NONE );
gDPSetTextureConvert( G_TC_FILT );
gDPSetTextureFilter( G_TF_POINT );
gDPSetTextureLUT( G_TT_NONE );
gDPSetTextureLOD( G_TL_TILE );
gDPSetTextureDetail( G_TD_CLAMP );
gDPSetTexturePersp( G_TP_PERSP );
gDPSetCycleType( G_CYC_1CYCLE );
gDPPipelineMode( G_PM_NPRIMITIVE );
while (!RSP.halt)
{
if ((RSP.PC[RSP.PCi] + 8) > RDRAMSize)
{
#ifdef DEBUG
switch (Debug.level)
{
case DEBUG_LOW:
DebugMsg( DEBUG_LOW | DEBUG_ERROR, "ATTEMPTING TO EXECUTE RSP COMMAND AT INVALID RDRAM LOCATION\n" );
break;
case DEBUG_MEDIUM:
DebugMsg( DEBUG_MEDIUM | DEBUG_ERROR, "Attempting to execute RSP command at invalid RDRAM location\n" );
break;
case DEBUG_HIGH:
DebugMsg( DEBUG_HIGH | DEBUG_ERROR, "// Attempting to execute RSP command at invalid RDRAM location\n" );
break;
}
#endif
break;
}
// printf( "!!!!!! RDRAM = 0x%8.8x\n", RDRAM );//RSP.PC[RSP.PCi] );
/* {
static u8 *lastRDRAM = 0;
if (lastRDRAM == 0)
lastRDRAM = RDRAM;
if (RDRAM != lastRDRAM)
{
__asm__( "int $3" );
}
}*/
u32 w0 = *(u32*)&RDRAM[RSP.PC[RSP.PCi]];
u32 w1 = *(u32*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.cmd = _SHIFTR( w0, 24, 8 );
#ifdef DEBUG
DebugRSPState( RSP.PCi, RSP.PC[RSP.PCi], _SHIFTR( w0, 24, 8 ), w0, w1 );
DebugMsg( DEBUG_LOW | DEBUG_HANDLED, "0x%08lX: CMD=0x%02lX W0=0x%08lX W1=0x%08lX\n", RSP.PC[RSP.PCi], _SHIFTR( w0, 24, 8 ), w0, w1 );
#endif
RSP.PC[RSP.PCi] += 8;
RSP.nextCmd = _SHIFTR( *(u32*)&RDRAM[RSP.PC[RSP.PCi]], 24, 8 );
GBI.cmd[RSP.cmd]( w0, w1 );
}
/* if (OGL.frameBufferTextures && gDP.colorImage.changed)
{
FrameBuffer_SaveBuffer( gDP.colorImage.address, gDP.colorImage.size, gDP.colorImage.width, gDP.colorImage.height );
gDP.colorImage.changed = FALSE;
}*/
RSP.busy = FALSE;
RSP.DList++;
gSP.changed |= CHANGED_COLORBUFFER;
}
void RSP_Init()
{
u8 test;
u32 testAddress;
// Calculate RDRAM size by intentionally causing an access violation
#ifndef __LINUX__
__try
{
testAddress = 0;
while (TRUE)
{
test = RDRAM[testAddress];
testAddress++;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
RDRAMSize = testAddress;
}
#else // !__LINUX__
RDRAMSize = 1024 * 1024 * 8;
#endif // __LINUX__
RSP.DList = 0;
RSP.uc_start = RSP.uc_dstart = 0;
gDP.loadTile = &gDP.tiles[7];
gSP.textureTile[0] = &gDP.tiles[0];
gSP.textureTile[1] = &gDP.tiles[1];
DepthBuffer_Init();
GBI_Init();
OGL_Start();
}

52
RSP.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef RSP_H
#define RSP_H
#ifndef __LINUX__
# include <windows.h>
#else
# include "winlnxdefs.h"
# include "SDL.h"
# include "SDL_thread.h"
#endif
#include "N64.h"
#include "GBI.h"
#include "gSP.h"
#include "Types.h"
#define RSPMSG_CLOSE 0
#define RSPMSG_UPDATESCREEN 1
#define RSPMSG_PROCESSDLIST 2
#define RSPMSG_CAPTURESCREEN 3
#define RSPMSG_DESTROYTEXTURES 4
#define RSPMSG_INITTEXTURES 5
typedef struct
{
#ifdef RSPTHREAD
# ifndef __LINUX__
HANDLE thread;
// Events for thread messages, see defines at the top, or RSP_Thread
HANDLE threadMsg[6];
// Event to notify main process that the RSP is finished with what it was doing
HANDLE threadFinished;
# else
SDL_Thread *thread;
int threadMsg[6];
# endif // !__LINUX__
#endif // RSPTHREAD
u32 PC[18], PCi, busy, halt, close, DList, uc_start, uc_dstart, cmd, nextCmd, count;
} RSPInfo;
extern RSPInfo RSP;
#define RSP_SegmentToPhysical( segaddr ) ((gSP.segment[(segaddr >> 24) & 0x0F] + (segaddr & 0x00FFFFFF)) & 0x00FFFFFF)
void RSP_Init();
void RSP_ProcessDList();
#ifdef RSPTHREAD
DWORD WINAPI RSP_ThreadProc( LPVOID lpParameter );
#endif
void RSP_LoadMatrix( f32 mtx[4][4], u32 address );
#endif

BIN
Resource.aps Normal file

Binary file not shown.

243
Resource.rc Normal file
View File

@ -0,0 +1,243 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DEBUGDLG DIALOGEX 0, 0, 489, 238
STYLE DS_SETFONT | WS_VISIBLE | WS_CAPTION
EXSTYLE WS_EX_TOOLWINDOW
CAPTION "glN64 Debug Output"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
GROUPBOX "Debug Level",IDC_STATIC,4,161,240,28
CONTROL "High",IDC_DEBUGHIGH,"Button",BS_AUTORADIOBUTTON |
WS_GROUP,14,173,31,10
CONTROL "Medium",IDC_DEBUGMEDIUM,"Button",BS_AUTORADIOBUTTON,71,
173,41,10
CONTROL "Low",IDC_DEBUGLOW,"Button",BS_AUTORADIOBUTTON,138,173,
29,10
GROUPBOX "Show",IDC_STATIC,4,192,303,41
CONTROL "Unhandled",IDC_SHOWUNHANDLED,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,13,216,51,10
CONTROL "Unknown",IDC_SHOWUNKNOWN,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,80,216,47,10
CONTROL "Errors",IDC_SHOWERRORS,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,80,204,34,10
CONTROL "Handled",IDC_SHOWHANDLED,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,13,204,43,10
PUSHBUTTON "Pause",IDC_PAUSE,320,219,50,14
PUSHBUTTON "Step",IDC_STEP,376,219,50,14
PUSHBUTTON "Run",IDC_RUN,435,219,50,14
CONTROL "",IDC_DEBUGEDIT,"RichEdit20A",ES_MULTILINE |
ES_AUTOHSCROLL | ES_READONLY | WS_BORDER | WS_VSCROLL |
WS_TABSTOP,4,4,481,122
EDITTEXT IDC_PC,87,132,40,14,ES_AUTOHSCROLL
LTEXT "PC:",IDC_STATIC,71,135,12,8
EDITTEXT IDC_PCI,47,131,16,14,ES_AUTOHSCROLL
LTEXT "PC Index:",IDC_STATIC,11,134,32,8
LTEXT "Command:",IDC_STATIC,144,134,34,8
LTEXT "Word 0:",IDC_STATIC,210,134,26,8
LTEXT "Word 1:",IDC_STATIC,284,134,26,8
EDITTEXT IDC_W1,315,131,40,14,ES_AUTOHSCROLL
EDITTEXT IDC_W0,239,131,40,14,ES_AUTOHSCROLL
EDITTEXT IDC_CMD,181,131,17,14,ES_AUTOHSCROLL
CONTROL "Texture",IDC_SHOWTEXTURE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,251,204,40,10
CONTROL "Matrix",IDC_SHOWMATRIX,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,143,216,35,10
CONTROL "Vertex",IDC_SHOWVERTEX,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,194,204,36,10
CONTROL "Triangle",IDC_SHOWTRIANGLE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,194,216,41,10
CONTROL "Combine",IDC_SHOWCOMBINE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,251,216,43,10
CONTROL "Ignored",IDC_SHOWIGNORED,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,143,204,40,10
CONTROL "Detailed",IDC_DEBUGDETAIL,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,193,173,42,10
END
IDD_CONFIGDLG DIALOGEX 0, 0, 247, 201
STYLE DS_ABSALIGN | DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS |
DS_CENTER | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION
CAPTION "glN64 Configuration"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
LTEXT "Full Screen Mode:",IDC_STATIC,15,33,58,8
COMBOBOX IDC_FULLSCREENRES,125,31,60,111,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "Windowed Resolution:",IDC_STATIC,15,49,72,8
COMBOBOX IDC_WINDOWEDRES,125,47,60,100,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
CONTROL "Force Bilinear Filtering",IDC_FORCEBILINEAR,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,135,66,86,10
GROUPBOX "Textures",IDC_STATIC,7,104,233,69
LTEXT "Texture Cache Size:",IDC_STATIC,15,137,66,8
EDITTEXT IDC_CACHEMEGS,87,134,22,14,ES_NUMBER,WS_EX_RIGHT
LTEXT "MB",IDC_STATIC,111,137,10,8
PUSHBUTTON "OK",IDOK,71,180,50,14
PUSHBUTTON "Cancel",IDCANCEL,126,180,50,14
GROUPBOX "Display",IDC_STATIC,7,7,233,91
COMBOBOX IDC_FULLSCREENREFRESH,191,31,38,111,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "Bit Depth:",IDC_STATIC,81,18,33,8
LTEXT "Resolution:",IDC_STATIC,136,18,37,8
LTEXT "Refresh Rate:",IDC_STATIC,187,18,46,8
COMBOBOX IDC_FULLSCREENBITDEPTH,80,31,39,111,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
CONTROL "Enable 2xSaI texture scaling",IDC_ENABLE2XSAI,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,16,66,107,10
CONTROL "Enable Fog",IDC_FOG,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,135,81,51,10
CONTROL "Hardware Frame Buffer Textures (Experimental)",
IDC_FRAMEBUFFER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,
154,171,10
COMBOBOX IDC_TEXTUREBPP,87,118,107,75,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "Texture Bit Depth:",IDC_STATIC,15,120,60,8
CONTROL "Enabled Dithered Alpha Testing",IDC_DITHEREDALPHATEST,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,81,116,10
END
IDD_MICROCODEDLG DIALOGEX 0, 0, 384, 129
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "glN64 Unknown Microcode"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,136,108,50,14
PUSHBUTTON "Stop",IDCANCEL,198,108,50,14
COMBOBOX IDC_MICROCODE,168,86,87,80,CBS_DROPDOWN | WS_VSCROLL |
WS_TABSTOP
LTEXT "Microcode:",IDC_STATIC,129,88,36,8
LTEXT "Unknown microcode detected. Please notify Orkin, including the following information:",
IDC_STATIC,53,7,278,8
LTEXT "You can manually select the closest matching microcode, or stop the video thread",
IDC_STATIC,62,73,261,8
EDITTEXT IDC_TEXTBOX,7,20,370,31,ES_MULTILINE | ES_AUTOHSCROLL |
ES_READONLY
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_DEBUGDLG, DIALOG
BEGIN
LEFTMARGIN, 4
RIGHTMARGIN, 485
TOPMARGIN, 4
BOTTOMMARGIN, 233
END
IDD_CONFIGDLG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 240
TOPMARGIN, 7
BOTTOMMARGIN, 194
END
IDD_MICROCODEDLG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 377
TOPMARGIN, 7
BOTTOMMARGIN, 122
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog Info
//
IDD_CONFIGDLG DLGINIT
BEGIN
IDC_FULLSCREENRES, 0x403, 10, 0
0x3631, 0x3030, 0x3178, 0x3032, 0x0030,
IDC_FULLSCREENREFRESH, 0x403, 6, 0
0x3036, 0x4820, 0x007a,
IDC_TEXTUREBPP, 0x403, 21, 0
0x3631, 0x622d, 0x7469, 0x6f20, 0x6c6e, 0x2079, 0x6628, 0x7361, 0x6574,
0x2972, "\000"
IDC_TEXTUREBPP, 0x403, 27, 0
0x3631, 0x622d, 0x7469, 0x6120, 0x646e, 0x3320, 0x2d32, 0x6962, 0x2074,
0x6e28, 0x726f, 0x616d, 0x296c, "\000"
IDC_TEXTUREBPP, 0x403, 29, 0
0x3233, 0x622d, 0x7469, 0x6f20, 0x6c6e, 0x2079, 0x6228, 0x7365, 0x2074,
0x6f66, 0x2072, 0x7832, 0x4153, 0x2949, "\000"
0
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

102
S2DEX.cpp Normal file
View File

@ -0,0 +1,102 @@
#include "OpenGL.h"
#include "S2DEX.h"
#include "F3D.h"
#include "F3DEX.h"
#include "GBI.h"
#include "gSP.h"
#include "gDP.h"
#include "RSP.h"
#include "Types.h"
void S2DEX_BG_1Cyc( u32 w0, u32 w1 )
{
gSPBgRect1Cyc( w1 );
}
void S2DEX_BG_Copy( u32 w0, u32 w1 )
{
gSPBgRectCopy( w1 );
}
void S2DEX_Obj_Rectangle( u32 w0, u32 w1 )
{
gSPObjRectangle( w1 );
}
void S2DEX_Obj_Sprite( u32 w0, u32 w1 )
{
gSPObjSprite( w1 );
}
void S2DEX_Obj_MoveMem( u32 w0, u32 w1 )
{
if (_SHIFTR( w0, 0, 16 ) == 0)
gSPObjMatrix( w1 );
else
gSPObjSubMatrix( w1 );
}
void S2DEX_Select_DL( u32 w0, u32 w1 )
{
}
void S2DEX_Obj_RenderMode( u32 w0, u32 w1 )
{
}
void S2DEX_Obj_Rectangle_R( u32 w0, u32 w1 )
{
}
void S2DEX_Obj_LoadTxtr( u32 w0, u32 w1 )
{
gSPObjLoadTxtr( w1 );
}
void S2DEX_Obj_LdTx_Sprite( u32 w0, u32 w1 )
{
gSPObjLoadTxSprite( w1 );
}
void S2DEX_Obj_LdTx_Rect( u32 w0, u32 w1 )
{
}
void S2DEX_Obj_LdTx_Rect_R( u32 w0, u32 w1 )
{
gSPObjLoadTxRectR( w1 );
}
void S2DEX_Init()
{
// Set GeometryMode flags
GBI_InitFlags( F3DEX );
gSP.geometryMode = 0;
GBI.PCStackSize = 18;
// GBI Command Command Value Command Function
GBI_SetGBI( G_SPNOOP, F3D_SPNOOP, F3D_SPNoOp );
GBI_SetGBI( G_BG_1CYC, S2DEX_BG_1CYC, S2DEX_BG_1Cyc );
GBI_SetGBI( G_BG_COPY, S2DEX_BG_COPY, S2DEX_BG_Copy );
GBI_SetGBI( G_OBJ_RECTANGLE, S2DEX_OBJ_RECTANGLE, S2DEX_Obj_Rectangle );
GBI_SetGBI( G_OBJ_SPRITE, S2DEX_OBJ_SPRITE, S2DEX_Obj_Sprite );
GBI_SetGBI( G_OBJ_MOVEMEM, S2DEX_OBJ_MOVEMEM, S2DEX_Obj_MoveMem );
GBI_SetGBI( G_DL, F3D_DL, F3D_DList );
GBI_SetGBI( G_SELECT_DL, S2DEX_SELECT_DL, S2DEX_Select_DL );
GBI_SetGBI( G_OBJ_RENDERMODE, S2DEX_OBJ_RENDERMODE, S2DEX_Obj_RenderMode );
GBI_SetGBI( G_OBJ_RECTANGLE_R, S2DEX_OBJ_RECTANGLE_R, S2DEX_Obj_Rectangle_R );
GBI_SetGBI( G_OBJ_LOADTXTR, S2DEX_OBJ_LOADTXTR, S2DEX_Obj_LoadTxtr );
GBI_SetGBI( G_OBJ_LDTX_SPRITE, S2DEX_OBJ_LDTX_SPRITE, S2DEX_Obj_LdTx_Sprite );
GBI_SetGBI( G_OBJ_LDTX_RECT, S2DEX_OBJ_LDTX_RECT, S2DEX_Obj_LdTx_Rect );
GBI_SetGBI( G_OBJ_LDTX_RECT_R, S2DEX_OBJ_LDTX_RECT_R, S2DEX_Obj_LdTx_Rect_R );
GBI_SetGBI( G_MOVEWORD, F3D_MOVEWORD, F3D_MoveWord );
GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H );
GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L );
GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL );
GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 );
GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 );
GBI_SetGBI( G_LOAD_UCODE, S2DEX_LOAD_UCODE, F3DEX_Load_uCode );
}

219
S2DEX.h Normal file
View File

@ -0,0 +1,219 @@
#ifndef S2DEX_H
#define S2DEX_H
#define G_BGLT_LOADBLOCK 0x0033
#define G_BGLT_LOADTILE 0xfff4
#define G_BG_FLAG_FLIPS 0x01
#define G_BG_FLAG_FLIPT 0x10
struct uObjScaleBg
{
u16 imageW; /* Texture width (8-byte alignment, u10.2) */
u16 imageX; /* x-coordinate of upper-left
position of texture (u10.5) */
u16 frameW; /* Transfer destination frame width (u10.2) */
s16 frameX; /* x-coordinate of upper-left
position of transfer destination frame (s10.2) */
u16 imageH; /* Texture height (u10.2) */
u16 imageY; /* y-coordinate of upper-left position of
texture (u10.5) */
u16 frameH; /* Transfer destination frame height (u10.2) */
s16 frameY; /* y-coordinate of upper-left position of transfer
destination frame (s10.2) */
u32 imagePtr; /* Address of texture source in DRAM*/
u8 imageSiz; /* Texel size
G_IM_SIZ_4b (4 bits/texel)
G_IM_SIZ_8b (8 bits/texel)
G_IM_SIZ_16b (16 bits/texel)
G_IM_SIZ_32b (32 bits/texel) */
u8 imageFmt; /*Texel format
G_IM_FMT_RGBA (RGBA format)
G_IM_FMT_YUV (YUV format)
G_IM_FMT_CI (CI format)
G_IM_FMT_IA (IA format)
G_IM_FMT_I (I format) */
u16 imageLoad; /* Method for loading the BG image texture
G_BGLT_LOADBLOCK (use LoadBlock)
G_BGLT_LOADTILE (use LoadTile) */
u16 imageFlip; /* Image inversion on/off (horizontal
direction only)
0 (normal display (no inversion))
G_BG_FLAG_FLIPS (horizontal inversion of texture image) */
u16 imagePal; /* Position of palette for 4-bit color
index texture (4-bit precision, 0~15) */
u16 scaleH; /* y-direction scale value (u5.10) */
u16 scaleW; /* x-direction scale value (u5.10) */
s32 imageYorig; /* image drawing origin (s20.5)*/
u8 padding[4]; /* Padding */
}; /* 40 bytes */
struct uObjBg
{
u16 imageW; /* Texture width (8-byte alignment, u10.2) */
u16 imageX; /* x-coordinate of upper-left position of texture (u10.5) */
u16 frameW; /* Transfer destination frame width (u10.2) */
s16 frameX; /* x-coordinate of upper-left position of
transfer destination frame (s10.2) */
u16 imageH; /* Texture height (u10.2) */
u16 imageY; /* y-coordinate of upper-left position of
texture (u10.5) */
u16 frameH; /* Transfer destination frame height (u10.2) */
s16 frameY; /* y-coordinate of upper-left position of
transfer destination frame (s10.2) */
u32 imagePtr; /* Address of texture source in DRAM*/
u8 imageSiz; /* Texel size
G_IM_SIZ_4b (4 bits/texel)
G_IM_SIZ_8b (8 bits/texel)
G_IM_SIZ_16b (16 bits/texel)
G_IM_SIZ_32b (32 bits/texel) */
u8 imageFmt; /*Texel format
G_IM_FMT_RGBA (RGBA format)
G_IM_FMT_YUV (YUV format)
G_IM_FMT_CI (CI format)
G_IM_FMT_IA (IA format)
G_IM_FMT_I (I format) */
u16 imageLoad; /* Method for loading the BG image texture
G_BGLT_LOADBLOCK (use LoadBlock)
G_BGLT_LOADTILE (use LoadTile) */
u16 imageFlip; /* Image inversion on/off (horizontal direction only)
0 (normal display (no inversion))
G_BG_FLAG_FLIPS (horizontal inversion of
texture image) */
u16 imagePal; /* Position of palette for 4-bit color
index texture (4-bit precision, 0~15) */
/* The following is set in the initialization routine guS2DInitBg */
u16 tmemH; /* TMEM height for a single load (quadruple
value, s13.2) */
u16 tmemW; /* TMEM width for one frame line (word size) */
u16 tmemLoadTH; /* TH value or Stride value */
u16 tmemLoadSH; /* SH value */
u16 tmemSize; /* imagePtr skip value for a single load */
u16 tmemSizeW; /* imagePtr skip value for one image line */
}; /* 40 bytes */
struct uObjSprite
{
u16 scaleW; /* Width-direction scaling (u5.10) */
s16 objX; /* x-coordinate of upper-left corner of OBJ (s10.2) */
u16 paddingX; /* Unused (always 0) */
u16 imageW; /* Texture width (length in s direction, u10.5) */
u16 scaleH; /* Height-direction scaling (u5.10) */
s16 objY; /* y-coordinate of upper-left corner of OBJ (s10.2) */
u16 paddingY; /* Unused (always 0) */
u16 imageH; /* Texture height (length in t direction, u10.5) */
u16 imageAdrs; /* Texture starting position in TMEM (In units of 64-bit words) */
u16 imageStride; /* Texel wrapping width (In units of 64-bit words) */
u8 imageFlags; /* Display flag
(*) More than one of the following flags can be specified as the bit sum of the flags:
0 (Normal display (no inversion))
G_OBJ_FLAG_FLIPS (s-direction (x) inversion)
G_OBJ_FLAG_FLIPT (t-direction (y) inversion) */
u8 imagePal; /* Position of palette for 4-bit color index texture (4-bit precision, 0~7) */
u8 imageSiz; /* Texel size
G_IM_SIZ_4b (4 bits/texel)
G_IM_SIZ_8b (8 bits/texel)
G_IM_SIZ_16b (16 bits/texel)
G_IM_SIZ_32b (32 bits/texel) */
u8 imageFmt; /* Texel format
G_IM_FMT_RGBA (RGBA format)
G_IM_FMT_YUV (YUV format)
G_IM_FMT_CI (CI format)
G_IM_FMT_IA (IA format)
G_IM_FMT_I (I format) */
}; /* 24 bytes */
struct uObjTxtrBlock
{
u32 type; /* Structure identifier (G_OBJLT_TXTRBLOCK) */
u32 image; /* Texture source address in DRAM (8-byte alignment) */
u16 tsize; /* Texture size (specified by GS_TB_TSIZE) */
u16 tmem; /* TMEM word address where texture will be loaded (8-byte word) */
u16 sid; /* Status ID (multiple of 4: either 0, 4, 8, or 12) */
u16 tline; /* Texture line width (specified by GS_TB_TLINE) */
u32 flag; /* Status flag */
u32 mask; /* Status mask */
}; /* 24 bytes */
struct uObjTxtrTile
{
u32 type; /* Structure identifier (G_OBJLT_TXTRTILE) */
u32 image; /* Texture source address in DRAM (8-byte alignment) */
u16 twidth; /* Texture width (specified by GS_TT_TWIDTH) */
u16 tmem; /* TMEM word address where texture will be loaded (8-byte word) */
u16 sid; /* Status ID (multiple of 4: either 0, 4, 8, or 12) */
u16 theight;/* Texture height (specified by GS_TT_THEIGHT) */
u32 flag; /* Status flag */
u32 mask; /* Status mask */
}; /* 24 bytes */
struct uObjTxtrTLUT
{
u32 type; /* Structure identifier (G_OBJLT_TLUT) */
u32 image; /* Texture source address in DRAM */
u16 pnum; /* Number of palettes to load - 1 */
u16 phead; /* Palette position at start of load (256~511) */
u16 sid; /* Status ID (multiple of 4: either 0, 4, 8, or 12) */
u16 zero; /* Always assign 0 */
u32 flag; /* Status flag */
u32 mask; /* Status mask */
}; /* 24 bytes */
typedef union
{
uObjTxtrBlock block;
uObjTxtrTile tile;
uObjTxtrTLUT tlut;
} uObjTxtr;
struct uObjTxSprite
{
uObjTxtr txtr;
uObjSprite sprite;
};
struct uObjMtx
{
s32 A, B, C, D; /* s15.16 */
s16 Y, X; /* s10.2 */
u16 BaseScaleY; /* u5.10 */
u16 BaseScaleX; /* u5.10 */
};
void S2DEX_BG_1Cyc( u32 w0, u32 w1 );
void S2DEX_BG_Copy( u32 w0, u32 w1 );
void S2DEX_Obj_Rectangle( u32 w0, u32 w1 );
void S2DEX_Obj_Sprite( u32 w0, u32 w1 );
void S2DEX_Obj_MoveMem( u32 w0, u32 w1 );
void S2DEX_Select_DL( u32 w0, u32 w1 );
void S2DEX_Obj_RenderMode( u32 w0, u32 w1 );
void S2DEX_Obj_Rectangle_R( u32 w0, u32 w1 );
void S2DEX_Obj_LoadTxtr( u32 w0, u32 w1 );
void S2DEX_Obj_LdTx_Sprite( u32 w0, u32 w1 );
void S2DEX_Obj_LdTx_Rect( u32 w0, u32 w1 );
void S2DEX_Obj_LdTx_Rect_R( u32 w0, u32 w1 );
void S2DEX_Init();
#define S2DEX_BG_1CYC 0x01
#define S2DEX_BG_COPY 0x02
#define S2DEX_OBJ_RECTANGLE 0x03
#define S2DEX_OBJ_SPRITE 0x04
#define S2DEX_OBJ_MOVEMEM 0x05
#define S2DEX_LOAD_UCODE 0xAF
#define S2DEX_SELECT_DL 0xB0
#define S2DEX_OBJ_RENDERMODE 0xB1
#define S2DEX_OBJ_RECTANGLE_R 0xB2
#define S2DEX_OBJ_LOADTXTR 0xC1
#define S2DEX_OBJ_LDTX_SPRITE 0xC2
#define S2DEX_OBJ_LDTX_RECT 0xC3
#define S2DEX_OBJ_LDTX_RECT_R 0xC4
#define S2DEX_RDPHALF_0 0xE4
#endif

45
S2DEX2.cpp Normal file
View File

@ -0,0 +1,45 @@
#include "OpenGL.h"
#include "S2DEX.h"
#include "S2DEX2.h"
#include "F3D.h"
#include "F3DEX.h"
#include "F3DEX2.h"
#include "GBI.h"
#include "gSP.h"
#include "gDP.h"
#include "RSP.h"
#include "Types.h"
void S2DEX2_Init()
{
// Set GeometryMode flags
GBI_InitFlags( F3DEX2 );
gSP.geometryMode = 0;
GBI.PCStackSize = 18;
// GBI Command Command Value Command Function
GBI_SetGBI( G_SPNOOP, F3DEX2_SPNOOP, F3D_SPNoOp );
GBI_SetGBI( G_BG_1CYC, S2DEX2_BG_1CYC, S2DEX_BG_1Cyc );
GBI_SetGBI( G_BG_COPY, S2DEX2_BG_COPY, S2DEX_BG_Copy );
GBI_SetGBI( G_OBJ_RECTANGLE, S2DEX2_OBJ_RECTANGLE, S2DEX_Obj_Rectangle );
GBI_SetGBI( G_OBJ_SPRITE, S2DEX2_OBJ_SPRITE, S2DEX_Obj_Sprite );
GBI_SetGBI( G_OBJ_MOVEMEM, S2DEX2_OBJ_MOVEMEM, S2DEX_Obj_MoveMem );
GBI_SetGBI( G_DL, F3DEX2_DL, F3D_DList );
GBI_SetGBI( G_SELECT_DL, S2DEX2_SELECT_DL, S2DEX_Select_DL );
GBI_SetGBI( G_OBJ_RENDERMODE, S2DEX2_OBJ_RENDERMODE, S2DEX_Obj_RenderMode );
GBI_SetGBI( G_OBJ_RECTANGLE_R, S2DEX2_OBJ_RECTANGLE_R, S2DEX_Obj_Rectangle_R );
GBI_SetGBI( G_OBJ_LOADTXTR, S2DEX2_OBJ_LOADTXTR, S2DEX_Obj_LoadTxtr );
GBI_SetGBI( G_OBJ_LDTX_SPRITE, S2DEX2_OBJ_LDTX_SPRITE, S2DEX_Obj_LdTx_Sprite );
GBI_SetGBI( G_OBJ_LDTX_RECT, S2DEX2_OBJ_LDTX_RECT, S2DEX_Obj_LdTx_Rect );
GBI_SetGBI( G_OBJ_LDTX_RECT_R, S2DEX2_OBJ_LDTX_RECT_R, S2DEX_Obj_LdTx_Rect_R );
GBI_SetGBI( G_MOVEWORD, F3DEX2_MOVEWORD, F3DEX2_MoveWord );
GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H );
GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L );
GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL );
GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 );
GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 );
GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode );
}

20
S2DEX2.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef S2DEX2_H
#define S2DEX2_H
void S2DEX2_Init();
#define S2DEX2_OBJ_RECTANGLE_R 0xDA
#define S2DEX2_OBJ_MOVEMEM 0xDC
#define S2DEX2_RDPHALF_0 0xE4
#define S2DEX2_OBJ_RECTANGLE 0x01
#define S2DEX2_OBJ_SPRITE 0x02
#define S2DEX2_SELECT_DL 0x04
#define S2DEX2_OBJ_LOADTXTR 0x05
#define S2DEX2_OBJ_LDTX_SPRITE 0x06
#define S2DEX2_OBJ_LDTX_RECT 0x07
#define S2DEX2_OBJ_LDTX_RECT_R 0x08
#define S2DEX2_BG_1CYC 0x09
#define S2DEX2_BG_COPY 0x0A
#define S2DEX2_OBJ_RENDERMODE 0x0B
#endif

1128
Textures.cpp Normal file

File diff suppressed because it is too large Load Diff

89
Textures.h Normal file
View File

@ -0,0 +1,89 @@
#ifndef TEXTURES_H
#define TEXTURES_H
#include <GL/gl.h>
#include "convert.h"
struct CachedTexture
{
GLuint glName;
u32 address;
u32 crc;
// float fulS, fulT;
// WORD ulS, ulT, lrS, lrT;
float offsetS, offsetT;
u32 maskS, maskT;
u32 clampS, clampT;
u32 mirrorS, mirrorT;
u32 line;
u32 size;
u32 format;
u32 tMem;
u32 palette;
u32 width, height; // N64 width and height
u32 clampWidth, clampHeight; // Size to clamp to
u32 realWidth, realHeight; // Actual texture size
f32 scaleS, scaleT; // Scale to map to 0.0-1.0
f32 shiftScaleS, shiftScaleT; // Scale to shift
u32 textureBytes;
CachedTexture *lower, *higher;
u32 lastDList;
u32 frameBufferTexture;
};
struct TextureCache
{
CachedTexture *bottom, *top;
CachedTexture *(current[2]);
u32 maxBytes;
u32 cachedBytes;
u32 numCached;
u32 hits, misses;
GLuint glNoiseNames[32];
//GLuint glDummyName;
CachedTexture *dummy;
u32 enable2xSaI, bitDepth;
};
extern TextureCache cache;
inline u32 pow2( u32 dim )
{
u32 i = 1;
while (i < dim) i <<= 1;
return i;
}
inline u32 powof( u32 dim )
{
u32 num = 1;
u32 i = 0;
while (num < dim)
{
num <<= 1;
i++;
}
return i;
}
CachedTexture *TextureCache_AddTop();
void TextureCache_MoveToTop( CachedTexture *newtop );
void TextureCache_Remove( CachedTexture *texture );
void TextureCache_RemoveBottom();
void TextureCache_Init();
void TextureCache_Destroy();
void TextureCache_Update( u32 t );
void TextureCache_ActivateTexture( u32 t, CachedTexture *texture );
void TextureCache_ActivateNoise( u32 t );
void TextureCache_ActivateDummy( u32 t );
BOOL TextureCache_Verify();
#endif

39
Types.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef TYPES_H
#define TYPES_H
typedef unsigned char u8; /* unsigned 8-bit */
typedef unsigned short u16; /* unsigned 16-bit */
typedef unsigned long u32; /* unsigned 32-bit */
typedef unsigned long long u64; /* unsigned 64-bit */
typedef signed char s8; /* signed 8-bit */
typedef short s16; /* signed 16-bit */
typedef long s32; /* signed 32-bit */
typedef long long s64; /* signed 64-bit */
typedef volatile unsigned char vu8; /* unsigned 8-bit */
typedef volatile unsigned short vu16; /* unsigned 16-bit */
typedef volatile unsigned long vu32; /* unsigned 32-bit */
typedef volatile unsigned long long vu64; /* unsigned 64-bit */
typedef volatile signed char vs8; /* signed 8-bit */
typedef volatile short vs16; /* signed 16-bit */
typedef volatile long vs32; /* signed 32-bit */
typedef volatile long long vs64; /* signed 64-bit */
typedef float f32; /* single prec floating point */
typedef double f64; /* double prec floating point */
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
#endif // TYPES_H

79
VI.cpp Normal file
View File

@ -0,0 +1,79 @@
#include "glN64.h"
#include "Types.h"
#include "VI.h"
#include "OpenGL.h"
#include "N64.h"
#include "gSP.h"
#include "gDP.h"
#include "RSP.h"
#include "FrameBuffer.h"
#include "Debug.h"
VIInfo VI;
void VI_UpdateSize()
{
f32 xScale = _FIXED2FLOAT( _SHIFTR( *REG.VI_X_SCALE, 0, 12 ), 10 );
f32 xOffset = _FIXED2FLOAT( _SHIFTR( *REG.VI_X_SCALE, 16, 12 ), 10 );
f32 yScale = _FIXED2FLOAT( _SHIFTR( *REG.VI_Y_SCALE, 0, 12 ), 10 );
f32 yOffset = _FIXED2FLOAT( _SHIFTR( *REG.VI_Y_SCALE, 16, 12 ), 10 );
u32 hEnd = _SHIFTR( *REG.VI_H_START, 0, 10 );
u32 hStart = _SHIFTR( *REG.VI_H_START, 16, 10 );
// These are in half-lines, so shift an extra bit
u32 vEnd = _SHIFTR( *REG.VI_V_START, 1, 9 );
u32 vStart = _SHIFTR( *REG.VI_V_START, 17, 9 );
VI.width = (hEnd - hStart) * xScale;
VI.height = (vEnd - vStart) * yScale * 1.0126582f;
if (VI.width == 0.0f) VI.width = 320.0f;
if (VI.height == 0.0f) VI.height = 240.0f;
}
void VI_UpdateScreen()
{
glFinish();
if (OGL.frameBufferTextures)
{
FrameBuffer *current = FrameBuffer_FindBuffer( *REG.VI_ORIGIN );
if ((*REG.VI_ORIGIN != VI.lastOrigin) || ((current) && current->changed))
{
if (gDP.colorImage.changed)
{
FrameBuffer_SaveBuffer( gDP.colorImage.address, gDP.colorImage.size, gDP.colorImage.width, gDP.colorImage.height );
gDP.colorImage.changed = FALSE;
}
FrameBuffer_RenderBuffer( *REG.VI_ORIGIN );
gDP.colorImage.changed = FALSE;
VI.lastOrigin = *REG.VI_ORIGIN;
#ifdef DEBUG
while (Debug.paused && !Debug.step);
Debug.step = FALSE;
#endif
}
}
else
{
if (gSP.changed & CHANGED_COLORBUFFER)
{
#ifndef __LINUX__
SwapBuffers( OGL.hDC );
#else
OGL_SwapBuffers();
#endif
gSP.changed &= ~CHANGED_COLORBUFFER;
#ifdef DEBUG
while (Debug.paused && !Debug.step);
Debug.step = FALSE;
#endif
}
}
glFinish();
}

17
VI.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef VI_H
#define VI_H
#include "Types.h"
struct VIInfo
{
u32 width, height;
u32 lastOrigin;
};
extern VIInfo VI;
void VI_UpdateSize();
void VI_UpdateScreen();
#endif

279
Zilmar GFX 1.3.h Normal file
View File

@ -0,0 +1,279 @@
/**********************************************************************************
Common gfx plugin spec, version #1.3 maintained by zilmar (zilmar@emulation64.com)
All questions or suggestions should go through the mailing list.
http://www.egroups.com/group/Plugin64-Dev
***********************************************************************************
Notes:
------
Setting the approprate bits in the MI_INTR_REG and calling CheckInterrupts which
are both passed to the DLL in InitiateGFX will generate an Interrupt from with in
the plugin.
The Setting of the RSP flags and generating an SP interrupt should not be done in
the plugin
**********************************************************************************/
#ifndef _GFX_H_INCLUDED__
#define _GFX_H_INCLUDED__
#if defined(__cplusplus)
extern "C" {
#endif
/* Plugin types */
#define PLUGIN_TYPE_GFX 2
#define EXPORT __declspec(dllexport)
#define CALL _cdecl
/***** Structures *****/
typedef struct {
WORD Version; /* Set to 0x0103 */
WORD Type; /* Set to PLUGIN_TYPE_GFX */
char Name[100]; /* Name of the DLL */
/* If DLL supports memory these memory options then set them to TRUE or FALSE
if it does not support it */
BOOL NormalMemory; /* a normal BYTE array */
BOOL MemoryBswaped; /* a normal BYTE array where the memory has been pre
bswap on a dword (32 bits) boundry */
} PLUGIN_INFO;
typedef struct {
HWND hWnd; /* Render window */
HWND hStatusBar; /* if render window does not have a status bar then this is NULL */
BOOL MemoryBswaped; // If this is set to TRUE, then the memory has been pre
// bswap on a dword (32 bits) boundry
// eg. the first 8 bytes are stored like this:
// 4 3 2 1 8 7 6 5
BYTE * HEADER; // This is the rom header (first 40h bytes of the rom
// This will be in the same memory format as the rest of the memory.
BYTE * RDRAM;
BYTE * DMEM;
BYTE * IMEM;
DWORD * MI_INTR_REG;
DWORD * DPC_START_REG;
DWORD * DPC_END_REG;
DWORD * DPC_CURRENT_REG;
DWORD * DPC_STATUS_REG;
DWORD * DPC_CLOCK_REG;
DWORD * DPC_BUFBUSY_REG;
DWORD * DPC_PIPEBUSY_REG;
DWORD * DPC_TMEM_REG;
DWORD * VI_STATUS_REG;
DWORD * VI_ORIGIN_REG;
DWORD * VI_WIDTH_REG;
DWORD * VI_INTR_REG;
DWORD * VI_V_CURRENT_LINE_REG;
DWORD * VI_TIMING_REG;
DWORD * VI_V_SYNC_REG;
DWORD * VI_H_SYNC_REG;
DWORD * VI_LEAP_REG;
DWORD * VI_H_START_REG;
DWORD * VI_V_START_REG;
DWORD * VI_V_BURST_REG;
DWORD * VI_X_SCALE_REG;
DWORD * VI_Y_SCALE_REG;
void (*CheckInterrupts)( void );
} GFX_INFO;
/******************************************************************
Function: CaptureScreen
Purpose: This function dumps the current frame to a file
input: pointer to the directory to save the file to
output: none
*******************************************************************/
EXPORT void CALL CaptureScreen ( char * Directory );
/******************************************************************
Function: ChangeWindow
Purpose: to change the window between fullscreen and window
mode. If the window was in fullscreen this should
change the screen to window mode and vice vesa.
input: none
output: none
*******************************************************************/
EXPORT void CALL ChangeWindow (void);
/******************************************************************
Function: CloseDLL
Purpose: This function is called when the emulator is closing
down allowing the dll to de-initialise.
input: none
output: none
*******************************************************************/
EXPORT void CALL CloseDLL (void);
/******************************************************************
Function: DllAbout
Purpose: This function is optional function that is provided
to give further information about the DLL.
input: a handle to the window that calls this function
output: none
*******************************************************************/
EXPORT void CALL DllAbout ( HWND hParent );
/******************************************************************
Function: DllConfig
Purpose: This function is optional function that is provided
to allow the user to configure the dll
input: a handle to the window that calls this function
output: none
*******************************************************************/
EXPORT void CALL DllConfig ( HWND hParent );
/******************************************************************
Function: DllTest
Purpose: This function is optional function that is provided
to allow the user to test the dll
input: a handle to the window that calls this function
output: none
*******************************************************************/
EXPORT void CALL DllTest ( HWND hParent );
/******************************************************************
Function: DrawScreen
Purpose: This function is called when the emulator receives a
WM_PAINT message. This allows the gfx to fit in when
it is being used in the desktop.
input: none
output: none
*******************************************************************/
EXPORT void CALL DrawScreen (void);
/******************************************************************
Function: GetDllInfo
Purpose: This function allows the emulator to gather information
about the dll by filling in the PluginInfo structure.
input: a pointer to a PLUGIN_INFO stucture that needs to be
filled by the function. (see def above)
output: none
*******************************************************************/
EXPORT void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo );
/******************************************************************
Function: InitiateGFX
Purpose: This function is called when the DLL is started to give
information from the emulator that the n64 graphics
uses. This is not called from the emulation thread.
Input: Gfx_Info is passed to this function which is defined
above.
Output: TRUE on success
FALSE on failure to initialise
** note on interrupts **:
To generate an interrupt set the appropriate bit in MI_INTR_REG
and then call the function CheckInterrupts to tell the emulator
that there is a waiting interrupt.
*******************************************************************/
EXPORT BOOL CALL InitiateGFX (GFX_INFO Gfx_Info);
/******************************************************************
Function: MoveScreen
Purpose: This function is called in response to the emulator
receiving a WM_MOVE passing the xpos and ypos passed
from that message.
input: xpos - the x-coordinate of the upper-left corner of the
client area of the window.
ypos - y-coordinate of the upper-left corner of the
client area of the window.
output: none
*******************************************************************/
EXPORT void CALL MoveScreen (int xpos, int ypos);
/******************************************************************
Function: ProcessDList
Purpose: This function is called when there is a Dlist to be
processed. (High level GFX list)
input: none
output: none
*******************************************************************/
EXPORT void CALL ProcessDList(void);
/******************************************************************
Function: ProcessRDPList
Purpose: This function is called when there is a Dlist to be
processed. (Low level GFX list)
input: none
output: none
*******************************************************************/
EXPORT void CALL ProcessRDPList(void);
/******************************************************************
Function: RomClosed
Purpose: This function is called when a rom is closed.
input: none
output: none
*******************************************************************/
EXPORT void CALL RomClosed (void);
/******************************************************************
Function: RomOpen
Purpose: This function is called when a rom is open. (from the
emulation thread)
input: none
output: none
*******************************************************************/
EXPORT void CALL RomOpen (void);
/******************************************************************
Function: ShowCFB
Purpose: Useally once Dlists are started being displayed, cfb is
ignored. This function tells the dll to start displaying
them again.
input: none
output: none
*******************************************************************/
EXPORT void CALL ShowCFB (void);
/******************************************************************
Function: UpdateScreen
Purpose: This function is called in response to a vsync of the
screen were the VI bit in MI_INTR_REG has already been
set
input: none
output: none
*******************************************************************/
EXPORT void CALL UpdateScreen (void);
/******************************************************************
Function: ViStatusChanged
Purpose: This function is called to notify the dll that the
ViStatus registers value has been changed.
input: none
output: none
*******************************************************************/
EXPORT void CALL ViStatusChanged (void);
/******************************************************************
Function: ViWidthChanged
Purpose: This function is called to notify the dll that the
ViWidth registers value has been changed.
input: none
output: none
*******************************************************************/
EXPORT void CALL ViWidthChanged (void);
/******************************************************************
Function: ReadScreen
Purpose: Capture the current screen
Input: none
Output: dest - 24-bit RGB data (flipped horizontally)
width - width of image
height - height of image
******************************************************************/
EXPORT void CALL ReadScreen (void **dest, long *width, long *height);
#if defined(__cplusplus)
}
#endif
#endif

1228
convert.h Normal file

File diff suppressed because it is too large Load Diff

932
gDP.cpp Normal file
View File

@ -0,0 +1,932 @@
#include "glN64.h"
#include "N64.h"
#include "GBI.h"
#include "RSP.h"
#include "gDP.h"
#include "gSP.h"
#include "Types.h"
#include "Debug.h"
#include "convert.h"
#include "OpenGL.h"
#include "CRC.h"
#include "FrameBuffer.h"
#include "DepthBuffer.h"
#include "VI.h"
gDPInfo gDP;
void gDPSetOtherMode( u32 mode0, u32 mode1 )
{
gDP.otherMode.h = mode0;
gDP.otherMode.l = mode1;
gDP.changed |= CHANGED_RENDERMODE | CHANGED_CYCLETYPE | CHANGED_ALPHACOMPARE;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetOtherMode( %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s, %s | %s | %s%s%s%s%s | %s | %s%s%s );\n",
AlphaDitherText[gDP.otherMode.alphaDither],
ColorDitherText[gDP.otherMode.colorDither],
CombineKeyText[gDP.otherMode.combineKey],
TextureConvertText[gDP.otherMode.textureConvert],
TextureFilterText[gDP.otherMode.textureFilter],
TextureLUTText[gDP.otherMode.textureLUT],
TextureLODText[gDP.otherMode.textureLOD],
TextureDetailText[gDP.otherMode.textureDetail],
TexturePerspText[gDP.otherMode.texturePersp],
CycleTypeText[gDP.otherMode.cycleType],
PipelineModeText[gDP.otherMode.pipelineMode],
AlphaCompareText[gDP.otherMode.alphaCompare],
DepthSourceText[gDP.otherMode.depthSource],
gDP.otherMode.AAEnable ? "AA_EN | " : "",
gDP.otherMode.depthCompare ? "Z_CMP | " : "",
gDP.otherMode.depthUpdate ? "Z_UPD | " : "",
gDP.otherMode.imageRead ? "IM_RD | " : "",
CvgDestText[gDP.otherMode.cvgDest],
DepthModeText[gDP.otherMode.depthMode],
gDP.otherMode.cvgXAlpha ? "CVG_X_ALPHA | " : "",
gDP.otherMode.alphaCvgSel ? "ALPHA_CVG_SEL | " : "",
gDP.otherMode.forceBlender ? "FORCE_BL" : "" );
#endif
}
void gDPSetPrimDepth( u16 z, u16 dz )
{
gDP.primDepth.z = min( 1.0f, max( 0.0f, (_FIXED2FLOAT( z, 15 ) - gSP.viewport.vtrans[2]) / gSP.viewport.vscale[2] ) );
gDP.primDepth.deltaZ = dz;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetPrimDepth( %f, %f );\n",
gDP.primDepth.z,
gDP.primDepth.deltaZ);
#endif
}
void gDPPipelineMode( u32 mode )
{
gDP.otherMode.pipelineMode = mode;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPPipelineMode( %s );\n",
PipelineModeText[gDP.otherMode.pipelineMode] );
#endif
}
void gDPSetCycleType( u32 type )
{
gDP.otherMode.cycleType = type;
gDP.changed |= CHANGED_CYCLETYPE;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetCycleType( %s );\n",
CycleTypeText[gDP.otherMode.cycleType] );
#endif
}
void gDPSetTexturePersp( u32 enable )
{
gDP.otherMode.texturePersp = enable;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTexturePersp( %s );\n",
TexturePerspText[gDP.otherMode.texturePersp] );
#endif
}
void gDPSetTextureDetail( u32 type )
{
gDP.otherMode.textureDetail = type;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTextureDetail( %s );\n",
TextureDetailText[gDP.otherMode.textureDetail] );
#endif
}
void gDPSetTextureLOD( u32 mode )
{
gDP.otherMode.textureLOD = mode;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTextureLOD( %s );\n",
TextureLODText[gDP.otherMode.textureLOD] );
#endif
}
void gDPSetTextureLUT( u32 mode )
{
gDP.otherMode.textureLUT = mode;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTextureLUT( %s );\n",
TextureLUTText[gDP.otherMode.textureLUT] );
#endif
}
void gDPSetTextureFilter( u32 type )
{
gDP.otherMode.textureFilter = type;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTextureFilter( %s );\n",
TextureFilterText[gDP.otherMode.textureFilter] );
#endif
}
void gDPSetTextureConvert( u32 type )
{
gDP.otherMode.textureConvert = type;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTextureConvert( %s );\n",
TextureConvertText[gDP.otherMode.textureConvert] );
#endif
}
void gDPSetCombineKey( u32 type )
{
gDP.otherMode.combineKey = type;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, "gDPSetCombineKey( %s );\n",
CombineKeyText[gDP.otherMode.combineKey] );
#endif
}
void gDPSetColorDither( u32 type )
{
gDP.otherMode.colorDither = type;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetColorDither( %s );\n",
ColorDitherText[gDP.otherMode.colorDither] );
#endif
}
void gDPSetAlphaDither( u32 type )
{
gDP.otherMode.alphaDither = type;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetAlphaDither( %s );\n",
AlphaDitherText[gDP.otherMode.alphaDither] );
#endif
}
void gDPSetAlphaCompare( u32 mode )
{
gDP.otherMode.alphaCompare = mode;
gDP.changed |= CHANGED_ALPHACOMPARE;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetAlphaCompare( %s );\n",
AlphaCompareText[gDP.otherMode.alphaCompare] );
#endif
}
void gDPSetDepthSource( u32 source )
{
gDP.otherMode.depthSource = source;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetDepthSource( %s );\n",
DepthSourceText[gDP.otherMode.depthSource] );
#endif
}
void gDPSetRenderMode( u32 mode1, u32 mode2 )
{
gDP.otherMode.l &= 0x00000007;
gDP.otherMode.l |= mode1 | mode2;
gDP.changed |= CHANGED_RENDERMODE;
#ifdef DEBUG
// THIS IS INCOMPLETE!!!
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetRenderMode( %s%s%s%s%s | %s | %s%s%s );\n",
gDP.otherMode.AAEnable ? "AA_EN | " : "",
gDP.otherMode.depthCompare ? "Z_CMP | " : "",
gDP.otherMode.depthUpdate ? "Z_UPD | " : "",
gDP.otherMode.imageRead ? "IM_RD | " : "",
CvgDestText[gDP.otherMode.cvgDest],
DepthModeText[gDP.otherMode.depthMode],
gDP.otherMode.cvgXAlpha ? "CVG_X_ALPHA | " : "",
gDP.otherMode.alphaCvgSel ? "ALPHA_CVG_SEL | " : "",
gDP.otherMode.forceBlender ? "FORCE_BL" : "" );
#endif
}
void gDPSetCombine( s32 muxs0, s32 muxs1 )
{
gDP.combine.muxs0 = muxs0;
gDP.combine.muxs1 = muxs1;
gDP.changed |= CHANGED_COMBINE;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, "gDPSetCombine( %s, %s, %s, %s, %s, %s, %s, %s,\n",
saRGBText[gDP.combine.saRGB0],
sbRGBText[gDP.combine.sbRGB0],
mRGBText[gDP.combine.mRGB0],
aRGBText[gDP.combine.aRGB0],
saAText[gDP.combine.saA0],
sbAText[gDP.combine.sbA0],
mAText[gDP.combine.mA0],
aAText[gDP.combine.aA0] );
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, " %s, %s, %s, %s, %s, %s, %s, %s );\n",
saRGBText[gDP.combine.saRGB1],
sbRGBText[gDP.combine.sbRGB1],
mRGBText[gDP.combine.mRGB1],
aRGBText[gDP.combine.aRGB1],
saAText[gDP.combine.saA1],
sbAText[gDP.combine.sbA1],
mAText[gDP.combine.mA1],
aAText[gDP.combine.aA1] );
#endif
}
/*void RSP_UpdateColorImage()
{
WORD *colorBuffer = (WORD*)&RDRAM[RDP.colorImage.address];
BYTE *frameBuffer = (BYTE*)malloc( OGL.width * OGL.height * 3 );
BYTE *framePixel;
int x, y, frameX, frameY, i;
glReadBuffer( GL_BACK );
glReadPixels( 0, 0, OGL.width - 1, OGL.height - 1, GL_RGB, GL_UNSIGNED_BYTE, frameBuffer );
i = 0;
for (y = 0; y < RDP.height; y++)
{
frameY = OGL.height - (y * OGL.scaleY);
for (x = 0; x < RDP.width; x++)
{
frameX = x * OGL.scaleX;
framePixel = &frameBuffer[(OGL.width * frameY + frameX) * 3];
colorBuffer[i^1] = ((framePixel[0] >> 3) << 11) |
((framePixel[1] >> 3) << 6) |
((framePixel[2] >> 3) << 1);
i++;
}
}
free( frameBuffer );
}*/
void gDPUpdateColorImage()
{
return;
if ((gDP.colorImage.size == G_IM_SIZ_16b) && (gDP.colorImage.format == G_IM_FMT_RGBA))
{
u16 *frameBuffer = (u16*)malloc( gDP.colorImage.width * OGL.scaleX * gDP.colorImage.height * OGL.scaleY * 2 );
u16 *colorImage = (u16*)&RDRAM[gDP.colorImage.address];
u32 frameX, frameY;
u32 i = 0;
glReadBuffer( GL_BACK );
glReadPixels( 0, OGL.height - gDP.colorImage.height * OGL.scaleY + OGL.heightOffset, gDP.colorImage.width * OGL.scaleX, gDP.colorImage.height * OGL.scaleY, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1_EXT, frameBuffer );
for (u32 y = 0; y < gDP.colorImage.height; y++)
{
frameY = (gDP.colorImage.height - 1) * OGL.scaleY - y * OGL.scaleY;
for (u32 x = 0; x < gDP.colorImage.width; x++)
{
frameX = x * OGL.scaleX;
colorImage[i^1] = frameBuffer[(u32)(gDP.colorImage.width * OGL.scaleX) * frameY + frameX];
i++;
}
}
free( frameBuffer );
}
else if ((gDP.colorImage.size == G_IM_SIZ_8b) && (gDP.colorImage.format == G_IM_FMT_I))
{
u8 *frameBuffer = (u8*)malloc( gDP.colorImage.width * OGL.scaleX * gDP.colorImage.height * OGL.scaleY );
u8 *colorImage = (u8*)&RDRAM[gDP.colorImage.address];
u32 frameX, frameY;
u32 i = 0;
glReadPixels( 0, OGL.height - gDP.colorImage.height * OGL.scaleY + OGL.heightOffset, gDP.colorImage.width * OGL.scaleX, gDP.colorImage.height * OGL.scaleY, GL_LUMINANCE, GL_UNSIGNED_BYTE, frameBuffer );
for (u32 y = 0; y < gDP.colorImage.height; y++)
{
frameY = (gDP.colorImage.height - 1) * OGL.scaleY - y * OGL.scaleY;
for (u32 x = 0; x < gDP.colorImage.width; x++)
{
frameX = x * OGL.scaleX;
colorImage[i^3] = frameBuffer[(u32)(gDP.colorImage.width * OGL.scaleX) * frameY + frameX];
i++;
}
}
free( frameBuffer );
}
}
void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address )
{
/* if (gDP.colorImage.changed &&
// (gDP.colorImage.address != gDP.depthImageAddress) &&
(gDP.colorImage.address != RSP_SegmentToPhysical( address )))
{
gDPUpdateColorImage();
OGL_ClearDepthBuffer();
gDP.colorImage.changed = FALSE;
gDP.colorImage.height = 1;
}*/
/* for (int i = 0; i < (gDP.colorImage.width * gDP.colorImage.height ) << gDP.colorImage.size >> 1; i++)
{
RDRAM[gDP.colorImage.address + i] = 0;
}*/
address = RSP_SegmentToPhysical( address );
if (gDP.colorImage.address != address)
{
if (OGL.frameBufferTextures)
{
if (gDP.colorImage.changed)
FrameBuffer_SaveBuffer( gDP.colorImage.address, gDP.colorImage.size, gDP.colorImage.width, gDP.colorImage.height );
if (address != gDP.depthImageAddress)
FrameBuffer_RestoreBuffer( address, size, width );
//OGL_ClearDepthBuffer();
}
gDP.colorImage.changed = FALSE;
if (width == VI.width)
gDP.colorImage.height = VI.height;
else
gDP.colorImage.height = 1;
}
gDP.colorImage.format = format;
gDP.colorImage.size = size;
gDP.colorImage.width = width;
gDP.colorImage.address = RSP_SegmentToPhysical( address );
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetColorImage( %s, %s, %i, 0x%08X );\n",
ImageFormatText[gDP.colorImage.format],
ImageSizeText[gDP.colorImage.size],
gDP.colorImage.width,
gDP.colorImage.address );
#endif
}
void gDPSetTextureImage( u32 format, u32 size, u32 width, u32 address )
{
gDP.textureImage.format = format;
gDP.textureImage.size = size;
gDP.textureImage.width = width;
gDP.textureImage.address = RSP_SegmentToPhysical( address );
gDP.textureImage.bpl = gDP.textureImage.width << gDP.textureImage.size >> 1;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTextureImage( %s, %s, %i, 0x%08X );\n",
ImageFormatText[gDP.textureImage.format],
ImageSizeText[gDP.textureImage.size],
gDP.textureImage.width,
gDP.textureImage.address );
#endif
}
void gDPSetDepthImage( u32 address )
{
// if (address != gDP.depthImageAddress)
// OGL_ClearDepthBuffer();
DepthBuffer_SetBuffer( RSP_SegmentToPhysical( address ) );
if (depthBuffer.current->cleared)
OGL_ClearDepthBuffer();
gDP.depthImageAddress = RSP_SegmentToPhysical( address );
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetDepthImage( 0x%08X );\n", gDP.depthImageAddress );
#endif
}
void gDPSetEnvColor( u32 r, u32 g, u32 b, u32 a )
{
gDP.envColor.r = r * 0.0039215689f;
gDP.envColor.g = g * 0.0039215689f;
gDP.envColor.b = b * 0.0039215689f;
gDP.envColor.a = a * 0.0039215689f;
gDP.changed |= CHANGED_COMBINE_COLORS;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, "gDPSetEnvColor( %i, %i, %i, %i );\n",
r, g, b, a );
#endif
}
void gDPSetBlendColor( u32 r, u32 g, u32 b, u32 a )
{
gDP.blendColor.r = r * 0.0039215689f;
gDP.blendColor.g = g * 0.0039215689f;
gDP.blendColor.b = b * 0.0039215689f;
gDP.blendColor.a = a * 0.0039215689f;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetBlendColor( %i, %i, %i, %i );\n",
r, g, b, a );
#endif
}
void gDPSetFogColor( u32 r, u32 g, u32 b, u32 a )
{
gDP.fogColor.r = r * 0.0039215689f;
gDP.fogColor.g = g * 0.0039215689f;
gDP.fogColor.b = b * 0.0039215689f;
gDP.fogColor.a = a * 0.0039215689f;
gDP.changed |= CHANGED_FOGCOLOR;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetFogColor( %i, %i, %i, %i );\n",
r, g, b, a );
#endif
}
void gDPSetFillColor( u32 c )
{
gDP.fillColor.r = _SHIFTR( c, 11, 5 ) * 0.032258064f;
gDP.fillColor.g = _SHIFTR( c, 6, 5 ) * 0.032258064f;
gDP.fillColor.b = _SHIFTR( c, 1, 5 ) * 0.032258064f;
gDP.fillColor.a = _SHIFTR( c, 0, 1 );
gDP.fillColor.z = _SHIFTR( c, 2, 14 );
gDP.fillColor.dz = _SHIFTR( c, 0, 2 );
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetFillColor( 0x%08X );\n", c );
#endif
}
void gDPSetPrimColor( u32 m, u32 l, u32 r, u32 g, u32 b, u32 a )
{
gDP.primColor.m = m;
gDP.primColor.l = l * 0.0039215689f;
gDP.primColor.r = r * 0.0039215689f;
gDP.primColor.g = g * 0.0039215689f;
gDP.primColor.b = b * 0.0039215689f;
gDP.primColor.a = a * 0.0039215689f;
gDP.changed |= CHANGED_COMBINE_COLORS;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_COMBINE, "gDPSetPrimColor( %i, %i, %i, %i, %i, %i );\n",
m, l, r, g, b, a );
#endif
}
void gDPSetTile( u32 format, u32 size, u32 line, u32 tmem, u32 tile, u32 palette, u32 cmt, u32 cms, u32 maskt, u32 masks, u32 shiftt, u32 shifts )
{
if (((size == G_IM_SIZ_4b) || (size == G_IM_SIZ_8b)) && (format == G_IM_FMT_RGBA))
format = G_IM_FMT_CI;
gDP.tiles[tile].format = format;
gDP.tiles[tile].size = size;
gDP.tiles[tile].line = line;
gDP.tiles[tile].tmem = tmem;
gDP.tiles[tile].palette = palette;
gDP.tiles[tile].cmt = cmt;
gDP.tiles[tile].cms = cms;
gDP.tiles[tile].maskt = maskt;
gDP.tiles[tile].masks = masks;
gDP.tiles[tile].shiftt = shiftt;
gDP.tiles[tile].shifts = shifts;
if (!gDP.tiles[tile].masks) gDP.tiles[tile].clamps = 1;
if (!gDP.tiles[tile].maskt) gDP.tiles[tile].clampt = 1;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTile( %s, %s, %i, %i, %i, %i, %s%s, %s%s, %i, %i, %i, %i );\n",
ImageFormatText[format],
ImageSizeText[size],
line,
tmem,
tile,
palette,
cmt & G_TX_MIRROR ? "G_TX_MIRROR" : "G_TX_NOMIRROR",
cmt & G_TX_CLAMP ? " | G_TX_CLAMP" : "",
cms & G_TX_MIRROR ? "G_TX_MIRROR" : "G_TX_NOMIRROR",
cms & G_TX_CLAMP ? " | G_TX_CLAMP" : "",
maskt,
masks,
shiftt,
shifts );
#endif
}
void gDPSetTileSize( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt )
{
gDP.tiles[tile].uls = _SHIFTR( uls, 2, 10 );
gDP.tiles[tile].ult = _SHIFTR( ult, 2, 10 );
gDP.tiles[tile].lrs = _SHIFTR( lrs, 2, 10 );
gDP.tiles[tile].lrt = _SHIFTR( lrt, 2, 10 );
gDP.tiles[tile].fuls = _FIXED2FLOAT( uls, 2 );
gDP.tiles[tile].fult = _FIXED2FLOAT( ult, 2 );
gDP.tiles[tile].flrs = _FIXED2FLOAT( lrs, 2 );
gDP.tiles[tile].flrt = _FIXED2FLOAT( lrt, 2 );
gDP.changed |= CHANGED_TILE;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPSetTileSize( %i, %.2f, %.2f, %.2f, %.2f );\n",
tile,
gDP.tiles[tile].fuls,
gDP.tiles[tile].fult,
gDP.tiles[tile].flrs,
gDP.tiles[tile].flrt );
#endif
}
void gDPLoadTile( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt )
{
void (*Interleave)( void *mem, u32 numDWords );
u32 address, height, bpl, line, y;
u64 *dest;
u8 *src;
gDPSetTileSize( tile, uls, ult, lrs, lrt );
gDP.loadTile = &gDP.tiles[tile];
if (gDP.loadTile->line == 0)
return;
address = gDP.textureImage.address + gDP.loadTile->ult * gDP.textureImage.bpl + (gDP.loadTile->uls << gDP.textureImage.size >> 1);
dest = &TMEM[gDP.loadTile->tmem];
bpl = (gDP.loadTile->lrs - gDP.loadTile->uls + 1) << gDP.loadTile->size >> 1;
height = gDP.loadTile->lrt - gDP.loadTile->ult + 1;
src = &RDRAM[address];
if (((address + height * bpl) > RDRAMSize) ||
(((gDP.loadTile->tmem << 3) + bpl * height) > 4096)) // Stay within TMEM
{
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_TEXTURE, "// Attempting to load texture tile out of range\n" );
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadTile( %i, %i, %i, %i, %i );\n",
tile, gDP.loadTile->uls, gDP.loadTile->ult, gDP.loadTile->lrs, gDP.loadTile->lrt );
#endif
return;
}
if (OGL.frameBufferTextures)
{
FrameBuffer *buffer;
if (((buffer = FrameBuffer_FindBuffer( address )) != NULL) &&
((*(u32*)&RDRAM[buffer->startAddress] & 0xFFFEFFFE) == (buffer->startAddress & 0xFFFEFFFE)))
{
gDP.loadTile->frameBuffer = buffer;
gDP.textureMode = TEXTUREMODE_FRAMEBUFFER;
gDP.loadType = LOADTYPE_TILE;
gDP.changed |= CHANGED_TMEM;
return;
}
}
// Line given for 32-bit is half what it seems it should since they split the
// high and low words. I'm cheating by putting them together.
if (gDP.loadTile->size == G_IM_SIZ_32b)
{
line = gDP.loadTile->line << 1;
Interleave = QWordInterleave;
}
else
{
line = gDP.loadTile->line;
Interleave = DWordInterleave;
}
for (y = 0; y < height; y++)
{
UnswapCopy( src, dest, bpl );
if (y & 1) Interleave( dest, line );
src += gDP.textureImage.bpl;
dest += line;
}
gDP.textureMode = TEXTUREMODE_NORMAL;
gDP.loadType = LOADTYPE_TILE;
gDP.changed |= CHANGED_TMEM;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadTile( %i, %i, %i, %i, %i );\n",
tile, gDP.loadTile->uls, gDP.loadTile->ult, gDP.loadTile->lrs, gDP.loadTile->lrt );
#endif
}
void gDPLoadBlock( u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt )
{
gDPSetTileSize( tile, uls, ult, lrs, dxt );
gDP.loadTile = &gDP.tiles[tile];
u32 bytes = (lrs + 1) << gDP.loadTile->size >> 1;
u32 address = gDP.textureImage.address + ult * gDP.textureImage.bpl + (uls << gDP.textureImage.size >> 1);
if ((bytes == 0) ||
((address + bytes) > RDRAMSize) ||
(((gDP.loadTile->tmem << 3) + bytes) > 4096))
{
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_TEXTURE, "// Attempting to load texture block out of range\n" );
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadBlock( %i, %i, %i, %i, %i );\n",
tile, uls, ult, lrs, dxt );
#endif
// bytes = min( bytes, min( RDRAMSize - gDP.textureImage.address, 4096 - (gDP.loadTile->tmem << 3) ) );
return;
}
if (OGL.frameBufferTextures)
{
FrameBuffer *buffer;
if (((buffer = FrameBuffer_FindBuffer( address )) != NULL) &&
((*(u32*)&RDRAM[buffer->startAddress] & 0xFFFEFFFE) == (buffer->startAddress & 0xFFFEFFFE)))
{
gDP.loadTile->frameBuffer = buffer;
gDP.textureMode = TEXTUREMODE_FRAMEBUFFER;
gDP.loadType = LOADTYPE_BLOCK;
gDP.changed |= CHANGED_TMEM;
return;
}
}
u64* src = (u64*)&RDRAM[address];
u64* dest = &TMEM[gDP.loadTile->tmem];
if (dxt > 0)
{
void (*Interleave)( void *mem, u32 numDWords );
u32 line = (2047 + dxt) / dxt;
u32 bpl = line << 3;
u32 height = bytes / bpl;
if (gDP.loadTile->size == G_IM_SIZ_32b)
Interleave = QWordInterleave;
else
Interleave = DWordInterleave;
for (u32 y = 0; y < height; y++)
{
UnswapCopy( src, dest, bpl );
if (y & 1) Interleave( dest, line );
src += line;
dest += line;
}
}
else
UnswapCopy( src, dest, bytes );
gDP.textureMode = TEXTUREMODE_NORMAL;
gDP.loadType = LOADTYPE_BLOCK;
gDP.changed |= CHANGED_TMEM;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadBlock( %i, %i, %i, %i, %i );\n",
tile, uls, ult, lrs, dxt );
#endif
}
void gDPLoadTLUT( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt )
{
gDPSetTileSize( tile, uls, ult, lrs, lrt );
u16 count = (gDP.tiles[tile].lrs - gDP.tiles[tile].uls + 1) * (gDP.tiles[tile].lrt - gDP.tiles[tile].ult + 1);
u32 address = gDP.textureImage.address + gDP.tiles[tile].ult * gDP.textureImage.bpl + (gDP.tiles[tile].uls << gDP.textureImage.size >> 1);
u16 *dest = (u16*)&TMEM[gDP.tiles[tile].tmem];
u16 *src = (u16*)&RDRAM[address];
u16 pal = (gDP.tiles[tile].tmem - 256) >> 4;
int i = 0;
while (i < count)
{
for (u16 j = 0; (j < 16) && (i < count); j++, i++)
{
u16 color = swapword( src[i^1] );
*dest = color;
//dest[1] = color;
//dest[2] = color;
//dest[3] = color;
dest += 4;
}
gDP.paletteCRC16[pal] = CRC_CalculatePalette( 0xFFFFFFFF, &TMEM[256 + (pal << 4)], 16 );
pal++;
}
gDP.paletteCRC256 = CRC_Calculate( 0xFFFFFFFF, gDP.paletteCRC16, 64 );
gDP.changed |= CHANGED_TMEM;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED | DEBUG_TEXTURE, "gDPLoadTLUT( %i, %i, %i, %i, %i );\n",
tile, gDP.tiles[tile].uls, gDP.tiles[tile].ult, gDP.tiles[tile].lrs, gDP.tiles[tile].lrt );
#endif
}
void gDPSetScissor( u32 mode, f32 ulx, f32 uly, f32 lrx, f32 lry )
{
gDP.scissor.mode = mode;
gDP.scissor.ulx = ulx;
gDP.scissor.uly = uly;
gDP.scissor.lrx = lrx;
gDP.scissor.lry = lry;
gDP.changed |= CHANGED_SCISSOR;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPSetScissor( %s, %.2f, %.2f, %.2f, %.2f );\n",
ScissorModeText[gDP.scissor.mode],
gDP.scissor.ulx,
gDP.scissor.uly,
gDP.scissor.lrx,
gDP.scissor.lry );
#endif
}
void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry )
{
DepthBuffer *buffer = DepthBuffer_FindBuffer( gDP.colorImage.address );
if (buffer)
buffer->cleared = TRUE;
if (gDP.depthImageAddress == gDP.colorImage.address)
{
OGL_ClearDepthBuffer();
return;
}
if (gDP.otherMode.cycleType == G_CYC_FILL)
{
//if (gDP.fillColor.a == 0.0f)
// return;
lrx++;
lry++;
if ((ulx == 0) && (uly == 0) && (lrx == VI.width) && (lry == VI.height))
{
OGL_ClearColorBuffer( &gDP.fillColor.r );
return;
}
}
OGL_DrawRect( ulx, uly, lrx, lry, (gDP.otherMode.cycleType == G_CYC_FILL) ? &gDP.fillColor.r : &gDP.blendColor.r );
if (depthBuffer.current) depthBuffer.current->cleared = FALSE;
gDP.colorImage.changed = TRUE;
gDP.colorImage.height = max( gDP.colorImage.height, lry );
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPFillRectangle( %i, %i, %i, %i );\n",
ulx, uly, lrx, lry );
#endif
}
void gDPSetConvert( s32 k0, s32 k1, s32 k2, s32 k3, s32 k4, s32 k5 )
{
gDP.convert.k0 = k0;
gDP.convert.k1 = k1;
gDP.convert.k2 = k2;
gDP.convert.k3 = k3;
gDP.convert.k4 = k4;
gDP.convert.k5 = k5;
}
void gDPSetKeyR( u32 cR, u32 sR, u32 wR )
{
gDP.key.center.r = cR * 0.0039215689f;;
gDP.key.scale.r = sR * 0.0039215689f;;
gDP.key.width.r = wR * 0.0039215689f;;
}
void gDPSetKeyGB(u32 cG, u32 sG, u32 wG, u32 cB, u32 sB, u32 wB )
{
gDP.key.center.g = cG * 0.0039215689f;;
gDP.key.scale.g = sG * 0.0039215689f;;
gDP.key.width.g = wG * 0.0039215689f;;
gDP.key.center.b = cB * 0.0039215689f;;
gDP.key.scale.b = sB * 0.0039215689f;;
gDP.key.width.b = wB * 0.0039215689f;;
}
void gDPTextureRectangle( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy )
{
if (gDP.otherMode.cycleType == G_CYC_COPY)
{
dsdx = 1.0f;
lrx += 1.0f;
lry += 1.0f;
}
gSP.textureTile[0] = &gDP.tiles[tile];
gSP.textureTile[1] = &gDP.tiles[tile < 7 ? tile + 1 : tile];
f32 lrs = s + (lrx - ulx - 1) * dsdx;
f32 lrt = t + (lry - uly - 1) * dtdy;
if (gDP.textureMode == TEXTUREMODE_NORMAL)
gDP.textureMode = TEXTUREMODE_TEXRECT;
gDP.texRect.width = max( lrs, s ) + dsdx;
gDP.texRect.height = max( lrt, t ) + dtdy;
if (lrs > s)
{
if (lrt > t)
OGL_DrawTexturedRect( ulx, uly, lrx, lry, s, t, lrs, lrt, (RSP.cmd == G_TEXRECTFLIP) );
else
OGL_DrawTexturedRect( ulx, lry, lrx, uly, s, lrt, lrs, t, (RSP.cmd == G_TEXRECTFLIP) );
}
else
{
if (lrt > t)
OGL_DrawTexturedRect( lrx, uly, ulx, lry, lrs, t, s, lrt, (RSP.cmd == G_TEXRECTFLIP) );
else
OGL_DrawTexturedRect( lrx, lry, ulx, uly, lrs, lrt, s, t, (RSP.cmd == G_TEXRECTFLIP) );
}
gSP.textureTile[0] = &gDP.tiles[gSP.texture.tile];
gSP.textureTile[1] = &gDP.tiles[gSP.texture.tile < 7 ? gSP.texture.tile + 1 : gSP.texture.tile];
if (depthBuffer.current) depthBuffer.current->cleared = FALSE;
gDP.colorImage.changed = TRUE;
gDP.colorImage.height = max( gDP.colorImage.height, gDP.scissor.lry );
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPTextureRectangle( %f, %f, %f, %f, %i, %i, %f, %f, %f, %f );\n",
ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy );
#endif
}
void gDPTextureRectangleFlip( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy )
{
gDPTextureRectangle( ulx, uly, lrx, lry, tile, s + (lrx - ulx) * dsdx, t + (lry - uly) * dtdy, -dsdx, -dtdy );
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPTextureRectangleFlip( %f, %f, %f, %f, %i, %i, %f, %f, %f, %f );\n",
ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy );
#endif
}
void gDPFullSync()
{
*REG.MI_INTR |= MI_INTR_DP;
CheckInterrupts();
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPFullSync();\n" );
#endif
}
void gDPTileSync()
{
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_IGNORED | DEBUG_TEXTURE, "gDPTileSync();\n" );
#endif
}
void gDPPipeSync()
{
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPPipeSync();\n" );
#endif
}
void gDPLoadSync()
{
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPLoadSync();\n" );
#endif
}
void gDPNoOp()
{
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_IGNORED, "gDPNoOp();\n" );
#endif
}

281
gDP.h Normal file
View File

@ -0,0 +1,281 @@
#ifndef GDP_H
#define GDP_H
#include "Types.h"
#include "FrameBuffer.h"
#define CHANGED_RENDERMODE 0x001
#define CHANGED_CYCLETYPE 0x002
#define CHANGED_SCISSOR 0x004
#define CHANGED_TMEM 0x008
#define CHANGED_TILE 0x010
#define CHANGED_COMBINE_COLORS 0x020
#define CHANGED_COMBINE 0x040
#define CHANGED_ALPHACOMPARE 0x080
#define CHANGED_FOGCOLOR 0x100
#define TEXTUREMODE_NORMAL 0
#define TEXTUREMODE_TEXRECT 1
#define TEXTUREMODE_BGIMAGE 2
#define TEXTUREMODE_FRAMEBUFFER 3
#define LOADTYPE_BLOCK 0
#define LOADTYPE_TILE 1
struct gDPCombine
{
union
{
struct
{
// muxs1
unsigned aA1 : 3;
unsigned sbA1 : 3;
unsigned aRGB1 : 3;
unsigned aA0 : 3;
unsigned sbA0 : 3;
unsigned aRGB0 : 3;
unsigned mA1 : 3;
unsigned saA1 : 3;
unsigned sbRGB1 : 4;
unsigned sbRGB0 : 4;
// muxs0
unsigned mRGB1 : 5;
unsigned saRGB1 : 4;
unsigned mA0 : 3;
unsigned saA0 : 3;
unsigned mRGB0 : 5;
unsigned saRGB0 : 4;
};
struct
{
u32 muxs1, muxs0;
};
u64 mux;
};
};
struct gDPTile
{
u32 format, size, line, tmem, palette;
union
{
struct
{
unsigned mirrort : 1;
unsigned clampt : 1;
unsigned pad0 : 30;
unsigned mirrors : 1;
unsigned clamps : 1;
unsigned pad1 : 30;
};
struct
{
u32 cmt, cms;
};
};
FrameBuffer *frameBuffer;
u32 maskt, masks;
u32 shiftt, shifts;
f32 fuls, fult, flrs, flrt;
u32 uls, ult, lrs, lrt;
};
struct gDPInfo
{
struct
{
union
{
struct
{
unsigned int alphaCompare : 2;
unsigned int depthSource : 1;
// struct
// {
unsigned int AAEnable : 1;
unsigned int depthCompare : 1;
unsigned int depthUpdate : 1;
unsigned int imageRead : 1;
unsigned int clearOnCvg : 1;
unsigned int cvgDest : 2;
unsigned int depthMode : 2;
unsigned int cvgXAlpha : 1;
unsigned int alphaCvgSel : 1;
unsigned int forceBlender : 1;
unsigned int textureEdge : 1;
// } renderMode;
// struct
// {
unsigned int c2_m2b : 2;
unsigned int c1_m2b : 2;
unsigned int c2_m2a : 2;
unsigned int c1_m2a : 2;
unsigned int c2_m1b : 2;
unsigned int c1_m1b : 2;
unsigned int c2_m1a : 2;
unsigned int c1_m1a : 2;
// } blender;
unsigned int blendMask : 4;
unsigned int alphaDither : 2;
unsigned int colorDither : 2;
unsigned int combineKey : 1;
unsigned int textureConvert : 3;
unsigned int textureFilter : 2;
unsigned int textureLUT : 2;
unsigned int textureLOD : 1;
unsigned int textureDetail : 2;
unsigned int texturePersp : 1;
unsigned int cycleType : 2;
unsigned int unusedColorDither : 1; // unsupported
unsigned int pipelineMode : 1;
unsigned int pad : 8;
};
u64 _u64;
struct
{
u32 l, h;
};
};
} otherMode;
gDPCombine combine;
gDPTile tiles[8], *loadTile;
struct
{
f32 r, g, b, a;
} fogColor, blendColor, envColor;
struct
{
f32 r, g, b, a;
f32 z, dz;
} fillColor;
struct
{
u32 m;
f32 l, r, g, b, a;
} primColor;
struct
{
f32 z, deltaZ;
} primDepth;
struct
{
u32 format, size, width, bpl;
u32 address;
} textureImage;
struct
{
u32 format, size, width, height, bpl;
u32 address, changed;
u32 depthImage;
} colorImage;
u32 depthImageAddress;
struct
{
u32 mode;
f32 ulx, uly, lrx, lry;
} scissor;
struct
{
s32 k0, k1, k2, k3, k4, k5;
} convert;
struct
{
struct
{
f32 r, g, b, a;
} center, scale, width;
} key;
struct
{
u32 width, height;
} texRect;
u32 changed;
//u16 palette[256];
u32 paletteCRC16[16];
u32 paletteCRC256;
u32 half_1, half_2;
u32 textureMode;
u32 loadType;
};
extern gDPInfo gDP;
void gDPSetOtherMode( u32 mode0, u32 mode1 );
void gDPSetPrimDepth( u16 z, u16 dz );
void gDPPipelineMode( u32 mode );
void gDPSetCycleType( u32 type );
void gDPSetTexturePersp( u32 enable );
void gDPSetTextureDetail( u32 type );
void gDPSetTextureLOD( u32 mode );
void gDPSetTextureLUT( u32 mode );
void gDPSetTextureFilter( u32 type );
void gDPSetTextureConvert( u32 type );
void gDPSetCombineKey( u32 type );
void gDPSetColorDither( u32 type );
void gDPSetAlphaDither( u32 type );
void gDPSetAlphaCompare( u32 mode );
void gDPSetDepthSource( u32 source );
void gDPSetRenderMode( u32 mode1, u32 mode2 );
void gDPSetCombine( s32 muxs0, s32 muxs1 );
void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address );
void gDPSetTextureImage( u32 format, u32 size, u32 width, u32 address );
void gDPSetDepthImage( u32 address );
void gDPSetEnvColor( u32 r, u32 g, u32 b, u32 a );
void gDPSetBlendColor( u32 r, u32 g, u32 b, u32 a );
void gDPSetFogColor( u32 r, u32 g, u32 b, u32 a );
void gDPSetFillColor( u32 c );
void gDPSetPrimColor( u32 m, u32 l, u32 r, u32 g, u32 b, u32 a );
void gDPSetTile( u32 format, u32 size, u32 line, u32 tmem, u32 tile, u32 palette, u32 cmt, u32 cms, u32 maskt, u32 masks, u32 shiftt, u32 shifts );
void gDPSetTileSize( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt );
void gDPLoadTile( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt );
void gDPLoadBlock( u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt );
void gDPLoadTLUT( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt );
void gDPSetScissor( u32 mode, f32 ulx, f32 uly, f32 lrx, f32 lry );
void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry );
void gDPSetConvert( s32 k0, s32 k1, s32 k2, s32 k3, s32 k4, s32 k5 );
void gDPSetKeyR( u32 cR, u32 sR, u32 wR );
void gDPSetKeyGB(u32 cG, u32 sG, u32 wG, u32 cB, u32 sB, u32 wB );
void gDPTextureRectangle( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy );
void gDPTextureRectangleFlip( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32 s, f32 t, f32 dsdx, f32 dtdy );
void gDPFullSync();
void gDPTileSync();
void gDPPipeSync();
void gDPLoadSync();
void gDPNoOp();
#endif

1672
gSP.cpp Normal file

File diff suppressed because it is too large Load Diff

153
gSP.h Normal file
View File

@ -0,0 +1,153 @@
#ifndef GSP_H
#define GSP_H
#include "Types.h"
#include "GBI.h"
#include "gDP.h"
#define CHANGED_VIEWPORT 0x01
#define CHANGED_MATRIX 0x02
#define CHANGED_COLORBUFFER 0x04
#define CHANGED_GEOMETRYMODE 0x08
#define CHANGED_TEXTURE 0x10
#define CHANGED_FOGPOSITION 0x10
struct SPVertex
{
f32 x, y, z, w;
f32 nx, ny, nz;
f32 r, g, b, a;
f32 s, t;
f32 xClip, yClip, zClip;
s16 flag;
};
typedef SPVertex SPTriangle[3];
struct gSPInfo
{
u32 segment[16];
struct
{
u32 modelViewi, stackSize, billboard;
f32 modelView[32][4][4];
f32 projection[4][4];
f32 combined[4][4];
} matrix;
struct
{
f32 A, B, C, D;
f32 X, Y;
f32 baseScaleX, baseScaleY;
} objMatrix;
SPVertex vertices[80];
u32 vertexColorBase;
u32 vertexi;
struct
{
f32 r, g, b;
f32 x, y, z;
} lights[8];
struct
{
f32 scales, scalet;
s32 level, on, tile;
} texture;
gDPTile *textureTile[2];
struct
{
f32 vscale[4];
f32 vtrans[4];
f32 x, y, width, height;
f32 nearz, farz;
} viewport;
struct
{
s16 multiplier, offset;
} fog;
struct
{
u32 address, width, height, format, size, palette;
} bgImage;
u32 geometryMode;
s32 numLights;
u32 changed;
u32 status[4];
struct
{
u32 vtx, mtx;
} DMAOffsets;
};
extern gSPInfo gSP;
void gSPLoadUcodeEx( u32 uc_start, u32 uc_dstart, u16 uc_dsize );
void gSPNoOp();
void gSPMatrix( u32 matrix, u8 param );
void gSPDMAMatrix( u32 matrix, u8 index, u8 multiply );
void gSPViewport( u32 v );
void gSPForceMatrix( u32 mptr );
void gSPLight( u32 l, s32 n );
void gSPLookAt( u32 l );
void gSPVertex( u32 v, u32 n, u32 v0 );
void gSPCIVertex( u32 v, u32 n, u32 v0 );
void gSPDMAVertex( u32 v, u32 n, u32 v0 );
void gSPDisplayList( u32 dl );
void gSPDMADisplayList( u32 dl, u32 n );
void gSPBranchList( u32 dl );
void gSPBranchLessZ( u32 branchdl, u32 vtx, f32 zval );
void gSPSprite2DBase( u32 base );
void gSP1Triangle( s32 v0, s32 v1, s32 v2, s32 flag );
void gSP2Triangles( s32 v00, s32 v01, s32 v02, s32 flag0,
s32 v10, s32 v11, s32 v12, s32 flag1 );
void gSP4Triangles( s32 v00, s32 v01, s32 v02,
s32 v10, s32 v11, s32 v12,
s32 v20, s32 v21, s32 v22,
s32 v30, s32 v31, s32 v32 );
void gSPDMATriangles( u32 tris, u32 n );
void gSP1Quadrangle( s32 v0, s32 v1, s32 v2, s32 v4 );
void gSPCullDisplayList( u32 v0, u32 vn );
void gSPPopMatrix( u32 param );
void gSPPopMatrixN( u32 param, u32 num );
void gSPSegment( s32 seg, s32 base );
void gSPClipRatio( u32 r );
void gSPInsertMatrix( u32 where, u32 num );
void gSPModifyVertex( u32 vtx, u32 where, u32 val );
void gSPNumLights( s32 n );
void gSPLightColor( u32 lightNum, u32 packedColor );
void gSPFogFactor( s16 fm, s16 fo );
void gSPPerspNormalize( u16 scale );
void gSPTexture( f32 sc, f32 tc, s32 level, s32 tile, s32 on );
void gSPEndDisplayList();
void gSPGeometryMode( u32 clear, u32 set );
void gSPSetGeometryMode( u32 mode );
void gSPClearGeometryMode( u32 mode );
void gSPLine3D( s32 v0, s32 v1, s32 flag );
void gSPLineW3D( s32 v0, s32 v1, s32 wd, s32 flag );
void gSPObjRectangle( u32 sp );
void gSPObjSprite( u32 sp );
void gSPObjLoadTxtr( u32 tx );
void gSPObjLoadTxSprite( u32 txsp );
void gSPObjLoadTxRectR( u32 txsp );
void gSPBgRect1Cyc( u32 bg );
void gSPBgRectCopy( u32 bg );
void gSPObjMatrix( u32 mtx );
void gSPObjSubMatrix( u32 mtx );
void gSPSetDMAOffsets( u32 mtxoffset, u32 vtxoffset );
void gSPSetVertexColorBase( u32 base );
#endif

2497
glATI.h Normal file

File diff suppressed because it is too large Load Diff

406
glN64.cpp Normal file
View File

@ -0,0 +1,406 @@
#ifndef __LINUX__
# include <windows.h>
# include <commctrl.h>
# include <process.h>
#else
# include "winlnxdefs.h"
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#include "glN64.h"
#include "Debug.h"
#include "Zilmar GFX 1.3.h"
#include "OpenGL.h"
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "VI.h"
#include "Config.h"
#include "Textures.h"
#include "Combiner.h"
#ifndef __LINUX__
HWND hWnd;
HWND hStatusBar;
//HWND hFullscreen;
HWND hToolBar;
HINSTANCE hInstance;
#endif // !__LINUX__
char pluginName[] = "glN64 v0.4.1-rc2";
char *screenDirectory;
void (*CheckInterrupts)( void );
#ifndef __LINUX__
LONG windowedStyle;
LONG windowedExStyle;
RECT windowedRect;
HMENU windowedMenu;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
hInstance = hinstDLL;
if (dwReason == DLL_PROCESS_ATTACH)
{
Config_LoadConfig();
#ifdef RSPTHREAD
RSP.thread = NULL;
#endif
OGL.hRC = NULL;
OGL.hDC = NULL;
/* OGL.hPbufferRC = NULL;
OGL.hPbufferDC = NULL;
OGL.hPbuffer = NULL;*/
// hFullscreen = NULL;
}
return TRUE;
}
#else
void
_init( void )
{
Config_LoadConfig();
OGL.hScreen = NULL;
# ifdef RSPTHREAD
RSP.thread = NULL;
# endif
}
#endif // !__LINUX__
EXPORT void CALL CaptureScreen ( char * Directory )
{
screenDirectory = Directory;
#ifdef RSPTHREAD
if (RSP.thread)
{
SetEvent( RSP.threadMsg[RSPMSG_CAPTURESCREEN] );
WaitForSingleObject( RSP.threadFinished, INFINITE );
}
#else
OGL_SaveScreenshot();
#endif
}
EXPORT void CALL ChangeWindow (void)
{
#ifdef RSPTHREAD
// Textures seem to get corrupted when changing video modes (at least on my Radeon), so destroy them
SetEvent( RSP.threadMsg[RSPMSG_DESTROYTEXTURES] );
WaitForSingleObject( RSP.threadFinished, INFINITE );
if (!OGL.fullscreen)
{
DEVMODE fullscreenMode;
memset( &fullscreenMode, 0, sizeof(DEVMODE) );
fullscreenMode.dmSize = sizeof(DEVMODE);
fullscreenMode.dmPelsWidth = OGL.fullscreenWidth;
fullscreenMode.dmPelsHeight = OGL.fullscreenHeight;
fullscreenMode.dmBitsPerPel = OGL.fullscreenBits;
fullscreenMode.dmDisplayFrequency = OGL.fullscreenRefresh;
fullscreenMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
if (ChangeDisplaySettings( &fullscreenMode, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL)
{
MessageBox( NULL, "Failed to change display mode", pluginName, MB_ICONERROR | MB_OK );
return;
}
ShowCursor( FALSE );
windowedMenu = GetMenu( hWnd );
if (windowedMenu)
SetMenu( hWnd, NULL );
if (hStatusBar)
ShowWindow( hStatusBar, SW_HIDE );
windowedExStyle = GetWindowLong( hWnd, GWL_EXSTYLE );
windowedStyle = GetWindowLong( hWnd, GWL_STYLE );
SetWindowLong( hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST );
SetWindowLong( hWnd, GWL_STYLE, WS_POPUP );
GetWindowRect( hWnd, &windowedRect );
OGL.fullscreen = TRUE;
OGL_ResizeWindow();
}
else
{
ChangeDisplaySettings( NULL, 0 );
ShowCursor( TRUE );
if (windowedMenu)
SetMenu( hWnd, windowedMenu );
if (hStatusBar)
ShowWindow( hStatusBar, SW_SHOW );
SetWindowLong( hWnd, GWL_STYLE, windowedStyle );
SetWindowLong( hWnd, GWL_EXSTYLE, windowedExStyle );
SetWindowPos( hWnd, NULL, windowedRect.left, windowedRect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE );
OGL.fullscreen = FALSE;
OGL_ResizeWindow();
}
SetEvent( RSP.threadMsg[RSPMSG_INITTEXTURES] );
WaitForSingleObject( RSP.threadFinished, INFINITE );
#else // RSPTHREAD
# ifdef __LINUX__
SDL_WM_ToggleFullScreen( OGL.hScreen );
# endif // __LINUX__
#endif // !RSPTHREAD
}
EXPORT void CALL CloseDLL (void)
{
}
EXPORT void CALL DllAbout ( HWND hParent )
{
#ifndef __LINUX__
MessageBox( hParent, "glN64 v0.4 by Orkin\n\nWebsite: http://gln64.emulation64.com/\n\nThanks to Clements, Rice, Gonetz, Malcolm, Dave2001, cryhlove, icepir8, zilmar, Azimer, and StrmnNrmn", pluginName, MB_OK | MB_ICONINFORMATION );
#else
puts( "glN64 v0.4 by Orkin\nWebsite: http://gln64.emulation64.com/\n\nThanks to Clements, Rice, Gonetz, Malcolm, Dave2001, cryhlove, icepir8, zilmar, Azimer, and StrmnNrmn\nported by blight" );
#endif
}
EXPORT void CALL DllConfig ( HWND hParent )
{
Config_DoConfig();
}
EXPORT void CALL DllTest ( HWND hParent )
{
}
EXPORT void CALL DrawScreen (void)
{
}
EXPORT void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo )
{
PluginInfo->Version = 0x103;
PluginInfo->Type = PLUGIN_TYPE_GFX;
strcpy( PluginInfo->Name, pluginName );
PluginInfo->NormalMemory = FALSE;
PluginInfo->MemoryBswaped = TRUE;
}
#ifndef __LINUX__
BOOL CALLBACK FindToolBarProc( HWND hWnd, LPARAM lParam )
{
if (GetWindowLong( hWnd, GWL_STYLE ) & RBS_VARHEIGHT)
{
hToolBar = hWnd;
return FALSE;
}
return TRUE;
}
#endif // !__LINUX__
EXPORT BOOL CALL InitiateGFX (GFX_INFO Gfx_Info)
{
#ifndef __LINUX__
hWnd = Gfx_Info.hWnd;
hStatusBar = Gfx_Info.hStatusBar;
hToolBar = NULL;
EnumChildWindows( hWnd, FindToolBarProc,0 );
#else // !__LINUX__
Config_LoadConfig();
OGL.hScreen = NULL;
# ifdef RSPTHREAD
RSP.thread = NULL;
# endif
#endif // __LINUX__
DMEM = Gfx_Info.DMEM;
IMEM = Gfx_Info.IMEM;
RDRAM = Gfx_Info.RDRAM;
REG.MI_INTR = Gfx_Info.MI_INTR_REG;
REG.DPC_START = Gfx_Info.DPC_START_REG;
REG.DPC_END = Gfx_Info.DPC_END_REG;
REG.DPC_CURRENT = Gfx_Info.DPC_CURRENT_REG;
REG.DPC_STATUS = Gfx_Info.DPC_STATUS_REG;
REG.DPC_CLOCK = Gfx_Info.DPC_CLOCK_REG;
REG.DPC_BUFBUSY = Gfx_Info.DPC_BUFBUSY_REG;
REG.DPC_PIPEBUSY = Gfx_Info.DPC_PIPEBUSY_REG;
REG.DPC_TMEM = Gfx_Info.DPC_TMEM_REG;
REG.VI_STATUS = Gfx_Info.VI_STATUS_REG;
REG.VI_ORIGIN = Gfx_Info.VI_ORIGIN_REG;
REG.VI_WIDTH = Gfx_Info.VI_WIDTH_REG;
REG.VI_INTR = Gfx_Info.VI_INTR_REG;
REG.VI_V_CURRENT_LINE = Gfx_Info.VI_V_CURRENT_LINE_REG;
REG.VI_TIMING = Gfx_Info.VI_TIMING_REG;
REG.VI_V_SYNC = Gfx_Info.VI_V_SYNC_REG;
REG.VI_H_SYNC = Gfx_Info.VI_H_SYNC_REG;
REG.VI_LEAP = Gfx_Info.VI_LEAP_REG;
REG.VI_H_START = Gfx_Info.VI_H_START_REG;
REG.VI_V_START = Gfx_Info.VI_V_START_REG;
REG.VI_V_BURST = Gfx_Info.VI_V_BURST_REG;
REG.VI_X_SCALE = Gfx_Info.VI_X_SCALE_REG;
REG.VI_Y_SCALE = Gfx_Info.VI_Y_SCALE_REG;
CheckInterrupts = Gfx_Info.CheckInterrupts;
return TRUE;
}
EXPORT void CALL MoveScreen (int xpos, int ypos)
{
}
EXPORT void CALL ProcessDList(void)
{
#ifdef RSPTHREAD
if (RSP.thread)
{
SetEvent( RSP.threadMsg[RSPMSG_PROCESSDLIST] );
WaitForSingleObject( RSP.threadFinished, INFINITE );
}
#else
RSP_ProcessDList();
#endif
}
EXPORT void CALL ProcessRDPList(void)
{
//*REG.DPC_CURRENT = *REG.DPC_START;
/* RSP.PCi = 0;
RSP.PC[RSP.PCi] = *REG.DPC_CURRENT;
RSP.halt = FALSE;
while (RSP.PC[RSP.PCi] < *REG.DPC_END)
{
RSP.cmd0 = *(DWORD*)&RDRAM[RSP.PC[RSP.PCi]];
RSP.cmd1 = *(DWORD*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
/* if ((RSP.cmd0 >> 24) == 0xE9)
{
*REG.MI_INTR |= MI_INTR_DP;
CheckInterrupts();
}
if ((RSP.cmd0 >> 24) == 0xCD)
RSP.cmd0 = RSP.cmd0;
GFXOp[RSP.cmd0 >> 24]();*/
//*REG.DPC_CURRENT += 8;
// }
}
EXPORT void CALL RomClosed (void)
{
#ifdef RSPTHREAD
int i;
if (RSP.thread)
{
// if (OGL.fullscreen)
// ChangeWindow();
if (RSP.busy)
{
RSP.halt = TRUE;
WaitForSingleObject( RSP.threadFinished, INFINITE );
}
SetEvent( RSP.threadMsg[RSPMSG_CLOSE] );
WaitForSingleObject( RSP.threadFinished, INFINITE );
for (i = 0; i < 4; i++)
if (RSP.threadMsg[i])
CloseHandle( RSP.threadMsg[i] );
CloseHandle( RSP.threadFinished );
CloseHandle( RSP.thread );
}
RSP.thread = NULL;
#else
OGL_Stop();
#endif
#ifdef DEBUG
CloseDebugDlg();
#endif
}
EXPORT void CALL RomOpen (void)
{
#ifdef RSPTHREAD
# ifndef __LINUX__
DWORD threadID;
int i;
// Create RSP message events
for (i = 0; i < 6; i++)
{
RSP.threadMsg[i] = CreateEvent( NULL, FALSE, FALSE, NULL );
if (RSP.threadMsg[i] == NULL)
{
MessageBox( hWnd, "Error creating video thread message events, closing video thread...", "glN64 Error", MB_OK | MB_ICONERROR );
return;
}
}
// Create RSP finished event
RSP.threadFinished = CreateEvent( NULL, FALSE, FALSE, NULL );
if (RSP.threadFinished == NULL)
{
MessageBox( hWnd, "Error creating video thread finished event, closing video thread...", "glN64 Error", MB_OK | MB_ICONERROR );
return;
}
RSP.thread = CreateThread( NULL, 4096, RSP_ThreadProc, NULL, NULL, &threadID );
WaitForSingleObject( RSP.threadFinished, INFINITE );
# else // !__LINUX__
# endif // __LINUX__
#else
RSP_Init();
#endif
OGL_ResizeWindow();
#ifdef DEBUG
OpenDebugDlg();
#endif
}
EXPORT void CALL ShowCFB (void)
{
}
EXPORT void CALL UpdateScreen (void)
{
#ifdef RSPTHREAD
if (RSP.thread)
{
SetEvent( RSP.threadMsg[RSPMSG_UPDATESCREEN] );
WaitForSingleObject( RSP.threadFinished, INFINITE );
}
#else
VI_UpdateScreen();
#endif
}
EXPORT void CALL ViStatusChanged (void)
{
}
EXPORT void CALL ViWidthChanged (void)
{
}
EXPORT void CALL ReadScreen (void **dest, long *width, long *height)
{
OGL_ReadScreen( dest, width, height );
}

28
glN64.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef GLN64_H
#define GLN64_H
#ifndef __LINUX__
#include <windows.h>
//#include <commctrl.h>
#else
# include "winlnxdefs.h"
#endif
//#define DEBUG
//#define RSPTHREAD
#ifndef __LINUX__
extern HWND hWnd;
//extern HWND hFullscreen;
extern HWND hStatusBar;
extern HWND hToolBar;
extern HINSTANCE hInstance;
#endif // !__LINUX__
extern char pluginName[];
extern void (*CheckInterrupts)( void );
extern char *screenDirectory;
#endif

22
glN64.sln Normal file
View File

@ -0,0 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glN64", "glN64.vcproj", "{37D31D7F-C4E7-45B0-AEF6-D6824A243CF7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug 1964|Win32 = Debug 1964|Win32
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{37D31D7F-C4E7-45B0-AEF6-D6824A243CF7}.Debug 1964|Win32.ActiveCfg = Debug 1964|Win32
{37D31D7F-C4E7-45B0-AEF6-D6824A243CF7}.Debug 1964|Win32.Build.0 = Debug 1964|Win32
{37D31D7F-C4E7-45B0-AEF6-D6824A243CF7}.Debug|Win32.ActiveCfg = Debug|Win32
{37D31D7F-C4E7-45B0-AEF6-D6824A243CF7}.Debug|Win32.Build.0 = Debug|Win32
{37D31D7F-C4E7-45B0-AEF6-D6824A243CF7}.Release|Win32.ActiveCfg = Release|Win32
{37D31D7F-C4E7-45B0-AEF6-D6824A243CF7}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

585
glN64.vcproj Normal file
View File

@ -0,0 +1,585 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="glN64"
ProjectGUID="{37D31D7F-C4E7-45B0-AEF6-D6824A243CF7}"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;NEWGLNINTENDO64_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="glN64.h"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib winmm.lib"
OutputFile="c:\game files\emulators\nintendo 64\plugin\glN64.dll"
LinkIncremental="2"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/New glNintendo64().pdb"
SubSystem="2"
ImportLibrary="$(OutDir)/New glNintendo64().lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;NEWGLNINTENDO64_EXPORTS"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib winmm.lib"
OutputFile="c:/game files/emulators/nintendo 64/plugin/glN64.dll"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(OutDir)/New glNintendo64().lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug 1964|Win32"
OutputDirectory="Debug 1964"
IntermediateDirectory="Debug 1964"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;NEWGLNINTENDO64_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib winmm.lib"
OutputFile="c:\game files\emulators\nintendo 64\plugin\glN64.dll"
LinkIncremental="2"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/New glNintendo64().pdb"
SubSystem="2"
ImportLibrary="$(OutDir)/New glNintendo64().lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="2xSAI.cpp"
>
</File>
<File
RelativePath="Combiner.cpp"
>
</File>
<File
RelativePath="Config.cpp"
>
</File>
<File
RelativePath="CRC.cpp"
>
</File>
<File
RelativePath="Debug.cpp"
>
</File>
<File
RelativePath="DepthBuffer.cpp"
>
</File>
<File
RelativePath="FrameBuffer.cpp"
>
</File>
<File
RelativePath="GBI.cpp"
>
</File>
<File
RelativePath="gDP.cpp"
>
</File>
<File
RelativePath="glN64.cpp"
>
</File>
<File
RelativePath="gSP.cpp"
>
</File>
<File
RelativePath="N64.cpp"
>
</File>
<File
RelativePath="OpenGL.cpp"
>
</File>
<File
RelativePath="RDP.CPP"
>
</File>
<File
RelativePath="RSP.cpp"
>
</File>
<File
RelativePath="Textures.cpp"
>
</File>
<File
RelativePath="VI.cpp"
>
</File>
<Filter
Name="uCodes"
>
<File
RelativePath="F3D.cpp"
>
</File>
<File
RelativePath="F3DDKR.cpp"
>
</File>
<File
RelativePath="F3DEX.cpp"
>
</File>
<File
RelativePath="F3DEX2.cpp"
>
</File>
<File
RelativePath="F3DPD.cpp"
>
</File>
<File
RelativePath="F3DWRUS.cpp"
>
</File>
<File
RelativePath="L3D.cpp"
>
</File>
<File
RelativePath="L3DEX.cpp"
>
</File>
<File
RelativePath="L3DEX2.cpp"
>
</File>
<File
RelativePath="S2DEX.cpp"
>
</File>
<File
RelativePath="S2DEX2.cpp"
>
</File>
</Filter>
<Filter
Name="Combiners"
>
<File
RelativePath="NV_register_combiners.cpp"
>
</File>
<File
RelativePath="texture_env.cpp"
>
</File>
<File
RelativePath="texture_env_combine.cpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="2xSAI.h"
>
</File>
<File
RelativePath="3DMath.h"
>
</File>
<File
RelativePath="Combiner.h"
>
</File>
<File
RelativePath="Config.h"
>
</File>
<File
RelativePath="convert.h"
>
</File>
<File
RelativePath="CRC.h"
>
</File>
<File
RelativePath="Debug.h"
>
</File>
<File
RelativePath="DepthBuffer.h"
>
</File>
<File
RelativePath="FrameBuffer.h"
>
</File>
<File
RelativePath="GBI.h"
>
</File>
<File
RelativePath="gDP.h"
>
</File>
<File
RelativePath="glATI.h"
>
</File>
<File
RelativePath="glext.h"
>
</File>
<File
RelativePath="glN64.h"
>
</File>
<File
RelativePath="gSP.h"
>
</File>
<File
RelativePath="N64.h"
>
</File>
<File
RelativePath="OpenGL.h"
>
</File>
<File
RelativePath="RDP.h"
>
</File>
<File
RelativePath="resource.h"
>
</File>
<File
RelativePath="RSP.h"
>
</File>
<File
RelativePath="Textures.h"
>
</File>
<File
RelativePath="Types.h"
>
</File>
<File
RelativePath="VI.h"
>
</File>
<File
RelativePath="wglext.h"
>
</File>
<File
RelativePath="Zilmar GFX 1.3.h"
>
</File>
<Filter
Name="uCodes"
>
<File
RelativePath="F3D.h"
>
</File>
<File
RelativePath="F3DDKR.h"
>
</File>
<File
RelativePath="F3DEX.h"
>
</File>
<File
RelativePath="F3DEX2.h"
>
</File>
<File
RelativePath="F3DPD.h"
>
</File>
<File
RelativePath="F3DWRUS.h"
>
</File>
<File
RelativePath="L3D.h"
>
</File>
<File
RelativePath="L3DEX.h"
>
</File>
<File
RelativePath="L3DEX2.h"
>
</File>
<File
RelativePath="S2DEX.h"
>
</File>
<File
RelativePath="S2DEX2.h"
>
</File>
</Filter>
<Filter
Name="Combiners"
>
<File
RelativePath="NV_register_combiners.h"
>
</File>
<File
RelativePath="texture_env.h"
>
</File>
<File
RelativePath="texture_env_combine.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
<File
RelativePath="Resource.rc"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

13142
glext.h Normal file

File diff suppressed because it is too large Load Diff

72
resource.h Normal file
View File

@ -0,0 +1,72 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Resource.rc
//
#define IDD_DEBUGDLG 101
#define IDD_CONFIGDLG 102
#define IDD_MICROCODEDLG 107
#define IDC_DUMP 1002
#define IDC_DEBUGEDIT 1032
#define IDC_UCODE 1036
#define IDC_MICROCODE 1036
#define IDC_FORCEUCODE 1037
#define IDC_BUTTON3 1040
#define IDC_APPLY 1040
#define IDC_VERIFYCACHE 1040
#define IDC_RUN 1040
#define IDC_PURPLECOMBINE 1043
#define IDC_PURPLECOMBINERS 1043
#define IDC_CACHEMEGS 1044
#define IDC_FORCEBILINEAR 1048
#define IDC_WINDOWEDRES 1049
#define IDC_FULLSCREENMODE 1050
#define IDC_FULLSCREENRES 1050
#define IDC_FULLSCREENREFRESH 1052
#define IDC_WIREFRAME 1053
#define IDC_FULLSCREENBITDEPTH 1054
#define IDC_ALPHATESTSHARPNESS 1055
#define IDC_ENABLE2XSAI 1061
#define IDC_COMBO1 1064
#define IDC_COMBINER 1064
#define IDC_TEXTUREBPP 1064
#define IDC_FOG 1066
#define IDC_CHECK1 1067
#define IDC_FRAMEBUFFER 1067
#define IDC_SHOWTEXTURE 1067
#define IDC_DEBUGHIGH 1069
#define IDC_DEBUGMEDIUM 1070
#define IDC_DEBUGLOW 1071
#define IDC_SHOWUNHANDLED 1072
#define IDC_SHOWERRORS 1073
#define IDC_SHOWUNKNOWN 1074
#define IDC_SHOWHANDLED 1076
#define IDC_BUTTON1 1077
#define IDC_PAUSE 1077
#define IDC_BUTTON2 1078
#define IDC_STEP 1078
#define IDC_RICHEDIT21 1079
#define IDC_PC 1081
#define IDC_PCI 1082
#define IDC_W1 1083
#define IDC_W0 1084
#define IDC_CMD 1085
#define IDC_SHOWMATRIX 1087
#define IDC_SHOWVERTEX 1088
#define IDC_SHOWTRIANGLE 1089
#define IDC_SHOWCOMBINE 1090
#define IDC_SHOWIGNORED 1091
#define IDC_DEBUGDETAIL 1092
#define IDC_TEXTBOX 1097
#define IDC_CHECK2 1098
#define IDC_DITHEREDALPHATEST 1098
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1099
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

183
texture_env.cpp Normal file
View File

@ -0,0 +1,183 @@
#ifndef __LINUX__
# include <windows.h>
#else
# include "winlnxdefs.h"
#endif
#include "OpenGL.h"
#include "Combiner.h"
#include "texture_env.h"
void Init_texture_env()
{
}
void Uninit_texture_env()
{
}
void Update_texture_env_Colors( TexEnv *texEnv )
{
}
TexEnv *Compile_texture_env( Combiner *color, Combiner *alpha )
{
TexEnv *texEnv = (TexEnv*)malloc( sizeof( TexEnv ) );
texEnv->usesT0 = FALSE;
texEnv->usesT1 = FALSE;
texEnv->fragment.color = texEnv->fragment.alpha = COMBINED;
for (int i = 0; i < alpha->numStages; i++)
{
for (int j = 0; j < alpha->stage[i].numOps; j++)
{
switch (alpha->stage[i].op[j].op)
{
case LOAD:
if ((alpha->stage[i].op[j].param1 != TEXEL0_ALPHA) && (alpha->stage[i].op[j].param1 != TEXEL1_ALPHA))
{
texEnv->fragment.alpha = alpha->stage[i].op[j].param1;
texEnv->usesT0 = FALSE;
texEnv->usesT1 = FALSE;
}
else
{
texEnv->mode = GL_REPLACE;
texEnv->usesT0 = alpha->stage[i].op[j].param1 == TEXEL0_ALPHA;
texEnv->usesT1 = alpha->stage[i].op[j].param1 == TEXEL1_ALPHA;
}
break;
case SUB:
break;
case MUL:
if (((alpha->stage[i].op[j].param1 == TEXEL0_ALPHA) || (alpha->stage[i].op[j].param1 == TEXEL1_ALPHA)) &&
((alpha->stage[i].op[j - 1].param1 != TEXEL0_ALPHA) || (alpha->stage[i].op[j - 1].param1 != TEXEL1_ALPHA)))
{
texEnv->mode = GL_MODULATE;
}
else if (((alpha->stage[i].op[j].param1 != TEXEL0_ALPHA) || (alpha->stage[i].op[j].param1 != TEXEL1_ALPHA)) &&
((alpha->stage[i].op[j - 1].param1 == TEXEL0_ALPHA) || (alpha->stage[i].op[j - 1].param1 == TEXEL1_ALPHA)))
{
texEnv->fragment.alpha = alpha->stage[i].op[j].param1;
texEnv->mode = GL_MODULATE;
}
break;
case ADD:
break;
case INTER:
break;
}
}
}
for (int i = 0; i < color->numStages; i++)
{
for (int j = 0; j < color->stage[i].numOps; j++)
{
switch (color->stage[i].op[j].op)
{
case LOAD:
if ((color->stage[i].op[j].param1 == TEXEL0) || (color->stage[i].op[j].param1 == TEXEL0_ALPHA))
{
if (texEnv->mode == GL_MODULATE)
texEnv->fragment.color = ONE;
texEnv->usesT0 = TRUE;
texEnv->usesT1 = FALSE;
}
else if ((color->stage[i].op[j].param1 == TEXEL1) || (color->stage[i].op[j].param1 == TEXEL1_ALPHA))
{
if (texEnv->mode == GL_MODULATE)
texEnv->fragment.color = ONE;
texEnv->usesT0 = FALSE;
texEnv->usesT1 = TRUE;
}
else
{
texEnv->fragment.color = color->stage[i].op[j].param1;
texEnv->usesT0 = texEnv->usesT1 = FALSE;
}
break;
case SUB:
break;
case MUL:
if ((color->stage[i].op[j].param1 == TEXEL0) || (color->stage[i].op[j].param1 == TEXEL0_ALPHA))
{
if (!texEnv->usesT0 && !texEnv->usesT1)
{
texEnv->mode = GL_MODULATE;
texEnv->usesT0 = TRUE;
texEnv->usesT1 = FALSE;
}
}
else if ((color->stage[i].op[j].param1 == TEXEL1) || (color->stage[i].op[j].param1 == TEXEL1_ALPHA))
{
if (!texEnv->usesT0 && !texEnv->usesT1)
{
texEnv->mode = GL_MODULATE;
texEnv->usesT0 = FALSE;
texEnv->usesT1 = TRUE;
}
}
else if (texEnv->usesT0 || texEnv->usesT1)
{
texEnv->mode = GL_MODULATE;
texEnv->fragment.color = color->stage[i].op[j].param1;
}
break;
case ADD:
break;
case INTER:
if ((color->stage[i].op[j].param1 == TEXEL0) &&
((color->stage[i].op[j].param2 != TEXEL0) && (color->stage[i].op[j].param2 != TEXEL0_ALPHA) &&
(color->stage[i].op[j].param2 != TEXEL1) && (color->stage[i].op[j].param2 != TEXEL1_ALPHA)) &&
(color->stage[i].op[j].param3 == TEXEL0_ALPHA))
{
texEnv->mode = GL_DECAL;
texEnv->fragment.color = color->stage[i].op[j].param2;
texEnv->usesT0 = TRUE;
texEnv->usesT1 = FALSE;
}
else if ((color->stage[i].op[j].param1 == TEXEL0) &&
((color->stage[i].op[j].param2 != TEXEL0) && (color->stage[i].op[j].param2 != TEXEL0_ALPHA) &&
(color->stage[i].op[j].param2 != TEXEL1) && (color->stage[i].op[j].param2 != TEXEL1_ALPHA)) &&
(color->stage[i].op[j].param3 == TEXEL0_ALPHA))
{
texEnv->mode = GL_DECAL;
texEnv->fragment.color = color->stage[i].op[j].param2;
texEnv->usesT0 = FALSE;
texEnv->usesT1 = TRUE;
}
break;
}
}
}
return texEnv;
}
void Set_texture_env( TexEnv *texEnv )
{
combiner.usesT0 = texEnv->usesT0;
combiner.usesT1 = texEnv->usesT1;
combiner.usesNoise = FALSE;
combiner.vertex.color = texEnv->fragment.color;
combiner.vertex.secondaryColor = COMBINED;
combiner.vertex.alpha = texEnv->fragment.alpha;
// Shouldn't ever happen, but who knows?
if (OGL.ARB_multitexture)
glActiveTextureARB( GL_TEXTURE0_ARB );
if (texEnv->usesT0 || texEnv->usesT1)
glEnable( GL_TEXTURE_2D );
else
glDisable( GL_TEXTURE_2D );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texEnv->mode );
}

23
texture_env.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef TEXTURE_ENV_H
#define TEXTURE_ENV_H
struct TexEnv
{
GLint mode;
struct
{
WORD color, alpha;
} fragment;
BOOL usesT0, usesT1;
};
void Init_texture_env();
TexEnv *Compile_texture_env( Combiner *color, Combiner *alpha );
void Set_texture_env( TexEnv *texEnv );
void Update_texture_env_Colors( TexEnv *texEnv );
void Uninit_texture_env();
#endif

575
texture_env_combine.cpp Normal file
View File

@ -0,0 +1,575 @@
#ifndef __LINUX__
# include <windows.h>
#else
# include "winlnxdefs.h"
# include <stdlib.h> // malloc()
#endif
#include "OpenGL.h"
#include "Combiner.h"
#include "texture_env_combine.h"
/* if ((i == COMBINED) && (OGL.ATIX_texture_env_route)) \
{ \
envCombiner->color[combinedUnit].outputTexture = GL_TEXTURE0_ARB + n; \
envCombiner->color[n].a.source = GL_PRIMARY_COLOR_NV; \
envCombiner->color[n].a.operand = GL_SRC_COLOR; \
} \
else if ((i == LOD_FRACTION) && (envCombiner->vertex.secondaryColor == COMBINED) && (OGL.ATIX_texture_env_route)) \
{ \
envCombiner->vertex.secondaryColor = LOD_FRACTION; \
envCombiner->color[n].a.source = GL_SECONDARY_COLOR_ATIX; \
envCombiner->color[n].a.operand = GL_SRC_COLOR; \
} \*/
#define SetColorCombinerArg( n, a, i ) \
if (TexEnvArgs[i].source == GL_CONSTANT_ARB) \
{ \
if ((i > 5) && ((envCombiner->alpha[n].constant == COMBINED) || (envCombiner->alpha[n].constant == i))) \
{ \
envCombiner->alpha[n].constant = i; \
envCombiner->color[n].a.source = GL_CONSTANT_ARB; \
envCombiner->color[n].a.operand = GL_SRC_ALPHA; \
} \
else if ((i > 5) && ((envCombiner->vertex.alpha == COMBINED) || (envCombiner->vertex.alpha == i))) \
{ \
envCombiner->vertex.alpha = i; \
envCombiner->color[n].a.source = GL_PRIMARY_COLOR_ARB; \
envCombiner->color[n].a.operand = GL_SRC_ALPHA; \
} \
else if ((envCombiner->color[n].constant == COMBINED) || (envCombiner->color[n].constant == i)) \
{ \
envCombiner->color[n].constant = i; \
envCombiner->color[n].a.source = GL_CONSTANT_ARB; \
envCombiner->color[n].a.operand = GL_SRC_COLOR; \
} \
else if (OGL.ATIX_texture_env_route && ((envCombiner->vertex.secondaryColor == COMBINED) || (envCombiner->vertex.secondaryColor == i))) \
{ \
envCombiner->vertex.secondaryColor = i; \
envCombiner->color[n].a.source = GL_SECONDARY_COLOR_ATIX; \
envCombiner->color[n].a.operand = GL_SRC_COLOR; \
} \
else if ((envCombiner->vertex.color == COMBINED) || (envCombiner->vertex.color == i))\
{ \
envCombiner->vertex.color = i; \
envCombiner->color[n].a.source = GL_PRIMARY_COLOR_ARB; \
envCombiner->color[n].a.operand = GL_SRC_COLOR; \
} \
} \
else \
{ \
envCombiner->color[n].a.source = TexEnvArgs[i].source; \
envCombiner->color[n].a.operand = TexEnvArgs[i].operand; \
}
#define SetColorCombinerValues( n, a, s, o ) \
envCombiner->color[n].a.source = s; \
envCombiner->color[n].a.operand = o
/* if ((TexEnvArgs[i].source == GL_PREVIOUS_ARB) && (OGL.ATIX_texture_env_route)) \
{ \
envCombiner->alpha[combinedUnit].outputTexture = GL_TEXTURE0_ARB + n; \
envCombiner->alpha[n].a.source = GL_TEXTURE0_ARB + n; \
envCombiner->alpha[n].a.operand = GL_SRC_ALPHA; \
} \
else*/
#define SetAlphaCombinerArg( n, a, i ) \
if (TexEnvArgs[i].source == GL_CONSTANT_ARB) \
{ \
if ((envCombiner->alpha[n].constant == COMBINED) || (envCombiner->alpha[n].constant == i)) \
{ \
envCombiner->alpha[n].constant = i; \
envCombiner->alpha[n].a.source = GL_CONSTANT_ARB; \
envCombiner->alpha[n].a.operand = GL_SRC_ALPHA; \
} \
else if ((envCombiner->vertex.alpha == COMBINED) || (envCombiner->vertex.alpha == i)) \
{ \
envCombiner->vertex.alpha = i; \
envCombiner->alpha[n].a.source = GL_PRIMARY_COLOR_ARB; \
envCombiner->alpha[n].a.operand = GL_SRC_ALPHA; \
} \
} \
else \
{ \
envCombiner->alpha[n].a.source = TexEnvArgs[i].source; \
envCombiner->alpha[n].a.operand = GL_SRC_ALPHA; \
}
#define SetAlphaCombinerValues( n, a, s, o ) \
envCombiner->alpha[n].a.source = s; \
envCombiner->alpha[n].a.operand = o
void Init_texture_env_combine()
{
DWORD tex[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (int i = 0; i < OGL.maxTextureUnits; i++)
{
TextureCache_ActivateDummy( i );
//glActiveTextureARB( GL_TEXTURE0_ARB + i );
//glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
//glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex );
//glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
//glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
}
if ((OGL.ARB_texture_env_crossbar) || (OGL.NV_texture_env_combine4) || (OGL.ATIX_texture_env_route))
{
TexEnvArgs[TEXEL0].source = GL_TEXTURE0_ARB;
TexEnvArgs[TEXEL0_ALPHA].source = GL_TEXTURE0_ARB;
TexEnvArgs[TEXEL1].source = GL_TEXTURE1_ARB;
TexEnvArgs[TEXEL1_ALPHA].source = GL_TEXTURE1_ARB;
}
if (OGL.ATI_texture_env_combine3)
{
TexEnvArgs[ONE].source = GL_ONE;
TexEnvArgs[ZERO].source = GL_ZERO;
}
}
void Uninit_texture_env_combine()
{
for (int i = 0; i < OGL.maxTextureUnits; i++)
{
glActiveTextureARB( GL_TEXTURE0_ARB + i );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
}
}
void Update_texture_env_combine_Colors( TexEnvCombiner *envCombiner )
{
GLcolor color;
for (int i = 0; i < OGL.maxTextureUnits; i++)
{
SetConstant( color, envCombiner->color[i].constant, envCombiner->alpha[i].constant );
glActiveTextureARB( GL_TEXTURE0_ARB + i );
glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &color.r );
}
}
TexEnvCombiner *Compile_texture_env_combine( Combiner *color, Combiner *alpha )
{
TexEnvCombiner *envCombiner = (TexEnvCombiner*)malloc( sizeof( TexEnvCombiner ) );
int curUnit, combinedUnit;
for (int i = 0; i < OGL.maxTextureUnits; i++)
{
envCombiner->color[i].combine = GL_REPLACE;
envCombiner->alpha[i].combine = GL_REPLACE;
SetColorCombinerValues( i, arg0, GL_PREVIOUS_ARB, GL_SRC_COLOR );
SetColorCombinerValues( i, arg1, GL_PREVIOUS_ARB, GL_SRC_COLOR );
SetColorCombinerValues( i, arg2, GL_PREVIOUS_ARB, GL_SRC_COLOR );
envCombiner->color[i].constant = COMBINED;
envCombiner->color[i].outputTexture = GL_TEXTURE0_ARB + i;
SetAlphaCombinerValues( i, arg0, GL_PREVIOUS_ARB, GL_SRC_ALPHA );
SetAlphaCombinerValues( i, arg1, GL_PREVIOUS_ARB, GL_SRC_ALPHA );
SetAlphaCombinerValues( i, arg2, GL_PREVIOUS_ARB, GL_SRC_ALPHA );
envCombiner->alpha[i].constant = COMBINED;
envCombiner->alpha[i].outputTexture = GL_TEXTURE0_ARB + i;
}
envCombiner->usesT0 = FALSE;
envCombiner->usesT1 = FALSE;
envCombiner->vertex.color = COMBINED;
envCombiner->vertex.secondaryColor = COMBINED;
envCombiner->vertex.alpha = COMBINED;
curUnit = 0;
for (int i = 0; i < alpha->numStages; i++)
{
for (int j = 0; j < alpha->stage[i].numOps; j++)
{
float sb = 0.0f;
if (alpha->stage[i].op[j].param1 == PRIMITIVE_ALPHA)
sb = gDP.primColor.a;
else if (alpha->stage[i].op[j].param1 == ENV_ALPHA)
sb = gDP.envColor.a;
else if (alpha->stage[i].op[j].param1 == ONE)
sb = 1.0f;
if (((alpha->stage[i].numOps - j) >= 3) &&
(alpha->stage[i].op[j].op == SUB) &&
(alpha->stage[i].op[j+1].op == MUL) &&
(alpha->stage[i].op[j+2].op == ADD) &&
(sb > 0.5f) &&
(OGL.ARB_texture_env_combine))
{
envCombiner->usesT0 |= alpha->stage[i].op[j].param1 == TEXEL0_ALPHA;
envCombiner->usesT1 |= alpha->stage[i].op[j].param1 == TEXEL1_ALPHA;
if (alpha->stage[i].op[j].param1 == ONE)
{
SetAlphaCombinerValues( curUnit, arg0, envCombiner->alpha[curUnit].arg0.source, GL_ONE_MINUS_SRC_ALPHA );
}
else
{
envCombiner->alpha[curUnit].combine = GL_SUBTRACT_ARB;
SetAlphaCombinerValues( curUnit, arg1, envCombiner->alpha[curUnit].arg0.source, GL_SRC_ALPHA );
SetAlphaCombinerArg( curUnit, arg0, alpha->stage[i].op[j].param1 );
curUnit++;
}
j++;
envCombiner->usesT0 |= alpha->stage[i].op[j].param1 == TEXEL0_ALPHA;
envCombiner->usesT1 |= alpha->stage[i].op[j].param1 == TEXEL1_ALPHA;
envCombiner->alpha[curUnit].combine = GL_MODULATE;
SetAlphaCombinerArg( curUnit, arg1, alpha->stage[i].op[j].param1 );
curUnit++;
j++;
envCombiner->usesT0 |= alpha->stage[i].op[j].param1 == TEXEL0_ALPHA;
envCombiner->usesT1 |= alpha->stage[i].op[j].param1 == TEXEL1_ALPHA;
envCombiner->alpha[curUnit].combine = GL_SUBTRACT_ARB;
SetAlphaCombinerArg( curUnit, arg0, alpha->stage[i].op[j].param1 );
curUnit++;
}
else
{
envCombiner->usesT0 |= alpha->stage[i].op[j].param1 == TEXEL0_ALPHA;
envCombiner->usesT1 |= alpha->stage[i].op[j].param1 == TEXEL1_ALPHA;
switch (alpha->stage[i].op[j].op)
{
case LOAD:
if (!(OGL.ARB_texture_env_crossbar || OGL.NV_texture_env_combine4) &&
(alpha->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0))
curUnit++;
envCombiner->alpha[curUnit].combine = GL_REPLACE;
SetAlphaCombinerArg( curUnit, arg0, alpha->stage[i].op[j].param1 );
break;
case SUB:
if (!OGL.ARB_texture_env_combine)
break;
if (!(OGL.ARB_texture_env_crossbar || OGL.NV_texture_env_combine4) &&
(alpha->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0))
curUnit++;
if ((j > 0) && (alpha->stage[i].op[j-1].op == LOAD) && (alpha->stage[i].op[j-1].param1 == ONE))
{
SetAlphaCombinerArg( curUnit, arg0, alpha->stage[i].op[j].param1 );
envCombiner->alpha[curUnit].arg0.operand = GL_ONE_MINUS_SRC_ALPHA;
}
else if ((OGL.ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->alpha[curUnit - 1].combine == GL_MODULATE))
{
curUnit--;
SetAlphaCombinerValues( curUnit, arg2, envCombiner->alpha[curUnit].arg1.source, envCombiner->alpha[curUnit].arg1.operand );
envCombiner->alpha[curUnit].combine = GL_MODULATE_SUBTRACT_ATI;
SetAlphaCombinerArg( curUnit, arg1, alpha->stage[i].op[j].param1 );
curUnit++;
}
else
{
envCombiner->alpha[curUnit].combine = GL_SUBTRACT_ARB;
SetAlphaCombinerArg( curUnit, arg1, alpha->stage[i].op[j].param1 );
curUnit++;
}
break;
case MUL:
if (!(OGL.ARB_texture_env_crossbar || OGL.NV_texture_env_combine4) &&
(alpha->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0))
curUnit++;
envCombiner->alpha[curUnit].combine = GL_MODULATE;
SetAlphaCombinerArg( curUnit, arg1, alpha->stage[i].op[j].param1 );
curUnit++;
break;
case ADD:
if (!(OGL.ARB_texture_env_crossbar || OGL.NV_texture_env_combine4) &&
(alpha->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0))
curUnit++;
if ((OGL.ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->alpha[curUnit - 1].combine == GL_MODULATE))
{
curUnit--;
SetAlphaCombinerValues( curUnit, arg2, envCombiner->alpha[curUnit].arg1.source, envCombiner->alpha[curUnit].arg1.operand );
envCombiner->alpha[curUnit].combine = GL_MODULATE_ADD_ATI;
SetAlphaCombinerArg( curUnit, arg1, alpha->stage[i].op[j].param1 );
}
else
{
envCombiner->alpha[curUnit].combine = GL_ADD;
SetAlphaCombinerArg( curUnit, arg1, alpha->stage[i].op[j].param1 );
}
curUnit++;
break;
case INTER:
envCombiner->usesT0 |= (alpha->stage[i].op[j].param2 == TEXEL0_ALPHA) || (alpha->stage[i].op[j].param3 == TEXEL0_ALPHA);
envCombiner->usesT1 |= (alpha->stage[i].op[j].param2 == TEXEL1_ALPHA) || (alpha->stage[i].op[j].param3 == TEXEL1_ALPHA);
envCombiner->alpha[curUnit].combine = GL_INTERPOLATE_ARB;
SetAlphaCombinerArg( curUnit, arg0, alpha->stage[i].op[j].param1 );
SetAlphaCombinerArg( curUnit, arg1, alpha->stage[i].op[j].param2 );
SetAlphaCombinerArg( curUnit, arg2, alpha->stage[i].op[j].param3 );
curUnit++;
break;
}
}
}
combinedUnit = max( curUnit - 1, 0 );
}
envCombiner->usedUnits = max( curUnit, 1 );
curUnit = 0;
for (int i = 0; i < color->numStages; i++)
{
for (int j = 0; j < color->stage[i].numOps; j++)
{
float sb = 0.0f;
if (color->stage[i].op[j].param1 == PRIMITIVE)
sb = (gDP.primColor.r + gDP.primColor.b + gDP.primColor.g) / 3.0f;
else if (color->stage[i].op[j].param1 == ENVIRONMENT)
sb = (gDP.envColor.r + gDP.envColor.b + gDP.envColor.g) / 3.0f;
// This helps with problems caused by not using signed values between texture units
if (((color->stage[i].numOps - j) >= 3) &&
(color->stage[i].op[j].op == SUB) &&
(color->stage[i].op[j+1].op == MUL) &&
(color->stage[i].op[j+2].op == ADD) &&
(sb > 0.5f) &&
(OGL.ARB_texture_env_combine))
{
envCombiner->usesT0 |= ((color->stage[i].op[j].param1 == TEXEL0) || (color->stage[i].op[j].param1 == TEXEL0_ALPHA));
envCombiner->usesT1 |= ((color->stage[i].op[j].param1 == TEXEL1) || (color->stage[i].op[j].param1 == TEXEL1_ALPHA));
envCombiner->color[curUnit].combine = GL_SUBTRACT_ARB;
SetColorCombinerValues( curUnit, arg1, envCombiner->color[curUnit].arg0.source, envCombiner->color[curUnit].arg0.operand );
SetColorCombinerArg( curUnit, arg0, color->stage[i].op[j].param1 );
curUnit++;
j++;
envCombiner->usesT0 |= ((color->stage[i].op[j].param1 == TEXEL0) || (color->stage[i].op[j].param1 == TEXEL0_ALPHA));
envCombiner->usesT1 |= ((color->stage[i].op[j].param1 == TEXEL1) || (color->stage[i].op[j].param1 == TEXEL1_ALPHA));
envCombiner->color[curUnit].combine = GL_MODULATE;
SetColorCombinerArg( curUnit, arg1, color->stage[i].op[j].param1 );
curUnit++;
j++;
envCombiner->usesT0 |= ((color->stage[i].op[j].param1 == TEXEL0) || (color->stage[i].op[j].param1 == TEXEL0_ALPHA));
envCombiner->usesT1 |= ((color->stage[i].op[j].param1 == TEXEL1) || (color->stage[i].op[j].param1 == TEXEL1_ALPHA));
envCombiner->color[curUnit].combine = GL_SUBTRACT_ARB;
SetColorCombinerArg( curUnit, arg0, color->stage[i].op[j].param1 );
curUnit++;
}
else
{
envCombiner->usesT0 |= ((color->stage[i].op[j].param1 == TEXEL0) || (color->stage[i].op[j].param1 == TEXEL0_ALPHA));
envCombiner->usesT1 |= ((color->stage[i].op[j].param1 == TEXEL1) || (color->stage[i].op[j].param1 == TEXEL1_ALPHA));
switch (color->stage[i].op[j].op)
{
case LOAD:
if (!(OGL.ARB_texture_env_crossbar || OGL.NV_texture_env_combine4) &&
((color->stage[i].op[j].param1 == TEXEL1) || (color->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0))
curUnit++;
envCombiner->color[curUnit].combine = GL_REPLACE;
SetColorCombinerArg( curUnit, arg0, color->stage[i].op[j].param1 );
break;
case SUB:
if (!OGL.ARB_texture_env_combine)
break;
if (!(OGL.ARB_texture_env_crossbar || OGL.NV_texture_env_combine4) &&
((color->stage[i].op[j].param1 == TEXEL1) || (color->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0))
curUnit++;
if ((j > 0) && (color->stage[i].op[j-1].op == LOAD) && (color->stage[i].op[j-1].param1 == ONE))
{
SetColorCombinerArg( curUnit, arg0, color->stage[i].op[j].param1 );
envCombiner->color[curUnit].arg0.operand = GL_ONE_MINUS_SRC_COLOR;
}
else if ((OGL.ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->color[curUnit - 1].combine == GL_MODULATE))
{
curUnit--;
SetColorCombinerValues( curUnit, arg2, envCombiner->color[curUnit].arg1.source, envCombiner->color[curUnit].arg1.operand );
envCombiner->color[curUnit].combine = GL_MODULATE_SUBTRACT_ATI;
SetColorCombinerArg( curUnit, arg1, color->stage[i].op[j].param1 );
curUnit++;
}
else
{
envCombiner->color[curUnit].combine = GL_SUBTRACT_ARB;
SetColorCombinerArg( curUnit, arg1, color->stage[i].op[j].param1 );
curUnit++;
}
break;
case MUL:
if (!(OGL.ARB_texture_env_crossbar || OGL.NV_texture_env_combine4) &&
((color->stage[i].op[j].param1 == TEXEL1) || (color->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0))
curUnit++;
envCombiner->color[curUnit].combine = GL_MODULATE;
SetColorCombinerArg( curUnit, arg1, color->stage[i].op[j].param1 );
curUnit++;
break;
case ADD:
if (!(OGL.ARB_texture_env_crossbar || OGL.NV_texture_env_combine4) &&
((color->stage[i].op[j].param1 == TEXEL1) || (color->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0))
curUnit++;
// ATI_texture_env_combine3 adds GL_MODULATE_ADD_ATI; saves texture units
if ((OGL.ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->color[curUnit - 1].combine == GL_MODULATE))
{
curUnit--;
SetColorCombinerValues( curUnit, arg2, envCombiner->color[curUnit].arg1.source, envCombiner->color[curUnit].arg1.operand );
envCombiner->color[curUnit].combine = GL_MODULATE_ADD_ATI;
SetColorCombinerArg( curUnit, arg1, color->stage[i].op[j].param1 );
}
else
{
envCombiner->color[curUnit].combine = GL_ADD;
SetColorCombinerArg( curUnit, arg1, color->stage[i].op[j].param1 );
}
curUnit++;
break;
case INTER:
envCombiner->usesT0 |= (color->stage[i].op[j].param2 == TEXEL0) || (color->stage[i].op[j].param3 == TEXEL0) || (color->stage[i].op[j].param3 == TEXEL0_ALPHA);
envCombiner->usesT1 |= (color->stage[i].op[j].param2 == TEXEL1) || (color->stage[i].op[j].param3 == TEXEL1) || (color->stage[i].op[j].param3 == TEXEL1_ALPHA);
if (!(OGL.ARB_texture_env_crossbar || OGL.NV_texture_env_combine4) &&
((color->stage[i].op[j].param1 == TEXEL1) || (color->stage[i].op[j].param2 == TEXEL1) || (color->stage[i].op[j].param3 == TEXEL1) || (color->stage[i].op[j].param3 == TEXEL1_ALPHA)) && (curUnit == 0))
{
if (color->stage[i].op[j].param1 == TEXEL0)
{
envCombiner->color[curUnit].combine = GL_REPLACE;
SetColorCombinerArg( curUnit, arg0, color->stage[i].op[j].param1 );
color->stage[i].op[j].param1 = COMBINED;
}
if (color->stage[i].op[j].param2 == TEXEL0)
{
envCombiner->color[curUnit].combine = GL_REPLACE;
SetColorCombinerArg( curUnit, arg0, color->stage[i].op[j].param2 )
color->stage[i].op[j].param2 = COMBINED;
}
if (color->stage[i].op[j].param3 == TEXEL0)
{
envCombiner->color[curUnit].combine = GL_REPLACE;
SetColorCombinerArg( curUnit, arg0, color->stage[i].op[j].param3 );
color->stage[i].op[j].param3 = COMBINED;
}
if (color->stage[i].op[j].param3 == TEXEL0_ALPHA)
{
envCombiner->color[curUnit].combine = GL_REPLACE;
SetColorCombinerArg( curUnit, arg0, color->stage[i].op[j].param3 );
color->stage[i].op[j].param3 = COMBINED_ALPHA;
}
curUnit++;
}
envCombiner->color[curUnit].combine = GL_INTERPOLATE_ARB;
SetColorCombinerArg( curUnit, arg0, color->stage[i].op[j].param1 );
SetColorCombinerArg( curUnit, arg1, color->stage[i].op[j].param2 );
SetColorCombinerArg( curUnit, arg2, color->stage[i].op[j].param3 );
curUnit++;
break;
}
}
}
combinedUnit = max( curUnit - 1, 0 );
}
envCombiner->usedUnits = max( curUnit, envCombiner->usedUnits );
return envCombiner;
}
void BeginTextureUpdate_texture_env_combine()
{
for (int i = 0; i < OGL.maxTextureUnits; i++)
{
glActiveTextureARB( GL_TEXTURE0_ARB + i );
glDisable( GL_TEXTURE_2D );
}
}
void EndTextureUpdate_texture_env_combine()
{
for (int i = 0; i < ((TexEnvCombiner*)combiner.current->compiled)->usedUnits; i++)
{
glActiveTextureARB( GL_TEXTURE0_ARB + i );
glEnable( GL_TEXTURE_2D );
}
}
void Set_texture_env_combine( TexEnvCombiner *envCombiner )
{
combiner.usesT0 = envCombiner->usesT0;
combiner.usesT1 = envCombiner->usesT1;
combiner.usesNoise = FALSE;
combiner.vertex.color = envCombiner->vertex.color;
combiner.vertex.secondaryColor = envCombiner->vertex.secondaryColor;
combiner.vertex.alpha = envCombiner->vertex.alpha;
for (int i = 0; i < OGL.maxTextureUnits; i++)
{
glActiveTextureARB( GL_TEXTURE0_ARB + i );
if ((i < envCombiner->usedUnits ) || ((i < 2) && envCombiner->usesT1))
{
glEnable( GL_TEXTURE_2D );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, envCombiner->color[i].combine );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, envCombiner->color[i].arg0.source );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, envCombiner->color[i].arg0.operand );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, envCombiner->color[i].arg1.source );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, envCombiner->color[i].arg1.operand );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, envCombiner->color[i].arg2.source );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, envCombiner->color[i].arg2.operand );
// if (OGL.ATIX_texture_env_route)
// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_OUTPUT_RGB_ATIX, envCombiner->color[i].outputTexture );
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, envCombiner->alpha[i].combine );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, envCombiner->alpha[i].arg0.source );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, envCombiner->alpha[i].arg0.operand );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, envCombiner->alpha[i].arg1.source );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, envCombiner->alpha[i].arg1.operand );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, envCombiner->alpha[i].arg2.source );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, envCombiner->alpha[i].arg2.operand );
// if (OGL.ATIX_texture_env_route)
// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_OUTPUT_ALPHA_ATIX, envCombiner->alpha[i].outputTexture );
}
else
{
glDisable( GL_TEXTURE_2D );
}
}
}

87
texture_env_combine.h Normal file
View File

@ -0,0 +1,87 @@
#ifndef TEXTURE_ENV_COMBINE_H
#define TEXTURE_ENV_COMBINE_H
struct TexEnvCombinerArg
{
GLenum source, operand;
};
struct TexEnvCombinerStage
{
WORD constant;
BOOL used;
GLenum combine;
TexEnvCombinerArg arg0, arg1, arg2;
WORD outputTexture;
};
struct TexEnvCombiner
{
BOOL usesT0, usesT1, usesNoise;
WORD usedUnits;
struct
{
WORD color, secondaryColor, alpha;
} vertex;
TexEnvCombinerStage color[8];
TexEnvCombinerStage alpha[8];
};
static TexEnvCombinerArg TexEnvArgs[] =
{
// CMB
{ GL_PREVIOUS_ARB, GL_SRC_COLOR },
// T0
{ GL_TEXTURE, GL_SRC_COLOR },
// T1
{ GL_TEXTURE, GL_SRC_COLOR },
// PRIM
{ GL_CONSTANT_ARB, GL_SRC_COLOR },
// SHADE
{ GL_PRIMARY_COLOR_ARB, GL_SRC_COLOR },
// ENV
{ GL_CONSTANT_ARB, GL_SRC_COLOR },
// CENTER
{ GL_CONSTANT_ARB, GL_SRC_COLOR },
// SCALE
{ GL_CONSTANT_ARB, GL_SRC_COLOR },
// CMBALPHA
{ GL_PREVIOUS_ARB, GL_SRC_ALPHA },
// T0ALPHA
{ GL_TEXTURE, GL_SRC_ALPHA },
// T1ALPHA
{ GL_TEXTURE, GL_SRC_ALPHA },
// PRIMALPHA
{ GL_CONSTANT_ARB, GL_SRC_ALPHA },
// SHADEALPHA
{ GL_PRIMARY_COLOR_ARB, GL_SRC_ALPHA },
// ENVALPHA
{ GL_CONSTANT_ARB, GL_SRC_COLOR },
// LODFRAC
{ GL_CONSTANT_ARB, GL_SRC_COLOR },
// PRIMLODFRAC
{ GL_CONSTANT_ARB, GL_SRC_COLOR },
// NOISE
{ GL_TEXTURE, GL_SRC_COLOR },
// K4
{ GL_CONSTANT_ARB, GL_SRC_COLOR },
// K5
{ GL_CONSTANT_ARB, GL_SRC_COLOR },
// ONE
{ GL_CONSTANT_ARB, GL_SRC_COLOR },
// ZERO
{ GL_CONSTANT_ARB, GL_SRC_COLOR }
};
void Init_texture_env_combine();
TexEnvCombiner *Compile_texture_env_combine( Combiner *color, Combiner *alpha );
void Set_texture_env_combine( TexEnvCombiner *envCombiner );
void Update_texture_env_combine_Colors( TexEnvCombiner* );
void Uninit_texture_env_combine();
void BeginTextureUpdate_texture_env_combine();
void EndTextureUpdate_texture_env_combine();
#endif

943
wglext.h Normal file
View File

@ -0,0 +1,943 @@
#ifndef __wglext_h_
#define __wglext_h_
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2007-2012 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Function declaration macros - to move into glplatform.h */
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#endif
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef APIENTRYP
#define APIENTRYP APIENTRY *
#endif
#ifndef GLAPI
#define GLAPI extern
#endif
/*************************************************************/
/* Header file version number */
/* wglext.h last updated 2012/01/04 */
/* Current version at http://www.opengl.org/registry/ */
#define WGL_WGLEXT_VERSION 24
#ifndef WGL_ARB_buffer_region
#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
#endif
#ifndef WGL_ARB_multisample
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
#define WGL_SAMPLES_ARB 0x2042
#endif
#ifndef WGL_ARB_extensions_string
#endif
#ifndef WGL_ARB_pixel_format
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NEED_PALETTE_ARB 0x2004
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
#define WGL_SWAP_METHOD_ARB 0x2007
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
#define WGL_TRANSPARENT_ARB 0x200A
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
#define WGL_SHARE_DEPTH_ARB 0x200C
#define WGL_SHARE_STENCIL_ARB 0x200D
#define WGL_SHARE_ACCUM_ARB 0x200E
#define WGL_SUPPORT_GDI_ARB 0x200F
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201A
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_ALPHA_SHIFT_ARB 0x201C
#define WGL_ACCUM_BITS_ARB 0x201D
#define WGL_ACCUM_RED_BITS_ARB 0x201E
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_SWAP_EXCHANGE_ARB 0x2028
#define WGL_SWAP_COPY_ARB 0x2029
#define WGL_SWAP_UNDEFINED_ARB 0x202A
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_TYPE_COLORINDEX_ARB 0x202C
#endif
#ifndef WGL_ARB_make_current_read
#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
#endif
#ifndef WGL_ARB_pbuffer
#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
#define WGL_PBUFFER_LARGEST_ARB 0x2033
#define WGL_PBUFFER_WIDTH_ARB 0x2034
#define WGL_PBUFFER_HEIGHT_ARB 0x2035
#define WGL_PBUFFER_LOST_ARB 0x2036
#endif
#ifndef WGL_ARB_render_texture
#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
#define WGL_TEXTURE_FORMAT_ARB 0x2072
#define WGL_TEXTURE_TARGET_ARB 0x2073
#define WGL_MIPMAP_TEXTURE_ARB 0x2074
#define WGL_TEXTURE_RGB_ARB 0x2075
#define WGL_TEXTURE_RGBA_ARB 0x2076
#define WGL_NO_TEXTURE_ARB 0x2077
#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
#define WGL_TEXTURE_1D_ARB 0x2079
#define WGL_TEXTURE_2D_ARB 0x207A
#define WGL_MIPMAP_LEVEL_ARB 0x207B
#define WGL_CUBE_MAP_FACE_ARB 0x207C
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
#define WGL_FRONT_LEFT_ARB 0x2083
#define WGL_FRONT_RIGHT_ARB 0x2084
#define WGL_BACK_LEFT_ARB 0x2085
#define WGL_BACK_RIGHT_ARB 0x2086
#define WGL_AUX0_ARB 0x2087
#define WGL_AUX1_ARB 0x2088
#define WGL_AUX2_ARB 0x2089
#define WGL_AUX3_ARB 0x208A
#define WGL_AUX4_ARB 0x208B
#define WGL_AUX5_ARB 0x208C
#define WGL_AUX6_ARB 0x208D
#define WGL_AUX7_ARB 0x208E
#define WGL_AUX8_ARB 0x208F
#define WGL_AUX9_ARB 0x2090
#endif
#ifndef WGL_ARB_pixel_format_float
#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
#endif
#ifndef WGL_ARB_framebuffer_sRGB
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
#endif
#ifndef WGL_ARB_create_context
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define ERROR_INVALID_VERSION_ARB 0x2095
#endif
#ifndef WGL_ARB_create_context_profile
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define ERROR_INVALID_PROFILE_ARB 0x2096
#endif
#ifndef WGL_ARB_create_context_robustness
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
#endif
#ifndef WGL_EXT_make_current_read
#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
#endif
#ifndef WGL_EXT_pixel_format
#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
#define WGL_DRAW_TO_WINDOW_EXT 0x2001
#define WGL_DRAW_TO_BITMAP_EXT 0x2002
#define WGL_ACCELERATION_EXT 0x2003
#define WGL_NEED_PALETTE_EXT 0x2004
#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
#define WGL_SWAP_METHOD_EXT 0x2007
#define WGL_NUMBER_OVERLAYS_EXT 0x2008
#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
#define WGL_TRANSPARENT_EXT 0x200A
#define WGL_TRANSPARENT_VALUE_EXT 0x200B
#define WGL_SHARE_DEPTH_EXT 0x200C
#define WGL_SHARE_STENCIL_EXT 0x200D
#define WGL_SHARE_ACCUM_EXT 0x200E
#define WGL_SUPPORT_GDI_EXT 0x200F
#define WGL_SUPPORT_OPENGL_EXT 0x2010
#define WGL_DOUBLE_BUFFER_EXT 0x2011
#define WGL_STEREO_EXT 0x2012
#define WGL_PIXEL_TYPE_EXT 0x2013
#define WGL_COLOR_BITS_EXT 0x2014
#define WGL_RED_BITS_EXT 0x2015
#define WGL_RED_SHIFT_EXT 0x2016
#define WGL_GREEN_BITS_EXT 0x2017
#define WGL_GREEN_SHIFT_EXT 0x2018
#define WGL_BLUE_BITS_EXT 0x2019
#define WGL_BLUE_SHIFT_EXT 0x201A
#define WGL_ALPHA_BITS_EXT 0x201B
#define WGL_ALPHA_SHIFT_EXT 0x201C
#define WGL_ACCUM_BITS_EXT 0x201D
#define WGL_ACCUM_RED_BITS_EXT 0x201E
#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
#define WGL_DEPTH_BITS_EXT 0x2022
#define WGL_STENCIL_BITS_EXT 0x2023
#define WGL_AUX_BUFFERS_EXT 0x2024
#define WGL_NO_ACCELERATION_EXT 0x2025
#define WGL_GENERIC_ACCELERATION_EXT 0x2026
#define WGL_FULL_ACCELERATION_EXT 0x2027
#define WGL_SWAP_EXCHANGE_EXT 0x2028
#define WGL_SWAP_COPY_EXT 0x2029
#define WGL_SWAP_UNDEFINED_EXT 0x202A
#define WGL_TYPE_RGBA_EXT 0x202B
#define WGL_TYPE_COLORINDEX_EXT 0x202C
#endif
#ifndef WGL_EXT_pbuffer
#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
#define WGL_PBUFFER_LARGEST_EXT 0x2033
#define WGL_PBUFFER_WIDTH_EXT 0x2034
#define WGL_PBUFFER_HEIGHT_EXT 0x2035
#endif
#ifndef WGL_EXT_depth_float
#define WGL_DEPTH_FLOAT_EXT 0x2040
#endif
#ifndef WGL_3DFX_multisample
#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
#define WGL_SAMPLES_3DFX 0x2061
#endif
#ifndef WGL_EXT_multisample
#define WGL_SAMPLE_BUFFERS_EXT 0x2041
#define WGL_SAMPLES_EXT 0x2042
#endif
#ifndef WGL_I3D_digital_video_control
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
#endif
#ifndef WGL_I3D_gamma
#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
#endif
#ifndef WGL_I3D_genlock
#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045
#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046
#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047
#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
#endif
#ifndef WGL_I3D_image_buffer
#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
#endif
#ifndef WGL_I3D_swap_frame_lock
#endif
#ifndef WGL_NV_render_depth_texture
#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
#define WGL_DEPTH_COMPONENT_NV 0x20A7
#endif
#ifndef WGL_NV_render_texture_rectangle
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
#endif
#ifndef WGL_ATI_pixel_format_float
#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
#endif
#ifndef WGL_NV_float_buffer
#define WGL_FLOAT_COMPONENTS_NV 0x20B0
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
#endif
#ifndef WGL_3DL_stereo_control
#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
#endif
#ifndef WGL_EXT_pixel_format_packed_float
#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
#endif
#ifndef WGL_EXT_framebuffer_sRGB
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
#endif
#ifndef WGL_NV_present_video
#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
#endif
#ifndef WGL_NV_video_out
#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
#define WGL_VIDEO_OUT_FRAME 0x20C8
#define WGL_VIDEO_OUT_FIELD_1 0x20C9
#define WGL_VIDEO_OUT_FIELD_2 0x20CA
#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
#endif
#ifndef WGL_NV_swap_group
#endif
#ifndef WGL_NV_gpu_affinity
#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
#endif
#ifndef WGL_AMD_gpu_association
#define WGL_GPU_VENDOR_AMD 0x1F00
#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
#define WGL_GPU_RAM_AMD 0x21A3
#define WGL_GPU_CLOCK_AMD 0x21A4
#define WGL_GPU_NUM_PIPES_AMD 0x21A5
#define WGL_GPU_NUM_SIMD_AMD 0x21A6
#define WGL_GPU_NUM_RB_AMD 0x21A7
#define WGL_GPU_NUM_SPI_AMD 0x21A8
#endif
#ifndef WGL_NV_video_capture
#define WGL_UNIQUE_ID_NV 0x20CE
#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
#endif
#ifndef WGL_NV_copy_image
#endif
#ifndef WGL_NV_multisample_coverage
#define WGL_COVERAGE_SAMPLES_NV 0x2042
#define WGL_COLOR_SAMPLES_NV 0x20B9
#endif
#ifndef WGL_EXT_create_context_es2_profile
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#endif
#ifndef WGL_NV_DX_interop
#define WGL_ACCESS_READ_ONLY_NV 0x00000000
#define WGL_ACCESS_READ_WRITE_NV 0x00000001
#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002
#endif
#ifndef WGL_NV_DX_interop2
#endif
#ifndef WGL_EXT_swap_control_tear
#endif
/*************************************************************/
#ifndef WGL_ARB_pbuffer
DECLARE_HANDLE(HPBUFFERARB);
#endif
#ifndef WGL_EXT_pbuffer
DECLARE_HANDLE(HPBUFFEREXT);
#endif
#ifndef WGL_NV_present_video
DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
#endif
#ifndef WGL_NV_video_output
DECLARE_HANDLE(HPVIDEODEV);
#endif
#ifndef WGL_NV_gpu_affinity
DECLARE_HANDLE(HPGPUNV);
DECLARE_HANDLE(HGPUNV);
typedef struct _GPU_DEVICE {
DWORD cb;
CHAR DeviceName[32];
CHAR DeviceString[128];
DWORD Flags;
RECT rcVirtualScreen;
} GPU_DEVICE, *PGPU_DEVICE;
#endif
#ifndef WGL_NV_video_capture
DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
#endif
#ifndef WGL_ARB_buffer_region
#define WGL_ARB_buffer_region 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType);
extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion);
extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height);
extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
#endif
#ifndef WGL_ARB_multisample
#define WGL_ARB_multisample 1
#endif
#ifndef WGL_ARB_extensions_string
#define WGL_ARB_extensions_string 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern const char * WINAPI wglGetExtensionsStringARB (HDC hdc);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
#endif
#ifndef WGL_ARB_pixel_format
#define WGL_ARB_pixel_format 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
extern BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif
#ifndef WGL_ARB_make_current_read
#define WGL_ARB_make_current_read 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
extern HDC WINAPI wglGetCurrentReadDCARB (void);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
#endif
#ifndef WGL_ARB_pbuffer
#define WGL_ARB_pbuffer 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer);
extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC);
extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer);
extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
#endif
#ifndef WGL_ARB_render_texture
#define WGL_ARB_render_texture 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
#endif
#ifndef WGL_ARB_pixel_format_float
#define WGL_ARB_pixel_format_float 1
#endif
#ifndef WGL_ARB_framebuffer_sRGB
#define WGL_ARB_framebuffer_sRGB 1
#endif
#ifndef WGL_ARB_create_context
#define WGL_ARB_create_context 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
#endif
#ifndef WGL_ARB_create_context_profile
#define WGL_ARB_create_context_profile 1
#endif
#ifndef WGL_ARB_create_context_robustness
#define WGL_ARB_create_context_robustness 1
#endif
#ifndef WGL_EXT_display_color_table
#define WGL_EXT_display_color_table 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id);
extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length);
extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id);
extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
#endif
#ifndef WGL_EXT_extensions_string
#define WGL_EXT_extensions_string 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern const char * WINAPI wglGetExtensionsStringEXT (void);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
#endif
#ifndef WGL_EXT_make_current_read
#define WGL_EXT_make_current_read 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
extern HDC WINAPI wglGetCurrentReadDCEXT (void);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
#endif
#ifndef WGL_EXT_pbuffer
#define WGL_EXT_pbuffer 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer);
extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC);
extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer);
extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
#endif
#ifndef WGL_EXT_pixel_format
#define WGL_EXT_pixel_format 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
extern BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif
#ifndef WGL_EXT_swap_control
#define WGL_EXT_swap_control 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglSwapIntervalEXT (int interval);
extern int WINAPI wglGetSwapIntervalEXT (void);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
#endif
#ifndef WGL_EXT_depth_float
#define WGL_EXT_depth_float 1
#endif
#ifndef WGL_NV_vertex_array_range
#define WGL_NV_vertex_array_range 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern void* WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
extern void WINAPI wglFreeMemoryNV (void *pointer);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
#endif
#ifndef WGL_3DFX_multisample
#define WGL_3DFX_multisample 1
#endif
#ifndef WGL_EXT_multisample
#define WGL_EXT_multisample 1
#endif
#ifndef WGL_OML_sync_control
#define WGL_OML_sync_control 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
extern BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator);
extern INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
extern BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
extern BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
#endif
#ifndef WGL_I3D_digital_video_control
#define WGL_I3D_digital_video_control 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue);
extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
#endif
#ifndef WGL_I3D_gamma
#define WGL_I3D_gamma 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue);
extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue);
extern BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
extern BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
#endif
#ifndef WGL_I3D_genlock
#define WGL_I3D_genlock 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglEnableGenlockI3D (HDC hDC);
extern BOOL WINAPI wglDisableGenlockI3D (HDC hDC);
extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag);
extern BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource);
extern BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource);
extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge);
extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge);
extern BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate);
extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate);
extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay);
extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay);
extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
#endif
#ifndef WGL_I3D_image_buffer
#define WGL_I3D_image_buffer 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags);
extern BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress);
extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
#endif
#ifndef WGL_I3D_swap_frame_lock
#define WGL_I3D_swap_frame_lock 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglEnableFrameLockI3D (void);
extern BOOL WINAPI wglDisableFrameLockI3D (void);
extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag);
extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
#endif
#ifndef WGL_I3D_swap_frame_usage
#define WGL_I3D_swap_frame_usage 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetFrameUsageI3D (float *pUsage);
extern BOOL WINAPI wglBeginFrameTrackingI3D (void);
extern BOOL WINAPI wglEndFrameTrackingI3D (void);
extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
#endif
#ifndef WGL_ATI_pixel_format_float
#define WGL_ATI_pixel_format_float 1
#endif
#ifndef WGL_NV_float_buffer
#define WGL_NV_float_buffer 1
#endif
#ifndef WGL_3DL_stereo_control
#define WGL_3DL_stereo_control 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState);
#endif
#ifndef WGL_EXT_pixel_format_packed_float
#define WGL_EXT_pixel_format_packed_float 1
#endif
#ifndef WGL_EXT_framebuffer_sRGB
#define WGL_EXT_framebuffer_sRGB 1
#endif
#ifndef WGL_NV_present_video
#define WGL_NV_present_video 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
extern BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
extern BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue);
#endif
#ifndef WGL_NV_video_output
#define WGL_NV_video_output 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
extern BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice);
extern BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
extern BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer);
extern BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
extern BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#endif
#ifndef WGL_NV_swap_group
#define WGL_NV_swap_group 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group);
extern BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier);
extern BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier);
extern BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
extern BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count);
extern BOOL WINAPI wglResetFrameCountNV (HDC hDC);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier);
typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count);
typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
#endif
#ifndef WGL_NV_gpu_affinity
#define WGL_NV_gpu_affinity 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu);
extern BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
extern HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList);
extern BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
extern BOOL WINAPI wglDeleteDCNV (HDC hdc);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
#endif
#ifndef WGL_AMD_gpu_association
#define WGL_AMD_gpu_association 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids);
extern INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data);
extern UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc);
extern HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id);
extern HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList);
extern BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc);
extern BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc);
extern HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
extern VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids);
typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data);
typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList);
typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#endif
#ifndef WGL_NV_video_capture
#define WGL_NV_video_capture 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
extern UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
extern BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
extern BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
extern BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
#endif
#ifndef WGL_NV_copy_image
#define WGL_NV_copy_image 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#endif
#ifndef WGL_NV_multisample_coverage
#define WGL_NV_multisample_coverage 1
#endif
#ifndef WGL_NV_DX_interop
#define WGL_NV_DX_interop 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle);
extern HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice);
extern BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice);
extern HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
extern BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject);
extern BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access);
extern BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
extern BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle);
typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice);
typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice);
typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject);
typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access);
typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
#endif
#ifndef WGL_NV_DX_interop2
#define WGL_NV_DX_interop2 1
#endif
#ifndef WGL_EXT_swap_control_tear
#define WGL_EXT_swap_control_tear 1
#endif
#ifdef __cplusplus
}
#endif
#endif

131
winlnxdefs.h Normal file
View File

@ -0,0 +1,131 @@
/**
* Mupen64 - winlnxdefs.h
* Copyright (C) 2002 Hacktarux
*
* Mupen64 homepage: http://mupen64.emulation64.com
* email address: hacktarux@yahoo.fr
*
* If you want to contribute to the project please contact
* me first (maybe someone is already making what you are
* planning to do).
*
*
* This program is free software; you can redistribute it and/
* or modify it under the terms of the GNU General Public Li-
* cence as published by the Free Software Foundation; either
* version 2 of the Licence, or any later version.
*
* This program is distributed in the hope that it will be use-
* ful, but WITHOUT ANY WARRANTY; without even the implied war-
* ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
* USA.
*
**/
#ifndef WINLNXDEFS_H
#define WINLNXDEFS_H
#include <features.h> // we want GNU extensions
#include <dlfcn.h>
#include <errno.h>
#include <limits.h> // PATH_MAX
#include <stdlib.h> // malloc(), srand()
#include <stdio.h>
#include <string.h>
#include <time.h> // time()
#include <unistd.h> // readlink()
#define timeGetTime() time( 0 )
typedef unsigned int BOOL, BOOLEAN;
typedef unsigned long DWORD;
typedef unsigned long long DWORD64, QWORD;
typedef unsigned short WORD;
typedef unsigned char BYTE, byte;
typedef unsigned int UINT;
typedef char CHAR;
typedef short SHORT;
typedef long LONG;
typedef float FLOAT;
typedef long __int32;
typedef int HINSTANCE;
typedef int HWND;
typedef int WPARAM;
typedef int LPARAM;
typedef void* LPVOID;
typedef const char *LPCSTR;
// types
/*#define BOOL unsigned int
#define BOOLEAN unsigned int
#define DWORD unsigned long
#define WORD unsigned short
#define BYTE unsigned char*/
#define __declspec(dllexport)
#define _cdecl
#define WINAPI
#define APIENTRY
//#define EXPORT
//#define CALL
#define max( a, b ) ((a > b) ? a : b)
#define min( a, b ) ((a > b) ? b : a)
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef false
#define false 0
#endif
#ifndef true
#define true 1
#endif
static inline const char *GetPluginDir()
{
static char path[PATH_MAX];
#ifdef __USE_GNU
Dl_info info;
void *addr = (void *)GetPluginDir;
//__asm__( "movl %%eip, %%eax" : "=a"(addr) );
if (dladdr( addr, &info ) != 0)
{
strncpy( path, info.dli_fname, PATH_MAX );
*(strrchr( path, '/' )) = '\0';
}
else
{
fprintf( stderr, "(WW) Couldn't get path of .so, trying to get emulator's path\n" );
#endif // __USE_GNU
if (readlink( "/proc/self/exe", path, PATH_MAX ) == -1)
{
fprintf( stderr, "(WW) readlink() /proc/self/exe failed: %s\n", strerror( errno ) );
path[0] = '.';
path[1] = '\0';
}
*(strrchr( path, '/' )) = '\0';
strncat( path, "/plugins", PATH_MAX );
#ifdef __USE_GNU
}
#endif
return path;
}
#endif