Merge branch 'blackmagic'
BAHAHAHHAHAHAHAAHAHAHAHHH HARK HARK HARK HARK HA-*~
This commit is contained in:
commit
94f5ecb647
75
melonDS.cbp
75
melonDS.cbp
|
@ -19,22 +19,6 @@
|
||||||
</Compiler>
|
</Compiler>
|
||||||
<Linker>
|
<Linker>
|
||||||
<Add option="-m64" />
|
<Add option="-m64" />
|
||||||
<Add library="SDL2" />
|
|
||||||
<Add library="shell32" />
|
|
||||||
<Add library="comctl32" />
|
|
||||||
<Add library="comdlg32" />
|
|
||||||
<Add library="advapi32" />
|
|
||||||
<Add library="wsock32" />
|
|
||||||
<Add library="oleacc" />
|
|
||||||
<Add library="ole32" />
|
|
||||||
<Add library="usp10" />
|
|
||||||
<Add library="gdi32" />
|
|
||||||
<Add library="d2d1" />
|
|
||||||
<Add library="dwrite" />
|
|
||||||
<Add library="uxtheme" />
|
|
||||||
<Add library="iphlpapi" />
|
|
||||||
<Add library="user32" />
|
|
||||||
<Add library="ws2_32" />
|
|
||||||
</Linker>
|
</Linker>
|
||||||
</Target>
|
</Target>
|
||||||
<Target title="Release Windows">
|
<Target title="Release Windows">
|
||||||
|
@ -51,22 +35,6 @@
|
||||||
<Linker>
|
<Linker>
|
||||||
<Add option="-s" />
|
<Add option="-s" />
|
||||||
<Add option="-m64" />
|
<Add option="-m64" />
|
||||||
<Add library="SDL2" />
|
|
||||||
<Add library="shell32" />
|
|
||||||
<Add library="comctl32" />
|
|
||||||
<Add library="comdlg32" />
|
|
||||||
<Add library="advapi32" />
|
|
||||||
<Add library="wsock32" />
|
|
||||||
<Add library="oleacc" />
|
|
||||||
<Add library="ole32" />
|
|
||||||
<Add library="usp10" />
|
|
||||||
<Add library="gdi32" />
|
|
||||||
<Add library="d2d1" />
|
|
||||||
<Add library="dwrite" />
|
|
||||||
<Add library="uxtheme" />
|
|
||||||
<Add library="iphlpapi" />
|
|
||||||
<Add library="user32" />
|
|
||||||
<Add library="ws2_32" />
|
|
||||||
</Linker>
|
</Linker>
|
||||||
</Target>
|
</Target>
|
||||||
<Target title="DebugFast Windows">
|
<Target title="DebugFast Windows">
|
||||||
|
@ -82,22 +50,6 @@
|
||||||
</Compiler>
|
</Compiler>
|
||||||
<Linker>
|
<Linker>
|
||||||
<Add option="-m64" />
|
<Add option="-m64" />
|
||||||
<Add library="SDL2" />
|
|
||||||
<Add library="shell32" />
|
|
||||||
<Add library="comctl32" />
|
|
||||||
<Add library="comdlg32" />
|
|
||||||
<Add library="advapi32" />
|
|
||||||
<Add library="wsock32" />
|
|
||||||
<Add library="oleacc" />
|
|
||||||
<Add library="ole32" />
|
|
||||||
<Add library="usp10" />
|
|
||||||
<Add library="gdi32" />
|
|
||||||
<Add library="d2d1" />
|
|
||||||
<Add library="dwrite" />
|
|
||||||
<Add library="uxtheme" />
|
|
||||||
<Add library="iphlpapi" />
|
|
||||||
<Add library="user32" />
|
|
||||||
<Add library="ws2_32" />
|
|
||||||
</Linker>
|
</Linker>
|
||||||
</Target>
|
</Target>
|
||||||
</Build>
|
</Build>
|
||||||
|
@ -107,6 +59,25 @@
|
||||||
<Add option="-pipe" />
|
<Add option="-pipe" />
|
||||||
<Add directory="src" />
|
<Add directory="src" />
|
||||||
</Compiler>
|
</Compiler>
|
||||||
|
<Linker>
|
||||||
|
<Add library="SDL2" />
|
||||||
|
<Add library="shell32" />
|
||||||
|
<Add library="comctl32" />
|
||||||
|
<Add library="comdlg32" />
|
||||||
|
<Add library="advapi32" />
|
||||||
|
<Add library="wsock32" />
|
||||||
|
<Add library="oleacc" />
|
||||||
|
<Add library="ole32" />
|
||||||
|
<Add library="usp10" />
|
||||||
|
<Add library="gdi32" />
|
||||||
|
<Add library="d2d1" />
|
||||||
|
<Add library="dwrite" />
|
||||||
|
<Add library="uxtheme" />
|
||||||
|
<Add library="iphlpapi" />
|
||||||
|
<Add library="user32" />
|
||||||
|
<Add library="ws2_32" />
|
||||||
|
<Add library="opengl32" />
|
||||||
|
</Linker>
|
||||||
<Unit filename="melon.rc">
|
<Unit filename="melon.rc">
|
||||||
<Option compilerVar="WINDRES" />
|
<Option compilerVar="WINDRES" />
|
||||||
</Unit>
|
</Unit>
|
||||||
|
@ -135,11 +106,15 @@
|
||||||
<Unit filename="src/GPU2D.h" />
|
<Unit filename="src/GPU2D.h" />
|
||||||
<Unit filename="src/GPU3D.cpp" />
|
<Unit filename="src/GPU3D.cpp" />
|
||||||
<Unit filename="src/GPU3D.h" />
|
<Unit filename="src/GPU3D.h" />
|
||||||
|
<Unit filename="src/GPU3D_OpenGL.cpp" />
|
||||||
|
<Unit filename="src/GPU3D_OpenGL_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" />
|
||||||
<Unit filename="src/NDSCart.cpp" />
|
<Unit filename="src/NDSCart.cpp" />
|
||||||
<Unit filename="src/NDSCart.h" />
|
<Unit filename="src/NDSCart.h" />
|
||||||
|
<Unit filename="src/OpenGLSupport.cpp" />
|
||||||
|
<Unit filename="src/OpenGLSupport.h" />
|
||||||
<Unit filename="src/Platform.h" />
|
<Unit filename="src/Platform.h" />
|
||||||
<Unit filename="src/RTC.cpp" />
|
<Unit filename="src/RTC.cpp" />
|
||||||
<Unit filename="src/RTC.h" />
|
<Unit filename="src/RTC.h" />
|
||||||
|
@ -159,6 +134,8 @@
|
||||||
<Unit filename="src/libui_sdl/DlgEmuSettings.h" />
|
<Unit filename="src/libui_sdl/DlgEmuSettings.h" />
|
||||||
<Unit filename="src/libui_sdl/DlgInputConfig.cpp" />
|
<Unit filename="src/libui_sdl/DlgInputConfig.cpp" />
|
||||||
<Unit filename="src/libui_sdl/DlgInputConfig.h" />
|
<Unit filename="src/libui_sdl/DlgInputConfig.h" />
|
||||||
|
<Unit filename="src/libui_sdl/DlgVideoSettings.cpp" />
|
||||||
|
<Unit filename="src/libui_sdl/DlgVideoSettings.h" />
|
||||||
<Unit filename="src/libui_sdl/DlgWifiSettings.cpp" />
|
<Unit filename="src/libui_sdl/DlgWifiSettings.cpp" />
|
||||||
<Unit filename="src/libui_sdl/DlgWifiSettings.h" />
|
<Unit filename="src/libui_sdl/DlgWifiSettings.h" />
|
||||||
<Unit filename="src/libui_sdl/LAN_PCap.cpp" />
|
<Unit filename="src/libui_sdl/LAN_PCap.cpp" />
|
||||||
|
@ -222,6 +199,7 @@
|
||||||
<Unit filename="src/libui_sdl/libui/windows/fontbutton.cpp" />
|
<Unit filename="src/libui_sdl/libui/windows/fontbutton.cpp" />
|
||||||
<Unit filename="src/libui_sdl/libui/windows/fontdialog.cpp" />
|
<Unit filename="src/libui_sdl/libui/windows/fontdialog.cpp" />
|
||||||
<Unit filename="src/libui_sdl/libui/windows/form.cpp" />
|
<Unit filename="src/libui_sdl/libui/windows/form.cpp" />
|
||||||
|
<Unit filename="src/libui_sdl/libui/windows/gl.cpp" />
|
||||||
<Unit filename="src/libui_sdl/libui/windows/graphemes.cpp" />
|
<Unit filename="src/libui_sdl/libui/windows/graphemes.cpp" />
|
||||||
<Unit filename="src/libui_sdl/libui/windows/grid.cpp" />
|
<Unit filename="src/libui_sdl/libui/windows/grid.cpp" />
|
||||||
<Unit filename="src/libui_sdl/libui/windows/group.cpp" />
|
<Unit filename="src/libui_sdl/libui/windows/group.cpp" />
|
||||||
|
@ -253,6 +231,7 @@
|
||||||
<Unit filename="src/libui_sdl/libui/windows/winpublic.cpp" />
|
<Unit filename="src/libui_sdl/libui/windows/winpublic.cpp" />
|
||||||
<Unit filename="src/libui_sdl/libui/windows/winutil.cpp" />
|
<Unit filename="src/libui_sdl/libui/windows/winutil.cpp" />
|
||||||
<Unit filename="src/libui_sdl/main.cpp" />
|
<Unit filename="src/libui_sdl/main.cpp" />
|
||||||
|
<Unit filename="src/libui_sdl/main_shaders.h" />
|
||||||
<Unit filename="src/pcap/bluetooth.h" />
|
<Unit filename="src/pcap/bluetooth.h" />
|
||||||
<Unit filename="src/pcap/bpf.h" />
|
<Unit filename="src/pcap/bpf.h" />
|
||||||
<Unit filename="src/pcap/can_socketcan.h" />
|
<Unit filename="src/pcap/can_socketcan.h" />
|
||||||
|
|
14
src/ARM.cpp
14
src/ARM.cpp
|
@ -159,7 +159,7 @@ void ARM::SetupCodeMem(u32 addr)
|
||||||
//NDS::ARM7GetMemRegion(addr, false, &CodeMem);
|
//NDS::ARM7GetMemRegion(addr, false, &CodeMem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
extern u64 vbltime;
|
||||||
void ARMv5::JumpTo(u32 addr, bool restorecpsr)
|
void ARMv5::JumpTo(u32 addr, bool restorecpsr)
|
||||||
{
|
{
|
||||||
if (restorecpsr)
|
if (restorecpsr)
|
||||||
|
@ -180,6 +180,16 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
|
||||||
if (R[15]==0x0204BE5E) printf("recvfrom() ret:%d errno:%d %08X\n", R[0], NDS::ARM9Read32(0x217F398), addr);
|
if (R[15]==0x0204BE5E) printf("recvfrom() ret:%d errno:%d %08X\n", R[0], NDS::ARM9Read32(0x217F398), addr);
|
||||||
if (R[15]==0x0205038A) printf("sgrecvfrom() ret:%d errno:%d %08X\n", R[0], NDS::ARM9Read32(0x217F398), addr);
|
if (R[15]==0x0205038A) printf("sgrecvfrom() ret:%d errno:%d %08X\n", R[0], NDS::ARM9Read32(0x217F398), addr);
|
||||||
if (addr==0x02050379 || addr==0x0205036D) printf("morp %08X->%08X, %d\n", R[15], addr, R[7]);*/
|
if (addr==0x02050379 || addr==0x0205036D) printf("morp %08X->%08X, %d\n", R[15], addr, R[7]);*/
|
||||||
|
/*if (addr==0x020B5F14) printf("VRAM UNMAP %02X %08X\n", R[0], R[15]);
|
||||||
|
if (addr==0x020B5FAC) printf("VRAM MAP %2X %08X\n", R[0], R[15]);
|
||||||
|
if (addr==0x0209F860) printf("VRAM BLORP %02X %08X\n", R[0], R[15]);
|
||||||
|
if (addr==0x02005A34) printf("VAZAVAZORP %08X. VCOUNT=%d\n", R[15], NDS::ARM9Read16(0x04000006));
|
||||||
|
if (addr==0x0209FBEC) printf("COUILLON. %08X %08X\n", R[0], R[1]);
|
||||||
|
if (addr==0x02004AA8) printf("ANEBATE 1 %d\n", NDS::ARM9Read16(0x04000006));
|
||||||
|
if (addr==0x020058C8) printf("ANEBATE 2 %d\n", NDS::ARM9Read16(0x04000006));
|
||||||
|
if (addr==0x02005398) printf("ANEBATE 3 %d %d\n", NDS::ARM9Read16(0x04000006), (u32)(NDS::ARM9Timestamp-vbltime));
|
||||||
|
if (addr==0x02005A5C) printf("PLAFORP %d\n", NDS::ARM9Read16(0x04000006));
|
||||||
|
if (addr==0x209FBDC) printf("ROLOLORP\n");*/
|
||||||
|
|
||||||
u32 oldregion = R[15] >> 24;
|
u32 oldregion = R[15] >> 24;
|
||||||
u32 newregion = addr >> 24;
|
u32 newregion = addr >> 24;
|
||||||
|
@ -508,6 +518,8 @@ void ARMv5::Execute()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
AddCycles_C();
|
AddCycles_C();
|
||||||
|
|
||||||
|
//if (R[15]>=0x02005A5C && R[15]<=0x02005A84) printf("NORP %08X %d\n", R[15]-8, NDS::ARM9Read16(0x04000006));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO optimize this shit!!!
|
// TODO optimize this shit!!!
|
||||||
|
|
|
@ -28,12 +28,20 @@ namespace Config
|
||||||
|
|
||||||
const char* kConfigFile = "melonDS.ini";
|
const char* kConfigFile = "melonDS.ini";
|
||||||
|
|
||||||
|
int _3DRenderer;
|
||||||
int Threaded3D;
|
int Threaded3D;
|
||||||
|
|
||||||
|
int GL_ScaleFactor;
|
||||||
|
int GL_Antialias;
|
||||||
|
|
||||||
ConfigEntry ConfigFile[] =
|
ConfigEntry ConfigFile[] =
|
||||||
{
|
{
|
||||||
|
{"3DRenderer", 0, &_3DRenderer, 1, NULL, 0},
|
||||||
{"Threaded3D", 0, &Threaded3D, 1, NULL, 0},
|
{"Threaded3D", 0, &Threaded3D, 1, NULL, 0},
|
||||||
|
|
||||||
|
{"GL_ScaleFactor", 0, &GL_ScaleFactor, 1, NULL, 0},
|
||||||
|
{"GL_Antialias", 0, &GL_Antialias, 0, NULL, 0},
|
||||||
|
|
||||||
{"", -1, NULL, 0, NULL, 0}
|
{"", -1, NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,12 @@ bool HasConfigFile(const char* fileName);
|
||||||
void Load();
|
void Load();
|
||||||
void Save();
|
void Save();
|
||||||
|
|
||||||
|
extern int _3DRenderer;
|
||||||
extern int Threaded3D;
|
extern int Threaded3D;
|
||||||
|
|
||||||
|
extern int GL_ScaleFactor;
|
||||||
|
extern int GL_Antialias;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CONFIG_H
|
#endif // CONFIG_H
|
||||||
|
|
101
src/GPU.cpp
101
src/GPU.cpp
|
@ -20,7 +20,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "NDS.h"
|
#include "NDS.h"
|
||||||
#include "GPU.h"
|
#include "GPU.h"
|
||||||
|
u64 vbltime;
|
||||||
|
|
||||||
namespace GPU
|
namespace GPU
|
||||||
{
|
{
|
||||||
|
@ -71,7 +71,9 @@ u32 VRAMMap_TexPal[8];
|
||||||
|
|
||||||
u32 VRAMMap_ARM7[2];
|
u32 VRAMMap_ARM7[2];
|
||||||
|
|
||||||
u32 Framebuffer[256*192*2];
|
int FrontBuffer;
|
||||||
|
u32* Framebuffer[2][2];
|
||||||
|
bool Accelerated;
|
||||||
|
|
||||||
GPU2D* GPU2D_A;
|
GPU2D* GPU2D_A;
|
||||||
GPU2D* GPU2D_B;
|
GPU2D* GPU2D_B;
|
||||||
|
@ -83,6 +85,12 @@ bool Init()
|
||||||
GPU2D_B = new GPU2D(1);
|
GPU2D_B = new GPU2D(1);
|
||||||
if (!GPU3D::Init()) return false;
|
if (!GPU3D::Init()) return false;
|
||||||
|
|
||||||
|
FrontBuffer = 0;
|
||||||
|
Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL;
|
||||||
|
Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL;
|
||||||
|
Accelerated = false;
|
||||||
|
SetDisplaySettings(false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +99,11 @@ void DeInit()
|
||||||
delete GPU2D_A;
|
delete GPU2D_A;
|
||||||
delete GPU2D_B;
|
delete GPU2D_B;
|
||||||
GPU3D::DeInit();
|
GPU3D::DeInit();
|
||||||
|
|
||||||
|
if (Framebuffer[0][0]) delete[] Framebuffer[0][0];
|
||||||
|
if (Framebuffer[0][1]) delete[] Framebuffer[0][1];
|
||||||
|
if (Framebuffer[1][0]) delete[] Framebuffer[1][0];
|
||||||
|
if (Framebuffer[1][1]) delete[] Framebuffer[1][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
|
@ -137,23 +150,39 @@ void Reset()
|
||||||
|
|
||||||
VRAMMap_ARM7[0] = 0;
|
VRAMMap_ARM7[0] = 0;
|
||||||
VRAMMap_ARM7[1] = 0;
|
VRAMMap_ARM7[1] = 0;
|
||||||
|
printf("RESET: ACCEL=%d FRAMEBUFFER=%p\n", Accelerated, Framebuffer[0][0]);
|
||||||
for (int i = 0; i < 256*192*2; i++)
|
int fbsize;
|
||||||
|
if (Accelerated) fbsize = (256*3 + 1) * 192;
|
||||||
|
else fbsize = 256 * 192;
|
||||||
|
for (int i = 0; i < fbsize; i++)
|
||||||
{
|
{
|
||||||
Framebuffer[i] = 0xFFFFFFFF;
|
Framebuffer[0][0][i] = 0xFFFFFFFF;
|
||||||
|
Framebuffer[1][0][i] = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < fbsize; i++)
|
||||||
|
{
|
||||||
|
Framebuffer[0][1][i] = 0xFFFFFFFF;
|
||||||
|
Framebuffer[1][1][i] = 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
GPU2D_A->Reset();
|
GPU2D_A->Reset();
|
||||||
GPU2D_B->Reset();
|
GPU2D_B->Reset();
|
||||||
GPU3D::Reset();
|
GPU3D::Reset();
|
||||||
|
|
||||||
GPU2D_A->SetFramebuffer(&Framebuffer[256*192]);
|
int backbuf = FrontBuffer ? 0 : 1;
|
||||||
GPU2D_B->SetFramebuffer(&Framebuffer[256*0]);
|
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]);
|
||||||
|
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stop()
|
void Stop()
|
||||||
{
|
{
|
||||||
memset(Framebuffer, 0, 256*192*2*4);
|
int fbsize;
|
||||||
|
if (Accelerated) fbsize = (256*3 + 1) * 192;
|
||||||
|
else fbsize = 256 * 192;
|
||||||
|
memset(Framebuffer[0][0], 0, fbsize*4);
|
||||||
|
memset(Framebuffer[0][1], 0, fbsize*4);
|
||||||
|
memset(Framebuffer[1][0], 0, fbsize*4);
|
||||||
|
memset(Framebuffer[1][1], 0, fbsize*4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoSavestate(Savestate* file)
|
void DoSavestate(Savestate* file)
|
||||||
|
@ -208,6 +237,48 @@ void DoSavestate(Savestate* file)
|
||||||
GPU3D::DoSavestate(file);
|
GPU3D::DoSavestate(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssignFramebuffers()
|
||||||
|
{
|
||||||
|
int backbuf = FrontBuffer ? 0 : 1;
|
||||||
|
if (NDS::PowerControl9 & (1<<15))
|
||||||
|
{
|
||||||
|
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]);
|
||||||
|
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]);
|
||||||
|
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDisplaySettings(bool accel)
|
||||||
|
{
|
||||||
|
int fbsize;
|
||||||
|
if (accel) fbsize = (256*3 + 1) * 192;
|
||||||
|
else fbsize = 256 * 192;
|
||||||
|
if (Framebuffer[0][0]) delete[] Framebuffer[0][0];
|
||||||
|
if (Framebuffer[1][0]) delete[] Framebuffer[1][0];
|
||||||
|
if (Framebuffer[0][1]) delete[] Framebuffer[0][1];
|
||||||
|
if (Framebuffer[1][1]) delete[] Framebuffer[1][1];
|
||||||
|
Framebuffer[0][0] = new u32[fbsize];
|
||||||
|
Framebuffer[1][0] = new u32[fbsize];
|
||||||
|
Framebuffer[0][1] = new u32[fbsize];
|
||||||
|
Framebuffer[1][1] = new u32[fbsize];
|
||||||
|
|
||||||
|
memset(Framebuffer[0][0], 0, fbsize*4);
|
||||||
|
memset(Framebuffer[1][0], 0, fbsize*4);
|
||||||
|
memset(Framebuffer[0][1], 0, fbsize*4);
|
||||||
|
memset(Framebuffer[1][1], 0, fbsize*4);
|
||||||
|
|
||||||
|
AssignFramebuffers();
|
||||||
|
|
||||||
|
GPU2D_A->SetDisplaySettings(accel);
|
||||||
|
GPU2D_B->SetDisplaySettings(accel);
|
||||||
|
|
||||||
|
Accelerated = accel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// VRAM mapping notes
|
// VRAM mapping notes
|
||||||
//
|
//
|
||||||
|
@ -666,16 +737,7 @@ void SetPowerCnt(u32 val)
|
||||||
GPU2D_B->SetEnabled(val & (1<<9));
|
GPU2D_B->SetEnabled(val & (1<<9));
|
||||||
GPU3D::SetEnabled(val & (1<<3), val & (1<<2));
|
GPU3D::SetEnabled(val & (1<<3), val & (1<<2));
|
||||||
|
|
||||||
if (val & (1<<15))
|
AssignFramebuffers();
|
||||||
{
|
|
||||||
GPU2D_A->SetFramebuffer(&Framebuffer[256*0]);
|
|
||||||
GPU2D_B->SetFramebuffer(&Framebuffer[256*192]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GPU2D_A->SetFramebuffer(&Framebuffer[256*192]);
|
|
||||||
GPU2D_B->SetFramebuffer(&Framebuffer[256*0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -746,6 +808,9 @@ void StartHBlank(u32 line)
|
||||||
|
|
||||||
void FinishFrame(u32 lines)
|
void FinishFrame(u32 lines)
|
||||||
{
|
{
|
||||||
|
FrontBuffer = FrontBuffer ? 0 : 1;
|
||||||
|
AssignFramebuffers();
|
||||||
|
|
||||||
TotalScanlines = lines;
|
TotalScanlines = lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,8 @@ extern u32 VRAMMap_Texture[4];
|
||||||
extern u32 VRAMMap_TexPal[8];
|
extern u32 VRAMMap_TexPal[8];
|
||||||
extern u32 VRAMMap_ARM7[2];
|
extern u32 VRAMMap_ARM7[2];
|
||||||
|
|
||||||
extern u32 Framebuffer[256*192*2];
|
extern int FrontBuffer;
|
||||||
|
extern u32* Framebuffer[2][2];
|
||||||
|
|
||||||
extern GPU2D* GPU2D_A;
|
extern GPU2D* GPU2D_A;
|
||||||
extern GPU2D* GPU2D_B;
|
extern GPU2D* GPU2D_B;
|
||||||
|
@ -74,6 +75,8 @@ void Stop();
|
||||||
|
|
||||||
void DoSavestate(Savestate* file);
|
void DoSavestate(Savestate* file);
|
||||||
|
|
||||||
|
void SetDisplaySettings(bool accel);
|
||||||
|
|
||||||
|
|
||||||
void MapVRAM_AB(u32 bank, u8 cnt);
|
void MapVRAM_AB(u32 bank, u8 cnt);
|
||||||
void MapVRAM_CD(u32 bank, u8 cnt);
|
void MapVRAM_CD(u32 bank, u8 cnt);
|
||||||
|
|
737
src/GPU2D.cpp
737
src/GPU2D.cpp
File diff suppressed because it is too large
Load Diff
49
src/GPU2D.h
49
src/GPU2D.h
|
@ -31,6 +31,7 @@ public:
|
||||||
|
|
||||||
void SetEnabled(bool enable) { Enabled = enable; }
|
void SetEnabled(bool enable) { Enabled = enable; }
|
||||||
void SetFramebuffer(u32* buf);
|
void SetFramebuffer(u32* buf);
|
||||||
|
void SetDisplaySettings(bool accel);
|
||||||
|
|
||||||
u8 Read8(u32 addr);
|
u8 Read8(u32 addr);
|
||||||
u16 Read16(u32 addr);
|
u16 Read16(u32 addr);
|
||||||
|
@ -68,6 +69,14 @@ private:
|
||||||
bool Enabled;
|
bool Enabled;
|
||||||
u32* Framebuffer;
|
u32* Framebuffer;
|
||||||
|
|
||||||
|
bool Accelerated;
|
||||||
|
|
||||||
|
u32 BGOBJLine[256*3];
|
||||||
|
u32* _3DLine;
|
||||||
|
|
||||||
|
u8 WindowMask[256];
|
||||||
|
u32 OBJLine[256];
|
||||||
|
|
||||||
u16 DispFIFO[16];
|
u16 DispFIFO[16];
|
||||||
u32 DispFIFOReadPtr;
|
u32 DispFIFOReadPtr;
|
||||||
u32 DispFIFOWritePtr;
|
u32 DispFIFOWritePtr;
|
||||||
|
@ -114,27 +123,35 @@ private:
|
||||||
u32 BGExtPalStatus[4];
|
u32 BGExtPalStatus[4];
|
||||||
u32 OBJExtPalStatus;
|
u32 OBJExtPalStatus;
|
||||||
|
|
||||||
template<u32 bgmode> void DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst);
|
u32 ColorBlend4(u32 val1, u32 val2, u32 eva, u32 evb);
|
||||||
void DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst);
|
u32 ColorBlend5(u32 val1, u32 val2);
|
||||||
void DrawScanline_Mode1(u32 line, u32* dst);
|
u32 ColorBrightnessUp(u32 val, u32 factor);
|
||||||
|
u32 ColorBrightnessDown(u32 val, u32 factor);
|
||||||
|
u32 ColorComposite(int i, u32 val1, u32 val2);
|
||||||
|
|
||||||
void DrawPixel(u32* dst, u16 color, u32 flag);
|
template<u32 bgmode> void DrawScanlineBGMode(u32 line, u32 nsprites);
|
||||||
|
void DrawScanlineBGMode6(u32 line, u32 nsprites);
|
||||||
|
void DrawScanline_BGOBJ(u32 line);
|
||||||
|
|
||||||
void DrawBG_3D(u32 line, u32* dst);
|
static void DrawPixel_Normal(u32* dst, u16 color, u32 flag);
|
||||||
void DrawBG_Text(u32 line, u32* dst, u32 bgnum);
|
static void DrawPixel_Accel(u32* dst, u16 color, u32 flag);
|
||||||
void DrawBG_Affine(u32 line, u32* dst, u32 bgnum);
|
void (*DrawPixel)(u32* dst, u16 color, u32 flag);
|
||||||
void DrawBG_Extended(u32 line, u32* dst, u32 bgnum);
|
|
||||||
void DrawBG_Large(u32 line, u32* dst);
|
|
||||||
|
|
||||||
void InterleaveSprites(u32* buf, u32 prio, u32* dst);
|
void DrawBG_3D();
|
||||||
u32 DrawSprites(u32 line, u32* dst);
|
void DrawBG_Text(u32 line, u32 bgnum);
|
||||||
void DrawSpritesWindow(u32 line, u8* dst);
|
void DrawBG_Affine(u32 line, u32 bgnum);
|
||||||
template<bool window> void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos, u32* dst);
|
void DrawBG_Extended(u32 line, u32 bgnum);
|
||||||
template<bool window> void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* dst);
|
void DrawBG_Large(u32 line);
|
||||||
|
|
||||||
void DoCapture(u32 line, u32 width, u32* src);
|
void InterleaveSprites(u32 prio);
|
||||||
|
u32 DrawSprites(u32 line);
|
||||||
|
void DrawSpritesWindow(u32 line);
|
||||||
|
template<bool window> void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos);
|
||||||
|
template<bool window> void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos);
|
||||||
|
|
||||||
void CalculateWindowMask(u32 line, u8* mask);
|
void DoCapture(u32 line, u32 width);
|
||||||
|
|
||||||
|
void CalculateWindowMask(u32 line);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "NDS.h"
|
#include "NDS.h"
|
||||||
#include "GPU.h"
|
#include "GPU.h"
|
||||||
#include "FIFO.h"
|
#include "FIFO.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
|
||||||
// 3D engine notes
|
// 3D engine notes
|
||||||
|
@ -156,6 +157,8 @@ u32 NumCommands, CurCommand, ParamCount, TotalParams;
|
||||||
bool GeometryEnabled;
|
bool GeometryEnabled;
|
||||||
bool RenderingEnabled;
|
bool RenderingEnabled;
|
||||||
|
|
||||||
|
int Renderer;
|
||||||
|
|
||||||
u32 DispCnt;
|
u32 DispCnt;
|
||||||
u8 AlphaRefVal, AlphaRef;
|
u8 AlphaRefVal, AlphaRef;
|
||||||
|
|
||||||
|
@ -275,14 +278,16 @@ bool Init()
|
||||||
|
|
||||||
CmdStallQueue = new FIFO<CmdFIFOEntry>(64);
|
CmdStallQueue = new FIFO<CmdFIFOEntry>(64);
|
||||||
|
|
||||||
if (!SoftRenderer::Init()) return false;
|
Renderer = -1;
|
||||||
|
// SetRenderer() will be called to set it up later
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeInit()
|
void DeInit()
|
||||||
{
|
{
|
||||||
SoftRenderer::DeInit();
|
if (Renderer == 0) SoftRenderer::DeInit();
|
||||||
|
else GLRenderer::DeInit();
|
||||||
|
|
||||||
delete CmdFIFO;
|
delete CmdFIFO;
|
||||||
delete CmdPIPE;
|
delete CmdPIPE;
|
||||||
|
@ -382,7 +387,8 @@ void Reset()
|
||||||
FlushAttributes = 0;
|
FlushAttributes = 0;
|
||||||
|
|
||||||
ResetRenderingState();
|
ResetRenderingState();
|
||||||
SoftRenderer::Reset();
|
if (Renderer == 0) SoftRenderer::Reset();
|
||||||
|
else GLRenderer::Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoSavestate(Savestate* file)
|
void DoSavestate(Savestate* file)
|
||||||
|
@ -605,6 +611,43 @@ void SetEnabled(bool geometry, bool rendering)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int InitRenderer(bool hasGL)
|
||||||
|
{
|
||||||
|
int renderer = hasGL ? Config::_3DRenderer : 0;
|
||||||
|
|
||||||
|
if (renderer == 1)
|
||||||
|
{
|
||||||
|
if (!GLRenderer::Init())
|
||||||
|
renderer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderer == 0) SoftRenderer::Init();
|
||||||
|
|
||||||
|
Renderer = renderer;
|
||||||
|
UpdateRendererConfig();
|
||||||
|
GPU::SetDisplaySettings(Renderer != 0);
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeInitRenderer()
|
||||||
|
{
|
||||||
|
if (Renderer == 0) SoftRenderer::DeInit();
|
||||||
|
else GLRenderer::DeInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateRendererConfig()
|
||||||
|
{
|
||||||
|
if (Renderer == 0)
|
||||||
|
{
|
||||||
|
SoftRenderer::SetupRenderThread();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GLRenderer::UpdateDisplaySettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MatrixLoadIdentity(s32* m)
|
void MatrixLoadIdentity(s32* m)
|
||||||
{
|
{
|
||||||
|
@ -1191,6 +1234,16 @@ void SubmitPolygon()
|
||||||
vtx->FinalPosition[0] = posX & 0x1FF;
|
vtx->FinalPosition[0] = posX & 0x1FF;
|
||||||
vtx->FinalPosition[1] = posY & 0xFF;
|
vtx->FinalPosition[1] = posY & 0xFF;
|
||||||
|
|
||||||
|
// hi-res positions
|
||||||
|
if (w != 0)
|
||||||
|
{
|
||||||
|
posX = ((((s64)(vtx->Position[0] + w) * Viewport[4]) << 4) / (((s64)w) << 1)) + (Viewport[0] << 4);
|
||||||
|
posY = ((((s64)(-vtx->Position[1] + w) * Viewport[5]) << 4) / (((s64)w) << 1)) + (Viewport[3] << 4);
|
||||||
|
|
||||||
|
vtx->HiresPosition[0] = posX & 0x1FFF;
|
||||||
|
vtx->HiresPosition[1] = posY & 0xFFF;
|
||||||
|
}
|
||||||
|
|
||||||
vtx->FinalColor[0] = vtx->Color[0] >> 12;
|
vtx->FinalColor[0] = vtx->Color[0] >> 12;
|
||||||
if (vtx->FinalColor[0]) vtx->FinalColor[0] = ((vtx->FinalColor[0] << 4) + 0xF);
|
if (vtx->FinalColor[0]) vtx->FinalColor[0] = ((vtx->FinalColor[0] << 4) + 0xF);
|
||||||
vtx->FinalColor[1] = vtx->Color[1] >> 12;
|
vtx->FinalColor[1] = vtx->Color[1] >> 12;
|
||||||
|
@ -2331,7 +2384,7 @@ void CheckFIFODMA()
|
||||||
|
|
||||||
void VCount144()
|
void VCount144()
|
||||||
{
|
{
|
||||||
SoftRenderer::VCount144();
|
if (Renderer == 0) SoftRenderer::VCount144();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2413,17 +2466,14 @@ void VBlank()
|
||||||
|
|
||||||
void VCount215()
|
void VCount215()
|
||||||
{
|
{
|
||||||
SoftRenderer::RenderFrame();
|
if (Renderer == 0) SoftRenderer::RenderFrame();
|
||||||
}
|
else GLRenderer::RenderFrame();
|
||||||
|
|
||||||
void RequestLine(int line)
|
|
||||||
{
|
|
||||||
return SoftRenderer::RequestLine(line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32* GetLine(int line)
|
u32* GetLine(int line)
|
||||||
{
|
{
|
||||||
return SoftRenderer::GetLine(line);
|
if (Renderer == 0) return SoftRenderer::GetLine(line);
|
||||||
|
else return GLRenderer::GetLine(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
28
src/GPU3D.h
28
src/GPU3D.h
|
@ -39,6 +39,10 @@ typedef struct
|
||||||
s32 FinalPosition[2];
|
s32 FinalPosition[2];
|
||||||
s32 FinalColor[3];
|
s32 FinalColor[3];
|
||||||
|
|
||||||
|
// hi-res position (4-bit fractional part)
|
||||||
|
// TODO maybe: hi-res color? (that survives clipping)
|
||||||
|
s32 HiresPosition[2];
|
||||||
|
|
||||||
} Vertex;
|
} Vertex;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -86,6 +90,8 @@ extern u32 RenderNumPolygons;
|
||||||
|
|
||||||
extern u64 Timestamp;
|
extern u64 Timestamp;
|
||||||
|
|
||||||
|
extern int Renderer;
|
||||||
|
|
||||||
bool Init();
|
bool Init();
|
||||||
void DeInit();
|
void DeInit();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
@ -94,6 +100,10 @@ void DoSavestate(Savestate* file);
|
||||||
|
|
||||||
void SetEnabled(bool geometry, bool rendering);
|
void SetEnabled(bool geometry, bool rendering);
|
||||||
|
|
||||||
|
int InitRenderer(bool hasGL);
|
||||||
|
void DeInitRenderer();
|
||||||
|
void UpdateRendererConfig();
|
||||||
|
|
||||||
void ExecuteCommand();
|
void ExecuteCommand();
|
||||||
|
|
||||||
s32 CyclesToRunFor();
|
s32 CyclesToRunFor();
|
||||||
|
@ -104,7 +114,6 @@ void CheckFIFODMA();
|
||||||
void VCount144();
|
void VCount144();
|
||||||
void VBlank();
|
void VBlank();
|
||||||
void VCount215();
|
void VCount215();
|
||||||
void RequestLine(int line);
|
|
||||||
u32* GetLine(int line);
|
u32* GetLine(int line);
|
||||||
|
|
||||||
void WriteToGXFIFO(u32 val);
|
void WriteToGXFIFO(u32 val);
|
||||||
|
@ -127,11 +136,26 @@ void SetupRenderThread();
|
||||||
|
|
||||||
void VCount144();
|
void VCount144();
|
||||||
void RenderFrame();
|
void RenderFrame();
|
||||||
void RequestLine(int line);
|
|
||||||
u32* GetLine(int line);
|
u32* GetLine(int line);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace GLRenderer
|
||||||
|
{
|
||||||
|
|
||||||
|
bool Init();
|
||||||
|
void DeInit();
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
void UpdateDisplaySettings();
|
||||||
|
|
||||||
|
void RenderFrame();
|
||||||
|
void PrepareCaptureFrame();
|
||||||
|
u32* GetLine(int line);
|
||||||
|
void SetupAccelFrame();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,690 @@
|
||||||
|
/*
|
||||||
|
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_OPENGL_SHADERS_H
|
||||||
|
#define GPU3D_OPENGL_SHADERS_H
|
||||||
|
|
||||||
|
#define kShaderHeader "#version 140"
|
||||||
|
|
||||||
|
|
||||||
|
const char* kClearVS = kShaderHeader R"(
|
||||||
|
|
||||||
|
in vec2 vPosition;
|
||||||
|
|
||||||
|
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"(
|
||||||
|
|
||||||
|
uniform uvec4 uColor;
|
||||||
|
uniform uint uOpaquePolyID;
|
||||||
|
uniform uint uFogFlag;
|
||||||
|
|
||||||
|
out vec4 oColor;
|
||||||
|
out uvec3 oAttr;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
oColor = vec4(uColor).bgra / 31.0;
|
||||||
|
oAttr.r = uOpaquePolyID;
|
||||||
|
oAttr.g = uint(0);
|
||||||
|
oAttr.b = uFogFlag;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char* kFinalPassVS = kShaderHeader R"(
|
||||||
|
|
||||||
|
in vec2 vPosition;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// heh
|
||||||
|
gl_Position = vec4(vPosition, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kFinalPassFS = kShaderHeader R"(
|
||||||
|
|
||||||
|
uniform sampler2D DepthBuffer;
|
||||||
|
uniform usampler2D AttrBuffer;
|
||||||
|
|
||||||
|
layout(std140) uniform uConfig
|
||||||
|
{
|
||||||
|
vec2 uScreenSize;
|
||||||
|
int uDispCnt;
|
||||||
|
vec4 uToonColors[32];
|
||||||
|
vec4 uEdgeColors[8];
|
||||||
|
vec4 uFogColor;
|
||||||
|
float uFogDensity[34];
|
||||||
|
int uFogOffset;
|
||||||
|
int uFogShift;
|
||||||
|
};
|
||||||
|
|
||||||
|
out vec4 oColor;
|
||||||
|
|
||||||
|
vec4 CalculateFog(float depth)
|
||||||
|
{
|
||||||
|
int idepth = int(depth * 16777216.0);
|
||||||
|
int densityid, densityfrac;
|
||||||
|
|
||||||
|
if (idepth < uFogOffset)
|
||||||
|
{
|
||||||
|
densityid = 0;
|
||||||
|
densityfrac = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint udepth = uint(idepth);
|
||||||
|
udepth -= uint(uFogOffset);
|
||||||
|
udepth = (udepth >> 2) << uint(uFogShift);
|
||||||
|
|
||||||
|
densityid = int(udepth >> 17);
|
||||||
|
if (densityid >= 32)
|
||||||
|
{
|
||||||
|
densityid = 32;
|
||||||
|
densityfrac = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
densityfrac = int(udepth & uint(0x1FFFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
float density = mix(uFogDensity[densityid], uFogDensity[densityid+1], float(densityfrac)/131072.0);
|
||||||
|
|
||||||
|
return vec4(density, density, density, density);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||||
|
|
||||||
|
vec4 ret = vec4(0,0,0,0);
|
||||||
|
vec4 depth = texelFetch(DepthBuffer, coord, 0);
|
||||||
|
ivec4 attr = ivec4(texelFetch(AttrBuffer, coord, 0));
|
||||||
|
|
||||||
|
if (attr.b != 0) ret = CalculateFog(depth.r);
|
||||||
|
|
||||||
|
oColor = ret;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char* kRenderVSCommon = R"(
|
||||||
|
|
||||||
|
layout(std140) uniform uConfig
|
||||||
|
{
|
||||||
|
vec2 uScreenSize;
|
||||||
|
int uDispCnt;
|
||||||
|
vec4 uToonColors[32];
|
||||||
|
vec4 uEdgeColors[8];
|
||||||
|
vec4 uFogColor;
|
||||||
|
float uFogDensity[34];
|
||||||
|
int uFogOffset;
|
||||||
|
int uFogShift;
|
||||||
|
};
|
||||||
|
|
||||||
|
in uvec4 vPosition;
|
||||||
|
in uvec4 vColor;
|
||||||
|
in ivec2 vTexcoord;
|
||||||
|
in ivec3 vPolygonAttr;
|
||||||
|
|
||||||
|
smooth out vec4 fColor;
|
||||||
|
smooth out vec2 fTexcoord;
|
||||||
|
flat out ivec3 fPolygonAttr;
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFSCommon = R"(
|
||||||
|
|
||||||
|
uniform usampler2D TexMem;
|
||||||
|
uniform sampler2D TexPalMem;
|
||||||
|
|
||||||
|
layout(std140) uniform uConfig
|
||||||
|
{
|
||||||
|
vec2 uScreenSize;
|
||||||
|
int uDispCnt;
|
||||||
|
vec4 uToonColors[32];
|
||||||
|
vec4 uEdgeColors[8];
|
||||||
|
vec4 uFogColor;
|
||||||
|
float uFogDensity[34];
|
||||||
|
int uFogOffset;
|
||||||
|
int uFogShift;
|
||||||
|
};
|
||||||
|
|
||||||
|
smooth in vec4 fColor;
|
||||||
|
smooth in vec2 fTexcoord;
|
||||||
|
flat in ivec3 fPolygonAttr;
|
||||||
|
|
||||||
|
out vec4 oColor;
|
||||||
|
out uvec3 oAttr;
|
||||||
|
|
||||||
|
int TexcoordWrap(int c, int maxc, int 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, int 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);
|
||||||
|
ivec4 pixel = ivec4(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) + 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, int 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;
|
||||||
|
ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0));
|
||||||
|
pixel.r >>= (2 * (st.x & 3));
|
||||||
|
pixel.r &= 0x03;
|
||||||
|
|
||||||
|
addr.y = (addr.y << 2) + pixel.r;
|
||||||
|
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
|
||||||
|
return vec4(color.rgb, (pixel.r>0)?1:alpha0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TextureFetch_I4(ivec2 addr, ivec4 st, int 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;
|
||||||
|
ivec4 pixel = ivec4(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) + pixel.r;
|
||||||
|
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
|
||||||
|
return vec4(color.rgb, (pixel.r>0)?1:alpha0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TextureFetch_I8(ivec2 addr, ivec4 st, int 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);
|
||||||
|
ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0));
|
||||||
|
|
||||||
|
addr.y = (addr.y << 3) + pixel.r;
|
||||||
|
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
|
||||||
|
|
||||||
|
return vec4(color.rgb, (pixel.r>0)?1:alpha0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, int 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);
|
||||||
|
ivec4 p = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0));
|
||||||
|
int val = (p.r >> (2 * (st.x & 0x3))) & 0x3;
|
||||||
|
|
||||||
|
int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1);
|
||||||
|
if (addr.x >= 0x40000) slot1addr += 0x10000;
|
||||||
|
|
||||||
|
int palinfo;
|
||||||
|
p = ivec4(texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0));
|
||||||
|
palinfo = p.r;
|
||||||
|
slot1addr++;
|
||||||
|
p = ivec4(texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0));
|
||||||
|
palinfo |= (p.r << 8);
|
||||||
|
|
||||||
|
addr.y = (addr.y << 3) + ((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, int 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);
|
||||||
|
ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0));
|
||||||
|
|
||||||
|
pixel.a = (pixel.r & 0xF8) >> 3;
|
||||||
|
pixel.r &= 0x07;
|
||||||
|
|
||||||
|
addr.y = (addr.y << 3) + 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, int 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;
|
||||||
|
ivec4 pixelL = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0));
|
||||||
|
addr.x++;
|
||||||
|
ivec4 pixelH = ivec4(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)
|
||||||
|
{
|
||||||
|
int attr = int(fPolygonAttr.y);
|
||||||
|
int paladdr = int(fPolygonAttr.z);
|
||||||
|
|
||||||
|
float alpha0;
|
||||||
|
if ((attr & (1<<29)) != 0) alpha0 = 0.0;
|
||||||
|
else alpha0 = 1.0;
|
||||||
|
|
||||||
|
int tw = 8 << ((attr >> 20) & 0x7);
|
||||||
|
int th = 8 << ((attr >> 23) & 0x7);
|
||||||
|
ivec4 st_full = ivec4(ivec2(st), tw, th);
|
||||||
|
|
||||||
|
ivec2 vramaddr = ivec2((attr & 0xFFFF) << 3, paladdr);
|
||||||
|
int wrapmode = (attr >> 16);
|
||||||
|
|
||||||
|
int 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);
|
||||||
|
|
||||||
|
int attr = int(fPolygonAttr.y);
|
||||||
|
int paladdr = int(fPolygonAttr.z);
|
||||||
|
|
||||||
|
float alpha0;
|
||||||
|
if ((attr & (1<<29)) != 0) alpha0 = 0.0;
|
||||||
|
else alpha0 = 1.0;
|
||||||
|
|
||||||
|
int tw = 8 << ((attr >> 20) & 0x7);
|
||||||
|
int th = 8 << ((attr >> 23) & 0x7);
|
||||||
|
ivec4 st_full = ivec4(intpart, tw, th);
|
||||||
|
|
||||||
|
ivec2 vramaddr = ivec2((attr & 0xFFFF) << 3, paladdr);
|
||||||
|
int wrapmode = (attr >> 16);
|
||||||
|
|
||||||
|
vec4 A, B, C, D;
|
||||||
|
int 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;
|
||||||
|
int 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()
|
||||||
|
{
|
||||||
|
int attr = vPolygonAttr.x;
|
||||||
|
int 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()
|
||||||
|
{
|
||||||
|
int attr = vPolygonAttr.x;
|
||||||
|
int 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.r = uint((fPolygonAttr.x >> 24) & 0x3F);
|
||||||
|
oAttr.b = uint((fPolygonAttr.x >> 15) & 0x1);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFS_WO = R"(
|
||||||
|
|
||||||
|
smooth in float fZ;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 col = FinalColor();
|
||||||
|
if (col.a < 30.5/31) discard;
|
||||||
|
|
||||||
|
oColor = col;
|
||||||
|
oAttr.r = uint((fPolygonAttr.x >> 24) & 0x3F);
|
||||||
|
oAttr.b = uint((fPolygonAttr.x >> 15) & 0x1);
|
||||||
|
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.b = uint(0);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
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.b = uint(0);
|
||||||
|
gl_FragDepth = fZ;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFS_ZSM = R"(
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
oColor = vec4(0,0,0,1);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kRenderFS_WSM = R"(
|
||||||
|
|
||||||
|
smooth in float fZ;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
oColor = vec4(0,0,0,1);
|
||||||
|
gl_FragDepth = fZ;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
#endif // GPU3D_OPENGL_SHADERS_H
|
|
@ -129,9 +129,9 @@ void DeInit()
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
memset(ColorBuffer, 0, 256*192 * 4);
|
memset(ColorBuffer, 0, BufferSize * 2 * 4);
|
||||||
memset(DepthBuffer, 0, 256*192 * 4);
|
memset(DepthBuffer, 0, BufferSize * 2 * 4);
|
||||||
memset(AttrBuffer, 0, 256*192 * 4);
|
memset(AttrBuffer, 0, BufferSize * 2 * 4);
|
||||||
|
|
||||||
PrevIsShadowMask = false;
|
PrevIsShadowMask = false;
|
||||||
|
|
||||||
|
@ -2106,17 +2106,14 @@ void RenderThreadFunc()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestLine(int line)
|
u32* GetLine(int line)
|
||||||
{
|
{
|
||||||
if (RenderThreadRunning)
|
if (RenderThreadRunning)
|
||||||
{
|
{
|
||||||
if (line < 192)
|
if (line < 192)
|
||||||
Platform::Semaphore_Wait(Sema_ScanlineCount);
|
Platform::Semaphore_Wait(Sema_ScanlineCount);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
u32* GetLine(int line)
|
|
||||||
{
|
|
||||||
return &ColorBuffer[(line * ScanlineWidth) + FirstPixelOffset];
|
return &ColorBuffer[(line * ScanlineWidth) + FirstPixelOffset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1532,7 +1532,7 @@ void debug(u32 param)
|
||||||
// printf("VRAM %c: %02X\n", 'A'+i, GPU::VRAMCNT[i]);
|
// printf("VRAM %c: %02X\n", 'A'+i, GPU::VRAMCNT[i]);
|
||||||
|
|
||||||
FILE*
|
FILE*
|
||||||
shit = fopen("debug/lmnts.bin", "wb");
|
shit = fopen("debug/card.bin", "wb");
|
||||||
for (u32 i = 0x02000000; i < 0x02400000; i+=4)
|
for (u32 i = 0x02000000; i < 0x02400000; i+=4)
|
||||||
{
|
{
|
||||||
u32 val = ARM7Read32(i);
|
u32 val = ARM7Read32(i);
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "OpenGLSupport.h"
|
||||||
|
|
||||||
|
|
||||||
|
DO_PROCLIST(DECLPROC);
|
||||||
|
|
||||||
|
|
||||||
|
bool OpenGL_Init()
|
||||||
|
{
|
||||||
|
DO_PROCLIST(LOADPROC);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
ids[0] = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
len = strlen(vs);
|
||||||
|
glShaderSource(ids[0], 1, &vs, &len);
|
||||||
|
glCompileShader(ids[0]);
|
||||||
|
|
||||||
|
glGetShaderiv(ids[0], GL_COMPILE_STATUS, &res);
|
||||||
|
if (res != GL_TRUE)
|
||||||
|
{
|
||||||
|
glGetShaderiv(ids[0], GL_INFO_LOG_LENGTH, &res);
|
||||||
|
if (res < 1) res = 1024;
|
||||||
|
char* log = new char[res+1];
|
||||||
|
glGetShaderInfoLog(ids[0], res+1, NULL, log);
|
||||||
|
printf("OpenGL: failed to compile vertex shader %s: %s\n", name, log);
|
||||||
|
printf("shader source:\n--\n%s\n--\n", vs);
|
||||||
|
delete[] log;
|
||||||
|
|
||||||
|
glDeleteShader(ids[0]);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ids[1] = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
len = strlen(fs);
|
||||||
|
glShaderSource(ids[1], 1, &fs, &len);
|
||||||
|
glCompileShader(ids[1]);
|
||||||
|
|
||||||
|
glGetShaderiv(ids[1], GL_COMPILE_STATUS, &res);
|
||||||
|
if (res != GL_TRUE)
|
||||||
|
{
|
||||||
|
glGetShaderiv(ids[1], GL_INFO_LOG_LENGTH, &res);
|
||||||
|
if (res < 1) res = 1024;
|
||||||
|
char* log = new char[res+1];
|
||||||
|
glGetShaderInfoLog(ids[1], res+1, NULL, log);
|
||||||
|
printf("OpenGL: failed to compile fragment shader %s: %s\n", name, log);
|
||||||
|
//printf("shader source:\n--\n%s\n--\n", fs);
|
||||||
|
delete[] log;
|
||||||
|
|
||||||
|
FILE* logf = fopen("shaderfail.log", "w");
|
||||||
|
fwrite(fs, len+1, 1, logf);
|
||||||
|
fclose(logf);
|
||||||
|
|
||||||
|
glDeleteShader(ids[0]);
|
||||||
|
glDeleteShader(ids[1]);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ids[2] = glCreateProgram();
|
||||||
|
glAttachShader(ids[2], ids[0]);
|
||||||
|
glAttachShader(ids[2], ids[1]);
|
||||||
|
glLinkProgram(ids[2]);
|
||||||
|
|
||||||
|
glGetProgramiv(ids[2], GL_LINK_STATUS, &res);
|
||||||
|
if (res != GL_TRUE)
|
||||||
|
{
|
||||||
|
glGetProgramiv(ids[2], GL_INFO_LOG_LENGTH, &res);
|
||||||
|
if (res < 1) res = 1024;
|
||||||
|
char* log = new char[res+1];
|
||||||
|
glGetProgramInfoLog(ids[2], res+1, NULL, log);
|
||||||
|
printf("OpenGL: failed to link program %s: %s\n", name, log);
|
||||||
|
delete[] log;
|
||||||
|
|
||||||
|
glDeleteShader(ids[0]);
|
||||||
|
glDeleteShader(ids[1]);
|
||||||
|
glDeleteProgram(ids[2]);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGL_DeleteShaderProgram(GLuint* ids)
|
||||||
|
{
|
||||||
|
glDeleteShader(ids[0]);
|
||||||
|
glDeleteShader(ids[1]);
|
||||||
|
glDeleteProgram(ids[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGL_UseShaderProgram(GLuint* ids)
|
||||||
|
{
|
||||||
|
glUseProgram(ids[2]);
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
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 OPENGLSUPPORT_H
|
||||||
|
#define OPENGLSUPPORT_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <GL/glext.h>
|
||||||
|
|
||||||
|
#include "Platform.h"
|
||||||
|
|
||||||
|
|
||||||
|
// here, have some macro magic
|
||||||
|
// we at the melonDS company really love macro magic
|
||||||
|
// also, suggestion to the fine folks who write the OpenGL headers:
|
||||||
|
// pls make the type names follow the same capitalization as their
|
||||||
|
// matching function names, so this is more convenient to deal with
|
||||||
|
|
||||||
|
#define DECLPROC(type, name) \
|
||||||
|
PFN##type##PROC name ;
|
||||||
|
|
||||||
|
#define DECLPROC_EXT(type, name) \
|
||||||
|
extern PFN##type##PROC name ;
|
||||||
|
|
||||||
|
#define LOADPROC(type, name) \
|
||||||
|
name = (PFN##type##PROC)Platform::GL_GetProcAddress(#name); \
|
||||||
|
if (!name) { printf("OpenGL: " #name " not found\n"); return false; }
|
||||||
|
|
||||||
|
|
||||||
|
// if you need more OpenGL functions, add them to the macronator here
|
||||||
|
// TODO: handle conditionally loading certain functions for different GL versions
|
||||||
|
|
||||||
|
#define DO_PROCLIST(func) \
|
||||||
|
func(GLGENFRAMEBUFFERS, glGenFramebuffers); \
|
||||||
|
func(GLDELETEFRAMEBUFFERS, glDeleteFramebuffers); \
|
||||||
|
func(GLBINDFRAMEBUFFER, glBindFramebuffer); \
|
||||||
|
func(GLFRAMEBUFFERTEXTURE, glFramebufferTexture); \
|
||||||
|
func(GLBLITFRAMEBUFFER, glBlitFramebuffer); \
|
||||||
|
func(GLCHECKFRAMEBUFFERSTATUS, glCheckFramebufferStatus); \
|
||||||
|
\
|
||||||
|
func(GLGENBUFFERS, glGenBuffers); \
|
||||||
|
func(GLDELETEBUFFERS, glDeleteBuffers); \
|
||||||
|
func(GLBINDBUFFER, glBindBuffer); \
|
||||||
|
func(GLMAPBUFFER, glMapBuffer); \
|
||||||
|
func(GLMAPBUFFERRANGE, glMapBufferRange); \
|
||||||
|
func(GLUNMAPBUFFER, glUnmapBuffer); \
|
||||||
|
func(GLBUFFERDATA, glBufferData); \
|
||||||
|
func(GLBUFFERSUBDATA, glBufferSubData); \
|
||||||
|
func(GLBINDBUFFERBASE, glBindBufferBase); \
|
||||||
|
\
|
||||||
|
func(GLGENVERTEXARRAYS, glGenVertexArrays); \
|
||||||
|
func(GLDELETEVERTEXARRAYS, glDeleteVertexArrays); \
|
||||||
|
func(GLBINDVERTEXARRAY, glBindVertexArray); \
|
||||||
|
func(GLENABLEVERTEXATTRIBARRAY, glEnableVertexAttribArray); \
|
||||||
|
func(GLDISABLEVERTEXATTRIBARRAY, glDisableVertexAttribArray); \
|
||||||
|
func(GLVERTEXATTRIBPOINTER, glVertexAttribPointer); \
|
||||||
|
func(GLVERTEXATTRIBIPOINTER, glVertexAttribIPointer); \
|
||||||
|
func(GLBINDATTRIBLOCATION, glBindAttribLocation); \
|
||||||
|
func(GLBINDFRAGDATALOCATION, glBindFragDataLocation); \
|
||||||
|
\
|
||||||
|
func(GLCREATESHADER, glCreateShader); \
|
||||||
|
func(GLSHADERSOURCE, glShaderSource); \
|
||||||
|
func(GLCOMPILESHADER, glCompileShader); \
|
||||||
|
func(GLCREATEPROGRAM, glCreateProgram); \
|
||||||
|
func(GLATTACHSHADER, glAttachShader); \
|
||||||
|
func(GLLINKPROGRAM, glLinkProgram); \
|
||||||
|
func(GLUSEPROGRAM, glUseProgram); \
|
||||||
|
func(GLGETSHADERIV, glGetShaderiv); \
|
||||||
|
func(GLGETSHADERINFOLOG, glGetShaderInfoLog); \
|
||||||
|
func(GLGETPROGRAMIV, glGetProgramiv); \
|
||||||
|
func(GLGETPROGRAMINFOLOG, glGetProgramInfoLog); \
|
||||||
|
func(GLDELETESHADER, glDeleteShader); \
|
||||||
|
func(GLDELETEPROGRAM, glDeleteProgram); \
|
||||||
|
\
|
||||||
|
func(GLUNIFORM1I, glUniform1i); \
|
||||||
|
func(GLUNIFORM1UI, glUniform1ui); \
|
||||||
|
func(GLUNIFORM4UI, glUniform4ui); \
|
||||||
|
func(GLUNIFORMBLOCKBINDING, glUniformBlockBinding); \
|
||||||
|
func(GLGETUNIFORMLOCATION, glGetUniformLocation); \
|
||||||
|
func(GLGETUNIFORMBLOCKINDEX, glGetUniformBlockIndex); \
|
||||||
|
\
|
||||||
|
func(GLACTIVETEXTURE, glActiveTexture); \
|
||||||
|
func(GLBINDIMAGETEXTURE, glBindImageTexture); \
|
||||||
|
\
|
||||||
|
func(GLDRAWBUFFERS, glDrawBuffers); \
|
||||||
|
\
|
||||||
|
func(GLBLENDFUNCSEPARATE, glBlendFuncSeparate); \
|
||||||
|
func(GLBLENDEQUATIONSEPARATE, glBlendEquationSeparate); \
|
||||||
|
func(GLBLENDCOLOR, glBlendColor); \
|
||||||
|
\
|
||||||
|
func(GLCOLORMASKI, glColorMaski); \
|
||||||
|
\
|
||||||
|
func(GLMEMORYBARRIER, glMemoryBarrier); \
|
||||||
|
\
|
||||||
|
func(GLGETSTRINGI, glGetStringi); \
|
||||||
|
|
||||||
|
|
||||||
|
DO_PROCLIST(DECLPROC_EXT);
|
||||||
|
|
||||||
|
|
||||||
|
bool OpenGL_Init();
|
||||||
|
|
||||||
|
bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name);
|
||||||
|
void OpenGL_DeleteShaderProgram(GLuint* ids);
|
||||||
|
void OpenGL_UseShaderProgram(GLuint* ids);
|
||||||
|
|
||||||
|
#endif // OPENGLSUPPORT_H
|
|
@ -68,6 +68,8 @@ void Semaphore_Reset(void* sema);
|
||||||
void Semaphore_Wait(void* sema);
|
void Semaphore_Wait(void* sema);
|
||||||
void Semaphore_Post(void* sema);
|
void Semaphore_Post(void* sema);
|
||||||
|
|
||||||
|
void* GL_GetProcAddress(const char* proc);
|
||||||
|
|
||||||
// local multiplayer comm interface
|
// local multiplayer comm interface
|
||||||
// packet type: DS-style TX header (12 bytes) + original 802.11 frame
|
// packet type: DS-style TX header (12 bytes) + original 802.11 frame
|
||||||
bool MP_Init();
|
bool MP_Init();
|
||||||
|
|
|
@ -23,7 +23,9 @@
|
||||||
|
|
||||||
|
|
||||||
// SPU TODO
|
// SPU TODO
|
||||||
// * loop mode 3, what does it do?
|
// * capture addition modes, overflow bugs
|
||||||
|
// * channel hold
|
||||||
|
// * 'length less than 4' glitch
|
||||||
|
|
||||||
|
|
||||||
namespace SPU
|
namespace SPU
|
||||||
|
|
|
@ -0,0 +1,309 @@
|
||||||
|
/*
|
||||||
|
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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "libui/ui.h"
|
||||||
|
|
||||||
|
#include "../types.h"
|
||||||
|
#include "PlatformConfig.h"
|
||||||
|
|
||||||
|
#include "DlgVideoSettings.h"
|
||||||
|
|
||||||
|
|
||||||
|
void ApplyNewSettings(int type);
|
||||||
|
|
||||||
|
|
||||||
|
namespace DlgVideoSettings
|
||||||
|
{
|
||||||
|
|
||||||
|
bool opened;
|
||||||
|
uiWindow* win;
|
||||||
|
|
||||||
|
uiRadioButtons* rbRenderer;
|
||||||
|
uiCheckbox* cbGLDisplay;
|
||||||
|
uiCheckbox* cbThreaded3D;
|
||||||
|
uiCombobox* cbResolution;
|
||||||
|
uiCheckbox* cbAntialias;
|
||||||
|
|
||||||
|
int old_renderer;
|
||||||
|
int old_gldisplay;
|
||||||
|
int old_threaded3D;
|
||||||
|
int old_resolution;
|
||||||
|
int old_antialias;
|
||||||
|
|
||||||
|
|
||||||
|
void UpdateControls()
|
||||||
|
{
|
||||||
|
int renderer = uiRadioButtonsSelected(rbRenderer);
|
||||||
|
|
||||||
|
if (renderer == 0)
|
||||||
|
{
|
||||||
|
uiControlEnable(uiControl(cbGLDisplay));
|
||||||
|
uiControlEnable(uiControl(cbThreaded3D));
|
||||||
|
uiControlDisable(uiControl(cbResolution));
|
||||||
|
uiControlDisable(uiControl(cbAntialias));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uiControlDisable(uiControl(cbGLDisplay));
|
||||||
|
uiControlDisable(uiControl(cbThreaded3D));
|
||||||
|
uiControlEnable(uiControl(cbResolution));
|
||||||
|
uiControlEnable(uiControl(cbAntialias));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int OnCloseWindow(uiWindow* window, void* blarg)
|
||||||
|
{
|
||||||
|
opened = false;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnRendererChanged(uiRadioButtons* rb, void* blarg)
|
||||||
|
{
|
||||||
|
int id = uiRadioButtonsSelected(rb);
|
||||||
|
bool old_usegl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0);
|
||||||
|
|
||||||
|
Config::_3DRenderer = id;
|
||||||
|
UpdateControls();
|
||||||
|
|
||||||
|
bool new_usegl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0);
|
||||||
|
if (new_usegl != old_usegl)
|
||||||
|
ApplyNewSettings(2);
|
||||||
|
else
|
||||||
|
ApplyNewSettings(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGLDisplayChanged(uiCheckbox* cb, void* blarg)
|
||||||
|
{
|
||||||
|
Config::ScreenUseGL = uiCheckboxChecked(cb);
|
||||||
|
ApplyNewSettings(2);
|
||||||
|
uiControlSetFocus(uiControl(cb));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnThreaded3DChanged(uiCheckbox* cb, void* blarg)
|
||||||
|
{
|
||||||
|
Config::Threaded3D = uiCheckboxChecked(cb);
|
||||||
|
ApplyNewSettings(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnResolutionChanged(uiCombobox* cb, void* blarg)
|
||||||
|
{
|
||||||
|
int id = uiComboboxSelected(cb);
|
||||||
|
|
||||||
|
Config::GL_ScaleFactor = id+1;
|
||||||
|
ApplyNewSettings(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnAntialiasChanged(uiCheckbox* cb, void* blarg)
|
||||||
|
{
|
||||||
|
Config::GL_Antialias = uiCheckboxChecked(cb);
|
||||||
|
ApplyNewSettings(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnCancel(uiButton* btn, void* blarg)
|
||||||
|
{
|
||||||
|
bool apply0 = false;
|
||||||
|
bool apply2 = false;
|
||||||
|
bool apply3 = false;
|
||||||
|
|
||||||
|
bool old_usegl = (old_gldisplay != 0) || (old_renderer != 0);
|
||||||
|
bool new_usegl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0);
|
||||||
|
|
||||||
|
if (old_renderer != Config::_3DRenderer)
|
||||||
|
{
|
||||||
|
Config::_3DRenderer = old_renderer;
|
||||||
|
apply3 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_gldisplay != Config::ScreenUseGL)
|
||||||
|
{
|
||||||
|
Config::ScreenUseGL = old_gldisplay;
|
||||||
|
}
|
||||||
|
if (old_usegl != new_usegl)
|
||||||
|
{
|
||||||
|
apply2 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_threaded3D != Config::Threaded3D)
|
||||||
|
{
|
||||||
|
Config::Threaded3D = old_threaded3D;
|
||||||
|
apply0 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_resolution != Config::GL_ScaleFactor ||
|
||||||
|
old_antialias != Config::GL_Antialias)
|
||||||
|
{
|
||||||
|
Config::GL_ScaleFactor = old_resolution;
|
||||||
|
Config::GL_Antialias = old_antialias;
|
||||||
|
apply0 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apply2) ApplyNewSettings(2);
|
||||||
|
else if (apply3) ApplyNewSettings(3);
|
||||||
|
if (apply0) ApplyNewSettings(0);
|
||||||
|
|
||||||
|
uiControlDestroy(uiControl(win));
|
||||||
|
opened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnOk(uiButton* btn, void* blarg)
|
||||||
|
{
|
||||||
|
Config::Save();
|
||||||
|
|
||||||
|
uiControlDestroy(uiControl(win));
|
||||||
|
opened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Open()
|
||||||
|
{
|
||||||
|
if (opened)
|
||||||
|
{
|
||||||
|
uiControlSetFocus(uiControl(win));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
opened = true;
|
||||||
|
win = uiNewWindow("Video settings - melonDS", 400, 100, 0, 0, 0);
|
||||||
|
uiWindowSetMargined(win, 1);
|
||||||
|
uiWindowOnClosing(win, OnCloseWindow, NULL);
|
||||||
|
|
||||||
|
uiBox* top = uiNewVerticalBox();
|
||||||
|
uiWindowSetChild(win, uiControl(top));
|
||||||
|
uiBoxSetPadded(top, 1);
|
||||||
|
|
||||||
|
uiBox* splitter = uiNewHorizontalBox();
|
||||||
|
uiBoxAppend(top, uiControl(splitter), 0);
|
||||||
|
uiBoxSetPadded(splitter, 1);
|
||||||
|
|
||||||
|
uiBox* left = uiNewVerticalBox();
|
||||||
|
uiBoxAppend(splitter, uiControl(left), 1);
|
||||||
|
uiBoxSetPadded(left, 1);
|
||||||
|
uiBox* right = uiNewVerticalBox();
|
||||||
|
uiBoxAppend(splitter, uiControl(right), 1);
|
||||||
|
uiBoxSetPadded(right, 1);
|
||||||
|
|
||||||
|
{
|
||||||
|
uiGroup* grp = uiNewGroup("Display settings");
|
||||||
|
uiBoxAppend(left, uiControl(grp), 0);
|
||||||
|
uiGroupSetMargined(grp, 1);
|
||||||
|
|
||||||
|
uiBox* in_ctrl = uiNewVerticalBox();
|
||||||
|
uiGroupSetChild(grp, uiControl(in_ctrl));
|
||||||
|
|
||||||
|
uiLabel* lbl = uiNewLabel("3D renderer:");
|
||||||
|
uiBoxAppend(in_ctrl, uiControl(lbl), 0);
|
||||||
|
|
||||||
|
rbRenderer = uiNewRadioButtons();
|
||||||
|
uiRadioButtonsAppend(rbRenderer, "Software");
|
||||||
|
uiRadioButtonsAppend(rbRenderer, "OpenGL");
|
||||||
|
uiRadioButtonsOnSelected(rbRenderer, OnRendererChanged, NULL);
|
||||||
|
uiBoxAppend(in_ctrl, uiControl(rbRenderer), 0);
|
||||||
|
|
||||||
|
lbl = uiNewLabel("");
|
||||||
|
uiBoxAppend(in_ctrl, uiControl(lbl), 0);
|
||||||
|
|
||||||
|
cbGLDisplay = uiNewCheckbox("OpenGL display");
|
||||||
|
uiCheckboxOnToggled(cbGLDisplay, OnGLDisplayChanged, NULL);
|
||||||
|
uiBoxAppend(in_ctrl, uiControl(cbGLDisplay), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uiGroup* grp = uiNewGroup("Software renderer");
|
||||||
|
uiBoxAppend(right, uiControl(grp), 0);
|
||||||
|
uiGroupSetMargined(grp, 1);
|
||||||
|
|
||||||
|
uiBox* in_ctrl = uiNewVerticalBox();
|
||||||
|
uiGroupSetChild(grp, uiControl(in_ctrl));
|
||||||
|
|
||||||
|
cbThreaded3D = uiNewCheckbox("Threaded");
|
||||||
|
uiCheckboxOnToggled(cbThreaded3D, OnThreaded3DChanged, NULL);
|
||||||
|
uiBoxAppend(in_ctrl, uiControl(cbThreaded3D), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uiGroup* grp = uiNewGroup("OpenGL renderer");
|
||||||
|
uiBoxAppend(right, uiControl(grp), 0);
|
||||||
|
uiGroupSetMargined(grp, 1);
|
||||||
|
|
||||||
|
uiBox* in_ctrl = uiNewVerticalBox();
|
||||||
|
uiGroupSetChild(grp, uiControl(in_ctrl));
|
||||||
|
|
||||||
|
uiLabel* lbl = uiNewLabel("Internal resolution:");
|
||||||
|
uiBoxAppend(in_ctrl, uiControl(lbl), 0);
|
||||||
|
|
||||||
|
cbResolution = uiNewCombobox();
|
||||||
|
uiComboboxOnSelected(cbResolution, OnResolutionChanged, NULL);
|
||||||
|
for (int i = 1; i <= 8; i++)
|
||||||
|
{
|
||||||
|
char txt[64];
|
||||||
|
sprintf(txt, "%dx native (%dx%d)", i, 256*i, 192*i);
|
||||||
|
uiComboboxAppend(cbResolution, txt);
|
||||||
|
}
|
||||||
|
uiBoxAppend(in_ctrl, uiControl(cbResolution), 0);
|
||||||
|
|
||||||
|
lbl = uiNewLabel("");
|
||||||
|
uiBoxAppend(in_ctrl, uiControl(lbl), 0);
|
||||||
|
|
||||||
|
cbAntialias = uiNewCheckbox("Antialiasing");
|
||||||
|
uiCheckboxOnToggled(cbAntialias, OnAntialiasChanged, NULL);
|
||||||
|
uiBoxAppend(in_ctrl, uiControl(cbAntialias), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uiBox* in_ctrl = uiNewHorizontalBox();
|
||||||
|
uiBoxSetPadded(in_ctrl, 1);
|
||||||
|
uiBoxAppend(top, uiControl(in_ctrl), 0);
|
||||||
|
|
||||||
|
uiLabel* dummy = uiNewLabel("");
|
||||||
|
uiBoxAppend(in_ctrl, uiControl(dummy), 1);
|
||||||
|
|
||||||
|
uiButton* btncancel = uiNewButton("Cancel");
|
||||||
|
uiButtonOnClicked(btncancel, OnCancel, NULL);
|
||||||
|
uiBoxAppend(in_ctrl, uiControl(btncancel), 0);
|
||||||
|
|
||||||
|
uiButton* btnok = uiNewButton("Ok");
|
||||||
|
uiButtonOnClicked(btnok, OnOk, NULL);
|
||||||
|
uiBoxAppend(in_ctrl, uiControl(btnok), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Config::_3DRenderer = Config::_3DRenderer ? 1 : 0;
|
||||||
|
|
||||||
|
if (Config::GL_ScaleFactor < 1) Config::GL_ScaleFactor = 1;
|
||||||
|
else if (Config::GL_ScaleFactor > 8) Config::GL_ScaleFactor = 8;
|
||||||
|
|
||||||
|
old_renderer = Config::_3DRenderer;
|
||||||
|
old_gldisplay = Config::ScreenUseGL;
|
||||||
|
old_threaded3D = Config::Threaded3D;
|
||||||
|
old_resolution = Config::GL_ScaleFactor;
|
||||||
|
old_antialias = Config::GL_Antialias;
|
||||||
|
|
||||||
|
uiCheckboxSetChecked(cbGLDisplay, Config::ScreenUseGL);
|
||||||
|
uiCheckboxSetChecked(cbThreaded3D, Config::Threaded3D);
|
||||||
|
uiComboboxSetSelected(cbResolution, Config::GL_ScaleFactor-1);
|
||||||
|
uiCheckboxSetChecked(cbAntialias, Config::GL_Antialias);
|
||||||
|
uiRadioButtonsSetSelected(rbRenderer, Config::_3DRenderer);
|
||||||
|
UpdateControls();
|
||||||
|
|
||||||
|
uiControlShow(uiControl(win));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
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 DLGVIDEOSETTINGS_H
|
||||||
|
#define DLGVIDEOSETTINGS_H
|
||||||
|
|
||||||
|
namespace DlgVideoSettings
|
||||||
|
{
|
||||||
|
|
||||||
|
void Open();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DLGVIDEOSETTINGS_H
|
|
@ -24,6 +24,7 @@
|
||||||
#include "PlatformConfig.h"
|
#include "PlatformConfig.h"
|
||||||
#include "LAN_Socket.h"
|
#include "LAN_Socket.h"
|
||||||
#include "LAN_PCap.h"
|
#include "LAN_PCap.h"
|
||||||
|
#include "libui/ui.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
|
@ -302,6 +303,12 @@ void Semaphore_Post(void* sema)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void* GL_GetProcAddress(const char* proc)
|
||||||
|
{
|
||||||
|
return uiGLGetProcAddress(proc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool MP_Init()
|
bool MP_Init()
|
||||||
{
|
{
|
||||||
int opt_true = 1;
|
int opt_true = 1;
|
||||||
|
|
|
@ -40,6 +40,9 @@ int ScreenLayout;
|
||||||
int ScreenSizing;
|
int ScreenSizing;
|
||||||
int ScreenFilter;
|
int ScreenFilter;
|
||||||
|
|
||||||
|
int ScreenUseGL;
|
||||||
|
int ScreenRatio;
|
||||||
|
|
||||||
int LimitFPS;
|
int LimitFPS;
|
||||||
|
|
||||||
int DirectBoot;
|
int DirectBoot;
|
||||||
|
@ -101,6 +104,9 @@ ConfigEntry PlatformConfigFile[] =
|
||||||
{"ScreenSizing", 0, &ScreenSizing, 0, NULL, 0},
|
{"ScreenSizing", 0, &ScreenSizing, 0, NULL, 0},
|
||||||
{"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0},
|
{"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0},
|
||||||
|
|
||||||
|
{"ScreenUseGL", 0, &ScreenUseGL, 1, NULL, 0},
|
||||||
|
{"ScreenRatio", 0, &ScreenRatio, 0, NULL, 0},
|
||||||
|
|
||||||
{"LimitFPS", 0, &LimitFPS, 1, NULL, 0},
|
{"LimitFPS", 0, &LimitFPS, 1, NULL, 0},
|
||||||
|
|
||||||
{"DirectBoot", 0, &DirectBoot, 1, NULL, 0},
|
{"DirectBoot", 0, &DirectBoot, 1, NULL, 0},
|
||||||
|
|
|
@ -48,6 +48,9 @@ extern int ScreenLayout;
|
||||||
extern int ScreenSizing;
|
extern int ScreenSizing;
|
||||||
extern int ScreenFilter;
|
extern int ScreenFilter;
|
||||||
|
|
||||||
|
extern int ScreenUseGL;
|
||||||
|
extern int ScreenRatio;
|
||||||
|
|
||||||
extern int LimitFPS;
|
extern int LimitFPS;
|
||||||
|
|
||||||
extern int DirectBoot;
|
extern int DirectBoot;
|
||||||
|
|
|
@ -108,6 +108,8 @@ typedef struct uiWindow uiWindow;
|
||||||
#define uiWindow(this) ((uiWindow *) (this))
|
#define uiWindow(this) ((uiWindow *) (this))
|
||||||
_UI_EXTERN char *uiWindowTitle(uiWindow *w);
|
_UI_EXTERN char *uiWindowTitle(uiWindow *w);
|
||||||
_UI_EXTERN void uiWindowSetTitle(uiWindow *w, const char *title);
|
_UI_EXTERN void uiWindowSetTitle(uiWindow *w, const char *title);
|
||||||
|
_UI_EXTERN void uiWindowPosition(uiWindow *w, int *x, int *y);
|
||||||
|
_UI_EXTERN void uiWindowSetPosition(uiWindow *w, int x, int y);
|
||||||
_UI_EXTERN void uiWindowContentSize(uiWindow *w, int *width, int *height);
|
_UI_EXTERN void uiWindowContentSize(uiWindow *w, int *width, int *height);
|
||||||
_UI_EXTERN void uiWindowSetContentSize(uiWindow *w, int width, int height);
|
_UI_EXTERN void uiWindowSetContentSize(uiWindow *w, int width, int height);
|
||||||
_UI_EXTERN int uiWindowMinimized(uiWindow *w);
|
_UI_EXTERN int uiWindowMinimized(uiWindow *w);
|
||||||
|
@ -326,6 +328,10 @@ _UI_ENUM(uiWindowResizeEdge) {
|
||||||
// TODO way to bring up the system menu instead?
|
// TODO way to bring up the system menu instead?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define uiGLVersion(major, minor) ((major) | ((minor)<<16))
|
||||||
|
#define uiGLVerMajor(ver) ((ver) & 0xFFFF)
|
||||||
|
#define uiGLVerMinor(ver) ((ver) >> 16)
|
||||||
|
|
||||||
#define uiArea(this) ((uiArea *) (this))
|
#define uiArea(this) ((uiArea *) (this))
|
||||||
// TODO give a better name
|
// TODO give a better name
|
||||||
// TODO document the types of width and height
|
// TODO document the types of width and height
|
||||||
|
@ -342,6 +348,7 @@ _UI_EXTERN void uiAreaBeginUserWindowMove(uiArea *a);
|
||||||
_UI_EXTERN void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge);
|
_UI_EXTERN void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge);
|
||||||
_UI_EXTERN void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b);
|
_UI_EXTERN void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b);
|
||||||
_UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah);
|
_UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah);
|
||||||
|
_UI_EXTERN uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions);
|
||||||
_UI_EXTERN uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height);
|
_UI_EXTERN uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height);
|
||||||
|
|
||||||
struct uiAreaDrawParams {
|
struct uiAreaDrawParams {
|
||||||
|
@ -599,6 +606,18 @@ _UI_EXTERN void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, int startChar
|
||||||
|
|
||||||
_UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout);
|
_UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout);
|
||||||
|
|
||||||
|
|
||||||
|
// OpenGL support
|
||||||
|
|
||||||
|
typedef struct uiGLContext uiGLContext;
|
||||||
|
|
||||||
|
_UI_EXTERN uiGLContext *uiAreaGetGLContext(uiArea* a);
|
||||||
|
_UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx);
|
||||||
|
_UI_EXTERN unsigned int uiGLGetVersion(uiGLContext* ctx);
|
||||||
|
_UI_EXTERN void *uiGLGetProcAddress(const char* proc);
|
||||||
|
_UI_EXTERN void uiGLSwapBuffers(uiGLContext* ctx);
|
||||||
|
|
||||||
|
|
||||||
_UI_ENUM(uiModifiers) {
|
_UI_ENUM(uiModifiers) {
|
||||||
uiModifierCtrl = 1 << 0,
|
uiModifierCtrl = 1 << 0,
|
||||||
uiModifierAlt = 1 << 1,
|
uiModifierAlt = 1 << 1,
|
||||||
|
|
|
@ -25,8 +25,11 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
|
||||||
}
|
}
|
||||||
|
|
||||||
// always recreate the render target if necessary
|
// always recreate the render target if necessary
|
||||||
if (a->rt == NULL)
|
if (!a->openGL)
|
||||||
a->rt = makeHWNDRenderTarget(a->hwnd);
|
{
|
||||||
|
if (a->rt == NULL)
|
||||||
|
a->rt = makeHWNDRenderTarget(a->hwnd);
|
||||||
|
}
|
||||||
|
|
||||||
if (areaDoDraw(a, uMsg, wParam, lParam, &lResult) != FALSE)
|
if (areaDoDraw(a, uMsg, wParam, lParam, &lResult) != FALSE)
|
||||||
return lResult;
|
return lResult;
|
||||||
|
@ -34,12 +37,14 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
|
||||||
if (uMsg == WM_WINDOWPOSCHANGED) {
|
if (uMsg == WM_WINDOWPOSCHANGED) {
|
||||||
if ((wp->flags & SWP_NOSIZE) != 0)
|
if ((wp->flags & SWP_NOSIZE) != 0)
|
||||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||||
|
a->width = -1;
|
||||||
|
a->height = -1;
|
||||||
uiWindowsEnsureGetClientRect(a->hwnd, &client);
|
uiWindowsEnsureGetClientRect(a->hwnd, &client);
|
||||||
areaDrawOnResize(a, &client);
|
areaDrawOnResize(a, &client);
|
||||||
areaScrollOnResize(a, &client);
|
areaScrollOnResize(a, &client);
|
||||||
{
|
{
|
||||||
double w, h;
|
double w, h;
|
||||||
loadAreaSize(a, a->rt, &w, &h);
|
loadAreaSize(a, &w, &h);
|
||||||
a->ah->Resize(a->ah, a, (int)w, (int)h);
|
a->ah->Resize(a->ah, a, (int)w, (int)h);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -56,7 +61,15 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
|
||||||
|
|
||||||
// control implementation
|
// control implementation
|
||||||
|
|
||||||
uiWindowsControlAllDefaults(uiArea)
|
uiWindowsControlAllDefaultsExceptDestroy(uiArea)
|
||||||
|
|
||||||
|
static void uiAreaDestroy(uiControl *c)
|
||||||
|
{
|
||||||
|
uiArea* a = uiArea(c);
|
||||||
|
if (a->openGL && a->glcontext) freeGLContext(a->glcontext);
|
||||||
|
uiWindowsEnsureDestroyWindow(a->hwnd);
|
||||||
|
uiFreeControl(c);
|
||||||
|
}
|
||||||
|
|
||||||
static void uiAreaMinimumSize(uiWindowsControl *c, int *width, int *height)
|
static void uiAreaMinimumSize(uiWindowsControl *c, int *width, int *height)
|
||||||
{
|
{
|
||||||
|
@ -182,6 +195,9 @@ uiArea *uiNewArea(uiAreaHandler *ah)
|
||||||
|
|
||||||
uiWindowsNewControl(uiArea, a);
|
uiWindowsNewControl(uiArea, a);
|
||||||
|
|
||||||
|
a->width = -1;
|
||||||
|
a->height = -1;
|
||||||
|
|
||||||
a->ah = ah;
|
a->ah = ah;
|
||||||
a->scrolling = FALSE;
|
a->scrolling = FALSE;
|
||||||
clickCounterReset(&(a->cc));
|
clickCounterReset(&(a->cc));
|
||||||
|
@ -195,6 +211,50 @@ uiArea *uiNewArea(uiAreaHandler *ah)
|
||||||
|
|
||||||
uiAreaSetBackgroundColor(a, -1, -1, -1);
|
uiAreaSetBackgroundColor(a, -1, -1, -1);
|
||||||
|
|
||||||
|
a->openGL = 0;
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
uiGLContext *uiAreaGetGLContext(uiArea* a)
|
||||||
|
{
|
||||||
|
if (!a->openGL) userbug("trying to get GL context from non-GL area");
|
||||||
|
|
||||||
|
return a->glcontext;
|
||||||
|
}
|
||||||
|
|
||||||
|
uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions)
|
||||||
|
{
|
||||||
|
uiArea *a;
|
||||||
|
|
||||||
|
uiWindowsNewControl(uiArea, a);
|
||||||
|
|
||||||
|
a->width = -1;
|
||||||
|
a->height = -1;
|
||||||
|
|
||||||
|
a->ah = ah;
|
||||||
|
a->scrolling = FALSE;
|
||||||
|
clickCounterReset(&(a->cc));
|
||||||
|
|
||||||
|
// a->hwnd is assigned in areaWndProc()
|
||||||
|
uiWindowsEnsureCreateControlHWND(0,
|
||||||
|
areaClass, L"",
|
||||||
|
0,
|
||||||
|
hInstance, a,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
uiAreaSetBackgroundColor(a, -1, -1, -1);
|
||||||
|
|
||||||
|
a->openGL = 1;
|
||||||
|
|
||||||
|
for (int i = 0; req_versions[i]; i++)
|
||||||
|
{
|
||||||
|
int major = uiGLVerMajor(req_versions[i]);
|
||||||
|
int minor = uiGLVerMinor(req_versions[i]);
|
||||||
|
a->glcontext = createGLContext(a, major, minor);
|
||||||
|
if (a->glcontext) break;
|
||||||
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +264,9 @@ uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height)
|
||||||
|
|
||||||
uiWindowsNewControl(uiArea, a);
|
uiWindowsNewControl(uiArea, a);
|
||||||
|
|
||||||
|
a->width = -1;
|
||||||
|
a->height = -1;
|
||||||
|
|
||||||
a->ah = ah;
|
a->ah = ah;
|
||||||
a->scrolling = TRUE;
|
a->scrolling = TRUE;
|
||||||
a->scrollWidth = width;
|
a->scrollWidth = width;
|
||||||
|
@ -219,6 +282,8 @@ uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height)
|
||||||
|
|
||||||
uiAreaSetBackgroundColor(a, -1, -1, -1);
|
uiAreaSetBackgroundColor(a, -1, -1, -1);
|
||||||
|
|
||||||
|
a->openGL = 0; // TODO, eventually???
|
||||||
|
|
||||||
// set initial scrolling parameters
|
// set initial scrolling parameters
|
||||||
areaUpdateScroll(a);
|
areaUpdateScroll(a);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ struct uiArea {
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
uiAreaHandler *ah;
|
uiAreaHandler *ah;
|
||||||
|
|
||||||
|
int width, height;
|
||||||
|
|
||||||
BOOL scrolling;
|
BOOL scrolling;
|
||||||
int scrollWidth;
|
int scrollWidth;
|
||||||
int scrollHeight;
|
int scrollHeight;
|
||||||
|
@ -26,6 +28,9 @@ struct uiArea {
|
||||||
|
|
||||||
int bgR, bgG, bgB;
|
int bgR, bgG, bgB;
|
||||||
|
|
||||||
|
int openGL;
|
||||||
|
uiGLContext* glcontext;
|
||||||
|
|
||||||
ID2D1HwndRenderTarget *rt;
|
ID2D1HwndRenderTarget *rt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,6 +47,10 @@ extern void areaUpdateScroll(uiArea *a);
|
||||||
extern BOOL areaDoEvents(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult);
|
extern BOOL areaDoEvents(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult);
|
||||||
|
|
||||||
// areautil.cpp
|
// areautil.cpp
|
||||||
extern void loadAreaSize(uiArea *a, ID2D1RenderTarget *rt, double *width, double *height);
|
extern void loadAreaSize(uiArea *a, double *width, double *height);
|
||||||
extern void pixelsToDIP(uiArea *a, double *x, double *y);
|
extern void pixelsToDIP(uiArea *a, double *x, double *y);
|
||||||
extern void dipToPixels(uiArea *a, double *x, double *y);
|
extern void dipToPixels(uiArea *a, double *x, double *y);
|
||||||
|
|
||||||
|
// gl.cpp
|
||||||
|
extern uiGLContext* createGLContext(uiArea* a, int vermajor, int verminor);
|
||||||
|
extern void freeGLContext(uiGLContext* c);
|
||||||
|
|
|
@ -6,6 +6,13 @@ static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *clip)
|
||||||
{
|
{
|
||||||
uiAreaHandler *ah = a->ah;
|
uiAreaHandler *ah = a->ah;
|
||||||
uiAreaDrawParams dp;
|
uiAreaDrawParams dp;
|
||||||
|
|
||||||
|
if (a->openGL)
|
||||||
|
{
|
||||||
|
//(*(ah->Draw))(ah, a, &dp);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
COLORREF bgcolorref;
|
COLORREF bgcolorref;
|
||||||
D2D1_COLOR_F bgcolor;
|
D2D1_COLOR_F bgcolor;
|
||||||
D2D1_MATRIX_3X2_F scrollTransform;
|
D2D1_MATRIX_3X2_F scrollTransform;
|
||||||
|
@ -13,7 +20,7 @@ static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *clip)
|
||||||
// no need to save or restore the graphics state to reset transformations; it's handled by resetTarget() in draw.c, called during the following
|
// no need to save or restore the graphics state to reset transformations; it's handled by resetTarget() in draw.c, called during the following
|
||||||
dp.Context = newContext(rt);
|
dp.Context = newContext(rt);
|
||||||
|
|
||||||
loadAreaSize(a, rt, &(dp.AreaWidth), &(dp.AreaHeight));
|
loadAreaSize(a, &(dp.AreaWidth), &(dp.AreaHeight));
|
||||||
|
|
||||||
dp.ClipX = clip->left;
|
dp.ClipX = clip->left;
|
||||||
dp.ClipY = clip->top;
|
dp.ClipY = clip->top;
|
||||||
|
@ -113,6 +120,9 @@ static void onWM_PAINT(uiArea *a)
|
||||||
|
|
||||||
static void onWM_PRINTCLIENT(uiArea *a, HDC dc)
|
static void onWM_PRINTCLIENT(uiArea *a, HDC dc)
|
||||||
{
|
{
|
||||||
|
// TODO????
|
||||||
|
if (a->openGL) return;
|
||||||
|
|
||||||
ID2D1DCRenderTarget *rt;
|
ID2D1DCRenderTarget *rt;
|
||||||
RECT client;
|
RECT client;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -143,13 +153,16 @@ BOOL areaDoDraw(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lRe
|
||||||
// TODO only if the render target wasn't just created?
|
// TODO only if the render target wasn't just created?
|
||||||
void areaDrawOnResize(uiArea *a, RECT *newClient)
|
void areaDrawOnResize(uiArea *a, RECT *newClient)
|
||||||
{
|
{
|
||||||
D2D1_SIZE_U size;
|
if (!a->openGL)
|
||||||
|
{
|
||||||
|
D2D1_SIZE_U size;
|
||||||
|
|
||||||
size.width = newClient->right - newClient->left;
|
size.width = newClient->right - newClient->left;
|
||||||
size.height = newClient->bottom - newClient->top;
|
size.height = newClient->bottom - newClient->top;
|
||||||
// don't track the error; we'll get that in EndDraw()
|
// don't track the error; we'll get that in EndDraw()
|
||||||
// see https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994%28v=vs.85%29.aspx
|
// see https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994%28v=vs.85%29.aspx
|
||||||
a->rt->Resize(&size);
|
a->rt->Resize(&size);
|
||||||
|
}
|
||||||
|
|
||||||
// according to Rick Brewster, we must always redraw the entire client area after calling ID2D1RenderTarget::Resize() (see http://stackoverflow.com/a/33222983/3408572)
|
// according to Rick Brewster, we must always redraw the entire client area after calling ID2D1RenderTarget::Resize() (see http://stackoverflow.com/a/33222983/3408572)
|
||||||
// we used to have a uiAreaHandler.RedrawOnResize() method to decide this; now you know why we don't anymore
|
// we used to have a uiAreaHandler.RedrawOnResize() method to decide this; now you know why we don't anymore
|
||||||
|
|
|
@ -109,7 +109,7 @@ static void areaMouseEvent(uiArea *a, int down, int up, WPARAM wParam, LPARAM l
|
||||||
me.Y += a->vscrollpos;
|
me.Y += a->vscrollpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadAreaSize(a, NULL, &(me.AreaWidth), &(me.AreaHeight));
|
loadAreaSize(a, &(me.AreaWidth), &(me.AreaHeight));
|
||||||
|
|
||||||
me.Down = down;
|
me.Down = down;
|
||||||
me.Up = up;
|
me.Up = up;
|
||||||
|
|
|
@ -2,20 +2,35 @@
|
||||||
#include "uipriv_windows.hpp"
|
#include "uipriv_windows.hpp"
|
||||||
#include "area.hpp"
|
#include "area.hpp"
|
||||||
|
|
||||||
void loadAreaSize(uiArea *a, ID2D1RenderTarget *rt, double *width, double *height)
|
// TODO: make those int rather than double
|
||||||
|
void loadAreaSize(uiArea *a, double *width, double *height)
|
||||||
{
|
{
|
||||||
D2D1_SIZE_F size;
|
D2D1_SIZE_F size;
|
||||||
|
|
||||||
|
if (a->width != -1)
|
||||||
|
{
|
||||||
|
*width = (double)a->width;
|
||||||
|
*height = (double)a->height;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
*width = 0;
|
*width = 0;
|
||||||
*height = 0;
|
*height = 0;
|
||||||
if (!a->scrolling) {
|
if (!a->scrolling) {
|
||||||
if (rt == NULL)
|
/*if (rt == NULL)
|
||||||
rt = a->rt;
|
rt = a->rt;
|
||||||
size = realGetSize(rt);
|
size = realGetSize(rt);
|
||||||
*width = size.width;
|
*width = size.width;
|
||||||
*height = size.height;
|
*height = size.height;
|
||||||
dipToPixels(a, width, height);
|
dipToPixels(a, width, height);*/
|
||||||
|
RECT rect;
|
||||||
|
GetWindowRect(a->hwnd, &rect);
|
||||||
|
*width = (double)(rect.right - rect.left);
|
||||||
|
*height = (double)(rect.bottom - rect.top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a->width = (int)*width;
|
||||||
|
a->height = (int)*height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pixelsToDIP(uiArea *a, double *x, double *y)
|
void pixelsToDIP(uiArea *a, double *x, double *y)
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
// 31 march 2019
|
||||||
|
#include "uipriv_windows.hpp"
|
||||||
|
#include "area.hpp"
|
||||||
|
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <GL/wglext.h>
|
||||||
|
|
||||||
|
struct uiGLContext
|
||||||
|
{
|
||||||
|
uiArea* a;
|
||||||
|
|
||||||
|
HWND hwnd;
|
||||||
|
HDC dc;
|
||||||
|
HGLRC rc;
|
||||||
|
|
||||||
|
unsigned int version;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
uiGLContext* createGLContext(uiArea* a, int vermajor, int verminor)
|
||||||
|
{
|
||||||
|
uiGLContext* ctx;
|
||||||
|
BOOL res;
|
||||||
|
|
||||||
|
ctx = uiNew(uiGLContext);
|
||||||
|
|
||||||
|
ctx->a = a;
|
||||||
|
ctx->hwnd = a->hwnd;
|
||||||
|
|
||||||
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
memset(&pfd, 0, sizeof(pfd));
|
||||||
|
pfd.nSize = sizeof(pfd);
|
||||||
|
pfd.nVersion = 1;
|
||||||
|
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||||
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||||
|
pfd.cColorBits = 24;
|
||||||
|
pfd.cAlphaBits = 8;
|
||||||
|
pfd.cDepthBits = 24;
|
||||||
|
pfd.cStencilBits = 8;
|
||||||
|
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||||
|
|
||||||
|
ctx->dc = GetDC(ctx->hwnd);
|
||||||
|
if (!ctx->dc)
|
||||||
|
{
|
||||||
|
uiFree(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pixelformat = ChoosePixelFormat(ctx->dc, &pfd);
|
||||||
|
res = SetPixelFormat(ctx->dc, pixelformat, &pfd);
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
ReleaseDC(ctx->hwnd, ctx->dc);
|
||||||
|
uiFree(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->rc = wglCreateContext(ctx->dc);
|
||||||
|
if (!ctx->rc)
|
||||||
|
{
|
||||||
|
ReleaseDC(ctx->hwnd, ctx->dc);
|
||||||
|
uiFree(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wglMakeCurrent(ctx->dc, ctx->rc);
|
||||||
|
|
||||||
|
if (vermajor >= 3)
|
||||||
|
{
|
||||||
|
HGLRC (*wglCreateContextAttribsARB)(HDC,HGLRC,const int*);
|
||||||
|
HGLRC rc_better = NULL;
|
||||||
|
|
||||||
|
wglCreateContextAttribsARB = (HGLRC(*)(HDC,HGLRC,const int*))wglGetProcAddress("wglCreateContextAttribsARB");
|
||||||
|
if (wglCreateContextAttribsARB)
|
||||||
|
{
|
||||||
|
int attribs[15];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
|
||||||
|
attribs[i++] = vermajor;
|
||||||
|
attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB;
|
||||||
|
attribs[i++] = verminor;
|
||||||
|
|
||||||
|
attribs[i] = 0;
|
||||||
|
rc_better = wglCreateContextAttribsARB(ctx->dc, NULL, attribs);
|
||||||
|
}
|
||||||
|
|
||||||
|
wglMakeCurrent(NULL, NULL);
|
||||||
|
wglDeleteContext(ctx->rc);
|
||||||
|
|
||||||
|
if (!rc_better)
|
||||||
|
{
|
||||||
|
ReleaseDC(ctx->hwnd, ctx->dc);
|
||||||
|
uiFree(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->version = uiGLVersion(vermajor, verminor);
|
||||||
|
ctx->rc = rc_better;
|
||||||
|
wglMakeCurrent(ctx->dc, ctx->rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeGLContext(uiGLContext* ctx)
|
||||||
|
{
|
||||||
|
if (ctx == NULL) return;
|
||||||
|
wglMakeCurrent(NULL, NULL);
|
||||||
|
wglDeleteContext(ctx->rc);
|
||||||
|
ReleaseDC(ctx->hwnd, ctx->dc);
|
||||||
|
uiFree(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiGLMakeContextCurrent(uiGLContext* ctx)
|
||||||
|
{
|
||||||
|
if (ctx == NULL)
|
||||||
|
{
|
||||||
|
wglMakeCurrent(NULL, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wglGetCurrentContext() == ctx->rc) return;
|
||||||
|
int res = wglMakeCurrent(ctx->dc, ctx->rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int uiGLGetVersion(uiGLContext* ctx)
|
||||||
|
{
|
||||||
|
if (ctx == NULL) return 0;
|
||||||
|
return ctx->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *uiGLGetProcAddress(const char* proc)
|
||||||
|
{
|
||||||
|
return (void*)wglGetProcAddress(proc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiGLSwapBuffers(uiGLContext* ctx)
|
||||||
|
{
|
||||||
|
if (ctx == NULL) return;
|
||||||
|
SwapBuffers(ctx->dc);
|
||||||
|
}
|
|
@ -363,6 +363,21 @@ static void windowMonitorRect(HWND hwnd, RECT *r)
|
||||||
*r = mi.rcMonitor;
|
*r = mi.rcMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uiWindowPosition(uiWindow *w, int *x, int *y)
|
||||||
|
{
|
||||||
|
RECT rect;
|
||||||
|
if (GetWindowRect(w->hwnd, &rect) == 0)
|
||||||
|
logLastError(L"error getting window position");
|
||||||
|
*x = rect.left;
|
||||||
|
*y = rect.top;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiWindowSetPosition(uiWindow *w, int x, int y)
|
||||||
|
{
|
||||||
|
if (SetWindowPos(w->hwnd, NULL, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER) == 0)
|
||||||
|
logLastError(L"error moving window");
|
||||||
|
}
|
||||||
|
|
||||||
void uiWindowContentSize(uiWindow *w, int *width, int *height)
|
void uiWindowContentSize(uiWindow *w, int *width, int *height)
|
||||||
{
|
{
|
||||||
RECT r;
|
RECT r;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,201 @@
|
||||||
|
/*
|
||||||
|
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 MAIN_SHADERS_H
|
||||||
|
#define MAIN_SHADERS_H
|
||||||
|
|
||||||
|
const char* kScreenVS = R"(#version 140
|
||||||
|
|
||||||
|
layout(std140) uniform uConfig
|
||||||
|
{
|
||||||
|
vec2 uScreenSize;
|
||||||
|
uint u3DScale;
|
||||||
|
uint uFilterMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
in vec2 vPosition;
|
||||||
|
in vec2 vTexcoord;
|
||||||
|
|
||||||
|
smooth out vec2 fTexcoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 fpos;
|
||||||
|
fpos.xy = ((vPosition.xy * 2.0) / uScreenSize) - 1.0;
|
||||||
|
fpos.y *= -1;
|
||||||
|
fpos.z = 0.0;
|
||||||
|
fpos.w = 1.0;
|
||||||
|
|
||||||
|
gl_Position = fpos;
|
||||||
|
fTexcoord = vTexcoord;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kScreenFS = R"(#version 140
|
||||||
|
|
||||||
|
layout(std140) uniform uConfig
|
||||||
|
{
|
||||||
|
vec2 uScreenSize;
|
||||||
|
uint u3DScale;
|
||||||
|
uint uFilterMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform usampler2D ScreenTex;
|
||||||
|
|
||||||
|
smooth in vec2 fTexcoord;
|
||||||
|
|
||||||
|
out vec4 oColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0));
|
||||||
|
|
||||||
|
// TODO: filters
|
||||||
|
|
||||||
|
oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* kScreenFS_Accel = R"(#version 140
|
||||||
|
|
||||||
|
layout(std140) uniform uConfig
|
||||||
|
{
|
||||||
|
vec2 uScreenSize;
|
||||||
|
uint u3DScale;
|
||||||
|
uint uFilterMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform usampler2D ScreenTex;
|
||||||
|
uniform sampler2D _3DTex;
|
||||||
|
|
||||||
|
smooth in vec2 fTexcoord;
|
||||||
|
|
||||||
|
out vec4 oColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0));
|
||||||
|
|
||||||
|
ivec4 mbright = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0));
|
||||||
|
int dispmode = mbright.b & 0x3;
|
||||||
|
|
||||||
|
if (dispmode == 1)
|
||||||
|
{
|
||||||
|
ivec4 val1 = pixel;
|
||||||
|
ivec4 val2 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0));
|
||||||
|
ivec4 val3 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0));
|
||||||
|
|
||||||
|
int compmode = val3.a & 0xF;
|
||||||
|
int eva, evb, evy;
|
||||||
|
|
||||||
|
if (compmode == 4)
|
||||||
|
{
|
||||||
|
// 3D on top, blending
|
||||||
|
|
||||||
|
float xpos = val3.r + fract(fTexcoord.x);
|
||||||
|
float ypos = mod(fTexcoord.y, 192);
|
||||||
|
ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra
|
||||||
|
* vec4(63,63,63,31));
|
||||||
|
|
||||||
|
if (_3dpix.a > 0)
|
||||||
|
{
|
||||||
|
eva = (_3dpix.a & 0x1F) + 1;
|
||||||
|
evb = 32 - eva;
|
||||||
|
|
||||||
|
val1 = ((_3dpix * eva) + (val1 * evb)) >> 5;
|
||||||
|
if (eva <= 16) val1 += ivec4(1,1,1,0);
|
||||||
|
val1 = min(val1, 0x3F);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
val1 = val2;
|
||||||
|
}
|
||||||
|
else if (compmode == 1)
|
||||||
|
{
|
||||||
|
// 3D on bottom, blending
|
||||||
|
|
||||||
|
float xpos = val3.r + fract(fTexcoord.x);
|
||||||
|
float ypos = mod(fTexcoord.y, 192);
|
||||||
|
ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra
|
||||||
|
* vec4(63,63,63,31));
|
||||||
|
|
||||||
|
if (_3dpix.a > 0)
|
||||||
|
{
|
||||||
|
eva = val3.g;
|
||||||
|
evb = val3.b;
|
||||||
|
|
||||||
|
val1 = ((val1 * eva) + (_3dpix * evb)) >> 4;
|
||||||
|
val1 = min(val1, 0x3F);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
val1 = val2;
|
||||||
|
}
|
||||||
|
else if (compmode <= 3)
|
||||||
|
{
|
||||||
|
// 3D on top, normal/fade
|
||||||
|
|
||||||
|
float xpos = val3.r + fract(fTexcoord.x);
|
||||||
|
float ypos = mod(fTexcoord.y, 192);
|
||||||
|
ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra
|
||||||
|
* vec4(63,63,63,31));
|
||||||
|
|
||||||
|
if (_3dpix.a > 0)
|
||||||
|
{
|
||||||
|
evy = val3.g;
|
||||||
|
|
||||||
|
val1 = _3dpix;
|
||||||
|
if (compmode == 2) val1 += ((ivec4(0x3F,0x3F,0x3F,0) - val1) * evy) >> 4;
|
||||||
|
else if (compmode == 3) val1 -= (val1 * evy) >> 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
val1 = val2;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel = val1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dispmode != 0)
|
||||||
|
{
|
||||||
|
int brightmode = mbright.g >> 6;
|
||||||
|
if (brightmode == 1)
|
||||||
|
{
|
||||||
|
// up
|
||||||
|
int evy = mbright.r & 0x1F;
|
||||||
|
if (evy > 16) evy = 16;
|
||||||
|
|
||||||
|
pixel += ((ivec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4;
|
||||||
|
}
|
||||||
|
else if (brightmode == 2)
|
||||||
|
{
|
||||||
|
// down
|
||||||
|
int evy = mbright.r & 0x1F;
|
||||||
|
if (evy > 16) evy = 16;
|
||||||
|
|
||||||
|
pixel -= (pixel * evy) >> 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel.rgb <<= 2;
|
||||||
|
pixel.rgb |= (pixel.rgb >> 6);
|
||||||
|
|
||||||
|
// TODO: filters
|
||||||
|
|
||||||
|
oColor = vec4(vec3(pixel.rgb) / 255.0, 1.0);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
#endif // MAIN_SHADERS_H
|
Loading…
Reference in New Issue