diff --git a/desmume/src/frontend/cocoa/ClientDisplayView.cpp b/desmume/src/frontend/cocoa/ClientDisplayView.cpp index d398407bc..88af3f3a2 100644 --- a/desmume/src/frontend/cocoa/ClientDisplayView.cpp +++ b/desmume/src/frontend/cocoa/ClientDisplayView.cpp @@ -59,6 +59,7 @@ void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props) _pixelScaler = VideoFilterTypeID_None; _outputFilter = OutputFilterTypeID_Bilinear; + _useVerticalSync = false; _scaleFactor = 1.0; _hudObjectScale = 1.0; @@ -151,6 +152,16 @@ void ClientDisplayView::Init() // Do nothing. This is implementation dependent. } +bool ClientDisplayView::GetUseVerticalSync() const +{ + return this->_useVerticalSync; +} + +void ClientDisplayView::SetUseVerticalSync(const bool useVerticalSync) +{ + this->_useVerticalSync = useVerticalSync; +} + double ClientDisplayView::GetScaleFactor() const { return this->_scaleFactor; @@ -833,3 +844,247 @@ void ClientDisplay3DView::SetVideoBuffers(const uint32_t colorFormat, { // Do nothing. This is implementation dependent. } + +void ClientDisplay3DView::SetHUDVertices(float viewportWidth, float viewportHeight, float *vtxBufferPtr) +{ + const char *cString = this->_hudString.c_str(); + const size_t length = this->_hudString.length(); + const float charSize = this->_glyphSize; + const float lineHeight = charSize * 0.8f; + const float textBoxTextOffset = charSize * 0.25f; + float charLocX = textBoxTextOffset; + float charLocY = -textBoxTextOffset - lineHeight; + float textBoxWidth = 0.0f; + + // First, calculate the vertices of the text box. + // The text box should always be the first character in the string. + vtxBufferPtr[0] = 0.0f; vtxBufferPtr[1] = 0.0f; + vtxBufferPtr[2] = charLocX; vtxBufferPtr[3] = 0.0f; + vtxBufferPtr[4] = charLocX; vtxBufferPtr[5] = -textBoxTextOffset; + vtxBufferPtr[6] = 0.0f; vtxBufferPtr[7] = -textBoxTextOffset; + + // Calculate the vertices of the remaining characters in the string. + for (size_t i = 1; i < length; i++) + { + const char c = cString[i]; + + if (c == '\n') + { + if (charLocX > textBoxWidth) + { + textBoxWidth = charLocX; + } + + vtxBufferPtr[5] -= lineHeight; + vtxBufferPtr[7] -= lineHeight; + + charLocX = textBoxTextOffset; + charLocY -= lineHeight; + continue; + } + + const float charWidth = this->_glyphInfo[c].width * charSize / (float)this->_glyphTileSize; + + vtxBufferPtr[(i*8)+0] = charLocX; vtxBufferPtr[(i*8)+1] = charLocY + charSize; // Top Left + vtxBufferPtr[(i*8)+2] = charLocX + charWidth; vtxBufferPtr[(i*8)+3] = charLocY + charSize; // Top Right + vtxBufferPtr[(i*8)+4] = charLocX + charWidth; vtxBufferPtr[(i*8)+5] = charLocY; // Bottom Right + vtxBufferPtr[(i*8)+6] = charLocX; vtxBufferPtr[(i*8)+7] = charLocY; // Bottom Left + charLocX += (charWidth + (charSize * 0.03f) + 0.10f); + } + + float textBoxScale = HUD_TEXTBOX_BASE_SCALE * this->_hudObjectScale; + if (textBoxScale < (HUD_TEXTBOX_BASE_SCALE * HUD_TEXTBOX_MIN_SCALE)) + { + textBoxScale = HUD_TEXTBOX_BASE_SCALE * HUD_TEXTBOX_MIN_SCALE; + } + + float boxOffset = 8.0f * HUD_TEXTBOX_BASE_SCALE * this->_hudObjectScale; + if (boxOffset < 1.0f) + { + boxOffset = 1.0f; + } + else if (boxOffset > 8.0f) + { + boxOffset = 8.0f; + } + + boxOffset *= this->_scaleFactor; + + // Set the width of the text box + vtxBufferPtr[2] += textBoxWidth; + vtxBufferPtr[4] += textBoxWidth; + + // Scale and translate the box + for (size_t i = 0; i < (length * 8); i+=2) + { + // Scale + vtxBufferPtr[i+0] *= textBoxScale; + vtxBufferPtr[i+1] *= textBoxScale; + + // Translate + vtxBufferPtr[i+0] += boxOffset - (viewportWidth / 2.0f); + vtxBufferPtr[i+1] += (viewportHeight / 2.0f) - boxOffset; + } +} + +void ClientDisplay3DView::SetHUDTextureCoordinates(float *texCoordBufferPtr) +{ + const char *cString = this->_hudString.c_str(); + const size_t length = this->_hudString.length(); + + for (size_t i = 0; i < length; i++) + { + const char c = cString[i]; + const float *glyphTexCoord = this->_glyphInfo[c].texCoord; + float *hudTexCoord = &texCoordBufferPtr[i * 8]; + + hudTexCoord[0] = glyphTexCoord[0]; + hudTexCoord[1] = glyphTexCoord[1]; + hudTexCoord[2] = glyphTexCoord[2]; + hudTexCoord[3] = glyphTexCoord[3]; + hudTexCoord[4] = glyphTexCoord[4]; + hudTexCoord[5] = glyphTexCoord[5]; + hudTexCoord[6] = glyphTexCoord[6]; + hudTexCoord[7] = glyphTexCoord[7]; + } +} + +void ClientDisplay3DView::SetScreenVertices(float *vtxBufferPtr) +{ + const float w = this->_renderProperty.normalWidth / 2.0f; + const float h = this->_renderProperty.normalHeight / 2.0f; + const size_t f = (this->_renderProperty.order == ClientDisplayOrder_MainFirst) ? 0 : 8; + + if (this->_renderProperty.mode == ClientDisplayMode_Dual) + { + switch (this->_renderProperty.layout) + { + case ClientDisplayLayout_Horizontal: + { + vtxBufferPtr[0+f] = -w; vtxBufferPtr[1+f] = h; // Left display, top left + vtxBufferPtr[2+f] = 0.0f; vtxBufferPtr[3+f] = h; // Left display, top right + vtxBufferPtr[4+f] = -w; vtxBufferPtr[5+f] = -h; // Left display, bottom left + vtxBufferPtr[6+f] = 0.0f; vtxBufferPtr[7+f] = -h; // Left display, bottom right + + vtxBufferPtr[8-f] = 0.0f; vtxBufferPtr[9-f] = h; // Right display, top left + vtxBufferPtr[10-f] = w; vtxBufferPtr[11-f] = h; // Right display, top right + vtxBufferPtr[12-f] = 0.0f; vtxBufferPtr[13-f] = -h; // Right display, bottom left + vtxBufferPtr[14-f] = w; vtxBufferPtr[15-f] = -h; // Right display, bottom right + + memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); // Unused displays + break; + } + + case ClientDisplayLayout_Hybrid_2_1: + { + vtxBufferPtr[0] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[1] = -h + (96.0f * 2.0f); // Minor top display, top left + vtxBufferPtr[2] = w; vtxBufferPtr[3] = -h + (96.0f * 2.0f); // Minor top display, top right + vtxBufferPtr[4] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[5] = -h + 96.0f; // Minor top display, bottom left + vtxBufferPtr[6] = w; vtxBufferPtr[7] = -h + 96.0f; // Minor top display, bottom right + + vtxBufferPtr[8] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[9] = -h + 96.0f; // Minor bottom display, top left + vtxBufferPtr[10] = w; vtxBufferPtr[11] = -h + 96.0f; // Minor bottom display, top right + vtxBufferPtr[12] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[13] = -h; // Minor bottom display, bottom left + vtxBufferPtr[14] = w; vtxBufferPtr[15] = -h; // Minor bottom display, bottom right + + vtxBufferPtr[16] = -w; vtxBufferPtr[17] = h; // Major display, top left + vtxBufferPtr[18] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[19] = h; // Major display, top right + vtxBufferPtr[20] = -w; vtxBufferPtr[21] = -h; // Major display, bottom left + vtxBufferPtr[22] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[23] = -h; // Major display, bottom right + + memcpy(vtxBufferPtr + (3 * 8), vtxBufferPtr + (2 * 8), sizeof(float) * (1 * 8)); // Major display (bottom screen) + break; + } + + case ClientDisplayLayout_Hybrid_16_9: + { + const float g = (float)this->_renderProperty.gapDistance * (this->_renderProperty.normalWidth - (float)GPU_FRAMEBUFFER_NATIVE_WIDTH) / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; + + vtxBufferPtr[0] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[1] = -h + g + (64.0f * 2.0f); // Minor top display, top left + vtxBufferPtr[2] = w; vtxBufferPtr[3] = -h + g + (64.0f * 2.0f); // Minor top display, top right + vtxBufferPtr[4] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[5] = -h + g + 64.0f; // Minor top display, bottom left + vtxBufferPtr[6] = w; vtxBufferPtr[7] = -h + g + 64.0f; // Minor top display, bottom right + + vtxBufferPtr[8] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[9] = -h + 64.0f; // Minor bottom display, top left + vtxBufferPtr[10] = w; vtxBufferPtr[11] = -h + 64.0f; // Minor bottom display, top right + vtxBufferPtr[12] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[13] = -h; // Minor bottom display, bottom left + vtxBufferPtr[14] = w; vtxBufferPtr[15] = -h; // Minor bottom display, bottom right + + vtxBufferPtr[16] = -w; vtxBufferPtr[17] = h; // Major display, top left + vtxBufferPtr[18] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[19] = h; // Major display, top right + vtxBufferPtr[20] = -w; vtxBufferPtr[21] = -h; // Major display, bottom left + vtxBufferPtr[22] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[23] = -h; // Major display, bottom right + + memcpy(vtxBufferPtr + (3 * 8), vtxBufferPtr + (2 * 8), sizeof(float) * (1 * 8)); // Major display (bottom screen) + break; + } + + case ClientDisplayLayout_Hybrid_16_10: + { + const float g = (float)this->_renderProperty.gapDistance * (this->_renderProperty.normalWidth - (float)GPU_FRAMEBUFFER_NATIVE_WIDTH) / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; + + vtxBufferPtr[0] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[1] = -h + g + (38.4f * 2.0f); // Minor top display, top left + vtxBufferPtr[2] = w; vtxBufferPtr[3] = -h + g + (38.4f * 2.0f); // Minor top display, top right + vtxBufferPtr[4] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[5] = -h + g + 38.4f; // Minor top display, bottom left + vtxBufferPtr[6] = w; vtxBufferPtr[7] = -h + g + 38.4f; // Minor top display, bottom right + + vtxBufferPtr[8] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[9] = -h + 38.4f; // Minor bottom display, top left + vtxBufferPtr[10] = w; vtxBufferPtr[11] = -h + 38.4f; // Minor bottom display, top right + vtxBufferPtr[12] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[13] = -h; // Minor bottom display, bottom left + vtxBufferPtr[14] = w; vtxBufferPtr[15] = -h; // Minor bottom display, bottom right + + vtxBufferPtr[16] = -w; vtxBufferPtr[17] = h; // Major display, top left + vtxBufferPtr[18] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[19] = h; // Major display, top right + vtxBufferPtr[20] = -w; vtxBufferPtr[21] = -h; // Major display, bottom left + vtxBufferPtr[22] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[23] = -h; // Major display, bottom right + + memcpy(vtxBufferPtr + (3 * 8), vtxBufferPtr + (2 * 8), sizeof(float) * (1 * 8)); // Major display (bottom screen) + break; + } + + default: // Default to vertical orientation. + { + const float g = (float)this->_renderProperty.gapDistance; + + vtxBufferPtr[0+f] = -w; vtxBufferPtr[1+f] = h; // Top display, top left + vtxBufferPtr[2+f] = w; vtxBufferPtr[3+f] = h; // Top display, top right + vtxBufferPtr[4+f] = -w; vtxBufferPtr[5+f] = g/2.0f; // Top display, bottom left + vtxBufferPtr[6+f] = w; vtxBufferPtr[7+f] = g/2.0f; // Top display, bottom right + + vtxBufferPtr[8-f] = -w; vtxBufferPtr[9-f] = -g/2.0f; // Bottom display, top left + vtxBufferPtr[10-f] = w; vtxBufferPtr[11-f] = -g/2.0f; // Bottom display, top right + vtxBufferPtr[12-f] = -w; vtxBufferPtr[13-f] = -h; // Bottom display, bottom left + vtxBufferPtr[14-f] = w; vtxBufferPtr[15-f] = -h; // Bottom display, bottom right + + memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); // Unused displays + break; + } + } + } + else // displayModeID == ClientDisplayMode_Main || displayModeID == ClientDisplayMode_Touch + { + vtxBufferPtr[0] = -w; vtxBufferPtr[1] = h; // First display, top left + vtxBufferPtr[2] = w; vtxBufferPtr[3] = h; // First display, top right + vtxBufferPtr[4] = -w; vtxBufferPtr[5] = -h; // First display, bottom left + vtxBufferPtr[6] = w; vtxBufferPtr[7] = -h; // First display, bottom right + + memcpy(vtxBufferPtr + (1 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (1 * 8)); // Second display + memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (1 * 8)); // Unused display + memcpy(vtxBufferPtr + (3 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (1 * 8)); // Unused display + } +} + +void ClientDisplay3DView::SetScreenTextureCoordinates(float w0, float h0, float w1, float h1, float *texCoordBufferPtr) +{ + texCoordBufferPtr[0] = 0.0f; texCoordBufferPtr[1] = 0.0f; + texCoordBufferPtr[2] = w0; texCoordBufferPtr[3] = 0.0f; + texCoordBufferPtr[4] = 0.0f; texCoordBufferPtr[5] = h0; + texCoordBufferPtr[6] = w0; texCoordBufferPtr[7] = h0; + + texCoordBufferPtr[8] = 0.0f; texCoordBufferPtr[9] = 0.0f; + texCoordBufferPtr[10] = w1; texCoordBufferPtr[11] = 0.0f; + texCoordBufferPtr[12] = 0.0f; texCoordBufferPtr[13] = h1; + texCoordBufferPtr[14] = w1; texCoordBufferPtr[15] = h1; + + memcpy(texCoordBufferPtr + (2 * 8), texCoordBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); +} diff --git a/desmume/src/frontend/cocoa/ClientDisplayView.h b/desmume/src/frontend/cocoa/ClientDisplayView.h index c5712c8ec..7b28b3159 100644 --- a/desmume/src/frontend/cocoa/ClientDisplayView.h +++ b/desmume/src/frontend/cocoa/ClientDisplayView.h @@ -118,6 +118,7 @@ protected: VideoFilterTypeID _pixelScaler; OutputFilterTypeID _outputFilter; + bool _useVerticalSync; double _scaleFactor; double _hudObjectScale; @@ -154,6 +155,8 @@ public: virtual void Init(); + bool GetUseVerticalSync() const; + virtual void SetUseVerticalSync(const bool useVerticalSync); double GetScaleFactor() const; virtual void SetScaleFactor(const double scaleFactor); @@ -209,6 +212,10 @@ public: virtual void FrameRender() = 0; virtual void FrameFinish() = 0; + // Emulator interface + virtual void HandleGPUFrameEndEvent(const bool isMainSizeNative, const bool isTouchSizeNative) = 0; + virtual void HandleEmulatorFrameEndEvent(const NDSFrameInfo &frameInfo) = 0; + // Touch screen input handling void GetNDSPoint(const int inputID, const bool isInitialTouchPress, const double clientX, const double clientY, @@ -256,9 +263,11 @@ public: const void *customBuffer0, const size_t customWidth0, const size_t customHeight0, const void *customBuffer1, const size_t customWidth1, const size_t customHeight1) = 0; - virtual void FrameFlush() = 0; - virtual void FrameRenderAndFlush() = 0; - + void SetHUDVertices(float viewportWidth, float viewportHeight, float *vtxBufferPtr); + void SetHUDTextureCoordinates(float *texCoordBufferPtr); + void SetScreenVertices(float *vtxBufferPtr); + void SetScreenTextureCoordinates(float w0, float h0, float w1, float h1, float *texCoordBufferPtr); + virtual void UpdateView() = 0; }; diff --git a/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp b/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp index 89c315a01..0a863945c 100644 --- a/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp +++ b/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp @@ -4943,8 +4943,8 @@ void OGLVideoOutput::_UpdateRotation() void OGLVideoOutput::_UpdateClientSize() { - this->_viewportWidth = (GLsizei)(this->_renderProperty.clientWidth + 0.0015); - this->_viewportHeight = (GLsizei)(this->_renderProperty.clientHeight + 0.0015); + this->_viewportWidth = (GLsizei)(this->_renderProperty.clientWidth + 0.0001); + this->_viewportHeight = (GLsizei)(this->_renderProperty.clientHeight + 0.0001); this->_needUpdateViewport = true; this->GetHUDLayer()->SetNeedsUpdateVertices(); @@ -6435,87 +6435,11 @@ void OGLHUDLayer::_UpdateVerticesOGL() return; } - const char *cString = this->_output->GetHUDString().c_str(); - const GLfloat charSize = this->_glyphSize; - const GLfloat lineHeight = charSize * 0.8f; - const GLfloat textBoxTextOffset = charSize * 0.25f; - GLfloat charLocX = textBoxTextOffset; - GLfloat charLocY = -textBoxTextOffset - lineHeight; - GLfloat textBoxWidth = 0.0f; - glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboVertexID); glBufferDataARB(GL_ARRAY_BUFFER_ARB, HUD_VERTEX_ATTRIBUTE_BUFFER_SIZE, NULL, GL_STREAM_DRAW_ARB); - GLfloat *vtxBufferPtr = (GLfloat *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + float *vtxBufferPtr = (float *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - // First, calculate the vertices of the text box. - // The text box should always be the first character in the string. - vtxBufferPtr[0] = 0.0f; vtxBufferPtr[1] = 0.0f; - vtxBufferPtr[2] = charLocX; vtxBufferPtr[3] = 0.0f; - vtxBufferPtr[4] = charLocX; vtxBufferPtr[5] = -textBoxTextOffset; - vtxBufferPtr[6] = 0.0f; vtxBufferPtr[7] = -textBoxTextOffset; - - // Calculate the vertices of the remaining characters in the string. - for (size_t i = 1; i < length; i++) - { - const char c = cString[i]; - - if (c == '\n') - { - if (charLocX > textBoxWidth) - { - textBoxWidth = charLocX; - } - - vtxBufferPtr[5] -= lineHeight; - vtxBufferPtr[7] -= lineHeight; - - charLocX = textBoxTextOffset; - charLocY -= lineHeight; - continue; - } - - const GLfloat charWidth = this->_glyphInfo[c].width * charSize / this->_glyphTileSize; - - vtxBufferPtr[(i*8)+0] = charLocX; vtxBufferPtr[(i*8)+1] = charLocY + charSize; // Top Left - vtxBufferPtr[(i*8)+2] = charLocX + charWidth; vtxBufferPtr[(i*8)+3] = charLocY + charSize; // Top Right - vtxBufferPtr[(i*8)+4] = charLocX + charWidth; vtxBufferPtr[(i*8)+5] = charLocY; // Bottom Right - vtxBufferPtr[(i*8)+6] = charLocX; vtxBufferPtr[(i*8)+7] = charLocY; // Bottom Left - charLocX += (charWidth + (charSize * 0.03f) + 0.10f); - } - - GLfloat textBoxScale = HUD_TEXTBOX_BASE_SCALE * this->_output->GetHUDObjectScale(); - if (textBoxScale < (HUD_TEXTBOX_BASE_SCALE * HUD_TEXTBOX_MIN_SCALE)) - { - textBoxScale = HUD_TEXTBOX_BASE_SCALE * HUD_TEXTBOX_MIN_SCALE; - } - - GLfloat boxOffset = 8.0f * HUD_TEXTBOX_BASE_SCALE * this->_output->GetHUDObjectScale(); - if (boxOffset < 1.0f) - { - boxOffset = 1.0f; - } - else if (boxOffset > 8.0f) - { - boxOffset = 8.0f; - } - - boxOffset *= this->_output->GetScaleFactor(); - - // Set the width of the text box - vtxBufferPtr[2] += textBoxWidth; - vtxBufferPtr[4] += textBoxWidth; - - // Scale and translate the box - for (size_t i = 0; i < (length * 8); i+=2) - { - // Scale - vtxBufferPtr[i+0] *= textBoxScale; - vtxBufferPtr[i+1] *= textBoxScale; - - // Translate - vtxBufferPtr[i+0] += boxOffset - (this->_output->GetViewportWidth() / 2.0f); - vtxBufferPtr[i+1] += (this->_output->GetViewportHeight() / 2.0f) - boxOffset; - } + this->_output->SetHUDVertices((float)this->_output->GetViewportWidth(), (float)this->_output->GetViewportHeight(), vtxBufferPtr); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); @@ -6527,6 +6451,8 @@ void OGLHUDLayer::UpdateViewportOGL() { glUseProgram(this->_program->GetProgramID()); glUniform2f(this->_uniformViewSize, this->_output->GetViewProperties().clientWidth, this->_output->GetViewProperties().clientHeight); + + this->_needUpdateVertices = true; }; void OGLHUDLayer::ProcessOGL() @@ -6537,27 +6463,11 @@ void OGLHUDLayer::ProcessOGL() return; } - const char *cString = this->_output->GetHUDString().c_str(); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboTexCoordID); glBufferDataARB(GL_ARRAY_BUFFER_ARB, HUD_VERTEX_ATTRIBUTE_BUFFER_SIZE, NULL, GL_STREAM_DRAW_ARB); - GLfloat *texCoordBufferPtr = (GLfloat *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + float *texCoordBufferPtr = (float *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - for (size_t i = 0; i < length; i++) - { - const char c = cString[i]; - const float *glyphTexCoord = this->_glyphInfo[c].texCoord; - GLfloat *hudTexCoord = &texCoordBufferPtr[i * 8]; - - hudTexCoord[0] = glyphTexCoord[0]; - hudTexCoord[1] = glyphTexCoord[1]; - hudTexCoord[2] = glyphTexCoord[2]; - hudTexCoord[3] = glyphTexCoord[3]; - hudTexCoord[4] = glyphTexCoord[4]; - hudTexCoord[5] = glyphTexCoord[5]; - hudTexCoord[6] = glyphTexCoord[6]; - hudTexCoord[7] = glyphTexCoord[7]; - } + this->_output->SetHUDTextureCoordinates(texCoordBufferPtr); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); @@ -7005,132 +6915,10 @@ void OGLDisplayLayer::_UpdateRotationScaleOGL() void OGLDisplayLayer::_UpdateVerticesOGL() { - const ClientDisplayViewProperties &cdv = this->_output->GetViewProperties(); - - const GLfloat w = cdv.normalWidth / 2.0f; - const GLfloat h = cdv.normalHeight / 2.0f; - const size_t f = (cdv.order == ClientDisplayOrder_MainFirst) ? 0 : 8; - glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboVertexID); - GLfloat *vtxBufferPtr = (GLfloat *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + float *vtxBufferPtr = (float *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - if (cdv.mode == ClientDisplayMode_Dual) - { - switch (cdv.layout) - { - case ClientDisplayLayout_Horizontal: - { - vtxBufferPtr[0+f] = -w; vtxBufferPtr[1+f] = h; // Left display, top left - vtxBufferPtr[2+f] = 0.0f; vtxBufferPtr[3+f] = h; // Left display, top right - vtxBufferPtr[4+f] = -w; vtxBufferPtr[5+f] = -h; // Left display, bottom left - vtxBufferPtr[6+f] = 0.0f; vtxBufferPtr[7+f] = -h; // Left display, bottom right - - vtxBufferPtr[8-f] = 0.0f; vtxBufferPtr[9-f] = h; // Right display, top left - vtxBufferPtr[10-f] = w; vtxBufferPtr[11-f] = h; // Right display, top right - vtxBufferPtr[12-f] = 0.0f; vtxBufferPtr[13-f] = -h; // Right display, bottom left - vtxBufferPtr[14-f] = w; vtxBufferPtr[15-f] = -h; // Right display, bottom right - - memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(GLfloat) * (2 * 8)); // Unused displays - break; - } - - case ClientDisplayLayout_Hybrid_2_1: - { - vtxBufferPtr[0] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[1] = -h + (96.0f * 2.0f); // Minor top display, top left - vtxBufferPtr[2] = w; vtxBufferPtr[3] = -h + (96.0f * 2.0f); // Minor top display, top right - vtxBufferPtr[4] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[5] = -h + 96.0f; // Minor top display, bottom left - vtxBufferPtr[6] = w; vtxBufferPtr[7] = -h + 96.0f; // Minor top display, bottom right - - vtxBufferPtr[8] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[9] = -h + 96.0f; // Minor bottom display, top left - vtxBufferPtr[10] = w; vtxBufferPtr[11] = -h + 96.0f; // Minor bottom display, top right - vtxBufferPtr[12] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[13] = -h; // Minor bottom display, bottom left - vtxBufferPtr[14] = w; vtxBufferPtr[15] = -h; // Minor bottom display, bottom right - - vtxBufferPtr[16] = -w; vtxBufferPtr[17] = h; // Major display, top left - vtxBufferPtr[18] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[19] = h; // Major display, top right - vtxBufferPtr[20] = -w; vtxBufferPtr[21] = -h; // Major display, bottom left - vtxBufferPtr[22] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[23] = -h; // Major display, bottom right - - memcpy(vtxBufferPtr + (3 * 8), vtxBufferPtr + (2 * 8), sizeof(GLfloat) * (1 * 8)); // Major display (bottom screen) - break; - } - - case ClientDisplayLayout_Hybrid_16_9: - { - const GLfloat g = (GLfloat)cdv.gapDistance * (cdv.normalWidth - (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH) / (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; - - vtxBufferPtr[0] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[1] = -h + g + (64.0f * 2.0f); // Minor top display, top left - vtxBufferPtr[2] = w; vtxBufferPtr[3] = -h + g + (64.0f * 2.0f); // Minor top display, top right - vtxBufferPtr[4] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[5] = -h + g + 64.0f; // Minor top display, bottom left - vtxBufferPtr[6] = w; vtxBufferPtr[7] = -h + g + 64.0f; // Minor top display, bottom right - - vtxBufferPtr[8] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[9] = -h + 64.0f; // Minor bottom display, top left - vtxBufferPtr[10] = w; vtxBufferPtr[11] = -h + 64.0f; // Minor bottom display, top right - vtxBufferPtr[12] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[13] = -h; // Minor bottom display, bottom left - vtxBufferPtr[14] = w; vtxBufferPtr[15] = -h; // Minor bottom display, bottom right - - vtxBufferPtr[16] = -w; vtxBufferPtr[17] = h; // Major display, top left - vtxBufferPtr[18] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[19] = h; // Major display, top right - vtxBufferPtr[20] = -w; vtxBufferPtr[21] = -h; // Major display, bottom left - vtxBufferPtr[22] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[23] = -h; // Major display, bottom right - - memcpy(vtxBufferPtr + (3 * 8), vtxBufferPtr + (2 * 8), sizeof(GLfloat) * (1 * 8)); // Major display (bottom screen) - break; - } - - case ClientDisplayLayout_Hybrid_16_10: - { - const GLfloat g = (GLfloat)cdv.gapDistance * (cdv.normalWidth - (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH) / (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; - - vtxBufferPtr[0] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[1] = -h + g + (38.4f * 2.0f); // Minor top display, top left - vtxBufferPtr[2] = w; vtxBufferPtr[3] = -h + g + (38.4f * 2.0f); // Minor top display, top right - vtxBufferPtr[4] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[5] = -h + g + 38.4f; // Minor top display, bottom left - vtxBufferPtr[6] = w; vtxBufferPtr[7] = -h + g + 38.4f; // Minor top display, bottom right - - vtxBufferPtr[8] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[9] = -h + 38.4f; // Minor bottom display, top left - vtxBufferPtr[10] = w; vtxBufferPtr[11] = -h + 38.4f; // Minor bottom display, top right - vtxBufferPtr[12] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[13] = -h; // Minor bottom display, bottom left - vtxBufferPtr[14] = w; vtxBufferPtr[15] = -h; // Minor bottom display, bottom right - - vtxBufferPtr[16] = -w; vtxBufferPtr[17] = h; // Major display, top left - vtxBufferPtr[18] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[19] = h; // Major display, top right - vtxBufferPtr[20] = -w; vtxBufferPtr[21] = -h; // Major display, bottom left - vtxBufferPtr[22] = -w + (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[23] = -h; // Major display, bottom right - - memcpy(vtxBufferPtr + (3 * 8), vtxBufferPtr + (2 * 8), sizeof(GLfloat) * (1 * 8)); // Major display (bottom screen) - break; - } - - default: // Default to vertical orientation. - { - const GLfloat g = (GLfloat)cdv.gapDistance; - - vtxBufferPtr[0+f] = -w; vtxBufferPtr[1+f] = h; // Top display, top left - vtxBufferPtr[2+f] = w; vtxBufferPtr[3+f] = h; // Top display, top right - vtxBufferPtr[4+f] = -w; vtxBufferPtr[5+f] = g/2.0f; // Top display, bottom left - vtxBufferPtr[6+f] = w; vtxBufferPtr[7+f] = g/2.0f; // Top display, bottom right - - vtxBufferPtr[8-f] = -w; vtxBufferPtr[9-f] = -g/2.0f; // Bottom display, top left - vtxBufferPtr[10-f] = w; vtxBufferPtr[11-f] = -g/2.0f; // Bottom display, top right - vtxBufferPtr[12-f] = -w; vtxBufferPtr[13-f] = -h; // Bottom display, bottom left - vtxBufferPtr[14-f] = w; vtxBufferPtr[15-f] = -h; // Bottom display, bottom right - - memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(GLfloat) * (2 * 8)); // Unused displays - break; - } - } - } - else // displayModeID == ClientDisplayMode_Main || displayModeID == ClientDisplayMode_Touch - { - vtxBufferPtr[0] = -w; vtxBufferPtr[1] = h; // First display, top left - vtxBufferPtr[2] = w; vtxBufferPtr[3] = h; // First display, top right - vtxBufferPtr[4] = -w; vtxBufferPtr[5] = -h; // First display, bottom left - vtxBufferPtr[6] = w; vtxBufferPtr[7] = -h; // First display, bottom right - - memcpy(vtxBufferPtr + (1 * 8), vtxBufferPtr + (0 * 8), sizeof(GLfloat) * (1 * 8)); // Second display - memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(GLfloat) * (1 * 8)); // Unused display - memcpy(vtxBufferPtr + (3 * 8), vtxBufferPtr + (0 * 8), sizeof(GLfloat) * (1 * 8)); // Unused display - } + this->_output->SetScreenVertices(vtxBufferPtr); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); @@ -7788,19 +7576,9 @@ void OGLDisplayLayer::ProcessOGL() // Update the texture coordinates glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboTexCoordID); glBufferDataARB(GL_ARRAY_BUFFER_ARB, (4 * 8) * sizeof(GLfloat), NULL, GL_STREAM_DRAW_ARB); - GLfloat *texCoordBufferPtr = (GLfloat *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + float *texCoordPtr = (float *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - texCoordBufferPtr[0] = 0.0f; texCoordBufferPtr[1] = 0.0f; - texCoordBufferPtr[2] = w0; texCoordBufferPtr[3] = 0.0f; - texCoordBufferPtr[4] = 0.0f; texCoordBufferPtr[5] = h0; - texCoordBufferPtr[6] = w0; texCoordBufferPtr[7] = h0; - - texCoordBufferPtr[8] = 0.0f; texCoordBufferPtr[9] = 0.0f; - texCoordBufferPtr[10] = w1; texCoordBufferPtr[11] = 0.0f; - texCoordBufferPtr[12] = 0.0f; texCoordBufferPtr[13] = h1; - texCoordBufferPtr[14] = w1; texCoordBufferPtr[15] = h1; - - memcpy(texCoordBufferPtr + (2 * 8), texCoordBufferPtr + (0 * 8), sizeof(GLfloat) * (2 * 8)); + this->_output->SetScreenTextureCoordinates(w0, h0, w1, h1, texCoordPtr); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); @@ -7901,6 +7679,12 @@ MacOGLDisplayView::MacOGLDisplayView(CGLContextObj context) this->_context = context; } +void MacOGLDisplayView::_FrameRenderAndFlush() +{ + this->FrameRender(); + CGLFlushDrawable(this->_context); +} + CGLContextObj MacOGLDisplayView::GetContext() const { return this->_context; @@ -7911,17 +7695,6 @@ void MacOGLDisplayView::SetContext(CGLContextObj context) this->_context = context; } -void MacOGLDisplayView::SetHUDInfo(const NDSFrameInfo &frameInfo) -{ - this->OGLVideoOutput::SetHUDInfo(frameInfo); - - CGLLockContext(this->_context); - CGLSetCurrentContext(this->_context); - this->FrameProcessHUD(); - this->FrameRenderAndFlush(); - CGLUnlockContext(this->_context); -} - void MacOGLDisplayView::SetVideoBuffers(const uint32_t colorFormat, const void *videoBufferHead, const void *nativeBuffer0, @@ -7942,6 +7715,121 @@ void MacOGLDisplayView::SetVideoBuffers(const uint32_t colorFormat, CGLUnlockContext(this->_context); } +void MacOGLDisplayView::SetUseVerticalSync(const bool useVerticalSync) +{ + const GLint swapInt = (useVerticalSync) ? 1 : 0; + + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + CGLSetParameter(this->_context, kCGLCPSwapInterval, &swapInt); + this->OGLVideoOutput::SetUseVerticalSync(useVerticalSync); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayView::SetScaleFactor(const double scaleFactor) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetScaleFactor(scaleFactor); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayView::SetupViewProperties() +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetupViewProperties(); + this->_FrameRenderAndFlush(); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayView::SetFiltersPreferGPU(const bool preferGPU) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetFiltersPreferGPU(preferGPU); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayView::SetOutputFilter(const OutputFilterTypeID filterID) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetOutputFilter(filterID); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayView::SetPixelScaler(const VideoFilterTypeID filterID) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetPixelScaler(filterID); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayView::SetHUDVisibility(const bool visibleState) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetHUDVisibility(visibleState); + this->_FrameRenderAndFlush(); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayView::SetHUDShowVideoFPS(const bool visibleState) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetHUDShowVideoFPS(visibleState); + this->_FrameRenderAndFlush(); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayView::SetHUDShowRender3DFPS(const bool visibleState) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetHUDShowRender3DFPS(visibleState); + this->_FrameRenderAndFlush(); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayView::SetHUDShowFrameIndex(const bool visibleState) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetHUDShowFrameIndex(visibleState); + this->_FrameRenderAndFlush(); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayView::SetHUDShowLagFrameCount(const bool visibleState) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetHUDShowLagFrameCount(visibleState); + this->_FrameRenderAndFlush(); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayView::SetHUDShowCPULoadAverage(const bool visibleState) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetHUDShowCPULoadAverage(visibleState); + this->_FrameRenderAndFlush(); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayView::SetHUDShowRTC(const bool visibleState) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetHUDShowRTC(visibleState); + this->_FrameRenderAndFlush(); + CGLUnlockContext(this->_context); +} + void MacOGLDisplayView::FrameFinish() { CGLLockContext(this->_context); @@ -7950,21 +7838,30 @@ void MacOGLDisplayView::FrameFinish() CGLUnlockContext(this->_context); } -void MacOGLDisplayView::FrameFlush() +void MacOGLDisplayView::HandleGPUFrameEndEvent(const bool isMainSizeNative, const bool isTouchSizeNative) { - CGLFlushDrawable(this->_context); + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->FrameLoadGPU(isMainSizeNative, isTouchSizeNative); + this->FrameProcessGPU(); + CGLUnlockContext(this->_context); } -void MacOGLDisplayView::FrameRenderAndFlush() +void MacOGLDisplayView::HandleEmulatorFrameEndEvent(const NDSFrameInfo &frameInfo) { - this->FrameRender(); - this->FrameFlush(); + this->SetHUDInfo(frameInfo); + + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->FrameProcessHUD(); + this->_FrameRenderAndFlush(); + CGLUnlockContext(this->_context); } void MacOGLDisplayView::UpdateView() { CGLLockContext(this->_context); CGLSetCurrentContext(this->_context); - this->FrameRenderAndFlush(); + this->_FrameRenderAndFlush(); CGLUnlockContext(this->_context); } diff --git a/desmume/src/frontend/cocoa/OGLDisplayOutput.h b/desmume/src/frontend/cocoa/OGLDisplayOutput.h index 5deceb488..b681b70ce 100644 --- a/desmume/src/frontend/cocoa/OGLDisplayOutput.h +++ b/desmume/src/frontend/cocoa/OGLDisplayOutput.h @@ -442,13 +442,13 @@ class MacOGLDisplayView : public OGLVideoOutput protected: CGLContextObj _context; + void _FrameRenderAndFlush(); + public: MacOGLDisplayView(CGLContextObj context); CGLContextObj GetContext() const; void SetContext(CGLContextObj context); - - virtual void SetHUDInfo(const NDSFrameInfo &frameInfo); virtual void SetVideoBuffers(const uint32_t colorFormat, const void *videoBufferHead, @@ -457,10 +457,26 @@ public: const void *customBuffer0, const size_t customWidth0, const size_t customHeight0, const void *customBuffer1, const size_t customWidth1, const size_t customHeight1); - virtual void FrameFinish(); + virtual void SetUseVerticalSync(const bool useVerticalSync); + virtual void SetScaleFactor(const double scaleFactor); - virtual void FrameFlush(); - virtual void FrameRenderAndFlush(); + virtual void SetupViewProperties(); + + virtual void SetFiltersPreferGPU(const bool preferGPU); + virtual void SetOutputFilter(const OutputFilterTypeID filterID); + virtual void SetPixelScaler(const VideoFilterTypeID filterID); + + virtual void SetHUDVisibility(const bool visibleState); + virtual void SetHUDShowVideoFPS(const bool visibleState); + virtual void SetHUDShowRender3DFPS(const bool visibleState); + virtual void SetHUDShowFrameIndex(const bool visibleState); + virtual void SetHUDShowLagFrameCount(const bool visibleState); + virtual void SetHUDShowCPULoadAverage(const bool visibleState); + virtual void SetHUDShowRTC(const bool visibleState); + + virtual void FrameFinish(); + virtual void HandleGPUFrameEndEvent(const bool isMainSizeNative, const bool isTouchSizeNative); + virtual void HandleEmulatorFrameEndEvent(const NDSFrameInfo &frameInfo); virtual void UpdateView(); }; diff --git a/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.h b/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.h index 0d47ba428..0b6f23644 100644 --- a/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.h +++ b/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.h @@ -40,10 +40,7 @@ class OGLVideoOutput; InputManager *inputManager; ClientDisplay3DView *_cdv; ClientDisplayViewProperties _intermediateViewProps; - BOOL canUseShaderBasedFilters; - - BOOL _useVerticalSync; - + OSSpinLock spinlockIsHUDVisible; OSSpinLock spinlockUseVerticalSync; OSSpinLock spinlockVideoFiltersPreferGPU; @@ -75,7 +72,6 @@ class OGLVideoOutput; - (void) setScaleFactor:(float)theScaleFactor; - (void) commitViewProperties:(const ClientDisplayViewProperties &)viewProps; -- (void) setupViewProperties; - (BOOL) handleKeyPress:(NSEvent *)theEvent keyPressed:(BOOL)keyPressed; - (BOOL) handleMouseButton:(NSEvent *)theEvent buttonPressed:(BOOL)buttonPressed; - (void) requestScreenshot:(NSURL *)fileURL fileType:(NSBitmapImageFileType)fileType; diff --git a/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.mm b/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.mm index 8e3588d78..448f3bf9d 100644 --- a/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.mm +++ b/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.mm @@ -1576,7 +1576,7 @@ static std::unordered_map _screenMap; // @implementation DisplayView @synthesize inputManager; -@synthesize canUseShaderBasedFilters; +@dynamic canUseShaderBasedFilters; @dynamic isHUDVisible; @dynamic isHUDVideoFPSVisible; @dynamic isHUDRender3DFPSVisible; @@ -1651,12 +1651,8 @@ static std::unordered_map _screenMap; // NSString *fontPath = [[NSBundle mainBundle] pathForResource:@"SourceSansPro-Bold" ofType:@"otf"]; _cdv->SetHUDFontUsingPath([fontPath cStringUsingEncoding:NSUTF8StringEncoding]); - canUseShaderBasedFilters = (_cdv->CanFilterOnGPU()) ? YES : NO; - CGLSetCurrentContext(prevContext); - _useVerticalSync = NO; - spinlockIsHUDVisible = OS_SPINLOCK_INIT; spinlockUseVerticalSync = OS_SPINLOCK_INIT; spinlockVideoFiltersPreferGPU = OS_SPINLOCK_INIT; @@ -1685,16 +1681,15 @@ static std::unordered_map _screenMap; // #pragma mark Dynamic Property Methods +- (BOOL) canUseShaderBasedFilters +{ + return (_cdv->CanFilterOnGPU()) ? YES : NO; +} + - (void) setIsHUDVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); _cdv->SetHUDVisibility((theState) ? true : false); - _cdv->FrameRenderAndFlush(); - CGLUnlockContext(cglDisplayContext); - OSSpinLockUnlock(&spinlockIsHUDVisible); } @@ -1710,13 +1705,7 @@ static std::unordered_map _screenMap; // - (void) setIsHUDVideoFPSVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); _cdv->SetHUDShowVideoFPS((theState) ? true : false); - _cdv->FrameRenderAndFlush(); - CGLUnlockContext(cglDisplayContext); - OSSpinLockUnlock(&spinlockIsHUDVisible); } @@ -1732,13 +1721,7 @@ static std::unordered_map _screenMap; // - (void) setIsHUDRender3DFPSVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); _cdv->SetHUDShowRender3DFPS((theState) ? true : false); - _cdv->FrameRenderAndFlush(); - CGLUnlockContext(cglDisplayContext); - OSSpinLockUnlock(&spinlockIsHUDVisible); } @@ -1754,13 +1737,7 @@ static std::unordered_map _screenMap; // - (void) setIsHUDFrameIndexVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); _cdv->SetHUDShowFrameIndex((theState) ? true : false); - _cdv->FrameRenderAndFlush(); - CGLUnlockContext(cglDisplayContext); - OSSpinLockUnlock(&spinlockIsHUDVisible); } @@ -1776,13 +1753,7 @@ static std::unordered_map _screenMap; // - (void) setIsHUDLagFrameCountVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); _cdv->SetHUDShowLagFrameCount((theState) ? true : false); - _cdv->FrameRenderAndFlush(); - CGLUnlockContext(cglDisplayContext); - OSSpinLockUnlock(&spinlockIsHUDVisible); } @@ -1798,13 +1769,7 @@ static std::unordered_map _screenMap; // - (void) setIsHUDCPULoadAverageVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); _cdv->SetHUDShowCPULoadAverage((theState) ? true : false); - _cdv->FrameRenderAndFlush(); - CGLUnlockContext(cglDisplayContext); - OSSpinLockUnlock(&spinlockIsHUDVisible); } @@ -1820,13 +1785,7 @@ static std::unordered_map _screenMap; // - (void) setIsHUDRealTimeClockVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); _cdv->SetHUDShowRTC((theState) ? true : false); - _cdv->FrameRenderAndFlush(); - CGLUnlockContext(cglDisplayContext); - OSSpinLockUnlock(&spinlockIsHUDVisible); } @@ -1842,21 +1801,14 @@ static std::unordered_map _screenMap; // - (void) setUseVerticalSync:(BOOL)theState { OSSpinLockLock(&spinlockUseVerticalSync); - _useVerticalSync = theState; + _cdv->SetUseVerticalSync((theState) ? true : false); OSSpinLockUnlock(&spinlockUseVerticalSync); - - const GLint swapInt = (theState) ? 1 : 0; - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); - CGLSetParameter(cglDisplayContext, kCGLCPSwapInterval, &swapInt); - CGLUnlockContext(cglDisplayContext); } - (BOOL) useVerticalSync { OSSpinLockLock(&spinlockUseVerticalSync); - const BOOL theState = _useVerticalSync; + const BOOL theState = (_cdv->GetUseVerticalSync()) ? YES : NO; OSSpinLockUnlock(&spinlockUseVerticalSync); return theState; @@ -1865,12 +1817,7 @@ static std::unordered_map _screenMap; // - (void) setVideoFiltersPreferGPU:(BOOL)theState { OSSpinLockLock(&spinlockVideoFiltersPreferGPU); - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); _cdv->SetFiltersPreferGPU((theState) ? true : false); - CGLUnlockContext(cglDisplayContext); - OSSpinLockUnlock(&spinlockVideoFiltersPreferGPU); } @@ -1902,12 +1849,7 @@ static std::unordered_map _screenMap; // - (void) setOutputFilter:(NSInteger)filterID { OSSpinLockLock(&spinlockOutputFilter); - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); _cdv->SetOutputFilter((OutputFilterTypeID)filterID); - CGLUnlockContext(cglDisplayContext); - OSSpinLockUnlock(&spinlockOutputFilter); } @@ -1923,12 +1865,7 @@ static std::unordered_map _screenMap; // - (void) setPixelScaler:(NSInteger)filterID { OSSpinLockLock(&spinlockPixelScaler); - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); _cdv->SetPixelScaler((VideoFilterTypeID)filterID); - CGLUnlockContext(cglDisplayContext); - OSSpinLockUnlock(&spinlockPixelScaler); } @@ -1946,12 +1883,7 @@ static std::unordered_map _screenMap; // - (void) setScaleFactor:(float)theScaleFactor { OSSpinLockLock(&spinlockIsHUDVisible); - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); _cdv->SetScaleFactor(theScaleFactor); - CGLUnlockContext(cglDisplayContext); - OSSpinLockUnlock(&spinlockIsHUDVisible); } @@ -1965,19 +1897,6 @@ static std::unordered_map _screenMap; // [CocoaDSUtil messageSendOneWay:[[windowController cdsVideoOutput] receivePort] msgID:MESSAGE_CHANGE_VIEW_PROPERTIES]; } -- (void) setupViewProperties -{ - OSSpinLockLock(&spinlockViewProperties); - _cdv->CommitViewProperties(_intermediateViewProps); - OSSpinLockUnlock(&spinlockViewProperties); - - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); - _cdv->SetupViewProperties(); - _cdv->FrameRenderAndFlush(); - CGLUnlockContext(cglDisplayContext); -} - #pragma mark InputHIDManagerTarget Protocol - (BOOL) handleHIDQueue:(IOHIDQueueRef)hidQueue hidManager:(InputHIDManager *)hidManager { @@ -2254,11 +2173,7 @@ static std::unordered_map _screenMap; // - (void)doLoadVideoFrameWithMainSizeNative:(bool)isMainSizeNative touchSizeNative:(bool)isTouchSizeNative { - CGLLockContext(cglDisplayContext); - CGLSetCurrentContext(cglDisplayContext); - _cdv->FrameLoadGPU(isMainSizeNative, isTouchSizeNative); - _cdv->FrameProcessGPU(); - CGLUnlockContext(cglDisplayContext); + _cdv->HandleGPUFrameEndEvent(isMainSizeNative, isTouchSizeNative); } - (void) doSetVideoBuffersUsingFormat:(const uint32_t)colorFormat @@ -2287,12 +2202,16 @@ static std::unordered_map _screenMap; // - (void)doProcessVideoFrameWithInfo:(const NDSFrameInfo &)frameInfo { - _cdv->SetHUDInfo(frameInfo); + _cdv->HandleEmulatorFrameEndEvent(frameInfo); } - (void)doViewPropertiesChanged -{ - [self setupViewProperties]; +{ + OSSpinLockLock(&spinlockViewProperties); + _cdv->CommitViewProperties(_intermediateViewProps); + OSSpinLockUnlock(&spinlockViewProperties); + + _cdv->SetupViewProperties(); } - (void)doRedraw