Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Threaded screenshots using d3d9 instead of gdi+ (release/wip)

Joined
Jan 9, 2009
Messages
614
Reaction score
152
So, i got tired of the short jitter that ocurs when screenshotting in gunz, so i threaded it. NOte, it's incomplete, will probably crash after a few screenshots. I cba to bother reading about threading to fix it, so if anyone here thinks they can fix the problem, feel free to use this. If you don't know what to do with it, don't use and don't ask.

Code:
#include <thread>
//Custom: Threaded screenshot (true improvement, for some reason secrets just didn't help at all)
bool g_TakingScreenie = false;

void SaveSurface()
{

char szPath[_MAX_PATH];
char szFilename[_MAX_PATH];
char szFilenameSafe[_MAX_PATH];

TCHAR szMyDocPath[MAX_PATH];
if (GetMyDocumentsPath(szMyDocPath)) {
strcpy(szPath, szMyDocPath);
strcat(szPath, GUNZ_FOLDER);
CreatePath(szPath);
strcat(szPath, SCREENSHOT_FOLDER);
CreatePath(szPath);
strcat(szPath, "/");
}

// ÇöÀE°ÔÀÓ Á¤º¸·Î ÆÄÀϸúÜ» ±¸¼º
SYSTEMTIME t;
GetLocalTime(&t);
char szCharName[MATCHOBJECT_NAME_LENGTH];
ValidateFilename(szCharName, ZGetMyInfo()->GetCharName(), '_');

sprintf(szFilename, "%s_%4d%02d%02d_%02d%02d%02d",
szCharName, t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);

sprintf(szFilenameSafe, "nocharname_%4d%02d%02d_%02d%02d%02d",
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond); // ij¸¯¸úÜ» »ý·«ÇÑ ¹öÀE

LPDIRECT3DSURFACE9 frontbuffer = NULL;

HRESULT hr;
LPDIRECT3DDEVICE9 pDevice = RGetDevice();

D3DDISPLAYMODE d3ddm;
pDevice->GetDisplayMode(0, &d3ddm);

hr = pDevice->CreateOffscreenPlainSurface(d3ddm.Width,d3ddm.Height,D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &frontbuffer, NULL);
hr = pDevice->GetFrontBufferData(0, frontbuffer);

_ASSERT(hr == D3D_OK);

RECT rt;
GetWindowRect(g_hWnd, &rt);
char szFilePath[256];
sprintf_s(szFilePath, 256, "%s%s.jpg", szPath, szFilename);
hr = D3DXSaveSurfaceToFileA(szFilePath, D3DXIFF_JPG, frontbuffer, NULL, RGetScreenType() != 0 ? &rt : NULL);
if (SUCCEEDED(hr))
{
char szFilePathToNotify[256];
sprintf(szFilePathToNotify, GUNZ_FOLDER SCREENSHOT_FOLDER"/""%s.jpg", szFilename);
char szOutput[_MAX_PATH * 2];
ZTransMsg(szOutput, MSG_SCREENSHOT_SAVED, 1, szFilePathToNotify);
ZChatOutput(MCOLOR(ZCOLOR_CHAT_SYSTEM), szOutput);
frontbuffer->Release();
frontbuffer = NULL;
}
else
{
frontbuffer->Release();
frontbuffer = NULL;
ZChatOutput(MCOLOR(ZCOLOR_CHAT_SYSTEM),
ZMsg(MSG_SCREENSHOT_CANT_SAVE));
}
g_TakingScreenie = false;
}

void ZGameInterface::SaveScreenShot()
{
//todo: determine best method of syncing with detach to prevent application hangs
if (!g_TakingScreenie)
{
g_TakingScreenie = true;
thread t(SaveSurface);
t.detach();
}
}
 
Junior Spellweaver
Joined
Feb 4, 2008
Messages
122
Reaction score
148
I think you cannot call directx code outside of the main thread, which may be causing the crash. What you can do is copy the framebuffer to memory (not a directx surface) in the main thread (which is fast) and save it to a file in a secondary thread, yet if you write a file to disk asynchronous it may be done from the main thread.
 
Joined
Jan 9, 2009
Messages
614
Reaction score
152
I think you cannot call directx code outside of the main thread, which may be causing the crash. What you can do is copy the framebuffer to memory (not a directx surface) in the main thread (which is fast) and save it to a file in a secondary thread, yet if you write a file to disk asynchronous it may be done from the main thread.

Looks like you're right from what I'm reading, seems microsoft warns that it can cause a crash or a deadlock (ive had both happen).
 
Junior Spellweaver
Joined
Jun 14, 2015
Messages
123
Reaction score
20
it's prolly crashing cuz you didn't create the device with D3DCREATE_MULTITHREADED
 
Junior Spellweaver
Joined
Feb 4, 2008
Messages
122
Reaction score
148
it's prolly crashing cuz you didn't create the device with D3DCREATE_MULTITHREADED
I don't think it will help much, as it will only degrade performance instead of improving because of blocking the main thread
 
Junior Spellweaver
Joined
Jun 14, 2015
Messages
123
Reaction score
20
I don't think it will help much, as it will only degrade performance instead of improving because of blocking the main thread
well yeh making it block for most of the operations is the point, but it will presumably not block while inside d3dxsavesurfacetofile cuz that would be silly, and that should be the cause of the lag o-o
 
Back
Top