Skip to content

Commit c636d11

Browse files
committed
Add F2 screenshot functionality and image writing support
- Updated `EControllerActions` to include `MINECRAFT_ACTION_SCREENSHOT`. - Added conditional compilation for `stb_image_write.h` in `Minecraft.cpp`. - Modified `run_middle()` to handle screenshot key press. - Updated `tick()` to capture and save screenshots as PNG files. - Introduced `KEY_SCREENSHOT` in `KeyboardMouseInput.h` mapped to F2. - Added `stb_image_write.h` for image writing capabilities.
1 parent f896332 commit c636d11

File tree

4 files changed

+1809
-1
lines changed

4 files changed

+1809
-1
lines changed

Minecraft.Client/Common/App_enums.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,8 @@ enum EControllerActions
878878
MINECRAFT_ACTION_SPAWN_CREEPER,
879879
MINECRAFT_ACTION_CHANGE_SKIN,
880880
MINECRAFT_ACTION_FLY_TOGGLE,
881-
MINECRAFT_ACTION_RENDER_DEBUG
881+
MINECRAFT_ACTION_RENDER_DEBUG,
882+
MINECRAFT_ACTION_SCREENSHOT
882883
};
883884

884885
enum eMCLang

Minecraft.Client/Minecraft.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@
7373
#include "Common\UI\UIFontData.h"
7474
#include "DLCTexturePack.h"
7575

76+
#ifdef _WINDOWS64
77+
#define STB_IMAGE_WRITE_IMPLEMENTATION
78+
#include "Windows64/stb_image_write.h"
79+
#endif
80+
7681
#ifdef __ORBIS__
7782
#include "Orbis\Network\PsPlusUpsellWrapper_Orbis.h"
7883
#endif
@@ -1549,6 +1554,9 @@ void Minecraft::run_middle()
15491554
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_RENDER_DEBUG;
15501555
}
15511556

1557+
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_SCREENSHOT))
1558+
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_SCREENSHOT;
1559+
15521560
// In flying mode, Shift held = sneak/descend
15531561
if(g_KBMInput.IsKBMActive() && g_KBMInput.IsKeyDown(KeyboardMouseInput::KEY_SNEAK))
15541562
{
@@ -3737,6 +3745,80 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
37373745
//options->thirdPersonView = !options->thirdPersonView;
37383746
}
37393747

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+
37403822
if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_GAME_INFO)) && gameMode->isInputAllowed(MINECRAFT_ACTION_GAME_INFO))
37413823
{
37423824
ui.NavigateToScene(iPad,eUIScene_InGameInfoMenu);

Minecraft.Client/Windows64/KeyboardMouseInput.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class KeyboardMouseInput
3131
static const int KEY_THIRD_PERSON = VK_F5;
3232
static const int KEY_DEBUG_INFO = VK_F3;
3333
static const int KEY_DEBUG_MENU = VK_F4;
34+
static const int KEY_SCREENSHOT = VK_F2;
3435

3536
void Init();
3637
void Tick();

0 commit comments

Comments
 (0)