diff --git a/Source/Client/Mode/CMode.h b/Source/Client/Mode/CMode.h index 4d36419..9bbb6bb 100644 --- a/Source/Client/Mode/CMode.h +++ b/Source/Client/Mode/CMode.h @@ -22,10 +22,10 @@ public: /* 0020 */ std::uint32_t tooltipTick; /* 0024 */ std::uint32_t cursorTick; /* 0028 */ int unknown_0028; - /* 002C */ int unknown_002C; + /* 002C */ int screenshotRequested; /* 0030 */ int unknown_0030; /* 0034 */ int unknown_0034; - /* 0038 */ std::string unknown_0038; + /* 0038 */ std::string screenshotName; /* 0050 */ int unknown_0050; /* 0054 */ int unknown_0054; @@ -39,12 +39,13 @@ public: virtual void Slot7(int value); CMode(); + void TakeScreenshot(); void DrawTexture(const tagRECT& rect, int angle, float rhw, std::uint32_t color, CTexture* texture, TextureRegion region); }; #if defined(_WIN32) && !defined(_WIN64) static_assert(offsetof(CMode, cursorType) == 0x4); -static_assert(offsetof(CMode, unknown_0038) == 0x38); +static_assert(offsetof(CMode, screenshotName) == 0x38); static_assert(sizeof(CMode) == 0x58); #endif diff --git a/Source/Client/ModeScreenshot.cpp b/Source/Client/ModeScreenshot.cpp index 85eb644..a9810d5 100644 --- a/Source/Client/ModeScreenshot.cpp +++ b/Source/Client/ModeScreenshot.cpp @@ -1,5 +1,23 @@ #include "Client/ModeScreenshot.h" +#include "Client/Application/Launcher.h" +#include "Client/Mode/CMode.h" +#include "Client/Session.h" +#include "Contents/Configuration/ServiceConfiguration.h" +#include "Render/DeviceContext/DCSurface.h" +#include "Render/Renderer.h" +#include "UI/Window/UIWindowMgr.h" +#include "Utility/Text/FormatString.h" + +#include +#include +#include +#include +#include + +// GLOBAL: gl_24743 +int g_screenshotIndex; + // OFFSET: 0x00AD63F0 // FUNCTION: fn_17830 void SanitizeScreenshotName(std::string& name) { @@ -10,3 +28,105 @@ void SanitizeScreenshotName(std::string& name) { } } } + +// OFFSET: 0x00AD6A40 +// FUNCTION: fn_17848 +void CMode::TakeScreenshot() { + if (!this->screenshotRequested) { + return; + } + + SYSTEMTIME time; + GetLocalTime(&time); + + char text[128]; + std::memset(text, 0, sizeof(text)); + + const char* dayNames[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; + + if (g_serviceType != 0) { + std::sprintf( + text, "%d/%02d/%02d/%s %02d: %02d: %02d", time.wYear, time.wMonth, time.wDay, dayNames[time.wDayOfWeek], + time.wHour, time.wMinute, time.wSecond + ); + } else { + int gid = static_cast(g_session.m_gid); + if (gid != 0) { + char code[12] = {}; + int divisor = 100000000; + int length = 0; + do { + int digit = 0; + while (gid >= divisor) { + gid -= divisor; + ++digit; + } + divisor /= 10; + + if (length > 0) { + ++length; + } else if (digit > 0) { + length = 1; + } + + if (digit == 0) { + if (length > 0) { + code[length - 1] = 'R'; + } + } else if (digit == 1) { + code[length - 1] = 'O'; + } else if (digit == 2) { + code[length - 1] = 'H'; + } else if (digit == 3) { + code[length - 1] = 'U'; + } else if (digit == 4) { + code[length - 1] = 'T'; + } else if (digit == 5) { + code[length - 1] = 'N'; + } else if (digit == 6) { + code[length - 1] = 'A'; + } else if (digit == 7) { + code[length - 1] = 'S'; + } else if (digit == 8) { + code[length - 1] = 'E'; + } else if (digit == 9) { + code[length - 1] = 'W'; + } + } while (divisor > 0); + + std::sprintf( + text, "%d/%02d/%02d/%s %02d: %02d: %02d %s", time.wYear, time.wMonth, time.wDay, + dayNames[time.wDayOfWeek], time.wHour, time.wMinute, time.wSecond, code + ); + } + } + + DrawBackBufferText(5, g_renderer->viewport.height - 16, text, 0); + DrawBackBufferText(3, g_renderer->viewport.height - 16, text, 0); + DrawBackBufferText(4, g_renderer->viewport.height - 15, text, 0); + DrawBackBufferText(4, g_renderer->viewport.height - 17, text, 0); + DrawBackBufferText(4, g_renderer->viewport.height - 16, text, 0xFFFFFF); + + this->screenshotRequested = 0; + + std::string directory = FormatOwnedString("%s\\ScreenShot", g_applicationDirectory); + if (_access(directory.c_str(), 0) == 0 || _mkdir(directory.c_str()) == 0) { + std::string characterName(*reinterpret_cast(&g_session.unknown_52C4[0x278])); + SanitizeScreenshotName(characterName); + SanitizeScreenshotName(this->screenshotName); + + std::string base = directory + std::string("\\") + this->screenshotName + std::string("screen"); + std::string extension(".jpg"); + base += characterName; + + std::string path = base + FormatOwnedString("%03d", g_screenshotIndex++) + extension; + while (_access(path.c_str(), 0) == 0) { + path = base + FormatOwnedString("%03d", g_screenshotIndex++) + extension; + } + + g_renderer->SaveLogo(path); + path += " is Saved."; + g_windowMgr.SendNotice(1, reinterpret_cast(path.c_str()), 0xFF00, 0, 0, 0); + this->screenshotName = ""; + } +}