BAHAHAHAHAHAHAHAA
This commit is contained in:
parent
f2282e9e32
commit
c81bcccadc
|
@ -107,6 +107,7 @@
|
||||||
<Unit filename="src/GPU3D.cpp" />
|
<Unit filename="src/GPU3D.cpp" />
|
||||||
<Unit filename="src/GPU3D.h" />
|
<Unit filename="src/GPU3D.h" />
|
||||||
<Unit filename="src/GPU3D_OpenGL43.cpp" />
|
<Unit filename="src/GPU3D_OpenGL43.cpp" />
|
||||||
|
<Unit filename="src/GPU3D_OpenGL43_shaders.h" />
|
||||||
<Unit filename="src/GPU3D_Soft.cpp" />
|
<Unit filename="src/GPU3D_Soft.cpp" />
|
||||||
<Unit filename="src/NDS.cpp" />
|
<Unit filename="src/NDS.cpp" />
|
||||||
<Unit filename="src/NDS.h" />
|
<Unit filename="src/NDS.h" />
|
||||||
|
|
40
src/GPU.cpp
40
src/GPU.cpp
|
@ -74,6 +74,7 @@ u32 VRAMMap_ARM7[2];
|
||||||
int FrontBuffer;
|
int FrontBuffer;
|
||||||
u32* Framebuffer[2][2];
|
u32* Framebuffer[2][2];
|
||||||
int FBScale[2];
|
int FBScale[2];
|
||||||
|
bool Accelerated;
|
||||||
|
|
||||||
GPU2D* GPU2D_A;
|
GPU2D* GPU2D_A;
|
||||||
GPU2D* GPU2D_B;
|
GPU2D* GPU2D_B;
|
||||||
|
@ -88,9 +89,8 @@ bool Init()
|
||||||
FrontBuffer = 0;
|
FrontBuffer = 0;
|
||||||
Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL;
|
Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL;
|
||||||
Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL;
|
Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL;
|
||||||
FBScale[0] = -1; FBScale[1] = -1;
|
FBScale[0] = -1; FBScale[1] = -1; Accelerated = false;
|
||||||
//SetFramebufferScale(1);
|
SetDisplaySettings(0, 0, false);
|
||||||
SetFramebufferScale(1, 1);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -247,13 +247,15 @@ void AssignFramebuffers()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFramebufferScale(int top, int bottom)
|
void SetDisplaySettings(int topscale, int bottomscale, bool accel)
|
||||||
{
|
{accel=true;
|
||||||
if (top != FBScale[0])
|
if (topscale != FBScale[0] || accel != Accelerated)
|
||||||
{
|
{
|
||||||
FBScale[0] = top;
|
FBScale[0] = accel ? 0 : topscale;
|
||||||
|
|
||||||
int fbsize = (256 * 192) << (FBScale[0] * 2);
|
int fbsize;
|
||||||
|
if (accel) fbsize = 256*3 * 192;
|
||||||
|
else fbsize = (256 * 192) << (FBScale[0] * 2);
|
||||||
if (Framebuffer[0][0]) delete[] Framebuffer[0][0];
|
if (Framebuffer[0][0]) delete[] Framebuffer[0][0];
|
||||||
if (Framebuffer[1][0]) delete[] Framebuffer[1][0];
|
if (Framebuffer[1][0]) delete[] Framebuffer[1][0];
|
||||||
Framebuffer[0][0] = new u32[fbsize];
|
Framebuffer[0][0] = new u32[fbsize];
|
||||||
|
@ -266,21 +268,23 @@ void SetFramebufferScale(int top, int bottom)
|
||||||
if (NDS::PowerControl9 & (1<<15))
|
if (NDS::PowerControl9 & (1<<15))
|
||||||
{
|
{
|
||||||
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]);
|
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]);
|
||||||
GPU2D_A->SetScale(FBScale[0]);
|
GPU2D_A->SetDisplaySettings(FBScale[0], accel);
|
||||||
GPU3D::SetScale(FBScale[0]);
|
GPU3D::SetDisplaySettings(topscale, accel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]);
|
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]);
|
||||||
GPU2D_B->SetScale(FBScale[0]);
|
GPU2D_B->SetDisplaySettings(FBScale[0], accel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bottom != FBScale[1])
|
if (bottomscale != FBScale[1] || accel != Accelerated)
|
||||||
{
|
{
|
||||||
FBScale[1] = bottom;
|
FBScale[1] = accel ? 0 : bottomscale;
|
||||||
|
|
||||||
int fbsize = (256 * 192) << (FBScale[1] * 2);
|
int fbsize;
|
||||||
|
if (accel) fbsize = 256*3 * 192;
|
||||||
|
else fbsize = (256 * 192) << (FBScale[1] * 2);
|
||||||
if (Framebuffer[0][1]) delete[] Framebuffer[0][1];
|
if (Framebuffer[0][1]) delete[] Framebuffer[0][1];
|
||||||
if (Framebuffer[1][1]) delete[] Framebuffer[1][1];
|
if (Framebuffer[1][1]) delete[] Framebuffer[1][1];
|
||||||
Framebuffer[0][1] = new u32[fbsize];
|
Framebuffer[0][1] = new u32[fbsize];
|
||||||
|
@ -293,15 +297,17 @@ void SetFramebufferScale(int top, int bottom)
|
||||||
if (NDS::PowerControl9 & (1<<15))
|
if (NDS::PowerControl9 & (1<<15))
|
||||||
{
|
{
|
||||||
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]);
|
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]);
|
||||||
GPU2D_B->SetScale(FBScale[1]);
|
GPU2D_B->SetDisplaySettings(FBScale[1], accel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]);
|
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]);
|
||||||
GPU2D_A->SetScale(FBScale[1]);
|
GPU2D_A->SetDisplaySettings(FBScale[1], accel);
|
||||||
GPU3D::SetScale(FBScale[1]);
|
GPU3D::SetDisplaySettings(bottomscale, accel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Accelerated = accel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ void Stop();
|
||||||
|
|
||||||
void DoSavestate(Savestate* file);
|
void DoSavestate(Savestate* file);
|
||||||
|
|
||||||
void SetFramebufferScale(int top, int bottom);
|
void SetDisplaySettings(int topscale, int bottomscale, bool accel);
|
||||||
|
|
||||||
|
|
||||||
void MapVRAM_AB(u32 bank, u8 cnt);
|
void MapVRAM_AB(u32 bank, u8 cnt);
|
||||||
|
|
175
src/GPU2D.cpp
175
src/GPU2D.cpp
|
@ -82,7 +82,6 @@
|
||||||
GPU2D::GPU2D(u32 num)
|
GPU2D::GPU2D(u32 num)
|
||||||
{
|
{
|
||||||
Num = num;
|
Num = num;
|
||||||
SetScale(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GPU2D::~GPU2D()
|
GPU2D::~GPU2D()
|
||||||
|
@ -216,12 +215,16 @@ void GPU2D::SetFramebuffer(u32* buf)
|
||||||
Framebuffer = buf;
|
Framebuffer = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU2D::SetScale(int scale)
|
void GPU2D::SetDisplaySettings(int scale, bool accel)
|
||||||
{
|
{
|
||||||
|
if (accel) scale = 0;
|
||||||
|
Accelerated = accel;
|
||||||
|
|
||||||
LineScale = scale;
|
LineScale = scale;
|
||||||
LineStride = 256 << (scale*2);
|
LineStride = 256 << (scale*2);
|
||||||
|
|
||||||
if (scale == 1) DrawPixel = DrawPixel_2x;
|
if (Accelerated) DrawPixel = DrawPixel_Accel;
|
||||||
|
else if (scale == 1) DrawPixel = DrawPixel_2x;
|
||||||
else if (scale == 2) DrawPixel = DrawPixel_4x;
|
else if (scale == 2) DrawPixel = DrawPixel_4x;
|
||||||
else DrawPixel = DrawPixel_1x;
|
else DrawPixel = DrawPixel_1x;
|
||||||
}
|
}
|
||||||
|
@ -623,7 +626,8 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor)
|
||||||
|
|
||||||
void GPU2D::DrawScanline(u32 line)
|
void GPU2D::DrawScanline(u32 line)
|
||||||
{
|
{
|
||||||
u32* dst = &Framebuffer[LineStride * line];
|
int stride = Accelerated ? (256*3) : LineStride;
|
||||||
|
u32* dst = &Framebuffer[stride * line];
|
||||||
|
|
||||||
int n3dline = line;
|
int n3dline = line;
|
||||||
line = GPU::VCount;
|
line = GPU::VCount;
|
||||||
|
@ -652,7 +656,7 @@ void GPU2D::DrawScanline(u32 line)
|
||||||
u32 dispmode = DispCnt >> 16;
|
u32 dispmode = DispCnt >> 16;
|
||||||
dispmode &= (Num ? 0x1 : 0x3);
|
dispmode &= (Num ? 0x1 : 0x3);
|
||||||
|
|
||||||
if (Num == 0)
|
if (Num == 0 && !Accelerated)
|
||||||
_3DLine = GPU3D::GetLine(n3dline);
|
_3DLine = GPU3D::GetLine(n3dline);
|
||||||
|
|
||||||
// always render regular graphics
|
// always render regular graphics
|
||||||
|
@ -663,13 +667,13 @@ void GPU2D::DrawScanline(u32 line)
|
||||||
case 0: // screen off
|
case 0: // screen off
|
||||||
{
|
{
|
||||||
for (int i = 0; i < LineStride; i++)
|
for (int i = 0; i < LineStride; i++)
|
||||||
dst[i] = 0xFF3F3F3F;
|
dst[i] = 0x003F3F3F;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // regular display
|
case 1: // regular display
|
||||||
{
|
{
|
||||||
for (int i = 0; i < LineStride; i+=2)
|
for (int i = 0; i < stride; i+=2)
|
||||||
*(u64*)&dst[i] = *(u64*)&BGOBJLine[i];
|
*(u64*)&dst[i] = *(u64*)&BGOBJLine[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -783,6 +787,8 @@ void GPU2D::DrawScanline(u32 line)
|
||||||
DoCapture(line, capwidth);
|
DoCapture(line, capwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Accelerated) return;
|
||||||
|
|
||||||
// master brightness
|
// master brightness
|
||||||
if (dispmode != 0)
|
if (dispmode != 0)
|
||||||
{
|
{
|
||||||
|
@ -861,6 +867,8 @@ void GPU2D::DoCapture(u32 line, u32 width)
|
||||||
u16* dst = (u16*)GPU::VRAM[dstvram];
|
u16* dst = (u16*)GPU::VRAM[dstvram];
|
||||||
u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width);
|
u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width);
|
||||||
|
|
||||||
|
// TODO: handle 3D in accelerated mode!!
|
||||||
|
|
||||||
u32* srcA;
|
u32* srcA;
|
||||||
if (CaptureCnt & (1<<24))
|
if (CaptureCnt & (1<<24))
|
||||||
srcA = _3DLine;
|
srcA = _3DLine;
|
||||||
|
@ -1272,88 +1280,91 @@ void GPU2D::DrawScanline_Mode1(u32 line)
|
||||||
// color special effects
|
// color special effects
|
||||||
// can likely be optimized
|
// can likely be optimized
|
||||||
|
|
||||||
u32 bldcnteffect = (BlendCnt >> 6) & 0x3;
|
if (!Accelerated)
|
||||||
|
|
||||||
for (int i = 0; i < LineStride; i++)
|
|
||||||
{
|
{
|
||||||
int j = (i >> LineScale) & 0xFF;
|
u32 bldcnteffect = (BlendCnt >> 6) & 0x3;
|
||||||
|
|
||||||
u32 val1 = BGOBJLine[i];
|
for (int i = 0; i < LineStride; i++)
|
||||||
u32 val2 = BGOBJLine[4096+i];
|
|
||||||
|
|
||||||
u32 coloreffect, eva, evb;
|
|
||||||
|
|
||||||
u32 flag1 = val1 >> 24;
|
|
||||||
u32 flag2 = val2 >> 24;
|
|
||||||
|
|
||||||
u32 target2;
|
|
||||||
if (flag2 & 0x80) target2 = 0x1000;
|
|
||||||
else if (flag2 & 0x40) target2 = 0x0100;
|
|
||||||
else target2 = flag2 << 8;
|
|
||||||
|
|
||||||
if ((flag1 & 0x80) && (BlendCnt & target2))
|
|
||||||
{
|
{
|
||||||
// sprite blending
|
int j = (i >> LineScale) & 0xFF;
|
||||||
|
|
||||||
coloreffect = 1;
|
u32 val1 = BGOBJLine[i];
|
||||||
|
u32 val2 = BGOBJLine[4096+i];
|
||||||
|
|
||||||
if (flag1 & 0x40)
|
u32 coloreffect, eva, evb;
|
||||||
|
|
||||||
|
u32 flag1 = val1 >> 24;
|
||||||
|
u32 flag2 = val2 >> 24;
|
||||||
|
|
||||||
|
u32 target2;
|
||||||
|
if (flag2 & 0x80) target2 = 0x1000;
|
||||||
|
else if (flag2 & 0x40) target2 = 0x0100;
|
||||||
|
else target2 = flag2 << 8;
|
||||||
|
|
||||||
|
if ((flag1 & 0x80) && (BlendCnt & target2))
|
||||||
{
|
{
|
||||||
eva = flag1 & 0x1F;
|
// sprite blending
|
||||||
evb = 16 - eva;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
eva = EVA;
|
|
||||||
evb = EVB;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((flag1 & 0x40) && (BlendCnt & target2))
|
|
||||||
{
|
|
||||||
// 3D layer blending
|
|
||||||
|
|
||||||
BGOBJLine[i] = ColorBlend5(val1, val2);
|
coloreffect = 1;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (flag1 & 0x80) flag1 = 0x10;
|
|
||||||
else if (flag1 & 0x40) flag1 = 0x01;
|
|
||||||
|
|
||||||
if ((BlendCnt & flag1) && (WindowMask[j] & 0x20))
|
if (flag1 & 0x40)
|
||||||
{
|
{
|
||||||
if ((bldcnteffect == 1) && (BlendCnt & target2))
|
eva = flag1 & 0x1F;
|
||||||
|
evb = 16 - eva;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
coloreffect = 1;
|
|
||||||
eva = EVA;
|
eva = EVA;
|
||||||
evb = EVB;
|
evb = EVB;
|
||||||
}
|
}
|
||||||
else if (bldcnteffect >= 2)
|
}
|
||||||
coloreffect = bldcnteffect;
|
else if ((flag1 & 0x40) && (BlendCnt & target2))
|
||||||
|
{
|
||||||
|
// 3D layer blending
|
||||||
|
|
||||||
|
BGOBJLine[i] = ColorBlend5(val1, val2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (flag1 & 0x80) flag1 = 0x10;
|
||||||
|
else if (flag1 & 0x40) flag1 = 0x01;
|
||||||
|
|
||||||
|
if ((BlendCnt & flag1) && (WindowMask[j] & 0x20))
|
||||||
|
{
|
||||||
|
if ((bldcnteffect == 1) && (BlendCnt & target2))
|
||||||
|
{
|
||||||
|
coloreffect = 1;
|
||||||
|
eva = EVA;
|
||||||
|
evb = EVB;
|
||||||
|
}
|
||||||
|
else if (bldcnteffect >= 2)
|
||||||
|
coloreffect = bldcnteffect;
|
||||||
|
else
|
||||||
|
coloreffect = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
coloreffect = 0;
|
coloreffect = 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
coloreffect = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (coloreffect)
|
switch (coloreffect)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
BGOBJLine[i] = val1;
|
BGOBJLine[i] = val1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb);
|
BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
BGOBJLine[i] = ColorBrightnessUp(val1, EVY);
|
BGOBJLine[i] = ColorBrightnessUp(val1, EVY);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
BGOBJLine[i] = ColorBrightnessDown(val1, EVY);
|
BGOBJLine[i] = ColorBrightnessDown(val1, EVY);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1429,6 +1440,17 @@ void GPU2D::DrawPixel_4x(u32* dst, u16 color, u32 flag)
|
||||||
*(u64*)(dst+3072+2) = val;
|
*(u64*)(dst+3072+2) = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPU2D::DrawPixel_Accel(u32* dst, u16 color, u32 flag)
|
||||||
|
{
|
||||||
|
u8 r = (color & 0x001F) << 1;
|
||||||
|
u8 g = (color & 0x03E0) >> 4;
|
||||||
|
u8 b = (color & 0x7C00) >> 9;
|
||||||
|
|
||||||
|
*(dst+512) = *(dst+256);
|
||||||
|
*(dst+256) = *dst;
|
||||||
|
*dst = r | (g << 8) | (b << 16) | flag;
|
||||||
|
}
|
||||||
|
|
||||||
void GPU2D::DrawBG_3D()
|
void GPU2D::DrawBG_3D()
|
||||||
{
|
{
|
||||||
u16 xoff = BGXPos[0];
|
u16 xoff = BGXPos[0];
|
||||||
|
@ -1445,7 +1467,18 @@ void GPU2D::DrawBG_3D()
|
||||||
iend -= (xoff & 0xFF);
|
iend -= (xoff & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LineScale == 1)
|
if (Accelerated)
|
||||||
|
{
|
||||||
|
for (; i < iend; i++)
|
||||||
|
{
|
||||||
|
if (!(WindowMask[i] & 0x01)) continue;
|
||||||
|
|
||||||
|
BGOBJLine[i+512] = BGOBJLine[i+256];
|
||||||
|
BGOBJLine[i+256] = BGOBJLine[i];
|
||||||
|
BGOBJLine[i] = 0x40000000; // 3D-layer placeholder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (LineScale == 1)
|
||||||
{
|
{
|
||||||
for (; i < iend; i++)
|
for (; i < iend; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
|
|
||||||
void SetEnabled(bool enable) { Enabled = enable; }
|
void SetEnabled(bool enable) { Enabled = enable; }
|
||||||
void SetFramebuffer(u32* buf);
|
void SetFramebuffer(u32* buf);
|
||||||
void SetScale(int scale);
|
void SetDisplaySettings(int scale, bool accel);
|
||||||
|
|
||||||
u8 Read8(u32 addr);
|
u8 Read8(u32 addr);
|
||||||
u16 Read16(u32 addr);
|
u16 Read16(u32 addr);
|
||||||
|
@ -71,6 +71,7 @@ private:
|
||||||
|
|
||||||
u32 LineStride;
|
u32 LineStride;
|
||||||
u32 LineScale;
|
u32 LineScale;
|
||||||
|
bool Accelerated;
|
||||||
|
|
||||||
u32 BGOBJLine[1024*4 * 2];
|
u32 BGOBJLine[1024*4 * 2];
|
||||||
u32* _3DLine;
|
u32* _3DLine;
|
||||||
|
@ -136,6 +137,7 @@ private:
|
||||||
static void DrawPixel_1x(u32* dst, u16 color, u32 flag);
|
static void DrawPixel_1x(u32* dst, u16 color, u32 flag);
|
||||||
static void DrawPixel_2x(u32* dst, u16 color, u32 flag);
|
static void DrawPixel_2x(u32* dst, u16 color, u32 flag);
|
||||||
static void DrawPixel_4x(u32* dst, u16 color, u32 flag);
|
static void DrawPixel_4x(u32* dst, u16 color, u32 flag);
|
||||||
|
static void DrawPixel_Accel(u32* dst, u16 color, u32 flag);
|
||||||
void (*DrawPixel)(u32* dst, u16 color, u32 flag);
|
void (*DrawPixel)(u32* dst, u16 color, u32 flag);
|
||||||
|
|
||||||
void DrawBG_3D();
|
void DrawBG_3D();
|
||||||
|
|
|
@ -607,9 +607,9 @@ void SetEnabled(bool geometry, bool rendering)
|
||||||
if (!rendering) ResetRenderingState();
|
if (!rendering) ResetRenderingState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetScale(int scale)
|
void SetDisplaySettings(int scale, bool accel)
|
||||||
{
|
{
|
||||||
GLRenderer43::SetScale(scale);
|
GLRenderer43::SetDisplaySettings(scale, accel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ void Reset();
|
||||||
void DoSavestate(Savestate* file);
|
void DoSavestate(Savestate* file);
|
||||||
|
|
||||||
void SetEnabled(bool geometry, bool rendering);
|
void SetEnabled(bool geometry, bool rendering);
|
||||||
void SetScale(int scale);
|
void SetDisplaySettings(int scale, bool accel);
|
||||||
|
|
||||||
void ExecuteCommand();
|
void ExecuteCommand();
|
||||||
|
|
||||||
|
@ -110,6 +110,7 @@ void VCount144();
|
||||||
void VBlank();
|
void VBlank();
|
||||||
void VCount215();
|
void VCount215();
|
||||||
u32* GetLine(int line);
|
u32* GetLine(int line);
|
||||||
|
void SetupAccelFrame();
|
||||||
|
|
||||||
void WriteToGXFIFO(u32 val);
|
void WriteToGXFIFO(u32 val);
|
||||||
|
|
||||||
|
@ -127,13 +128,14 @@ bool Init();
|
||||||
void DeInit();
|
void DeInit();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
void SetScale(int scale);
|
void SetDisplaySettings(int scale, bool accel);
|
||||||
|
|
||||||
void SetupRenderThread();
|
void SetupRenderThread();
|
||||||
|
|
||||||
void VCount144();
|
void VCount144();
|
||||||
void RenderFrame();
|
void RenderFrame();
|
||||||
u32* GetLine(int line);
|
u32* GetLine(int line);
|
||||||
|
void SetupAccelFrame();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,11 +146,12 @@ bool Init();
|
||||||
void DeInit();
|
void DeInit();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
void SetScale(int scale);
|
void SetDisplaySettings(int scale, bool accel);
|
||||||
|
|
||||||
void VCount144();
|
void VCount144();
|
||||||
void RenderFrame();
|
void RenderFrame();
|
||||||
u32* GetLine(int line);
|
u32* GetLine(int line);
|
||||||
|
void SetupAccelFrame();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "NDS.h"
|
#include "NDS.h"
|
||||||
#include "GPU.h"
|
#include "GPU.h"
|
||||||
#include "OpenGLSupport.h"
|
#include "OpenGLSupport.h"
|
||||||
|
#include "GPU3D_OpenGL43_shaders.h"
|
||||||
|
|
||||||
namespace GPU3D
|
namespace GPU3D
|
||||||
{
|
{
|
||||||
|
@ -33,631 +34,6 @@ namespace GLRenderer43
|
||||||
// * UBO: 3.1
|
// * UBO: 3.1
|
||||||
// * glMemoryBarrier: 4.2
|
// * glMemoryBarrier: 4.2
|
||||||
|
|
||||||
// TODO: consider other way to handle uniforms (UBO?)
|
|
||||||
|
|
||||||
#define kShaderHeader "#version 430"
|
|
||||||
|
|
||||||
|
|
||||||
const char* kClearVS = kShaderHeader R"(
|
|
||||||
|
|
||||||
layout(location=0) in vec2 vPosition;
|
|
||||||
|
|
||||||
layout(location=1) uniform uint uDepth;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
float fdepth = (float(uDepth) / 8388608.0) - 1.0;
|
|
||||||
gl_Position = vec4(vPosition, fdepth, 1.0);
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
const char* kClearFS = kShaderHeader R"(
|
|
||||||
|
|
||||||
layout(location=0) uniform uvec4 uColor;
|
|
||||||
layout(location=2) uniform uint uOpaquePolyID;
|
|
||||||
layout(location=3) uniform uint uFogFlag;
|
|
||||||
|
|
||||||
layout(location=0) out vec4 oColor;
|
|
||||||
layout(location=1) out uvec3 oAttr;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
oColor = vec4(uColor).bgra / 31.0;
|
|
||||||
oAttr.r = 0;
|
|
||||||
oAttr.g = uOpaquePolyID;
|
|
||||||
oAttr.b = 0;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
|
|
||||||
const char* kRenderVSCommon = R"(
|
|
||||||
|
|
||||||
layout(std140, binding=0) uniform uConfig
|
|
||||||
{
|
|
||||||
vec2 uScreenSize;
|
|
||||||
uint uDispCnt;
|
|
||||||
vec4 uToonColors[32];
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(location=0) in uvec4 vPosition;
|
|
||||||
layout(location=1) in uvec4 vColor;
|
|
||||||
layout(location=2) in ivec2 vTexcoord;
|
|
||||||
layout(location=3) in uvec3 vPolygonAttr;
|
|
||||||
|
|
||||||
smooth out vec4 fColor;
|
|
||||||
smooth out vec2 fTexcoord;
|
|
||||||
flat out uvec3 fPolygonAttr;
|
|
||||||
)";
|
|
||||||
|
|
||||||
const char* kRenderFSCommon = R"(
|
|
||||||
|
|
||||||
layout(binding=0) uniform usampler2D TexMem;
|
|
||||||
layout(binding=1) uniform sampler2D TexPalMem;
|
|
||||||
|
|
||||||
layout(std140, binding=0) uniform uConfig
|
|
||||||
{
|
|
||||||
vec2 uScreenSize;
|
|
||||||
uint uDispCnt;
|
|
||||||
vec4 uToonColors[32];
|
|
||||||
};
|
|
||||||
|
|
||||||
smooth in vec4 fColor;
|
|
||||||
smooth in vec2 fTexcoord;
|
|
||||||
flat in uvec3 fPolygonAttr;
|
|
||||||
|
|
||||||
layout(location=0) out vec4 oColor;
|
|
||||||
layout(location=1) out uvec3 oAttr;
|
|
||||||
|
|
||||||
int TexcoordWrap(int c, int maxc, uint mode)
|
|
||||||
{
|
|
||||||
if ((mode & (1<<0)) != 0)
|
|
||||||
{
|
|
||||||
if ((mode & (1<<2)) != 0 && (c & maxc) != 0)
|
|
||||||
return (maxc-1) - (c & (maxc-1));
|
|
||||||
else
|
|
||||||
return (c & (maxc-1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return clamp(c, 0, maxc-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode)
|
|
||||||
{
|
|
||||||
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
|
||||||
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
|
||||||
|
|
||||||
addr.x += ((st.y * st.z) + st.x);
|
|
||||||
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
|
||||||
|
|
||||||
pixel.a = (pixel.r & 0xE0);
|
|
||||||
pixel.a = (pixel.a >> 3) + (pixel.a >> 6);
|
|
||||||
pixel.r &= 0x1F;
|
|
||||||
|
|
||||||
addr.y = (addr.y << 3) + int(pixel.r);
|
|
||||||
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
|
|
||||||
return vec4(color.rgb, float(pixel.a)/31.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0)
|
|
||||||
{
|
|
||||||
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
|
||||||
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
|
||||||
|
|
||||||
addr.x += ((st.y * st.z) + st.x) >> 2;
|
|
||||||
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
|
||||||
pixel.r >>= (2 * (st.x & 3));
|
|
||||||
pixel.r &= 0x03;
|
|
||||||
|
|
||||||
addr.y = (addr.y << 2) + int(pixel.r);
|
|
||||||
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
|
|
||||||
return vec4(color.rgb, max(step(1,pixel.r),alpha0));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0)
|
|
||||||
{
|
|
||||||
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
|
||||||
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
|
||||||
|
|
||||||
addr.x += ((st.y * st.z) + st.x) >> 1;
|
|
||||||
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
|
||||||
if ((st.x & 1) != 0) pixel.r >>= 4;
|
|
||||||
else pixel.r &= 0x0F;
|
|
||||||
|
|
||||||
addr.y = (addr.y << 3) + int(pixel.r);
|
|
||||||
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
|
|
||||||
return vec4(color.rgb, max(step(1,pixel.r),alpha0));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0)
|
|
||||||
{
|
|
||||||
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
|
||||||
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
|
||||||
|
|
||||||
addr.x += ((st.y * st.z) + st.x);
|
|
||||||
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
|
||||||
|
|
||||||
addr.y = (addr.y << 3) + int(pixel.r);
|
|
||||||
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
|
|
||||||
return vec4(color.rgb, max(step(1,pixel.r),alpha0));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode)
|
|
||||||
{
|
|
||||||
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
|
||||||
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
|
||||||
|
|
||||||
addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3);
|
|
||||||
uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
|
||||||
uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3;
|
|
||||||
|
|
||||||
int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1);
|
|
||||||
if (addr.x >= 0x40000) slot1addr += 0x10000;
|
|
||||||
|
|
||||||
uint palinfo;
|
|
||||||
p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0);
|
|
||||||
palinfo = p.r;
|
|
||||||
slot1addr++;
|
|
||||||
p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0);
|
|
||||||
palinfo |= (p.r << 8);
|
|
||||||
|
|
||||||
addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1);
|
|
||||||
palinfo >>= 14;
|
|
||||||
|
|
||||||
if (val == 0)
|
|
||||||
{
|
|
||||||
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
return vec4(color.rgb, 1.0);
|
|
||||||
}
|
|
||||||
else if (val == 1)
|
|
||||||
{
|
|
||||||
addr.y++;
|
|
||||||
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
return vec4(color.rgb, 1.0);
|
|
||||||
}
|
|
||||||
else if (val == 2)
|
|
||||||
{
|
|
||||||
if (palinfo == 1)
|
|
||||||
{
|
|
||||||
vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
addr.y++;
|
|
||||||
vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
return vec4((color0.rgb + color1.rgb) / 2.0, 1.0);
|
|
||||||
}
|
|
||||||
else if (palinfo == 3)
|
|
||||||
{
|
|
||||||
vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
addr.y++;
|
|
||||||
vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
addr.y += 2;
|
|
||||||
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
return vec4(color.rgb, 1.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (palinfo == 2)
|
|
||||||
{
|
|
||||||
addr.y += 3;
|
|
||||||
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
return vec4(color.rgb, 1.0);
|
|
||||||
}
|
|
||||||
else if (palinfo == 3)
|
|
||||||
{
|
|
||||||
vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
addr.y++;
|
|
||||||
vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return vec4(0.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode)
|
|
||||||
{
|
|
||||||
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
|
||||||
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
|
||||||
|
|
||||||
addr.x += ((st.y * st.z) + st.x);
|
|
||||||
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
|
||||||
|
|
||||||
pixel.a = (pixel.r & 0xF8) >> 3;
|
|
||||||
pixel.r &= 0x07;
|
|
||||||
|
|
||||||
addr.y = (addr.y << 3) + int(pixel.r);
|
|
||||||
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
|
||||||
|
|
||||||
return vec4(color.rgb, float(pixel.a)/31.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode)
|
|
||||||
{
|
|
||||||
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
|
||||||
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
|
||||||
|
|
||||||
addr.x += ((st.y * st.z) + st.x) << 1;
|
|
||||||
uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
|
||||||
addr.x++;
|
|
||||||
uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
|
||||||
|
|
||||||
vec4 color;
|
|
||||||
color.r = float(pixelL.r & 0x1F) / 31.0;
|
|
||||||
color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0;
|
|
||||||
color.b = float((pixelH.r & 0x7C) >> 2) / 31.0;
|
|
||||||
color.a = float(pixelH.r >> 7);
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 TextureLookup_Nearest(vec2 st)
|
|
||||||
{
|
|
||||||
uint attr = fPolygonAttr.y;
|
|
||||||
uint paladdr = fPolygonAttr.z;
|
|
||||||
|
|
||||||
float alpha0;
|
|
||||||
if ((attr & (1<<29)) != 0) alpha0 = 0.0;
|
|
||||||
else alpha0 = 1.0;
|
|
||||||
|
|
||||||
int tw = 8 << int((attr >> 20) & 0x7);
|
|
||||||
int th = 8 << int((attr >> 23) & 0x7);
|
|
||||||
ivec4 st_full = ivec4(ivec2(st), tw, th);
|
|
||||||
|
|
||||||
ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr));
|
|
||||||
uint wrapmode = attr >> 16;
|
|
||||||
|
|
||||||
uint type = (attr >> 26) & 0x7;
|
|
||||||
if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode);
|
|
||||||
else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0);
|
|
||||||
else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0);
|
|
||||||
else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0);
|
|
||||||
else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode);
|
|
||||||
else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode);
|
|
||||||
else return TextureFetch_Direct (vramaddr, st_full, wrapmode);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 TextureLookup_Linear(vec2 texcoord)
|
|
||||||
{
|
|
||||||
ivec2 intpart = ivec2(texcoord);
|
|
||||||
vec2 fracpart = fract(texcoord);
|
|
||||||
|
|
||||||
uint attr = fPolygonAttr.y;
|
|
||||||
uint paladdr = fPolygonAttr.z;
|
|
||||||
|
|
||||||
float alpha0;
|
|
||||||
if ((attr & (1<<29)) != 0) alpha0 = 0.0;
|
|
||||||
else alpha0 = 1.0;
|
|
||||||
|
|
||||||
int tw = 8 << int((attr >> 20) & 0x7);
|
|
||||||
int th = 8 << int((attr >> 23) & 0x7);
|
|
||||||
ivec4 st_full = ivec4(intpart, tw, th);
|
|
||||||
|
|
||||||
ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr));
|
|
||||||
uint wrapmode = attr >> 16;
|
|
||||||
|
|
||||||
vec4 A, B, C, D;
|
|
||||||
uint type = (attr >> 26) & 0x7;
|
|
||||||
if (type == 5)
|
|
||||||
{
|
|
||||||
A = TextureFetch_Compressed(vramaddr, st_full , wrapmode);
|
|
||||||
B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
|
|
||||||
C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
|
|
||||||
D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
|
|
||||||
}
|
|
||||||
else if (type == 2)
|
|
||||||
{
|
|
||||||
A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0);
|
|
||||||
B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0);
|
|
||||||
C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0);
|
|
||||||
D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0);
|
|
||||||
}
|
|
||||||
else if (type == 3)
|
|
||||||
{
|
|
||||||
A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0);
|
|
||||||
B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0);
|
|
||||||
C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0);
|
|
||||||
D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0);
|
|
||||||
}
|
|
||||||
else if (type == 4)
|
|
||||||
{
|
|
||||||
A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0);
|
|
||||||
B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0);
|
|
||||||
C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0);
|
|
||||||
D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0);
|
|
||||||
}
|
|
||||||
else if (type == 1)
|
|
||||||
{
|
|
||||||
A = TextureFetch_A3I5(vramaddr, st_full , wrapmode);
|
|
||||||
B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
|
|
||||||
C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
|
|
||||||
D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
|
|
||||||
}
|
|
||||||
else if (type == 6)
|
|
||||||
{
|
|
||||||
A = TextureFetch_A5I3(vramaddr, st_full , wrapmode);
|
|
||||||
B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
|
|
||||||
C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
|
|
||||||
D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
A = TextureFetch_Direct(vramaddr, st_full , wrapmode);
|
|
||||||
B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
|
|
||||||
C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
|
|
||||||
D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
|
|
||||||
}
|
|
||||||
|
|
||||||
float fx = fracpart.x;
|
|
||||||
vec4 AB;
|
|
||||||
if (A.a < (0.5/31.0) && B.a < (0.5/31.0))
|
|
||||||
AB = vec4(0);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//if (A.a < (0.5/31.0) || B.a < (0.5/31.0))
|
|
||||||
// fx = step(0.5, fx);
|
|
||||||
|
|
||||||
AB = mix(A, B, fx);
|
|
||||||
}
|
|
||||||
|
|
||||||
fx = fracpart.x;
|
|
||||||
vec4 CD;
|
|
||||||
if (C.a < (0.5/31.0) && D.a < (0.5/31.0))
|
|
||||||
CD = vec4(0);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//if (C.a < (0.5/31.0) || D.a < (0.5/31.0))
|
|
||||||
// fx = step(0.5, fx);
|
|
||||||
|
|
||||||
CD = mix(C, D, fx);
|
|
||||||
}
|
|
||||||
|
|
||||||
fx = fracpart.y;
|
|
||||||
vec4 ret;
|
|
||||||
if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0))
|
|
||||||
ret = vec4(0);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0))
|
|
||||||
// fx = step(0.5, fx);
|
|
||||||
|
|
||||||
ret = mix(AB, CD, fx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 FinalColor()
|
|
||||||
{
|
|
||||||
vec4 col;
|
|
||||||
vec4 vcol = fColor;
|
|
||||||
uint blendmode = (fPolygonAttr.x >> 4) & 0x3;
|
|
||||||
|
|
||||||
if (blendmode == 2)
|
|
||||||
{
|
|
||||||
if ((uDispCnt & (1<<1)) == 0)
|
|
||||||
{
|
|
||||||
// toon
|
|
||||||
vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb;
|
|
||||||
vcol.rgb = tooncolor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// highlight
|
|
||||||
vcol.rgb = vcol.rrr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0))
|
|
||||||
{
|
|
||||||
// no texture
|
|
||||||
col = vcol;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vec4 tcol = TextureLookup_Nearest(fTexcoord);
|
|
||||||
//vec4 tcol = TextureLookup_Linear(fTexcoord);
|
|
||||||
|
|
||||||
if ((blendmode & 1) != 0)
|
|
||||||
{
|
|
||||||
// decal
|
|
||||||
col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a));
|
|
||||||
col.a = vcol.a;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// modulate
|
|
||||||
col = vcol * tcol;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blendmode == 2)
|
|
||||||
{
|
|
||||||
if ((uDispCnt & (1<<1)) != 0)
|
|
||||||
{
|
|
||||||
vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb;
|
|
||||||
col.rgb = min(col.rgb + tooncolor, 1.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return col.bgra;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
|
|
||||||
const char* kRenderVS_Z = R"(
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
uint attr = vPolygonAttr.x;
|
|
||||||
uint zshift = (attr >> 16) & 0x1F;
|
|
||||||
|
|
||||||
vec4 fpos;
|
|
||||||
fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0;
|
|
||||||
fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0;
|
|
||||||
fpos.w = float(vPosition.w) / 65536.0f;
|
|
||||||
fpos.xyz *= fpos.w;
|
|
||||||
|
|
||||||
fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0);
|
|
||||||
fTexcoord = vec2(vTexcoord) / 16.0;
|
|
||||||
fPolygonAttr = vPolygonAttr;
|
|
||||||
|
|
||||||
gl_Position = fpos;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
const char* kRenderVS_W = R"(
|
|
||||||
|
|
||||||
smooth out float fZ;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
uint attr = vPolygonAttr.x;
|
|
||||||
uint zshift = (attr >> 16) & 0x1F;
|
|
||||||
|
|
||||||
vec4 fpos;
|
|
||||||
fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0;
|
|
||||||
fZ = float(vPosition.z << zshift) / 16777216.0;
|
|
||||||
fpos.w = float(vPosition.w) / 65536.0f;
|
|
||||||
fpos.xy *= fpos.w;
|
|
||||||
|
|
||||||
fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0);
|
|
||||||
fTexcoord = vec2(vTexcoord) / 16.0;
|
|
||||||
fPolygonAttr = vPolygonAttr;
|
|
||||||
|
|
||||||
gl_Position = fpos;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
|
|
||||||
const char* kRenderFS_ZO = R"(
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 col = FinalColor();
|
|
||||||
if (col.a < 30.5/31) discard;
|
|
||||||
|
|
||||||
oColor = col;
|
|
||||||
oAttr.g = (fPolygonAttr.x >> 24) & 0x3F;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
const char* kRenderFS_WO = R"(
|
|
||||||
|
|
||||||
smooth in float fZ;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 col = FinalColor();
|
|
||||||
if (col.a < 30.5/31) discard;
|
|
||||||
|
|
||||||
oColor = col;
|
|
||||||
oAttr.g = (fPolygonAttr.x >> 24) & 0x3F;
|
|
||||||
gl_FragDepth = fZ;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
const char* kRenderFS_ZT = R"(
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 col = FinalColor();
|
|
||||||
if (col.a < 0.5/31) discard;
|
|
||||||
if (col.a >= 30.5/31) discard;
|
|
||||||
|
|
||||||
oColor = col;
|
|
||||||
oAttr.g = 0xFF;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
const char* kRenderFS_WT = R"(
|
|
||||||
|
|
||||||
smooth in float fZ;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 col = FinalColor();
|
|
||||||
if (col.a < 0.5/31) discard;
|
|
||||||
if (col.a >= 30.5/31) discard;
|
|
||||||
|
|
||||||
oColor = col;
|
|
||||||
oAttr.g = 0xFF;
|
|
||||||
gl_FragDepth = fZ;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
const char* kRenderFS_ZSM = R"(
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
oColor = vec4(0,0,0,1);
|
|
||||||
oAttr.g = 0xFF;
|
|
||||||
oAttr.b = 1;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
const char* kRenderFS_WSM = R"(
|
|
||||||
|
|
||||||
smooth in float fZ;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
oColor = vec4(0,0,0,1);
|
|
||||||
oAttr.g = 0xFF;
|
|
||||||
oAttr.b = 1;
|
|
||||||
gl_FragDepth = fZ;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
const char* kRenderFS_ZS = R"(
|
|
||||||
|
|
||||||
layout(binding=2) uniform usampler2D iAttrTex;
|
|
||||||
//layout(origin_upper_left) in vec4 gl_FragCoord;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 col = FinalColor();
|
|
||||||
if (col.a < 0.5/31) discard;
|
|
||||||
if (col.a >= 30.5/31) discard;
|
|
||||||
|
|
||||||
uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0);
|
|
||||||
if (iAttr.b != 1) discard;
|
|
||||||
if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard;
|
|
||||||
|
|
||||||
oColor = col;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
const char* kRenderFS_WS = R"(
|
|
||||||
|
|
||||||
layout(binding=2) uniform usampler2D iAttrTex;
|
|
||||||
//layout(origin_upper_left) in vec4 gl_FragCoord;
|
|
||||||
|
|
||||||
smooth in float fZ;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 col = FinalColor();
|
|
||||||
if (col.a < 0.5/31) discard;
|
|
||||||
if (col.a >= 30.5/31) discard;
|
|
||||||
|
|
||||||
uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0);
|
|
||||||
if (iAttr.b != 1) discard;
|
|
||||||
if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard;
|
|
||||||
|
|
||||||
oColor = col;
|
|
||||||
gl_FragDepth = fZ;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -721,6 +97,7 @@ GLuint TexMemID;
|
||||||
GLuint TexPalMemID;
|
GLuint TexPalMemID;
|
||||||
|
|
||||||
int ScaleFactor;
|
int ScaleFactor;
|
||||||
|
bool Accelerated;
|
||||||
int ScreenW, ScreenH;
|
int ScreenW, ScreenH;
|
||||||
|
|
||||||
GLuint FramebufferTex[4];
|
GLuint FramebufferTex[4];
|
||||||
|
@ -968,9 +345,10 @@ void Reset()
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetScale(int scale)
|
void SetDisplaySettings(int scale, bool accel)
|
||||||
{
|
{
|
||||||
ScaleFactor = scale;
|
ScaleFactor = scale;
|
||||||
|
Accelerated = accel;
|
||||||
|
|
||||||
// TODO: antialiasing setting
|
// TODO: antialiasing setting
|
||||||
ScreenW = 256 << scale;
|
ScreenW = 256 << scale;
|
||||||
|
@ -986,10 +364,12 @@ void SetScale(int scale)
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID);
|
||||||
glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ);
|
if (accel) glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ);
|
||||||
|
else glBufferData(GL_PIXEL_PACK_BUFFER, 256*192, NULL, GL_DYNAMIC_READ);
|
||||||
|
|
||||||
if (Framebuffer) delete[] Framebuffer;
|
if (Framebuffer) delete[] Framebuffer;
|
||||||
Framebuffer = new u32[ScreenW*ScreenH];
|
if (accel) Framebuffer = new u32[256*192];
|
||||||
|
else Framebuffer = new u32[ScreenW*ScreenH];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1533,5 +913,10 @@ u32* GetLine(int line)
|
||||||
return &Framebuffer[stride * line];
|
return &Framebuffer[stride * line];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupAccelFrame()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,645 @@
|
||||||
|
/*
|
||||||
|
Copyright 2016-2019 Arisotura
|
||||||
|
|
||||||
|
This file is part of melonDS.
|
||||||
|
|
||||||
|
melonDS 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 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
melonDS 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 melonDS. If not, see http://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GPU3D_OPENGL43_SHADERS_H
|
||||||
|
#define GPU3D_OPENGL43_SHADERS_H
|
||||||
|
|
||||||
|
#define kShaderHeader "#version 430"
|
||||||
|
|
||||||
|
|
||||||
|
const char* kClearVS = kShaderHeader R"(
|
||||||
|
|
||||||
|
layout(location=0) in vec2 vPosition;
|
||||||
|
|
||||||
|
layout(location=1) uniform uint uDepth;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
float fdepth = (float(uDepth) / 8388608.0) - 1.0;
|
||||||
|
gl_Position = vec4(vPosition, fdepth, 1.0);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kClearFS = kShaderHeader R"(
|
||||||
|
|
||||||
|
layout(location=0) uniform uvec4 uColor;
|
||||||
|
layout(location=2) uniform uint uOpaquePolyID;
|
||||||
|
layout(location=3) uniform uint uFogFlag;
|
||||||
|
|
||||||
|
layout(location=0) out vec4 oColor;
|
||||||
|
layout(location=1) out uvec3 oAttr;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
oColor = vec4(uColor).bgra / 31.0;
|
||||||
|
oAttr.r = 0;
|
||||||
|
oAttr.g = uOpaquePolyID;
|
||||||
|
oAttr.b = 0;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
|
||||||
|
const char* kRenderVSCommon = R"(
|
||||||
|
|
||||||
|
layout(std140, binding=0) uniform uConfig
|
||||||
|
{
|
||||||
|
vec2 uScreenSize;
|
||||||
|
uint uDispCnt;
|
||||||
|
vec4 uToonColors[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(location=0) in uvec4 vPosition;
|
||||||
|
layout(location=1) in uvec4 vColor;
|
||||||
|
layout(location=2) in ivec2 vTexcoord;
|
||||||
|
layout(location=3) in uvec3 vPolygonAttr;
|
||||||
|
|
||||||
|
smooth out vec4 fColor;
|
||||||
|
smooth out vec2 fTexcoord;
|
||||||
|
flat out uvec3 fPolygonAttr;
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFSCommon = R"(
|
||||||
|
|
||||||
|
layout(binding=0) uniform usampler2D TexMem;
|
||||||
|
layout(binding=1) uniform sampler2D TexPalMem;
|
||||||
|
|
||||||
|
layout(std140, binding=0) uniform uConfig
|
||||||
|
{
|
||||||
|
vec2 uScreenSize;
|
||||||
|
uint uDispCnt;
|
||||||
|
vec4 uToonColors[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
smooth in vec4 fColor;
|
||||||
|
smooth in vec2 fTexcoord;
|
||||||
|
flat in uvec3 fPolygonAttr;
|
||||||
|
|
||||||
|
layout(location=0) out vec4 oColor;
|
||||||
|
layout(location=1) out uvec3 oAttr;
|
||||||
|
|
||||||
|
int TexcoordWrap(int c, int maxc, uint mode)
|
||||||
|
{
|
||||||
|
if ((mode & (1<<0)) != 0)
|
||||||
|
{
|
||||||
|
if ((mode & (1<<2)) != 0 && (c & maxc) != 0)
|
||||||
|
return (maxc-1) - (c & (maxc-1));
|
||||||
|
else
|
||||||
|
return (c & (maxc-1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return clamp(c, 0, maxc-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode)
|
||||||
|
{
|
||||||
|
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
||||||
|
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
||||||
|
|
||||||
|
addr.x += ((st.y * st.z) + st.x);
|
||||||
|
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
||||||
|
|
||||||
|
pixel.a = (pixel.r & 0xE0);
|
||||||
|
pixel.a = (pixel.a >> 3) + (pixel.a >> 6);
|
||||||
|
pixel.r &= 0x1F;
|
||||||
|
|
||||||
|
addr.y = (addr.y << 3) + int(pixel.r);
|
||||||
|
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
|
||||||
|
return vec4(color.rgb, float(pixel.a)/31.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0)
|
||||||
|
{
|
||||||
|
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
||||||
|
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
||||||
|
|
||||||
|
addr.x += ((st.y * st.z) + st.x) >> 2;
|
||||||
|
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
||||||
|
pixel.r >>= (2 * (st.x & 3));
|
||||||
|
pixel.r &= 0x03;
|
||||||
|
|
||||||
|
addr.y = (addr.y << 2) + int(pixel.r);
|
||||||
|
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
|
||||||
|
return vec4(color.rgb, max(step(1,pixel.r),alpha0));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0)
|
||||||
|
{
|
||||||
|
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
||||||
|
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
||||||
|
|
||||||
|
addr.x += ((st.y * st.z) + st.x) >> 1;
|
||||||
|
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
||||||
|
if ((st.x & 1) != 0) pixel.r >>= 4;
|
||||||
|
else pixel.r &= 0x0F;
|
||||||
|
|
||||||
|
addr.y = (addr.y << 3) + int(pixel.r);
|
||||||
|
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
|
||||||
|
return vec4(color.rgb, max(step(1,pixel.r),alpha0));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0)
|
||||||
|
{
|
||||||
|
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
||||||
|
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
||||||
|
|
||||||
|
addr.x += ((st.y * st.z) + st.x);
|
||||||
|
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
||||||
|
|
||||||
|
addr.y = (addr.y << 3) + int(pixel.r);
|
||||||
|
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
|
||||||
|
return vec4(color.rgb, max(step(1,pixel.r),alpha0));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode)
|
||||||
|
{
|
||||||
|
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
||||||
|
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
||||||
|
|
||||||
|
addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3);
|
||||||
|
uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
||||||
|
uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3;
|
||||||
|
|
||||||
|
int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1);
|
||||||
|
if (addr.x >= 0x40000) slot1addr += 0x10000;
|
||||||
|
|
||||||
|
uint palinfo;
|
||||||
|
p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0);
|
||||||
|
palinfo = p.r;
|
||||||
|
slot1addr++;
|
||||||
|
p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0);
|
||||||
|
palinfo |= (p.r << 8);
|
||||||
|
|
||||||
|
addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1);
|
||||||
|
palinfo >>= 14;
|
||||||
|
|
||||||
|
if (val == 0)
|
||||||
|
{
|
||||||
|
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
return vec4(color.rgb, 1.0);
|
||||||
|
}
|
||||||
|
else if (val == 1)
|
||||||
|
{
|
||||||
|
addr.y++;
|
||||||
|
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
return vec4(color.rgb, 1.0);
|
||||||
|
}
|
||||||
|
else if (val == 2)
|
||||||
|
{
|
||||||
|
if (palinfo == 1)
|
||||||
|
{
|
||||||
|
vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
addr.y++;
|
||||||
|
vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
return vec4((color0.rgb + color1.rgb) / 2.0, 1.0);
|
||||||
|
}
|
||||||
|
else if (palinfo == 3)
|
||||||
|
{
|
||||||
|
vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
addr.y++;
|
||||||
|
vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addr.y += 2;
|
||||||
|
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
return vec4(color.rgb, 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (palinfo == 2)
|
||||||
|
{
|
||||||
|
addr.y += 3;
|
||||||
|
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
return vec4(color.rgb, 1.0);
|
||||||
|
}
|
||||||
|
else if (palinfo == 3)
|
||||||
|
{
|
||||||
|
vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
addr.y++;
|
||||||
|
vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return vec4(0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode)
|
||||||
|
{
|
||||||
|
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
||||||
|
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
||||||
|
|
||||||
|
addr.x += ((st.y * st.z) + st.x);
|
||||||
|
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
||||||
|
|
||||||
|
pixel.a = (pixel.r & 0xF8) >> 3;
|
||||||
|
pixel.r &= 0x07;
|
||||||
|
|
||||||
|
addr.y = (addr.y << 3) + int(pixel.r);
|
||||||
|
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
|
||||||
|
return vec4(color.rgb, float(pixel.a)/31.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode)
|
||||||
|
{
|
||||||
|
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
|
||||||
|
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
|
||||||
|
|
||||||
|
addr.x += ((st.y * st.z) + st.x) << 1;
|
||||||
|
uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
||||||
|
addr.x++;
|
||||||
|
uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
|
||||||
|
|
||||||
|
vec4 color;
|
||||||
|
color.r = float(pixelL.r & 0x1F) / 31.0;
|
||||||
|
color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0;
|
||||||
|
color.b = float((pixelH.r & 0x7C) >> 2) / 31.0;
|
||||||
|
color.a = float(pixelH.r >> 7);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TextureLookup_Nearest(vec2 st)
|
||||||
|
{
|
||||||
|
uint attr = fPolygonAttr.y;
|
||||||
|
uint paladdr = fPolygonAttr.z;
|
||||||
|
|
||||||
|
float alpha0;
|
||||||
|
if ((attr & (1<<29)) != 0) alpha0 = 0.0;
|
||||||
|
else alpha0 = 1.0;
|
||||||
|
|
||||||
|
int tw = 8 << int((attr >> 20) & 0x7);
|
||||||
|
int th = 8 << int((attr >> 23) & 0x7);
|
||||||
|
ivec4 st_full = ivec4(ivec2(st), tw, th);
|
||||||
|
|
||||||
|
ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr));
|
||||||
|
uint wrapmode = attr >> 16;
|
||||||
|
|
||||||
|
uint type = (attr >> 26) & 0x7;
|
||||||
|
if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode);
|
||||||
|
else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0);
|
||||||
|
else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0);
|
||||||
|
else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0);
|
||||||
|
else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode);
|
||||||
|
else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode);
|
||||||
|
else return TextureFetch_Direct (vramaddr, st_full, wrapmode);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TextureLookup_Linear(vec2 texcoord)
|
||||||
|
{
|
||||||
|
ivec2 intpart = ivec2(texcoord);
|
||||||
|
vec2 fracpart = fract(texcoord);
|
||||||
|
|
||||||
|
uint attr = fPolygonAttr.y;
|
||||||
|
uint paladdr = fPolygonAttr.z;
|
||||||
|
|
||||||
|
float alpha0;
|
||||||
|
if ((attr & (1<<29)) != 0) alpha0 = 0.0;
|
||||||
|
else alpha0 = 1.0;
|
||||||
|
|
||||||
|
int tw = 8 << int((attr >> 20) & 0x7);
|
||||||
|
int th = 8 << int((attr >> 23) & 0x7);
|
||||||
|
ivec4 st_full = ivec4(intpart, tw, th);
|
||||||
|
|
||||||
|
ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr));
|
||||||
|
uint wrapmode = attr >> 16;
|
||||||
|
|
||||||
|
vec4 A, B, C, D;
|
||||||
|
uint type = (attr >> 26) & 0x7;
|
||||||
|
if (type == 5)
|
||||||
|
{
|
||||||
|
A = TextureFetch_Compressed(vramaddr, st_full , wrapmode);
|
||||||
|
B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
|
||||||
|
C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
|
||||||
|
D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
|
||||||
|
}
|
||||||
|
else if (type == 2)
|
||||||
|
{
|
||||||
|
A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0);
|
||||||
|
B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0);
|
||||||
|
C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0);
|
||||||
|
D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0);
|
||||||
|
}
|
||||||
|
else if (type == 3)
|
||||||
|
{
|
||||||
|
A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0);
|
||||||
|
B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0);
|
||||||
|
C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0);
|
||||||
|
D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0);
|
||||||
|
}
|
||||||
|
else if (type == 4)
|
||||||
|
{
|
||||||
|
A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0);
|
||||||
|
B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0);
|
||||||
|
C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0);
|
||||||
|
D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0);
|
||||||
|
}
|
||||||
|
else if (type == 1)
|
||||||
|
{
|
||||||
|
A = TextureFetch_A3I5(vramaddr, st_full , wrapmode);
|
||||||
|
B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
|
||||||
|
C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
|
||||||
|
D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
|
||||||
|
}
|
||||||
|
else if (type == 6)
|
||||||
|
{
|
||||||
|
A = TextureFetch_A5I3(vramaddr, st_full , wrapmode);
|
||||||
|
B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
|
||||||
|
C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
|
||||||
|
D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
A = TextureFetch_Direct(vramaddr, st_full , wrapmode);
|
||||||
|
B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
|
||||||
|
C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
|
||||||
|
D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
|
||||||
|
}
|
||||||
|
|
||||||
|
float fx = fracpart.x;
|
||||||
|
vec4 AB;
|
||||||
|
if (A.a < (0.5/31.0) && B.a < (0.5/31.0))
|
||||||
|
AB = vec4(0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//if (A.a < (0.5/31.0) || B.a < (0.5/31.0))
|
||||||
|
// fx = step(0.5, fx);
|
||||||
|
|
||||||
|
AB = mix(A, B, fx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fx = fracpart.x;
|
||||||
|
vec4 CD;
|
||||||
|
if (C.a < (0.5/31.0) && D.a < (0.5/31.0))
|
||||||
|
CD = vec4(0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//if (C.a < (0.5/31.0) || D.a < (0.5/31.0))
|
||||||
|
// fx = step(0.5, fx);
|
||||||
|
|
||||||
|
CD = mix(C, D, fx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fx = fracpart.y;
|
||||||
|
vec4 ret;
|
||||||
|
if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0))
|
||||||
|
ret = vec4(0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0))
|
||||||
|
// fx = step(0.5, fx);
|
||||||
|
|
||||||
|
ret = mix(AB, CD, fx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 FinalColor()
|
||||||
|
{
|
||||||
|
vec4 col;
|
||||||
|
vec4 vcol = fColor;
|
||||||
|
uint blendmode = (fPolygonAttr.x >> 4) & 0x3;
|
||||||
|
|
||||||
|
if (blendmode == 2)
|
||||||
|
{
|
||||||
|
if ((uDispCnt & (1<<1)) == 0)
|
||||||
|
{
|
||||||
|
// toon
|
||||||
|
vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb;
|
||||||
|
vcol.rgb = tooncolor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// highlight
|
||||||
|
vcol.rgb = vcol.rrr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0))
|
||||||
|
{
|
||||||
|
// no texture
|
||||||
|
col = vcol;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vec4 tcol = TextureLookup_Nearest(fTexcoord);
|
||||||
|
//vec4 tcol = TextureLookup_Linear(fTexcoord);
|
||||||
|
|
||||||
|
if ((blendmode & 1) != 0)
|
||||||
|
{
|
||||||
|
// decal
|
||||||
|
col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a));
|
||||||
|
col.a = vcol.a;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// modulate
|
||||||
|
col = vcol * tcol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blendmode == 2)
|
||||||
|
{
|
||||||
|
if ((uDispCnt & (1<<1)) != 0)
|
||||||
|
{
|
||||||
|
vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb;
|
||||||
|
col.rgb = min(col.rgb + tooncolor, 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return col.bgra;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
|
||||||
|
const char* kRenderVS_Z = R"(
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
uint attr = vPolygonAttr.x;
|
||||||
|
uint zshift = (attr >> 16) & 0x1F;
|
||||||
|
|
||||||
|
vec4 fpos;
|
||||||
|
fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0;
|
||||||
|
fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0;
|
||||||
|
fpos.w = float(vPosition.w) / 65536.0f;
|
||||||
|
fpos.xyz *= fpos.w;
|
||||||
|
|
||||||
|
fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0);
|
||||||
|
fTexcoord = vec2(vTexcoord) / 16.0;
|
||||||
|
fPolygonAttr = vPolygonAttr;
|
||||||
|
|
||||||
|
gl_Position = fpos;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderVS_W = R"(
|
||||||
|
|
||||||
|
smooth out float fZ;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
uint attr = vPolygonAttr.x;
|
||||||
|
uint zshift = (attr >> 16) & 0x1F;
|
||||||
|
|
||||||
|
vec4 fpos;
|
||||||
|
fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0;
|
||||||
|
fZ = float(vPosition.z << zshift) / 16777216.0;
|
||||||
|
fpos.w = float(vPosition.w) / 65536.0f;
|
||||||
|
fpos.xy *= fpos.w;
|
||||||
|
|
||||||
|
fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0);
|
||||||
|
fTexcoord = vec2(vTexcoord) / 16.0;
|
||||||
|
fPolygonAttr = vPolygonAttr;
|
||||||
|
|
||||||
|
gl_Position = fpos;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
|
||||||
|
const char* kRenderFS_ZO = R"(
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 col = FinalColor();
|
||||||
|
if (col.a < 30.5/31) discard;
|
||||||
|
|
||||||
|
oColor = col;
|
||||||
|
oAttr.g = (fPolygonAttr.x >> 24) & 0x3F;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFS_WO = R"(
|
||||||
|
|
||||||
|
smooth in float fZ;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 col = FinalColor();
|
||||||
|
if (col.a < 30.5/31) discard;
|
||||||
|
|
||||||
|
oColor = col;
|
||||||
|
oAttr.g = (fPolygonAttr.x >> 24) & 0x3F;
|
||||||
|
gl_FragDepth = fZ;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFS_ZT = R"(
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 col = FinalColor();
|
||||||
|
if (col.a < 0.5/31) discard;
|
||||||
|
if (col.a >= 30.5/31) discard;
|
||||||
|
|
||||||
|
oColor = col;
|
||||||
|
oAttr.g = 0xFF;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFS_WT = R"(
|
||||||
|
|
||||||
|
smooth in float fZ;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 col = FinalColor();
|
||||||
|
if (col.a < 0.5/31) discard;
|
||||||
|
if (col.a >= 30.5/31) discard;
|
||||||
|
|
||||||
|
oColor = col;
|
||||||
|
oAttr.g = 0xFF;
|
||||||
|
gl_FragDepth = fZ;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFS_ZSM = R"(
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
oColor = vec4(0,0,0,1);
|
||||||
|
oAttr.g = 0xFF;
|
||||||
|
oAttr.b = 1;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFS_WSM = R"(
|
||||||
|
|
||||||
|
smooth in float fZ;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
oColor = vec4(0,0,0,1);
|
||||||
|
oAttr.g = 0xFF;
|
||||||
|
oAttr.b = 1;
|
||||||
|
gl_FragDepth = fZ;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFS_ZS = R"(
|
||||||
|
|
||||||
|
layout(binding=2) uniform usampler2D iAttrTex;
|
||||||
|
//layout(origin_upper_left) in vec4 gl_FragCoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 col = FinalColor();
|
||||||
|
if (col.a < 0.5/31) discard;
|
||||||
|
if (col.a >= 30.5/31) discard;
|
||||||
|
|
||||||
|
uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0);
|
||||||
|
if (iAttr.b != 1) discard;
|
||||||
|
if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard;
|
||||||
|
|
||||||
|
oColor = col;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFS_WS = R"(
|
||||||
|
|
||||||
|
layout(binding=2) uniform usampler2D iAttrTex;
|
||||||
|
//layout(origin_upper_left) in vec4 gl_FragCoord;
|
||||||
|
|
||||||
|
smooth in float fZ;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 col = FinalColor();
|
||||||
|
if (col.a < 0.5/31) discard;
|
||||||
|
if (col.a >= 30.5/31) discard;
|
||||||
|
|
||||||
|
uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0);
|
||||||
|
if (iAttr.b != 1) discard;
|
||||||
|
if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard;
|
||||||
|
|
||||||
|
oColor = col;
|
||||||
|
gl_FragDepth = fZ;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
#endif // GPU3D_OPENGL43_SHADERS_H
|
|
@ -138,7 +138,7 @@ void Reset()
|
||||||
SetupRenderThread();
|
SetupRenderThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetScale(int scale)
|
void SetDisplaySettings(int scale, bool accel)
|
||||||
{
|
{
|
||||||
printf("SOFT RENDERER SCALE FACTOR: TODO!!!\n");
|
printf("SOFT RENDERER SCALE FACTOR: TODO!!!\n");
|
||||||
}
|
}
|
||||||
|
@ -2122,5 +2122,10 @@ u32* GetLine(int line)
|
||||||
return &ColorBuffer[(line * ScanlineWidth) + FirstPixelOffset];
|
return &ColorBuffer[(line * ScanlineWidth) + FirstPixelOffset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupAccelFrame()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,8 +240,8 @@ void GLDrawing_DrawScreen()
|
||||||
x1 = TopScreenRect.X + TopScreenRect.Width;
|
x1 = TopScreenRect.X + TopScreenRect.Width;
|
||||||
y1 = TopScreenRect.Y + TopScreenRect.Height;
|
y1 = TopScreenRect.Y + TopScreenRect.Height;
|
||||||
|
|
||||||
scwidth = 256 << ScreenScale[0];
|
scwidth = 256;// << ScreenScale[0];
|
||||||
scheight = 192 << ScreenScale[0];
|
scheight = 192;// << ScreenScale[0];
|
||||||
|
|
||||||
switch (ScreenRotation)
|
switch (ScreenRotation)
|
||||||
{
|
{
|
||||||
|
@ -286,8 +286,8 @@ void GLDrawing_DrawScreen()
|
||||||
x1 = BottomScreenRect.X + BottomScreenRect.Width;
|
x1 = BottomScreenRect.X + BottomScreenRect.Width;
|
||||||
y1 = BottomScreenRect.Y + BottomScreenRect.Height;
|
y1 = BottomScreenRect.Y + BottomScreenRect.Height;
|
||||||
|
|
||||||
scwidth = 256 << ScreenScale[1];
|
scwidth = 256;// << ScreenScale[1];
|
||||||
scheight = 192 << ScreenScale[1];
|
scheight = 192;// << ScreenScale[1];
|
||||||
|
|
||||||
switch (ScreenRotation)
|
switch (ScreenRotation)
|
||||||
{
|
{
|
||||||
|
@ -349,9 +349,13 @@ void GLDrawing_DrawScreen()
|
||||||
int frontbuf = GPU::FrontBuffer;
|
int frontbuf = GPU::FrontBuffer;
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture);
|
glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256<<ScreenScale[0], 192<<ScreenScale[0], GL_RGBA_INTEGER,
|
/*glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256<<ScreenScale[0], 192<<ScreenScale[0], GL_RGBA_INTEGER,
|
||||||
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]);
|
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256<<ScreenScale[1], 192<<ScreenScale[1], GL_RGBA_INTEGER,
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256<<ScreenScale[1], 192<<ScreenScale[1], GL_RGBA_INTEGER,
|
||||||
|
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]);*/
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3, 192, GL_RGBA_INTEGER,
|
||||||
|
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]);
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256*3, 192, GL_RGBA_INTEGER,
|
||||||
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]);
|
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID);
|
glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID);
|
||||||
|
@ -633,7 +637,8 @@ int EmuThreadFunc(void* burp)
|
||||||
ScreenScale[0] = ScreenScale[2];
|
ScreenScale[0] = ScreenScale[2];
|
||||||
ScreenScale[1] = ScreenScale[2];
|
ScreenScale[1] = ScreenScale[2];
|
||||||
|
|
||||||
int lastscale[2] = {-1, -1};
|
int lastscale[2] = {ScreenScale[0], ScreenScale[1]};
|
||||||
|
GPU::SetDisplaySettings(ScreenScale[0], ScreenScale[1], false);
|
||||||
|
|
||||||
Touching = false;
|
Touching = false;
|
||||||
KeyInputMask = 0xFFF;
|
KeyInputMask = 0xFFF;
|
||||||
|
@ -782,7 +787,7 @@ int EmuThreadFunc(void* burp)
|
||||||
if (ScreenScale[0] != lastscale[0] ||
|
if (ScreenScale[0] != lastscale[0] ||
|
||||||
ScreenScale[1] != lastscale[1])
|
ScreenScale[1] != lastscale[1])
|
||||||
{
|
{
|
||||||
GPU::SetFramebufferScale(ScreenScale[0], ScreenScale[1]);
|
GPU::SetDisplaySettings(ScreenScale[0], ScreenScale[1], false);
|
||||||
ScreenDrawInited = false;
|
ScreenDrawInited = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue