|
73 | 73 | #include "Common\UI\UIFontData.h" |
74 | 74 | #include "DLCTexturePack.h" |
75 | 75 |
|
| 76 | +#ifdef _WINDOWS64 |
| 77 | +#define STB_IMAGE_WRITE_IMPLEMENTATION |
| 78 | +#include "Windows64/stb_image_write.h" |
| 79 | +#endif |
| 80 | + |
76 | 81 | #ifdef __ORBIS__ |
77 | 82 | #include "Orbis\Network\PsPlusUpsellWrapper_Orbis.h" |
78 | 83 | #endif |
@@ -1549,6 +1554,9 @@ void Minecraft::run_middle() |
1549 | 1554 | localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_RENDER_DEBUG; |
1550 | 1555 | } |
1551 | 1556 |
|
| 1557 | + if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_SCREENSHOT)) |
| 1558 | + localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_SCREENSHOT; |
| 1559 | + |
1552 | 1560 | // In flying mode, Shift held = sneak/descend |
1553 | 1561 | if(g_KBMInput.IsKBMActive() && g_KBMInput.IsKeyDown(KeyboardMouseInput::KEY_SNEAK)) |
1554 | 1562 | { |
@@ -3737,6 +3745,80 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) |
3737 | 3745 | //options->thirdPersonView = !options->thirdPersonView; |
3738 | 3746 | } |
3739 | 3747 |
|
| 3748 | +#ifdef _WINDOWS64 |
| 3749 | + if(player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_SCREENSHOT)) |
| 3750 | + { |
| 3751 | + extern ID3D11Device* g_pd3dDevice; |
| 3752 | + extern ID3D11DeviceContext* g_pImmediateContext; |
| 3753 | + extern IDXGISwapChain* g_pSwapChain; |
| 3754 | + |
| 3755 | + ID3D11Texture2D* pBackBuffer = nullptr; |
| 3756 | + HRESULT hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBackBuffer); |
| 3757 | + if (SUCCEEDED(hr)) |
| 3758 | + { |
| 3759 | + D3D11_TEXTURE2D_DESC desc; |
| 3760 | + pBackBuffer->GetDesc(&desc); |
| 3761 | + desc.Usage = D3D11_USAGE_STAGING; |
| 3762 | + desc.BindFlags = 0; |
| 3763 | + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; |
| 3764 | + desc.MiscFlags = 0; |
| 3765 | + |
| 3766 | + ID3D11Texture2D* pStaging = nullptr; |
| 3767 | + hr = g_pd3dDevice->CreateTexture2D(&desc, nullptr, &pStaging); |
| 3768 | + if (SUCCEEDED(hr)) |
| 3769 | + { |
| 3770 | + g_pImmediateContext->CopyResource(pStaging, pBackBuffer); |
| 3771 | + |
| 3772 | + // Build path next to the executable |
| 3773 | + wchar_t exePath[MAX_PATH]; |
| 3774 | + GetModuleFileNameW(NULL, exePath, MAX_PATH); |
| 3775 | + wchar_t* lastSlash = wcsrchr(exePath, L'\\'); |
| 3776 | + if (lastSlash) *(lastSlash + 1) = L'\0'; |
| 3777 | + wstring screenshotDirPath = wstring(exePath) + L"screenshots"; |
| 3778 | + CreateDirectoryW(screenshotDirPath.c_str(), NULL); |
| 3779 | + |
| 3780 | + SYSTEMTIME st; |
| 3781 | + GetLocalTime(&st); |
| 3782 | + wchar_t filename[128]; |
| 3783 | + swprintf_s(filename, L"%04d-%02d-%02d_%02d.%02d.%02d.png", |
| 3784 | + st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); |
| 3785 | + wstring screenshotPath = screenshotDirPath + L"\\" + filename; |
| 3786 | + |
| 3787 | + D3D11_MAPPED_SUBRESOURCE mapped; |
| 3788 | + hr = g_pImmediateContext->Map(pStaging, 0, D3D11_MAP_READ, 0, &mapped); |
| 3789 | + if (SUCCEEDED(hr)) |
| 3790 | + { |
| 3791 | + // Copy rows and force alpha to fully opaque |
| 3792 | + unsigned char* rgba = new unsigned char[desc.Width * desc.Height * 4]; |
| 3793 | + for (UINT row = 0; row < desc.Height; row++) |
| 3794 | + { |
| 3795 | + unsigned char* src = (unsigned char*)mapped.pData + row * mapped.RowPitch; |
| 3796 | + unsigned char* dst = rgba + row * desc.Width * 4; |
| 3797 | + memcpy(dst, src, desc.Width * 4); |
| 3798 | + for (UINT x = 0; x < desc.Width; x++) |
| 3799 | + dst[x * 4 + 3] = 0xFF; |
| 3800 | + } |
| 3801 | + g_pImmediateContext->Unmap(pStaging, 0); |
| 3802 | + |
| 3803 | + // Save PNG via stb_image_write |
| 3804 | + string narrowPath(screenshotPath.begin(), screenshotPath.end()); |
| 3805 | + int writeResult = stbi_write_png(narrowPath.c_str(), desc.Width, desc.Height, 4, rgba, desc.Width * 4); |
| 3806 | + delete[] rgba; |
| 3807 | + |
| 3808 | + // Send local-only chat message on success |
| 3809 | + if (writeResult) |
| 3810 | + { |
| 3811 | + wstring msg = L"Saved screenshot to " + wstring(filename); |
| 3812 | + gui->addMessage(msg, iPad); |
| 3813 | + } |
| 3814 | + } |
| 3815 | + pStaging->Release(); |
| 3816 | + } |
| 3817 | + pBackBuffer->Release(); |
| 3818 | + } |
| 3819 | + } |
| 3820 | +#endif |
| 3821 | + |
3740 | 3822 | if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_GAME_INFO)) && gameMode->isInputAllowed(MINECRAFT_ACTION_GAME_INFO)) |
3741 | 3823 | { |
3742 | 3824 | ui.NavigateToScene(iPad,eUIScene_InGameInfoMenu); |
|
0 commit comments