GPU: NDSDisplayInfo now reports the backlight intensity for each display. The LMNTS demo now properly fades the backlights in and out, but only on frontends that support this feature. (Fixes #59.)

- Note: The backlight intensity is only emulated on frontends with 3D-based display methods, such as OpenGL and Metal. CPU-based display methods, such as DirectDraw, SDL and Cairo, are currently unsupported.
This commit is contained in:
rogerman 2017-10-02 11:39:40 -07:00
parent 059ea519bc
commit f5c9a36930
11 changed files with 358 additions and 199 deletions

View File

@ -35,7 +35,6 @@
#include "gfx3d.h"
#include "debug.h"
#include "NDSSystem.h"
#include "readwrite.h"
#include "matrix.h"
#include "emufile.h"
@ -7456,6 +7455,8 @@ void GPUSubsystem::Reset()
this->_willFrameSkip = false;
this->_videoFrameCount = 0;
this->_render3DFrameCount = 0;
this->_backlightIntensityTotal[NDSDisplayID_Main] = 0.0f;
this->_backlightIntensityTotal[NDSDisplayID_Touch] = 0.0f;
this->ClearWithColor(0xFFFF);
@ -7476,6 +7477,9 @@ void GPUSubsystem::Reset()
this->_displayInfo.engineID[NDSDisplayID_Main] = GPUEngineID_Main;
this->_displayInfo.engineID[NDSDisplayID_Touch] = GPUEngineID_Sub;
this->_displayInfo.backlightIntensity[NDSDisplayID_Main] = 1.0f;
this->_displayInfo.backlightIntensity[NDSDisplayID_Touch] = 1.0f;
this->_display[NDSDisplayID_Main]->SetEngineByID(GPUEngineID_Main);
this->_display[NDSDisplayID_Touch]->SetEngineByID(GPUEngineID_Sub);
@ -8111,6 +8115,12 @@ void GPUSubsystem::RenderLine(const size_t l)
this->_displayInfo.needConvertColorFormat[NDSDisplayID_Main] = (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev);
this->_displayInfo.needConvertColorFormat[NDSDisplayID_Touch] = (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev);
// Set the average backlight intensity and then reset the current total.
this->_displayInfo.backlightIntensity[NDSDisplayID_Main] = this->_backlightIntensityTotal[NDSDisplayID_Main] / 263.0f;
this->_displayInfo.backlightIntensity[NDSDisplayID_Touch] = this->_backlightIntensityTotal[NDSDisplayID_Touch] / 263.0f;
this->_backlightIntensityTotal[NDSDisplayID_Main] = 0.0f;
this->_backlightIntensityTotal[NDSDisplayID_Touch] = 0.0f;
this->_engineMain->UpdateMasterBrightnessDisplayInfo(this->_displayInfo);
this->_engineSub->UpdateMasterBrightnessDisplayInfo(this->_displayInfo);
@ -8135,6 +8145,32 @@ void GPUSubsystem::RenderLine(const size_t l)
}
}
void GPUSubsystem::UpdateAverageBacklightIntensityTotal()
{
// The values in this table are, more or less, arbitrarily chosen.
//
// It would be nice to get some real testing done on a hardware NDS to have some more
// accurate intensity values for each backlight level.
static const float backlightLevelToIntensityTable[] = {0.100, 0.300, 0.600, 1.000};
IOREG_POWERMANCTL POWERMANCTL;
IOREG_BACKLIGHTCTL BACKLIGHTCTL;
POWERMANCTL.value = MMU.powerMan_Reg[0];
BACKLIGHTCTL.value = MMU.powerMan_Reg[4];
if (POWERMANCTL.MainBacklight_Enable != 0)
{
const BacklightLevel level = ((BACKLIGHTCTL.ExternalPowerState != 0) && (BACKLIGHTCTL.ForceMaxBrightnessWithExtPower_Enable != 0)) ? BacklightLevel_Maximum : (BacklightLevel)BACKLIGHTCTL.Level;
this->_backlightIntensityTotal[NDSDisplayID_Main] += backlightLevelToIntensityTable[level];
}
if (POWERMANCTL.TouchBacklight_Enable != 0)
{
const BacklightLevel level = ((BACKLIGHTCTL.ExternalPowerState != 0) && (BACKLIGHTCTL.ForceMaxBrightnessWithExtPower_Enable != 0)) ? BacklightLevel_Maximum : (BacklightLevel)BACKLIGHTCTL.Level;
this->_backlightIntensityTotal[NDSDisplayID_Touch] += backlightLevelToIntensityTable[level];
}
}
void GPUSubsystem::ClearWithColor(const u16 colorBGRA5551)
{
u16 color16 = colorBGRA5551;

View File

@ -764,6 +764,70 @@ typedef struct
} GPU_IOREG; // 0x04000000, 0x04001000: GPU registers
#include "PACKED_END.h"
typedef union
{
u8 value;
struct
{
#ifndef MSB_FIRST
u8 SoundAmp_Enable:1; // 0: Sound amplifier; 0=Disable, 1=Enable
u8 SoundAmp_Mute:1; // 1: Sound amplifier mute control; 0=Normal, 1=Mute
u8 TouchBacklight_Enable:1; // 2: Touch display backlight; 0=Disable, 1=Enable
u8 MainBacklight_Enable:1; // 3: Main display backlight; 0=Disable, 1=Enable
u8 PowerLEDBlink_Enable:1; // 4: Power LED blink control; 0=Disable (Power LED remains steadily ON), 1=Enable
u8 PowerLEDBlinkSpeed:1; // 5: Power LED blink speed when enabled; 0=Slow, 1=Fast
u8 SystemPowerState:2; // 6: NDS system power state; 0=System is powered ON, 1=System is powered OFF
u8 :1; // 7: Unused bit (should always be read as 0)
#else
u8 :1; // 7: Unused bit (should always be read as 0)
u8 SystemPowerState:2; // 6: NDS system power state; 0=System is powered ON, 1=System is powered OFF
u8 PowerLEDBlinkSpeed:1; // 5: Power LED blink speed when enabled; 0=Slow, 1=Fast
u8 PowerLEDBlink_Enable:1; // 4: Power LED blink control; 0=Disable (LED is steady ON), 1=Enable
u8 MainBacklight_Enable:1; // 3: Main display backlight; 0=Disable, 1=Enable
u8 TouchBacklight_Enable:1; // 2: Touch display backlight; 0=Disable, 1=Enable
u8 SoundAmp_Mute:1; // 1: Sound amplifier mute control; 0=Normal, 1=Mute
u8 SoundAmp_Enable:1; // 0: Sound amplifier; 0=Disable, 1=Enable
#endif
};
} IOREG_POWERMANCTL;
typedef union
{
u8 value;
struct
{
#ifndef MSB_FIRST
u8 Level:2; // 0-1: Backlight brightness level;
// 0=Low
// 1=Medium
// 2=High
// 3=Maximum
u8 ForceMaxBrightnessWithExtPower_Enable:1; // 2: Forces maximum brightness if external power is present, interacts with Bit 3; 0=Disable, 1=Enable
u8 ExternalPowerState:1; // 3: External power state; 0=External power is not present, 1=External power is present
u8 :4; // 4-7: Unknown bits (should always be read as 4)
#else
u8 :4; // 4-7: Unknown bits (should always be read as 4)
u8 ExternalPowerState:1; // 3: External power state; 0=External power is not present, 1=External power is present
u8 ForceMaxBrightnessWithExtPower_Enable:1; // 2: Forces maximum brightness if external power is present, interacts with Bit 3; 0=Disable, 1=Enable
u8 Level:2; // 0-1: Backlight brightness level;
// 0=Low
// 1=Medium
// 2=High
// 3=Maximum
#endif
};
} IOREG_BACKLIGHTCTL;
enum BacklightLevel
{
BacklightLevel_Low = 0,
BacklightLevel_Medium = 1,
BacklightLevel_High = 2,
BacklightLevel_Maximum = 3
};
enum ColorEffect
{
ColorEffect_Disable = 0,
@ -1115,6 +1179,10 @@ typedef struct
u8 masterBrightnessMode[2][GPU_FRAMEBUFFER_NATIVE_HEIGHT]; // The master brightness mode of each display line.
u8 masterBrightnessIntensity[2][GPU_FRAMEBUFFER_NATIVE_HEIGHT]; // The master brightness intensity of each display line.
float backlightIntensity[2]; // Reports the intensity of the backlight.
// 0.000 - The backlight is completely off.
// 1.000 - The backlight is at its maximum brightness.
// Postprocessing information. These fields report the status of each postprocessing step.
@ -1671,6 +1739,7 @@ private:
GPUEngineA *_engineMain;
GPUEngineB *_engineSub;
NDSDisplay *_display[2];
float _backlightIntensityTotal[2];
u32 _videoFrameCount; // Internal variable that increments when a video frame is completed. Resets every 60 video frames.
u32 _render3DFrameCount; // The current 3D rendering frame count, saved to this variable once every 60 video frames.
@ -1757,6 +1826,7 @@ public:
void ResolveDisplayToCustomFramebuffer(const NDSDisplayID displayID, NDSDisplayInfo &mutableInfo);
template<NDSColorFormat OUTPUTFORMAT> void RenderLine(const size_t l);
void UpdateAverageBacklightIntensityTotal();
void ClearWithColor(const u16 colorBGRA5551);
};

View File

@ -1533,6 +1533,8 @@ static void execHardware_hstart()
{
gfx3d_VBlankEndSignal(frameSkipper.ShouldSkip3D());
}
GPU->UpdateAverageBacklightIntensityTotal();
if (nds.VCount == 263)
{

View File

@ -332,10 +332,11 @@ static const char *BicubicSample6x6Output_VertShader_110 = {"\
static const char *PassthroughOutputFragShader_110 = {"\
VARYING vec2 texCoord[1];\n\
uniform sampler2DRect tex;\n\
uniform float backlightIntensity;\n\
\n\
void main()\n\
{\n\
OUT_FRAG_COLOR.rgb = SAMPLE3_TEX_RECT(tex, texCoord[0]);\n\
OUT_FRAG_COLOR.rgb = SAMPLE3_TEX_RECT(tex, texCoord[0]) * backlightIntensity;\n\
OUT_FRAG_COLOR.a = 1.0;\n\
}\n\
"};
@ -583,6 +584,7 @@ static const char *FilterDeposterizeFragShader_110 = {"\
static const char *FilterBicubicBSplineFragShader_110 = {"\
VARYING vec2 texCoord[16];\n\
uniform sampler2DRect tex;\n\
uniform float backlightIntensity;\n\
\n\
vec4 WeightBSpline(float f)\n\
{\n\
@ -624,6 +626,7 @@ static const char *FilterBicubicBSplineFragShader_110 = {"\
+ SAMPLE3_TEX_RECT(tex, texCoord[14]) * wx.g\n\
+ SAMPLE3_TEX_RECT(tex, texCoord[13]) * wx.b\n\
+ SAMPLE3_TEX_RECT(tex, texCoord[12]) * wx.a) * wy.a;\n\
OUT_FRAG_COLOR.rgb *= backlightIntensity;\n\
OUT_FRAG_COLOR.a = 1.0;\n\
}\n\
"};
@ -631,6 +634,7 @@ static const char *FilterBicubicBSplineFragShader_110 = {"\
static const char *FilterBicubicBSplineFastFragShader_110 = {"\
VARYING vec2 texCoord[1];\n\
uniform sampler2DRect tex;\n\
uniform float backlightIntensity;\n\
\n\
void main()\n\
{\n\
@ -652,6 +656,7 @@ static const char *FilterBicubicBSplineFastFragShader_110 = {"\
SAMPLE3_TEX_RECT(tex, vec2(t1.x, t0.y)) * s1.x) * s0.y +\n\
(SAMPLE3_TEX_RECT(tex, vec2(t0.x, t1.y)) * s0.x +\n\
SAMPLE3_TEX_RECT(tex, vec2(t1.x, t1.y)) * s1.x) * s1.y;\n\
OUT_FRAG_COLOR.rgb *= backlightIntensity;\n\
OUT_FRAG_COLOR.a = 1.0;\n\
}\n\
"};
@ -659,6 +664,7 @@ static const char *FilterBicubicBSplineFastFragShader_110 = {"\
static const char *FilterBicubicMitchellNetravaliFragShader_110 = {"\
VARYING vec2 texCoord[16];\n\
uniform sampler2DRect tex;\n\
uniform float backlightIntensity;\n\
\n\
vec4 WeightMitchellNetravali(float f)\n\
{\n\
@ -700,6 +706,7 @@ static const char *FilterBicubicMitchellNetravaliFragShader_110 = {"\
+ SAMPLE3_TEX_RECT(tex, texCoord[14]) * wx.g\n\
+ SAMPLE3_TEX_RECT(tex, texCoord[13]) * wx.b\n\
+ SAMPLE3_TEX_RECT(tex, texCoord[12]) * wx.a) * wy.a;\n\
OUT_FRAG_COLOR.rgb *= backlightIntensity;\n\
OUT_FRAG_COLOR.a = 1.0;\n\
}\n\
"};
@ -707,6 +714,7 @@ static const char *FilterBicubicMitchellNetravaliFragShader_110 = {"\
static const char *FilterBicubicMitchellNetravaliFastFragShader_110 = {"\
VARYING vec2 texCoord[1];\n\
uniform sampler2DRect tex;\n\
uniform float backlightIntensity;\n\
\n\
void main()\n\
{\n\
@ -728,6 +736,7 @@ static const char *FilterBicubicMitchellNetravaliFastFragShader_110 = {"\
SAMPLE3_TEX_RECT(tex, vec2(t1.x, t0.y)) * s1.x) * s0.y +\n\
(SAMPLE3_TEX_RECT(tex, vec2(t0.x, t1.y)) * s0.x +\n\
SAMPLE3_TEX_RECT(tex, vec2(t1.x, t1.y)) * s1.x) * s1.y;\n\
OUT_FRAG_COLOR.rgb *= backlightIntensity;\n\
OUT_FRAG_COLOR.a = 1.0;\n\
}\n\
"};
@ -739,6 +748,7 @@ static const char *FilterLanczos2FragShader_110 = {"\
\n\
VARYING vec2 texCoord[16];\n\
uniform sampler2DRect tex;\n\
uniform float backlightIntensity;\n\
\n\
vec4 WeightLanczos2(float f)\n\
{\n\
@ -778,6 +788,7 @@ static const char *FilterLanczos2FragShader_110 = {"\
+ SAMPLE3_TEX_RECT(tex, texCoord[14]) * wx.g\n\
+ SAMPLE3_TEX_RECT(tex, texCoord[13]) * wx.b\n\
+ SAMPLE3_TEX_RECT(tex, texCoord[12]) * wx.a) * wy.a;\n\
OUT_FRAG_COLOR.rgb *= backlightIntensity;\n\
OUT_FRAG_COLOR.a = 1.0;\n\
}\n\
"};
@ -795,6 +806,7 @@ static const char *FilterLanczos3FragShader_110 = {"\
VARYING vec2 texCoord[16];\n\
#endif\n\
uniform sampler2DRect tex;\n\
uniform float backlightIntensity;\n\
\n\
vec3 weight3(float x)\n\
{\n\
@ -938,6 +950,7 @@ static const char *FilterLanczos3FragShader_110 = {"\
+ SAMPLE3_TEX_RECT(tex, texCoord[ 0] + vec2( 2.0, 3.0)) * wx1.b\n\
+ SAMPLE3_TEX_RECT(tex, texCoord[ 0] + vec2( 3.0, 3.0)) * wx2.b) * wy2.b;\n\
#endif\n\
OUT_FRAG_COLOR.rgb *= backlightIntensity;\n\
OUT_FRAG_COLOR.a = 1.0;\n\
}\n\
"};
@ -5695,6 +5708,7 @@ OGLImage::OGLImage(OGLContextInfo *contextInfo, GLsizei imageWidth, GLsizei imag
_uniformScalar = glGetUniformLocation(finalOutputProgramID, "scalar");
_uniformViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
_uniformRenderFlipped = glGetUniformLocation(finalOutputProgramID, "renderFlipped");
_uniformBacklightIntensity = glGetUniformLocation(finalOutputProgramID, "backlightIntensity");
glUseProgram(0);
}
else
@ -6225,7 +6239,12 @@ void OGLImage::ProcessOGL()
void OGLImage::RenderOGL()
{
glUseProgram(this->_finalOutputProgram->GetProgramID());
if (this->_canUseShaderOutput)
{
glUseProgram(this->_finalOutputProgram->GetProgramID());
glUniform1f(this->_uniformBacklightIntensity, 1.0f);
}
this->UploadTransformationOGL();
if (this->_needUploadVertices)
@ -6712,6 +6731,7 @@ OGLDisplayLayer::OGLDisplayLayer(OGLVideoOutput *oglVO)
_uniformScalar = glGetUniformLocation(finalOutputProgramID, "scalar");
_uniformViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
_uniformRenderFlipped = glGetUniformLocation(finalOutputProgramID, "renderFlipped");
_uniformBacklightIntensity = glGetUniformLocation(finalOutputProgramID, "backlightIntensity");
glUseProgram(0);
}
else
@ -7204,8 +7224,9 @@ void OGLDisplayLayer::ProcessOGL()
void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped)
{
const NDSDisplayInfo &emuDisplayInfo = this->_output->GetEmuDisplayInfo();
const bool isShaderSupported = this->_output->GetContextInfo()->IsShaderSupported();
if (this->_output->GetContextInfo()->IsShaderSupported())
if (isShaderSupported)
{
glUseProgram(this->_finalOutputProgram->GetProgramID());
@ -7258,6 +7279,11 @@ void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped)
{
if (this->_output->IsSelectedDisplayEnabled(NDSDisplayID_Main))
{
if (isShaderSupported)
{
glUniform1f(this->_uniformBacklightIntensity, emuDisplayInfo.backlightIntensity[NDSDisplayID_Main]);
}
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Main]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
@ -7270,6 +7296,11 @@ void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped)
{
if (this->_output->IsSelectedDisplayEnabled(NDSDisplayID_Touch))
{
if (isShaderSupported)
{
glUniform1f(this->_uniformBacklightIntensity, emuDisplayInfo.backlightIntensity[NDSDisplayID_Touch]);
}
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Touch]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);
@ -7291,6 +7322,11 @@ void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped)
{
if (this->_output->IsSelectedDisplayEnabled(majorDisplayID))
{
if (isShaderSupported)
{
glUniform1f(this->_uniformBacklightIntensity, emuDisplayInfo.backlightIntensity[majorDisplayID]);
}
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[majorDisplayID]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[majorDisplayID]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[majorDisplayID]);
@ -7305,6 +7341,11 @@ void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped)
if (this->_output->IsSelectedDisplayEnabled(NDSDisplayID_Main))
{
if (isShaderSupported)
{
glUniform1f(this->_uniformBacklightIntensity, emuDisplayInfo.backlightIntensity[NDSDisplayID_Main]);
}
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Main]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
@ -7313,6 +7354,11 @@ void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped)
if (this->_output->IsSelectedDisplayEnabled(NDSDisplayID_Touch))
{
if (isShaderSupported)
{
glUniform1f(this->_uniformBacklightIntensity, emuDisplayInfo.backlightIntensity[NDSDisplayID_Touch]);
}
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Touch]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);

View File

@ -213,6 +213,7 @@ protected:
GLint _uniformScalar;
GLint _uniformViewSize;
GLint _uniformRenderFlipped;
GLint _uniformBacklightIntensity;
void UploadVerticesOGL();
void UploadTexCoordsOGL();
@ -259,6 +260,7 @@ protected:
GLint _uniformScalar;
GLint _uniformViewSize;
GLint _uniformRenderFlipped;
GLint _uniformBacklightIntensity;
public:
virtual ~OGLVideoLayer() {};

View File

@ -1629,6 +1629,8 @@
// Draw the NDS displays.
if (_willDrawDisplays)
{
const NDSDisplayInfo &displayInfo = cdp->GetEmuDisplayInfo();
[rce setRenderPipelineState:outputPipelineState];
[rce setVertexBuffer:_displayVtxPositionBuffer offset:0 atIndex:0];
[rce setVertexBuffer:_displayTexCoordBuffer offset:0 atIndex:1];
@ -1640,6 +1642,7 @@
{
if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Main))
{
[rce setFragmentBytes:&displayInfo.backlightIntensity[NDSDisplayID_Main] length:sizeof(displayInfo.backlightIntensity[NDSDisplayID_Main]) atIndex:0];
[rce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0];
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
}
@ -1650,6 +1653,7 @@
{
if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Touch))
{
[rce setFragmentBytes:&displayInfo.backlightIntensity[NDSDisplayID_Touch] length:sizeof(displayInfo.backlightIntensity[NDSDisplayID_Touch]) atIndex:0];
[rce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Touch] atIndex:0];
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:4 vertexCount:4];
}
@ -1669,6 +1673,7 @@
{
if (cdp->IsSelectedDisplayEnabled(majorDisplayID))
{
[rce setFragmentBytes:&displayInfo.backlightIntensity[majorDisplayID] length:sizeof(displayInfo.backlightIntensity[majorDisplayID]) atIndex:0];
[rce setFragmentTexture:_texDisplayOutput[majorDisplayID] atIndex:0];
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:majorDisplayVtx vertexCount:4];
}
@ -1681,12 +1686,14 @@
if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Main))
{
[rce setFragmentBytes:&displayInfo.backlightIntensity[NDSDisplayID_Main] length:sizeof(displayInfo.backlightIntensity[NDSDisplayID_Main]) atIndex:0];
[rce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0];
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
}
if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Touch))
{
[rce setFragmentBytes:&displayInfo.backlightIntensity[NDSDisplayID_Touch] length:sizeof(displayInfo.backlightIntensity[NDSDisplayID_Touch]) atIndex:0];
[rce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Touch] atIndex:0];
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:4 vertexCount:4];
}

View File

@ -226,17 +226,21 @@ vertex DisplayVtx display_output_bicubic_vertex(const device float2 *inPosition
//---------------------------------------
// Input Pixel Mapping: 00
fragment float4 output_filter_nearest(const DisplayVtx vtx [[stage_in]], const texture2d<float> tex [[texture(0)]])
fragment float4 output_filter_nearest(const DisplayVtx vtx [[stage_in]],
const texture2d<float> tex [[texture(0)]],
const device float *inBacklightIntensity [[buffer(0)]])
{
return tex.sample(genSampler, vtx.texCoord);
return float4(tex.sample(genSampler, vtx.texCoord).rgb * *inBacklightIntensity, 1.0f);
}
//---------------------------------------
// Input Pixel Mapping: 00|01
// 02|03
fragment float4 output_filter_bilinear(const DisplayVtx vtx [[stage_in]], const texture2d<float> tex [[texture(0)]])
fragment float4 output_filter_bilinear(const DisplayVtx vtx [[stage_in]],
const texture2d<float> tex [[texture(0)]],
const device float *inBacklightIntensity [[buffer(0)]])
{
return tex.sample(outputSamplerBilinear, vtx.texCoord);
return float4(tex.sample(outputSamplerBilinear, vtx.texCoord).rgb * *inBacklightIntensity, 1.0f);
}
//---------------------------------------
@ -244,7 +248,9 @@ fragment float4 output_filter_bilinear(const DisplayVtx vtx [[stage_in]], const
// 04|05|06|07
// 08|09|10|11
// 12|13|14|15
fragment float4 output_filter_bicubic_bspline(const DisplayVtx vtx [[stage_in]], const texture2d<float> tex [[texture(0)]])
fragment float4 output_filter_bicubic_bspline(const DisplayVtx vtx [[stage_in]],
const texture2d<float> tex [[texture(0)]],
const device float *inBacklightIntensity [[buffer(0)]])
{
float2 f = fract(vtx.texCoord);
float4 wx = bicubic_weight_bspline(f.x);
@ -271,7 +277,7 @@ fragment float4 output_filter_bicubic_bspline(const DisplayVtx vtx [[stage_in]],
+ tex.sample(genSampler, vtx.texCoord, int2( 1, 2)) * wx.b
+ tex.sample(genSampler, vtx.texCoord, int2( 2, 2)) * wx.a) * wy.a;
return float4(outFragment.rgb, 1.0f);
return float4(outFragment.rgb * *inBacklightIntensity, 1.0f);
}
//---------------------------------------
@ -279,7 +285,9 @@ fragment float4 output_filter_bicubic_bspline(const DisplayVtx vtx [[stage_in]],
// 04|05|06|07
// 08|09|10|11
// 12|13|14|15
fragment float4 output_filter_bicubic_mitchell_netravali(const DisplayVtx vtx [[stage_in]], const texture2d<float> tex [[texture(0)]])
fragment float4 output_filter_bicubic_mitchell_netravali(const DisplayVtx vtx [[stage_in]],
const texture2d<float> tex [[texture(0)]],
const device float *inBacklightIntensity [[buffer(0)]])
{
float2 f = fract(vtx.texCoord);
float4 wx = bicubic_weight_mitchell_netravali(f.x);
@ -306,7 +314,7 @@ fragment float4 output_filter_bicubic_mitchell_netravali(const DisplayVtx vtx [[
+ tex.sample(genSampler, vtx.texCoord, int2( 1, 2)) * wx.b
+ tex.sample(genSampler, vtx.texCoord, int2( 2, 2)) * wx.a) * wy.a;
return float4(outFragment.rgb, 1.0f);
return float4(outFragment.rgb * *inBacklightIntensity, 1.0f);
}
//---------------------------------------
@ -314,7 +322,9 @@ fragment float4 output_filter_bicubic_mitchell_netravali(const DisplayVtx vtx [[
// 04|05|06|07
// 08|09|10|11
// 12|13|14|15
fragment float4 output_filter_lanczos2(const DisplayVtx vtx [[stage_in]], const texture2d<float> tex [[texture(0)]])
fragment float4 output_filter_lanczos2(const DisplayVtx vtx [[stage_in]],
const texture2d<float> tex [[texture(0)]],
const device float *inBacklightIntensity [[buffer(0)]])
{
const float2 f = fract(vtx.texCoord);
float4 wx = bicubic_weight_lanczos2(f.x);
@ -341,7 +351,7 @@ fragment float4 output_filter_lanczos2(const DisplayVtx vtx [[stage_in]], const
+ tex.sample(genSampler, vtx.texCoord, int2( 1, 2)) * wx.b
+ tex.sample(genSampler, vtx.texCoord, int2( 2, 2)) * wx.a) * wy.a;
return float4(outFragment.rgb, 1.0f);
return float4(outFragment.rgb * *inBacklightIntensity, 1.0f);
}
//---------------------------------------
@ -351,7 +361,9 @@ fragment float4 output_filter_lanczos2(const DisplayVtx vtx [[stage_in]], const
// 18|19|20|21|22|23
// 24|25|26|27|28|29
// 30|31|32|33|34|35
fragment float4 output_filter_lanczos3(const DisplayVtx vtx [[stage_in]], const texture2d<float> tex [[texture(0)]])
fragment float4 output_filter_lanczos3(const DisplayVtx vtx [[stage_in]],
const texture2d<float> tex [[texture(0)]],
const device float *inBacklightIntensity [[buffer(0)]])
{
const float2 f = fract(vtx.texCoord);
float3 wx1 = bicubic_weight_lanczos3(0.5f - f.x * 0.5f);
@ -404,7 +416,7 @@ fragment float4 output_filter_lanczos3(const DisplayVtx vtx [[stage_in]], const
+ tex.sample(genSampler, vtx.texCoord, int2( 2, 3)) * wx1.b
+ tex.sample(genSampler, vtx.texCoord, int2( 3, 3)) * wx2.b) * wy2.b;
return float4(outFragment.rgb, 1.0f);
return float4(outFragment.rgb * *inBacklightIntensity, 1.0f);
}
#pragma mark NDS Emulation Functions

View File

@ -1,6 +1,6 @@
/* main.c - this file is part of DeSmuME
*
* Copyright (C) 2006-2015 DeSmuME Team
* Copyright (C) 2006-2017 DeSmuME Team
* Copyright (C) 2007 Pascal Giard (evilynux)
*
* This file is free software; you can redistribute it and/or modify
@ -138,7 +138,6 @@ public:
#ifdef INCLUDE_OPENGL_2D
int opengl_2d;
int soft_colour_convert;
#endif
int firmware_language;
@ -155,7 +154,6 @@ init_config( class configured_features *config) {
#ifdef INCLUDE_OPENGL_2D
config->opengl_2d = 0;
config->soft_colour_convert = 0;
#endif
/* use the default language */
@ -184,7 +182,6 @@ fill_config( class configured_features *config,
"SAVETYPE"},
#ifdef INCLUDE_OPENGL_2D
{ "opengl-2d", 0, 0, G_OPTION_ARG_NONE, &config->opengl_2d, "Enables using OpenGL for screen rendering", NULL},
{ "soft-convert", 0, 0, G_OPTION_ARG_NONE, &config->soft_colour_convert, "Use software colour conversion during OpenGL screen rendering. May produce better or worse frame rates depending on hardware.",
NULL},
#endif
{ "fwlang", 0, 0, G_OPTION_ARG_INT, &config->firmware_language, "Set the language in the firmware, LANG as follows:\n"
@ -274,9 +271,9 @@ joinThread_gdb( void *thread_handle) {
static int
initGL( GLuint *screen_texture) {
GLenum errCode;
u16 blank_texture[256 * 512];
u16 blank_texture[256 * 256];
memset(blank_texture, 0x001f, sizeof(blank_texture));
memset(blank_texture, 0, sizeof(blank_texture));
/* Enable Texture Mapping */
glEnable( GL_TEXTURE_2D );
@ -294,19 +291,25 @@ initGL( GLuint *screen_texture) {
glDepthFunc( GL_LEQUAL );
/* Create The Texture */
glGenTextures( 1, &screen_texture[0]);
glGenTextures(2, screen_texture);
glBindTexture( GL_TEXTURE_2D, screen_texture[0]);
for (int i = 0; i < 2; i++)
{
glBindTexture(GL_TEXTURE_2D, screen_texture[i]);
/* Generate The Texture */
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 256, 512,
0, GL_RGBA,
GL_UNSIGNED_SHORT_1_5_5_5_REV,
blank_texture);
/* Generate The Texture */
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256,
0, GL_RGBA,
GL_UNSIGNED_SHORT_1_5_5_5_REV,
blank_texture);
/* Linear Filtering */
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
/* Linear Filtering */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
if ((errCode = glGetError()) != GL_NO_ERROR) {
const GLubyte *errString;
@ -368,9 +371,8 @@ resizeWindow( u16 width, u16 height, GLuint *screen_texture) {
static void
opengl_Draw( GLuint *texture, int software_convert) {
GLenum errCode;
u16 *gpuFramebuffer = (u16 *)GPU->GetDisplayInfo().masterNativeBuffer;
opengl_Draw(GLuint *texture) {
const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
/* Clear The Screen And The Depth Buffer */
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
@ -378,54 +380,39 @@ opengl_Draw( GLuint *texture, int software_convert) {
/* Move Into The Screen 5 Units */
glLoadIdentity( );
/* Select screen Texture */
glBindTexture( GL_TEXTURE_2D, texture[0]);
if ( software_convert) {
int i;
u8 converted[256 * 384 * 3];
/* Draw the main screen as a textured quad */
glBindTexture(GL_TEXTURE_2D, texture[NDSDisplayID_Main]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192,
GL_RGBA,
GL_UNSIGNED_SHORT_1_5_5_5_REV,
displayInfo.renderedBuffer[NDSDisplayID_Main]);
for ( i = 0; i < (256 * 384); i++) {
converted[(i * 3) + 0] = ((gpuFramebuffer[i] >> 0) & 0x1f) << 3;
converted[(i * 3) + 1] = ((gpuFramebuffer[i] >> 5) & 0x1f) << 3;
converted[(i * 3) + 2] = ((gpuFramebuffer[i] >> 10) & 0x1f) << 3;
}
GLfloat backlightIntensity = displayInfo.backlightIntensity[NDSDisplayID_Main];
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384,
GL_RGB,
GL_UNSIGNED_BYTE,
converted);
}
else {
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384,
GL_RGBA,
GL_UNSIGNED_SHORT_1_5_5_5_REV,
gpuFramebuffer);
}
glBegin(GL_QUADS);
glTexCoord2f(0.00f, 0.00f); glVertex2f( 0.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(1.00f, 0.00f); glVertex2f(256.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(1.00f, 0.75f); glVertex2f(256.0f, 192.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(0.00f, 0.75f); glVertex2f( 0.0f, 192.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glEnd();
if ((errCode = glGetError()) != GL_NO_ERROR) {
const GLubyte *errString;
/* Draw the touch screen as a textured quad */
glBindTexture(GL_TEXTURE_2D, texture[NDSDisplayID_Touch]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192,
GL_RGBA,
GL_UNSIGNED_SHORT_1_5_5_5_REV,
displayInfo.renderedBuffer[NDSDisplayID_Touch]);
errString = gluErrorString(errCode);
fprintf( stderr, "GL subimage failed: %s\n", errString);
}
backlightIntensity = displayInfo.backlightIntensity[NDSDisplayID_Touch];
glBegin(GL_QUADS);
glTexCoord2f(0.00f, 0.00f); glVertex2f( 0.0f, 192.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(1.00f, 0.00f); glVertex2f(256.0f, 192.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(1.00f, 0.75f); glVertex2f(256.0f, 384.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(0.00f, 0.75f); glVertex2f( 0.0f, 384.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glEnd();
/* Draw the screen as a textured quad */
glBegin( GL_QUADS);
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, 0.0f );
glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 256.0f, 0.0f, 0.0f );
glTexCoord2f( 1.0f, 0.75f ); glVertex3f( 256.0f, 384.0f, 0.0f );
glTexCoord2f( 0.0f, 0.75f ); glVertex3f( 0.0f, 384.0f, 0.0f );
glEnd( );
if ((errCode = glGetError()) != GL_NO_ERROR) {
const GLubyte *errString;
errString = gluErrorString(errCode);
fprintf( stderr, "GL draw failed: %s\n", errString);
}
/* Draw it to the screen */
/* Flush the drawing to the screen */
SDL_GL_SwapBuffers( );
}
#endif
@ -510,7 +497,7 @@ int main(int argc, char ** argv) {
#endif
#ifdef INCLUDE_OPENGL_2D
GLuint screen_texture[1];
GLuint screen_texture[2];
#endif
/* this holds some info about our display */
const SDL_VideoInfo *videoInfo;
@ -772,7 +759,7 @@ int main(int argc, char ** argv) {
#ifdef INCLUDE_OPENGL_2D
if ( my_config.opengl_2d) {
opengl_Draw( screen_texture, my_config.soft_colour_convert);
opengl_Draw(screen_texture);
ctrls_cfg.resize_cb = &resizeWindow;
}
else

View File

@ -1,6 +1,6 @@
/* gdk_gl.cpp - this file is part of DeSmuME
*
* Copyright (C) 2007-2016 DeSmuME Team
* Copyright (C) 2007-2017 DeSmuME Team
* Copyright (C) 2007 Damien Nozay (damdoum)
* Author: damdoum at users.sourceforge.net
*
@ -33,7 +33,6 @@
#define _DUP4(a) a,a,a,a
#define _DUP2(a) a,a
GLuint Textures[2];
// free number we can use in tools 0-1 reserved for screens
static int free_gl_drawable=2;
GdkGLConfig *my_glConfig=NULL;
@ -41,10 +40,7 @@ GdkGLContext *my_glContext[8]={_DUP8(NULL)};
GdkGLDrawable *my_glDrawable[8]={_DUP8(NULL)};
GtkWidget *pDrawingTexArea;
GLuint screen_texture[1];
/* enable software colour format conversion */
static int gtk_glade_use_software_colour_convert;
GLuint screen_texture[2];
#undef _DUP8
#undef _DUP4
@ -141,32 +137,45 @@ int init_GL_free(GtkWidget * widget) {
return r;
}
void init_GL_capabilities( int use_software_convert) {
void init_GL_capabilities() {
uint16_t blank_texture[256 * 512];
uint16_t blank_texture[256 * 256];
memset(blank_texture, 0, sizeof(blank_texture));
my_glConfig = gdk_gl_config_new_by_mode (
(GdkGLConfigMode) (GDK_GL_MODE_RGBA
| GDK_GL_MODE_DEPTH
| GDK_GL_MODE_DOUBLE)
);
gtk_glade_use_software_colour_convert = use_software_convert;
// initialize 1st drawing area
init_GL(pDrawingArea,0,0);
my_gl_Clear(0);
if (!my_gl_Begin(0)) return;
// generate ONE texture (display)
glEnable(GL_TEXTURE_2D);
glGenTextures(2, Textures);
glGenTextures(2, screen_texture);
/* Generate The Texture */
glBindTexture( GL_TEXTURE_2D, Textures[0]);
memset(blank_texture, 0, sizeof(blank_texture));
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 256, 512,
0, GL_RGBA,
GL_UNSIGNED_SHORT_1_5_5_5_REV,
blank_texture);
/* Generate The Texture */
for (int i = 0; i < 2; i++)
{
glBindTexture(GL_TEXTURE_2D, screen_texture[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#define MyFILTER GL_LINEAR
//#define MyFILTER GL_NEAREST
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MyFILTER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MyFILTER);
#undef MyFILTER
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256,
0, GL_RGBA,
GL_UNSIGNED_SHORT_1_5_5_5_REV,
blank_texture);
}
my_gl_End(0);
// initialize 2nd drawing area (sharing context)
@ -192,52 +201,44 @@ void reshape (GtkWidget * widget, int screen) {
/* TEXTURING */
/************************************************/
static void my_gl_Texture2D() {
glBindTexture(GL_TEXTURE_2D, Textures[0]);
#define MyFILTER GL_LINEAR
//#define MyFILTER GL_NEAREST
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MyFILTER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MyFILTER);
#undef MyFILTER
}
static void
my_gl_ScreenTex( int software_convert) {
u16 *gpuFramebuffer = (u16 *)GPU->GetDisplayInfo().masterNativeBuffer;
if ( software_convert) {
u8 converted[256 * 384 * 3];
int i;
for ( i = 0; i < (256 * 384); i++) {
converted[(i * 3) + 0] = ((gpuFramebuffer[i] >> 0) & 0x1f) << 3;
converted[(i * 3) + 1] = ((gpuFramebuffer[i] >> 5) & 0x1f) << 3;
converted[(i * 3) + 2] = ((gpuFramebuffer[i] >> 10) & 0x1f) << 3;
}
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384,
GL_RGB,
GL_UNSIGNED_BYTE,
converted);
}
else {
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384,
GL_RGBA,
GL_UNSIGNED_SHORT_1_5_5_5_REV,
gpuFramebuffer);
}
my_gl_ScreenTex() {
const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
glBindTexture(GL_TEXTURE_2D, screen_texture[NDSDisplayID_Main]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192,
GL_RGBA,
GL_UNSIGNED_SHORT_1_5_5_5_REV,
displayInfo.renderedBuffer[NDSDisplayID_Main]);
glBindTexture(GL_TEXTURE_2D, screen_texture[NDSDisplayID_Touch]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192,
GL_RGBA,
GL_UNSIGNED_SHORT_1_5_5_5_REV,
displayInfo.renderedBuffer[NDSDisplayID_Touch]);
}
static void my_gl_ScreenTexApply(int screen) {
float off = (screen)?0.375:0;
glColor4ub(255,255,255,255);
const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
GLfloat backlightIntensity = displayInfo.backlightIntensity[NDSDisplayID_Main];
glBindTexture(GL_TEXTURE_2D, screen_texture[NDSDisplayID_Main]);
glBegin(GL_QUADS);
// texcoords 0.375 means 192, 1 means 256
glTexCoord2f(0.0, off+0.000); glVertex2d(-1.0, 1.0);
glTexCoord2f(1.0, off+0.000); glVertex2d( 1.0, 1.0);
glTexCoord2f(1.0, off+0.375); glVertex2d( 1.0,-1.0);
glTexCoord2f(0.0, off+0.375); glVertex2d(-1.0,-1.0);
glTexCoord2f(0.00f, 0.00f); glVertex2f(-1.0f, 1.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(1.00f, 0.00f); glVertex2f( 1.0f, 1.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(1.00f, 0.75f); glVertex2f( 1.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(0.00f, 0.75f); glVertex2f(-1.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glEnd();
backlightIntensity = displayInfo.backlightIntensity[NDSDisplayID_Touch];
glBindTexture(GL_TEXTURE_2D, screen_texture[NDSDisplayID_Touch]);
glBegin(GL_QUADS);
glTexCoord2f(0.00f, 0.00f); glVertex2f(-1.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(1.00f, 0.00f); glVertex2f( 1.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(1.00f, 0.75f); glVertex2f( 1.0f, -1.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(0.00f, 0.75f); glVertex2f(-1.0f, -1.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glEnd();
}
@ -247,7 +248,6 @@ static void my_gl_ScreenTexApply(int screen) {
gboolean screen (GtkWidget * widget, int viewportscreen) {
int screen;
GPUEngineBase * gpu;
// we take care to draw the right thing the right place
// we need to rearrange widgets not to use this trick
@ -271,10 +271,8 @@ gboolean screen (GtkWidget * widget, int viewportscreen) {
if (desmume_running()) {
// rotate
glRotatef(ScreenRotate, 0.0, 0.0, 1.0);
// create the texture for both display
my_gl_Texture2D();
if (viewportscreen==0) {
my_gl_ScreenTex( gtk_glade_use_software_colour_convert);
my_gl_ScreenTex();
}
}

View File

@ -90,7 +90,6 @@ GPU3DInterface *core3DList[] = {
*/
struct configured_features {
int load_slot;
int software_colour_convert;
int opengl_2d;
int engine_3d;
int disable_limiter;
@ -110,8 +109,6 @@ init_configured_features( struct configured_features *config) {
config->arm9_gdb_port = 0;
config->arm7_gdb_port = 0;
config->software_colour_convert = 0;
config->opengl_2d = 0;
config->engine_3d = 1;
@ -137,12 +134,6 @@ fill_configured_features( struct configured_features *config,
g_print( _("OPTIONS:\n"));
g_print( _("\
--load-slot=NUM Load game saved under NUM position.\n\n"));
#ifdef GTKGLEXT_AVAILABLE
g_print( _("\
--soft-convert Use software colour conversion during OpenGL\n\
screen rendering. May produce better or worse\n\
frame rates depending on hardware.\n\n"));
#endif
g_print( _("\
--3d-engine=ENGINE Selects 3D rendering engine\n\
0 = disabled\n\
@ -198,9 +189,6 @@ fill_configured_features( struct configured_features *config,
// FIXME: to be implemented
config->opengl_2d = 1;
}
else if ( strcmp( argv[i], "--soft-convert") == 0) {
config->software_colour_convert = 1;
}
#define MAX3DEMU 2
#else
#define MAX3DEMU 1
@ -466,7 +454,7 @@ common_gtk_glade_main( struct configured_features *my_config) {
glade_xml_signal_autoconnect_StringObject(xml);
glade_xml_signal_autoconnect_StringObject(xml_tools);
init_GL_capabilities( my_config->software_colour_convert);
init_GL_capabilities();
/* check command line file */
if( my_config->nds_file) {

99
desmume/src/frontend/windows/main.cpp Normal file → Executable file
View File

@ -1567,25 +1567,25 @@ struct GLDISPLAY
active = false;
}
//http://stackoverflow.com/questions/589064/how-to-enable-vertical-sync-in-opengl
bool WGLExtensionSupported(const char *extension_name)
{
// this is pointer to function which returns pointer to string with list of all wgl extensions
PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglGetExtensionsStringEXT = NULL;
// determine pointer to wglGetExtensionsStringEXT function
_wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
if (strstr(_wglGetExtensionsStringEXT(), extension_name) == NULL)
{
// string was not found
return false;
}
// extension is supported
return true;
//http://stackoverflow.com/questions/589064/how-to-enable-vertical-sync-in-opengl
bool WGLExtensionSupported(const char *extension_name)
{
// this is pointer to function which returns pointer to string with list of all wgl extensions
PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglGetExtensionsStringEXT = NULL;
// determine pointer to wglGetExtensionsStringEXT function
_wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
if (strstr(_wglGetExtensionsStringEXT(), extension_name) == NULL)
{
// string was not found
return false;
}
// extension is supported
return true;
}
void setvsync(bool vsync)
@ -1598,17 +1598,17 @@ struct GLDISPLAY
//even if it doesn't work, we'll track it
haveVsync = wantVsync;
if (!WGLExtensionSupported("WGL_EXT_swap_control")) return;
if (!WGLExtensionSupported("WGL_EXT_swap_control")) return;
//http://stackoverflow.com/questions/589064/how-to-enable-vertical-sync-in-opengl
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = NULL;
{
// Extension is supported, init pointers.
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
// this is another function from WGL_EXT_swap_control extension
wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT");
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = NULL;
{
// Extension is supported, init pointers.
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
// this is another function from WGL_EXT_swap_control extension
wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT");
}
wglSwapIntervalEXT(wantVsync ? 1 : 0);
@ -1625,6 +1625,8 @@ static void OGL_DoDisplay()
{
if(!gldisplay.begin()) return;
const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
static GLuint tex = 0;
if(tex == 0)
glGenTextures(1,&tex);
@ -1641,8 +1643,8 @@ static void OGL_DoDisplay()
//the ds screen fills the texture entirely, so we dont have garbage at edge to worry about,
//but we need to make sure this is clamped for when filtering is selected
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
if(GetStyle()&DWS_FILTER)
{
@ -1700,7 +1702,7 @@ static void OGL_DoDisplay()
int r = (color_rev>>0)&0xFF;
int g = (color_rev>>8)&0xFF;
int b = (color_rev>>16)&0xFF;
glClearColor(r/255.0f,g/255.0f,b/255.0f,1);
glClearColor(r/255.0f,g/255.0f,b/255.0f,1.0f);
glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
@ -1708,7 +1710,7 @@ static void OGL_DoDisplay()
RECT srcRects [2];
const bool isMainGPUFirst = (GPU->GetDisplayInfo().engineID[NDSDisplayID_Main] == GPUEngineID_Main);
const bool isMainGPUFirst = (displayInfo.engineID[NDSDisplayID_Main] == GPUEngineID_Main);
if(video.swap == 0)
{
@ -1776,12 +1778,21 @@ static void OGL_DoDisplay()
float u[] = {u1,u2,u2,u1};
float v[] = {v1,v1,v2,v2};
const GLfloat backlightIntensity = displayInfo.backlightIntensity[i];
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(u[(ofs+0)%4],v[(ofs+0)%4]);
glVertex2i(dr[i].left,dr[i].top);
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(u[(ofs+1)%4],v[(ofs+1)%4]);
glVertex2i(dr[i].right,dr[i].top);
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(u[(ofs+2)%4],v[(ofs+2)%4]);
glVertex2i(dr[i].right,dr[i].bottom);
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
glTexCoord2f(u[(ofs+3)%4],v[(ofs+3)%4]);
glVertex2i(dr[i].left,dr[i].bottom);
}
@ -4251,14 +4262,14 @@ void ScreenshotToClipboard(bool extraInfo)
bmi.bV4Height = -height;
if(gpu_bpp == 15)
{
bmi.bV4Size = sizeof(bmi);
bmi.bV4Planes = 1;
bmi.bV4BitCount = 16;
bmi.bV4V4Compression = BI_RGB | BI_BITFIELDS;
bmi.bV4RedMask = 0x001F;
bmi.bV4GreenMask = 0x03E0;
bmi.bV4BlueMask = 0x7C00;
bmi.bV4Width = width;
bmi.bV4Size = sizeof(bmi);
bmi.bV4Planes = 1;
bmi.bV4BitCount = 16;
bmi.bV4V4Compression = BI_RGB | BI_BITFIELDS;
bmi.bV4RedMask = 0x001F;
bmi.bV4GreenMask = 0x03E0;
bmi.bV4BlueMask = 0x7C00;
bmi.bV4Width = width;
bmi.bV4Height = -height;
SetDIBitsToDevice(hMemDC, 0, 0, width, height, 0, 0, 0, height, dispInfo.masterCustomBuffer, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
@ -7293,9 +7304,9 @@ const char* OpenLuaScript(const char* filename, const char* extraDirToCheck, boo
}
else
{
#pragma warning( push )
//'type cast': pointer truncation from 'HWND' to 'int'
//it's just a hash key. it's probably safe
#pragma warning( push )
//'type cast': pointer truncation from 'HWND' to 'int'
//it's just a hash key. it's probably safe
#pragma warning( disable : 4311 )
RequestAbortLuaScript((int)scriptHWnd, "terminated to restart because of a call to emu.openscript");
#pragma warning( pop )