mirror of
https://github.com/SourMesen/Mesen.git
synced 2025-04-02 10:52:48 -04:00
Pause screen, show fps option, refactoring
This commit is contained in:
parent
1783578522
commit
4cd681c02b
7 changed files with 132 additions and 46 deletions
|
@ -46,7 +46,7 @@ void Console::SetFlags(int flags)
|
|||
|
||||
void Console::ClearFlags(int flags)
|
||||
{
|
||||
Console::Flags ^= flags;
|
||||
Console::Flags &= ~flags;
|
||||
}
|
||||
|
||||
bool Console::CheckFlag(int flag)
|
||||
|
|
BIN
GUI/GUI.rc
BIN
GUI/GUI.rc
Binary file not shown.
|
@ -194,16 +194,25 @@ namespace NES {
|
|||
SetMenuEnabled(ID_NES_RESET, true);
|
||||
SetMenuEnabled(ID_NES_STOP, true);
|
||||
SetMenuEnabled(ID_NES_RESUME, false);
|
||||
|
||||
_renderer->ClearFlags(UIFlags::ShowPauseScreen);
|
||||
if(IsMenuChecked(ID_OPTIONS_SHOWFPS)) {
|
||||
_renderer->SetFlags(UIFlags::ShowFPS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::Stop(bool powerOff)
|
||||
{
|
||||
_renderer->ClearFlags(UIFlags::ShowFPS | UIFlags::ShowPauseScreen);
|
||||
|
||||
_soundManager->Reset();
|
||||
if(_console) {
|
||||
_console->Stop();
|
||||
if(powerOff) {
|
||||
_console.release();
|
||||
} else {
|
||||
_renderer->SetFlags(UIFlags::ShowPauseScreen);
|
||||
}
|
||||
}
|
||||
if(_emuThread) {
|
||||
|
@ -258,6 +267,15 @@ namespace NES {
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::ShowFPS_Click()
|
||||
{
|
||||
if(ToggleMenuCheck(ID_OPTIONS_SHOWFPS)) {
|
||||
_renderer->SetFlags(UIFlags::ShowFPS);
|
||||
} else {
|
||||
_renderer->ClearFlags(UIFlags::ShowFPS);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::SaveTestResult()
|
||||
{
|
||||
if(_console) {
|
||||
|
@ -361,6 +379,9 @@ namespace NES {
|
|||
case ID_OPTIONS_LIMITFPS:
|
||||
mainWindow->LimitFPS_Click();
|
||||
break;
|
||||
case ID_OPTIONS_SHOWFPS:
|
||||
mainWindow->ShowFPS_Click();
|
||||
break;
|
||||
|
||||
case ID_TESTS_RUNTESTS:
|
||||
mainWindow->RunTests();
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace NES {
|
|||
vector<wstring> GetFilesInFolder(wstring folderMask);
|
||||
|
||||
void LimitFPS_Click();
|
||||
void ShowFPS_Click();
|
||||
|
||||
void SetMenuEnabled(int resourceID, bool enabled);
|
||||
|
||||
|
|
120
GUI/Renderer.cpp
120
GUI/Renderer.cpp
|
@ -23,13 +23,13 @@ namespace NES
|
|||
|
||||
void Renderer::CleanupDevice()
|
||||
{
|
||||
if(_pImmediateContext) _pImmediateContext->ClearState();
|
||||
if(_pDeviceContext) _pDeviceContext->ClearState();
|
||||
|
||||
if(_pRenderTargetView) _pRenderTargetView->Release();
|
||||
if(_samplerState) _samplerState->Release();
|
||||
|
||||
if(_pSwapChain) _pSwapChain->Release();
|
||||
if(_pImmediateContext1) _pImmediateContext1->Release();
|
||||
if(_pDeviceContext1) _pDeviceContext1->Release();
|
||||
if(_pd3dDevice1) _pd3dDevice1->Release();
|
||||
if(_pd3dDevice) _pd3dDevice->Release();
|
||||
}
|
||||
|
@ -85,12 +85,12 @@ namespace NES
|
|||
for(UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++) {
|
||||
_driverType = driverTypes[driverTypeIndex];
|
||||
hr = D3D11CreateDeviceAndSwapChain(nullptr, _driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
|
||||
D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &_featureLevel, &_pImmediateContext);
|
||||
D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &_featureLevel, &_pDeviceContext);
|
||||
|
||||
if(hr == E_INVALIDARG) {
|
||||
// DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it
|
||||
hr = D3D11CreateDeviceAndSwapChain(nullptr, _driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1,
|
||||
D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &_featureLevel, &_pImmediateContext);
|
||||
D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &_featureLevel, &_pDeviceContext);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hr)) {
|
||||
|
@ -104,7 +104,7 @@ namespace NES
|
|||
// Obtain the Direct3D 11.1 versions if available
|
||||
hr = _pd3dDevice->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&_pd3dDevice1));
|
||||
if(SUCCEEDED(hr)) {
|
||||
(void)_pImmediateContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&_pImmediateContext1));
|
||||
(void)_pDeviceContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&_pDeviceContext1));
|
||||
}
|
||||
|
||||
// Create a render target view
|
||||
|
@ -120,7 +120,7 @@ namespace NES
|
|||
return hr;
|
||||
}
|
||||
|
||||
_pImmediateContext->OMSetRenderTargets(1, &_pRenderTargetView, nullptr);
|
||||
_pDeviceContext->OMSetRenderTargets(1, &_pRenderTargetView, nullptr);
|
||||
|
||||
// Setup the viewport
|
||||
UINT fred;
|
||||
|
@ -131,7 +131,7 @@ namespace NES
|
|||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = 0;
|
||||
vp.TopLeftY = 0;
|
||||
_pImmediateContext->RSSetViewports(1, &vp);
|
||||
_pDeviceContext->RSSetViewports(1, &vp);
|
||||
|
||||
_pd3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_B8G8R8A8_UNORM, 16, &fred);
|
||||
|
||||
|
@ -193,8 +193,7 @@ namespace NES
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
_sprites.reset(new SpriteBatch(_pImmediateContext));
|
||||
_overlaySpriteBatch.reset(new SpriteBatch(_pImmediateContext));
|
||||
_spriteBatch.reset(new SpriteBatch(_pDeviceContext));
|
||||
|
||||
_font.reset(new SpriteFont(_pd3dDevice, L"Calibri.30.spritefont"));
|
||||
|
||||
|
@ -217,8 +216,34 @@ namespace NES
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
ID3D11ShaderResourceView* Renderer::GetDisplayBufferShaderResourceView()
|
||||
ID3D11ShaderResourceView* Renderer::GetShaderResourceView(ID3D11Texture2D* texture)
|
||||
{
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
D3D11_RESOURCE_DIMENSION type;
|
||||
texture->GetType(&type);
|
||||
texture->GetDesc(&desc);
|
||||
srvDesc.Format = desc.Format;
|
||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||
srvDesc.Texture2D.MostDetailedMip = desc.MipLevels - 1;
|
||||
|
||||
ID3D11ShaderResourceView *shaderResourceView = nullptr;
|
||||
_pd3dDevice->CreateShaderResourceView(texture, &srvDesc, &shaderResourceView);
|
||||
|
||||
return shaderResourceView;
|
||||
}
|
||||
|
||||
void Renderer::DrawNESScreen()
|
||||
{
|
||||
RECT sourceRect;
|
||||
sourceRect.left = 0;
|
||||
sourceRect.right = 256;
|
||||
sourceRect.bottom = 240;
|
||||
sourceRect.top = 0;
|
||||
|
||||
XMVECTOR position{ { 0, 0 } };
|
||||
|
||||
UINT screenwidth = 256, screenheight = 240;
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE dd;
|
||||
|
@ -226,25 +251,43 @@ namespace NES
|
|||
dd.RowPitch = screenwidth * 4;
|
||||
dd.DepthPitch = screenwidth* screenheight * 4;
|
||||
|
||||
_pImmediateContext->Map(_pTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &dd);
|
||||
_pDeviceContext->Map(_pTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &dd);
|
||||
memcpy(dd.pData, _nextFrameBuffer, screenwidth*screenheight * 4);
|
||||
_pImmediateContext->Unmap(_pTexture, 0);
|
||||
_pDeviceContext->Unmap(_pTexture, 0);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
D3D11_RESOURCE_DIMENSION type;
|
||||
_pTexture->GetType(&type);
|
||||
_pTexture->GetDesc(&desc);
|
||||
srvDesc.Format = desc.Format;
|
||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||
srvDesc.Texture2D.MostDetailedMip = desc.MipLevels - 1;
|
||||
ID3D11ShaderResourceView *nesOutputBuffer = GetShaderResourceView(_pTexture);
|
||||
_spriteBatch->Draw(nesOutputBuffer, position, &sourceRect, Colors::White, 0.0f, position, 4.0f);
|
||||
nesOutputBuffer->Release();
|
||||
}
|
||||
|
||||
ID3D11ShaderResourceView *pSRView = nullptr;
|
||||
_pd3dDevice->CreateShaderResourceView(_pTexture, &srvDesc, &pSRView);
|
||||
void Renderer::DrawPauseScreen()
|
||||
{
|
||||
RECT destRect;
|
||||
destRect.left = 0;
|
||||
destRect.right = 256*4;
|
||||
destRect.bottom = 240*4;
|
||||
destRect.top = 0;
|
||||
|
||||
XMVECTOR position{ { 0, 0 } };
|
||||
|
||||
UINT screenwidth = 256*4, screenheight = 240*4;
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE dd;
|
||||
dd.pData = (void *)_overlayBuffer;
|
||||
dd.RowPitch = screenwidth * 4;
|
||||
dd.DepthPitch = screenwidth* screenheight * 4;
|
||||
|
||||
_pDeviceContext->Map(_overlayTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &dd);
|
||||
std::fill_n((uint32_t*)dd.pData, screenwidth*screenheight, 0x99222222);
|
||||
_pDeviceContext->Unmap(_overlayTexture, 0);
|
||||
|
||||
ID3D11ShaderResourceView *shaderResourceView = GetShaderResourceView(_overlayTexture);
|
||||
_spriteBatch->Draw(shaderResourceView, destRect); // , position, &sourceRect, Colors::White, 0.0f, position, 4.0f);
|
||||
shaderResourceView->Release();
|
||||
|
||||
_font->DrawString(_spriteBatch.get(), L"PAUSED", XMFLOAT2(256 * 2 - 142, 240 * 2 - 37), Colors::Black, 0.0f, XMFLOAT2(0, 0), 2.0f);
|
||||
_font->DrawString(_spriteBatch.get(), L"PAUSED", XMFLOAT2(256 * 2 - 145, 240 * 2 - 40), Colors::AntiqueWhite, 0.0f, XMFLOAT2(0, 0), 2.0f);
|
||||
|
||||
return pSRView;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
@ -253,27 +296,24 @@ namespace NES
|
|||
void Renderer::Render()
|
||||
{
|
||||
// Clear the back buffer
|
||||
_pImmediateContext->ClearRenderTargetView(_pRenderTargetView, Colors::Black);
|
||||
_pDeviceContext->ClearRenderTargetView(_pRenderTargetView, Colors::Black);
|
||||
|
||||
ID3D11ShaderResourceView *shaderResourceView = GetDisplayBufferShaderResourceView();
|
||||
_spriteBatch->Begin(SpriteSortMode_Deferred, nullptr, _samplerState);
|
||||
|
||||
RECT sourceRect;
|
||||
sourceRect.left = 0;
|
||||
sourceRect.right = 256;
|
||||
sourceRect.bottom = 240;
|
||||
sourceRect.top = 0;
|
||||
//Draw nes screen
|
||||
DrawNESScreen();
|
||||
|
||||
XMVECTOR position{ { 0, 0 } };
|
||||
|
||||
_overlaySpriteBatch->Begin(SpriteSortMode_Deferred, nullptr, _samplerState);
|
||||
_overlaySpriteBatch->Draw(shaderResourceView, position, &sourceRect, Colors::White, 0.0f, position, 4.0f);
|
||||
//Draw FPS counter
|
||||
if(CheckFlag(UIFlags::ShowFPS)) {
|
||||
_font->DrawString(_spriteBatch.get(), (wstring(L"FPS: ") + std::to_wstring(Console::GetFPS())).c_str(), XMFLOAT2(256 * 4 - 150, 11), Colors::Yellow, 0.0f, XMFLOAT2(0, 0), 1.0f);
|
||||
}
|
||||
|
||||
_font->DrawString(_overlaySpriteBatch.get(), (wstring(L"FPS: ") + std::to_wstring(Console::GetFPS())).c_str(), XMFLOAT2(256*4-150,11), Colors::Yellow, 0.0f, XMFLOAT2(0,0), 1.0f);
|
||||
if(CheckFlag(UIFlags::ShowPauseScreen)) {
|
||||
DrawPauseScreen();
|
||||
}
|
||||
|
||||
_overlaySpriteBatch->End();
|
||||
_spriteBatch->End();
|
||||
|
||||
shaderResourceView->Release();
|
||||
|
||||
// Present the information rendered to the back buffer to the front buffer (the screen)
|
||||
_pSwapChain->Present(0, 0);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
using namespace DirectX;
|
||||
|
||||
namespace NES {
|
||||
enum UIFlags
|
||||
{
|
||||
ShowFPS = 1,
|
||||
ShowPauseScreen = 2,
|
||||
};
|
||||
|
||||
class Renderer : IVideoDevice
|
||||
{
|
||||
private:
|
||||
|
@ -15,8 +21,8 @@ namespace NES {
|
|||
D3D_FEATURE_LEVEL _featureLevel = D3D_FEATURE_LEVEL_11_0;
|
||||
ID3D11Device* _pd3dDevice = nullptr;
|
||||
ID3D11Device1* _pd3dDevice1 = nullptr;
|
||||
ID3D11DeviceContext* _pImmediateContext = nullptr;
|
||||
ID3D11DeviceContext1* _pImmediateContext1 = nullptr;
|
||||
ID3D11DeviceContext* _pDeviceContext = nullptr;
|
||||
ID3D11DeviceContext1* _pDeviceContext1 = nullptr;
|
||||
IDXGISwapChain* _pSwapChain = nullptr;
|
||||
ID3D11RenderTargetView* _pRenderTargetView = nullptr;
|
||||
|
||||
|
@ -29,19 +35,37 @@ namespace NES {
|
|||
unique_ptr<SpriteFont> _font;
|
||||
ID3D11Texture2D* _overlayTexture = nullptr;
|
||||
byte* _overlayBuffer;
|
||||
std::unique_ptr<SpriteBatch> _overlaySpriteBatch;
|
||||
std::unique_ptr<SpriteBatch> _spriteBatch;
|
||||
|
||||
std::unique_ptr<SpriteBatch> _sprites;
|
||||
uint32_t _flags = 0;
|
||||
|
||||
HRESULT InitDevice();
|
||||
void CleanupDevice();
|
||||
ID3D11ShaderResourceView* GetDisplayBufferShaderResourceView();
|
||||
|
||||
ID3D11ShaderResourceView* GetShaderResourceView(ID3D11Texture2D* texture);
|
||||
void DrawNESScreen();
|
||||
void DrawPauseScreen();
|
||||
|
||||
public:
|
||||
Renderer(HWND hWnd);
|
||||
~Renderer();
|
||||
|
||||
void Render();
|
||||
|
||||
void SetFlags(uint32_t flags)
|
||||
{
|
||||
_flags |= flags;
|
||||
}
|
||||
|
||||
void ClearFlags(uint32_t flags)
|
||||
{
|
||||
_flags &= ~flags;
|
||||
}
|
||||
|
||||
bool CheckFlag(uint32_t flag)
|
||||
{
|
||||
return (_flags & flag) == flag;
|
||||
}
|
||||
|
||||
void UpdateFrame(uint8_t* frameBuffer)
|
||||
{
|
||||
|
|
BIN
GUI/resource.h
BIN
GUI/resource.h
Binary file not shown.
Loading…
Add table
Reference in a new issue