diff --git a/src/FrameBuffer.cpp b/src/FrameBuffer.cpp index bcc586ae..f80172a8 100644 --- a/src/FrameBuffer.cpp +++ b/src/FrameBuffer.cpp @@ -958,14 +958,18 @@ void FrameBufferToRDRAM::Destroy() { void FrameBufferToRDRAM::CopyToRDRAM(u32 _address) { - const u32 numPixels = VI.width * VI.height; - if (numPixels == 0 || frameBufferList().getCurrent() == NULL) // Incorrect buffer size or no current buffer. Don't copy - return; - FrameBuffer *pBuffer = frameBufferList().findBuffer(_address); - if (pBuffer == NULL || pBuffer->m_width < VI.width || pBuffer->m_isOBScreen) + if (VI.width == 0 || frameBufferList().getCurrent() == NULL) return; - if ((config.generalEmulation.hacks & hack_subscreen) != 0) { + FrameBuffer *pBuffer = frameBufferList().findBuffer(_address); + if (pBuffer == NULL || pBuffer->m_isOBScreen) + return; + + const u32 numPixels = pBuffer->m_width * pBuffer->m_height; + if (numPixels == 0) + return; + + if ((config.generalEmulation.hacks & hack_subscreen) != 0 && pBuffer->m_width == VI.width && pBuffer->m_height == VI.height) { copyWhiteToRDRAM(pBuffer); return; } @@ -994,38 +998,39 @@ void FrameBufferToRDRAM::CopyToRDRAM(u32 _address) m_curIndex ^= 1; const u32 nextIndex = m_bSync ? m_curIndex : m_curIndex^1; glBindBuffer(GL_PIXEL_PACK_BUFFER, m_aPBO[m_curIndex]); - glReadPixels(0, 0, VI.width, VI.height, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glReadPixels(0, 0, pBuffer->m_width, pBuffer->m_height, GL_RGBA, GL_UNSIGNED_BYTE, 0); PBOBinder binder(GL_PIXEL_PACK_BUFFER, m_aPBO[nextIndex]); + GLubyte* pixelData = (GLubyte*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, numPixels * 4, GL_MAP_READ_BIT); - if(pixelData == NULL) + if (pixelData == NULL) return; #else GLubyte* pixelData = (GLubyte* )malloc(numPixels * 4); - if(pixelData == NULL) + if (pixelData == NULL) return; - glReadPixels( 0, 0, VI.width, VI.height, GL_RGBA, GL_UNSIGNED_BYTE, pixelData ); + glReadPixels(0, 0, VI.width, VI.height, GL_RGBA, GL_UNSIGNED_BYTE, pixelData); #endif // GLES2 const u32 stride = pBuffer->m_width << pBuffer->m_size >> 1; - const u32 height = _cutHeight(_address, VI.height, stride); + const u32 height = _cutHeight(_address, pBuffer->m_height, stride); if (pBuffer->m_size == G_IM_SIZ_32b) { u32 *ptr_dst = (u32*)(RDRAM + _address); u32 *ptr_src = (u32*)pixelData; for (u32 y = 0; y < height; ++y) { - for (u32 x = 0; x < VI.width; ++x) - ptr_dst[x + y*VI.width] = ptr_src[x + (height - y - 1)*VI.width]; + for (u32 x = 0; x < pBuffer->m_width; ++x) + ptr_dst[x + y*pBuffer->m_width] = ptr_src[x + (height - y - 1)*pBuffer->m_width]; } - } else { + } else if (pBuffer->m_size == G_IM_SIZ_16b) { u16 *ptr_dst = (u16*)(RDRAM + _address); u32 * ptr_src = (u32*)pixelData; RGBA c; for (u32 y = 0; y < height; ++y) { - for (u32 x = 0; x < VI.width; ++x) { - c.raw = ptr_src[x + (height - y - 1)*VI.width]; - ptr_dst[(x + y*VI.width)^1] = ((c.r>>3)<<11) | ((c.g>>3)<<6) | ((c.b>>3)<<1) | (c.a == 0 ? 0 : 1); + for (u32 x = 0; x < pBuffer->m_width; ++x) { + c.raw = ptr_src[x + (height - y - 1)*pBuffer->m_width]; + ptr_dst[(x + y*pBuffer->m_width) ^ 1] = ((c.r >> 3) << 11) | ((c.g >> 3) << 6) | ((c.b >> 3) << 1) | (c.a == 0 ? 0 : 1); } } }