port: grp.SaveScreenShot via next-frame swapchain readback + JPEG

CPythonGraphic::SaveScreenShot queues a readback of the next presented
frame (ScreenShotHost -> VulkanWindow::request_frame); WriteScreenShot runs
the rest of 40250's function verbatim (X8R8G8B8 rows, SaveJPEG, EXIF tag).
jpeg_save is encoded with stb_image_write. SHGetSpecialFolderPath returns
$HOME/Documents (else cwd); CreateDirectory/_access/jpeg_save accept '\\'.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-30 12:43:03 +09:00
co-authored by Claude Opus 5.5
parent c21e012965
commit bda85eea50
17 changed files with 2211 additions and 12 deletions
+11 -2
View File
@@ -32,9 +32,18 @@ void DeleteCriticalSection(LPCRITICAL_SECTION cs) { cs_mutex(cs).~recursive_mute
void EnterCriticalSection(LPCRITICAL_SECTION cs) { cs_mutex(cs).lock(); }
void LeaveCriticalSection(LPCRITICAL_SECTION cs) { cs_mutex(cs).unlock(); }
// Win32 takes '\\' and '/' as separators alike.
static std::string native_path(const char* path)
{
std::string normalized(path ? path : "");
for (char& ch : normalized)
if (ch == '\\') ch = '/';
return normalized;
}
BOOL CreateDirectory(LPCSTR path, void*)
{
return mkdir(path, 0777) == 0 ? TRUE : FALSE;
return mkdir(native_path(path).c_str(), 0777) == 0 ? TRUE : FALSE;
}
BOOL DeleteFile(LPCSTR path)
@@ -49,7 +58,7 @@ int _access(const char* path, int mode)
m |= W_OK;
if (mode & 4)
m |= R_OK;
return access(path, m);
return access(native_path(path).c_str(), m);
}
int _unlink(const char* path)