2017-01-09 10:21:41 +00:00
|
|
|
#include <assert.h>
|
2017-06-18 22:29:16 +00:00
|
|
|
#include <cstdlib>
|
2017-01-09 10:21:41 +00:00
|
|
|
#include "Config.h"
|
2017-11-08 11:29:53 +00:00
|
|
|
#include "RSP.h"
|
2017-01-09 10:21:41 +00:00
|
|
|
#include "VI.h"
|
|
|
|
#include "Graphics/Context.h"
|
2017-01-15 07:57:25 +00:00
|
|
|
#include "DisplayWindow.h"
|
2018-09-16 10:46:03 +00:00
|
|
|
#include "PluginAPI.h"
|
|
|
|
#include "FrameBuffer.h"
|
2017-01-09 10:21:41 +00:00
|
|
|
|
2019-10-04 12:54:40 +00:00
|
|
|
bool DisplayWindow::start()
|
2017-01-09 10:21:41 +00:00
|
|
|
{
|
2019-10-04 12:54:40 +00:00
|
|
|
if (!_start())
|
|
|
|
return false;
|
2018-04-03 15:08:06 +00:00
|
|
|
|
|
|
|
graphics::ObjectHandle::defaultFramebuffer = _getDefaultFramebuffer();
|
|
|
|
|
2017-01-09 10:21:41 +00:00
|
|
|
gfxContext.init();
|
2017-01-15 07:57:25 +00:00
|
|
|
m_drawer._initData();
|
2017-01-09 10:21:41 +00:00
|
|
|
m_buffersSwapCount = 0;
|
2019-10-04 12:54:40 +00:00
|
|
|
|
2020-12-23 22:47:13 +00:00
|
|
|
// only query max MSAA when needed
|
|
|
|
if (m_maxMsaa == 0) {
|
|
|
|
m_maxMsaa = gfxContext.getMaxMSAALevel();
|
|
|
|
}
|
|
|
|
|
2021-07-22 05:05:13 +00:00
|
|
|
if (m_maxAnisotropy == 0) {
|
|
|
|
m_maxAnisotropy = static_cast<u32>(gfxContext.getMaxAnisotropy());
|
|
|
|
}
|
|
|
|
|
2019-10-04 12:54:40 +00:00
|
|
|
return true;
|
2017-01-09 10:21:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayWindow::stop()
|
|
|
|
{
|
2017-01-15 07:57:25 +00:00
|
|
|
m_drawer._destroyData();
|
2017-01-09 10:21:41 +00:00
|
|
|
gfxContext.destroy();
|
|
|
|
_stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayWindow::restart()
|
|
|
|
{
|
2020-10-07 18:51:47 +00:00
|
|
|
_restart();
|
2017-01-09 10:21:41 +00:00
|
|
|
m_bResizeWindow = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayWindow::swapBuffers()
|
|
|
|
{
|
2017-01-15 07:57:25 +00:00
|
|
|
m_drawer.drawOSD();
|
2021-02-25 15:00:42 +00:00
|
|
|
m_drawer.clearStatistics();
|
2017-01-09 10:21:41 +00:00
|
|
|
_swapBuffers();
|
2017-11-08 11:29:53 +00:00
|
|
|
if (!RSP.LLE) {
|
|
|
|
if ((config.generalEmulation.hacks & hack_doNotResetOtherModeL) == 0)
|
|
|
|
gDP.otherMode.l = 0;
|
|
|
|
if ((config.generalEmulation.hacks & hack_doNotResetOtherModeH) == 0)
|
|
|
|
gDP.otherMode.h = 0x0CFF;
|
|
|
|
}
|
2017-01-09 10:21:41 +00:00
|
|
|
++m_buffersSwapCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayWindow::setCaptureScreen(const char * const _strDirectory)
|
|
|
|
{
|
|
|
|
::mbstowcs(m_strScreenDirectory, _strDirectory, PLUGIN_PATH_SIZE - 1);
|
|
|
|
m_bCaptureScreen = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayWindow::saveScreenshot()
|
|
|
|
{
|
|
|
|
if (!m_bCaptureScreen)
|
|
|
|
return;
|
|
|
|
_saveScreenshot();
|
|
|
|
m_bCaptureScreen = false;
|
|
|
|
}
|
|
|
|
|
2018-09-16 10:46:03 +00:00
|
|
|
void DisplayWindow::saveBufferContent(FrameBuffer * _pBuffer)
|
|
|
|
{
|
|
|
|
saveBufferContent(_pBuffer->m_FBO, _pBuffer->m_pTexture);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayWindow::saveBufferContent(graphics::ObjectHandle _fbo, CachedTexture *_pTexture)
|
|
|
|
{
|
|
|
|
if (wcslen(m_strScreenDirectory) == 0) {
|
|
|
|
api().FindPluginPath(m_strScreenDirectory);
|
|
|
|
std::wstring pluginPath(m_strScreenDirectory);
|
|
|
|
if (pluginPath.back() != L'/')
|
|
|
|
pluginPath += L'/';
|
2021-01-05 06:58:03 +00:00
|
|
|
::wcsncpy(m_strScreenDirectory, pluginPath.c_str(), std::min(size_t(PLUGIN_PATH_SIZE), pluginPath.length() + 1));
|
2018-09-16 10:46:03 +00:00
|
|
|
}
|
|
|
|
_saveBufferContent(_fbo, _pTexture);
|
|
|
|
}
|
|
|
|
|
2017-01-09 10:21:41 +00:00
|
|
|
bool DisplayWindow::changeWindow()
|
|
|
|
{
|
|
|
|
if (!m_bToggleFullscreen)
|
|
|
|
return false;
|
2017-01-15 07:57:25 +00:00
|
|
|
m_drawer._destroyData();
|
2017-01-09 10:21:41 +00:00
|
|
|
_changeWindow();
|
|
|
|
updateScale();
|
2017-01-15 07:57:25 +00:00
|
|
|
m_drawer._initData();
|
2017-01-09 10:21:41 +00:00
|
|
|
m_bToggleFullscreen = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-12-14 15:50:14 +00:00
|
|
|
void DisplayWindow::closeWindow()
|
|
|
|
{
|
|
|
|
if (!m_bToggleFullscreen || !m_bFullscreen)
|
|
|
|
return;
|
2021-06-05 15:32:01 +00:00
|
|
|
m_drawer._destroyData();
|
2017-12-14 15:50:14 +00:00
|
|
|
_changeWindow();
|
|
|
|
m_bToggleFullscreen = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-09 10:21:41 +00:00
|
|
|
void DisplayWindow::setWindowSize(u32 _width, u32 _height)
|
|
|
|
{
|
|
|
|
if (m_width != _width || m_height != _height) {
|
|
|
|
m_resizeWidth = _width;
|
|
|
|
m_resizeHeight = _height;
|
|
|
|
m_bResizeWindow = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DisplayWindow::resizeWindow()
|
|
|
|
{
|
|
|
|
if (!m_bResizeWindow)
|
|
|
|
return false;
|
2017-01-15 07:57:25 +00:00
|
|
|
m_drawer._destroyData();
|
2017-01-09 10:21:41 +00:00
|
|
|
if (!_resizeWindow())
|
2019-10-04 12:54:40 +00:00
|
|
|
if(!_start())
|
|
|
|
return false;
|
2017-01-09 10:21:41 +00:00
|
|
|
updateScale();
|
2017-01-15 07:57:25 +00:00
|
|
|
m_drawer._initData();
|
2017-01-09 10:21:41 +00:00
|
|
|
m_bResizeWindow = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayWindow::updateScale()
|
|
|
|
{
|
|
|
|
if (VI.width == 0 || VI.height == 0)
|
|
|
|
return;
|
2020-11-14 09:54:28 +00:00
|
|
|
m_scaleX = static_cast<f32>(m_width) / static_cast<f32>(VI.width);
|
|
|
|
m_scaleY = static_cast<f32>(m_height) / static_cast<f32>(VI.height);
|
2017-01-09 10:21:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayWindow::_setBufferSize()
|
|
|
|
{
|
|
|
|
m_bAdjustScreen = false;
|
2018-01-05 08:46:12 +00:00
|
|
|
switch (config.frameBufferEmulation.aspect) {
|
|
|
|
case Config::aStretch: // stretch
|
|
|
|
m_width = m_screenWidth;
|
|
|
|
m_height = m_screenHeight;
|
|
|
|
break;
|
|
|
|
case Config::a43: // force 4/3
|
|
|
|
if (m_screenWidth * 3 / 4 > m_screenHeight) {
|
2017-01-09 10:21:41 +00:00
|
|
|
m_height = m_screenHeight;
|
2018-01-05 08:46:12 +00:00
|
|
|
m_width = m_screenHeight * 4 / 3;
|
|
|
|
} else if (m_screenHeight * 4 / 3 > m_screenWidth) {
|
2017-01-09 10:21:41 +00:00
|
|
|
m_width = m_screenWidth;
|
2018-01-05 08:46:12 +00:00
|
|
|
m_height = m_screenWidth * 3 / 4;
|
|
|
|
} else {
|
|
|
|
m_width = m_screenWidth;
|
|
|
|
m_height = m_screenHeight;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Config::a169: // force 16/9
|
|
|
|
if (m_screenWidth * 9 / 16 > m_screenHeight) {
|
2017-01-09 10:21:41 +00:00
|
|
|
m_height = m_screenHeight;
|
2018-01-05 08:46:12 +00:00
|
|
|
m_width = m_screenHeight * 16 / 9;
|
|
|
|
} else if (m_screenHeight * 16 / 9 > m_screenWidth) {
|
|
|
|
m_width = m_screenWidth;
|
|
|
|
m_height = m_screenWidth * 9 / 16;
|
|
|
|
} else {
|
2017-01-09 10:21:41 +00:00
|
|
|
m_width = m_screenWidth;
|
|
|
|
m_height = m_screenHeight;
|
|
|
|
}
|
2018-01-05 08:46:12 +00:00
|
|
|
break;
|
|
|
|
case Config::aAdjust: // adjust
|
2017-01-09 10:21:41 +00:00
|
|
|
m_width = m_screenWidth;
|
|
|
|
m_height = m_screenHeight;
|
2018-01-05 08:46:12 +00:00
|
|
|
if (m_screenWidth * 3 / 4 > m_screenHeight) {
|
2017-01-09 10:21:41 +00:00
|
|
|
f32 width43 = m_screenHeight * 4.0f / 3.0f;
|
|
|
|
m_adjustScale = width43 / m_screenWidth;
|
|
|
|
m_bAdjustScreen = true;
|
|
|
|
}
|
2018-01-05 08:46:12 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(false && "Unknown aspect ratio");
|
|
|
|
m_width = m_screenWidth;
|
|
|
|
m_height = m_screenHeight;
|
2017-01-09 10:21:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayWindow::readScreen(void **_pDest, long *_pWidth, long *_pHeight)
|
|
|
|
{
|
|
|
|
_readScreen(_pDest, _pWidth, _pHeight);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayWindow::readScreen2(void * _dest, int * _width, int * _height, int _front)
|
|
|
|
{
|
|
|
|
_readScreen2(_dest, _width, _height, _front);
|
|
|
|
}
|
2020-12-06 14:01:04 +00:00
|
|
|
|
|
|
|
u32 DisplayWindow::maxMSAALevel() const
|
|
|
|
{
|
2020-12-23 22:47:13 +00:00
|
|
|
return m_maxMsaa;
|
2020-12-06 14:01:04 +00:00
|
|
|
}
|
2021-07-22 05:05:13 +00:00
|
|
|
|
|
|
|
u32 DisplayWindow::maxAnisotropy() const
|
|
|
|
{
|
|
|
|
return m_maxAnisotropy;
|
|
|
|
}
|