splash stuff
This commit is contained in:
parent
e135c5e033
commit
8a15addddf
@ -1,146 +1,93 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "loader/component_loader.hpp"
|
#include "loader/component_loader.hpp"
|
||||||
|
|
||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
|
|
||||||
#include "game_module.hpp"
|
#include "game_module.hpp"
|
||||||
|
|
||||||
#include <utils/hook.hpp>
|
|
||||||
#include <utils/nt.hpp>
|
#include <utils/nt.hpp>
|
||||||
|
#include <utils/hook.hpp>
|
||||||
|
|
||||||
namespace splash
|
namespace splash
|
||||||
{
|
{
|
||||||
namespace
|
|
||||||
{
|
|
||||||
HANDLE load_splash_image()
|
|
||||||
{
|
|
||||||
const auto self = game_module::get_host_module();
|
|
||||||
return LoadImageA(self, MAKEINTRESOURCE(IMAGE_SPLASH), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
component()
|
void post_start() override
|
||||||
: image_(load_splash_image())
|
|
||||||
{
|
{
|
||||||
this->window_thread_ = std::thread([this]
|
const utils::nt::library self;
|
||||||
{
|
image_ = LoadImageA(self, MAKEINTRESOURCE(IMAGE_SPLASH), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
|
||||||
this->draw();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~component()
|
void post_load() override
|
||||||
{
|
{
|
||||||
if (this->window_thread_.joinable())
|
if (game::environment::is_dedi())
|
||||||
{
|
{
|
||||||
this->window_thread_.detach();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void post_unpack() override
|
||||||
|
{
|
||||||
|
// Disable native splash screen
|
||||||
|
utils::hook::set<uint8_t>(0xD58240_b, 0xC3);
|
||||||
|
utils::hook::jump(0xD584F0_b, destroy_stub, true);
|
||||||
|
utils::hook::jump(0xD58530_b, destroy_stub, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pre_destroy() override
|
void pre_destroy() override
|
||||||
{
|
{
|
||||||
this->destroy();
|
this->destroy();
|
||||||
|
|
||||||
|
MSG msg;
|
||||||
|
while (this->window_ && IsWindow(this->window_))
|
||||||
|
{
|
||||||
|
if (PeekMessageA(&msg, nullptr, NULL, NULL, PM_REMOVE))
|
||||||
|
{
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(1ms);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void post_unpack() override
|
this->window_ = nullptr;
|
||||||
{
|
|
||||||
utils::hook::set<uint8_t>(0xD58240_b, 0xC3); // disable splash
|
|
||||||
this->destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void hide()
|
|
||||||
{
|
|
||||||
if (this->window_ && IsWindow(this->window_))
|
|
||||||
{
|
|
||||||
ShowWindow(this->window_, SW_HIDE);
|
|
||||||
UpdateWindow(this->window_);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic_bool join_safe_{ false };
|
|
||||||
HWND window_{};
|
HWND window_{};
|
||||||
HANDLE image_{};
|
HANDLE image_{};
|
||||||
std::thread window_thread_{};
|
|
||||||
|
|
||||||
void destroy()
|
static void destroy_stub()
|
||||||
|
{
|
||||||
|
component_loader::get<component>()->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy() const
|
||||||
{
|
{
|
||||||
if (this->window_ && IsWindow(this->window_))
|
if (this->window_ && IsWindow(this->window_))
|
||||||
{
|
{
|
||||||
ShowWindow(this->window_, SW_HIDE);
|
ShowWindow(this->window_, SW_HIDE);
|
||||||
DestroyWindow(this->window_);
|
DestroyWindow(this->window_);
|
||||||
this->window_ = nullptr;
|
UnregisterClassA("IW7 Splash Screen", utils::nt::library{});
|
||||||
|
|
||||||
if (this->window_thread_.joinable())
|
|
||||||
{
|
|
||||||
this->window_thread_.join();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->window_ = nullptr;
|
|
||||||
}
|
|
||||||
else if (this->window_thread_.joinable())
|
|
||||||
{
|
|
||||||
this->window_thread_.detach();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw()
|
|
||||||
{
|
|
||||||
this->show();
|
|
||||||
while (this->draw_frame())
|
|
||||||
{
|
|
||||||
std::this_thread::sleep_for(1ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->window_ = nullptr;
|
|
||||||
UnregisterClassA("IW7 Splash Screen", game_module::get_host_module());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool draw_frame() const
|
|
||||||
{
|
|
||||||
if (!this->window_)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSG msg{};
|
|
||||||
bool success = true;
|
|
||||||
|
|
||||||
while (PeekMessageW(&msg, nullptr, NULL, NULL, PM_REMOVE))
|
|
||||||
{
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessageW(&msg);
|
|
||||||
|
|
||||||
if (msg.message == WM_DESTROY && msg.hwnd == this->window_)
|
|
||||||
{
|
|
||||||
PostQuitMessage(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg.message == WM_QUIT)
|
|
||||||
{
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void show()
|
void show()
|
||||||
{
|
{
|
||||||
WNDCLASSA wnd_class;
|
WNDCLASSA wnd_class;
|
||||||
|
|
||||||
const utils::nt::library host = game_module::get_host_module();
|
const auto self = game_module::get_host_module();
|
||||||
|
|
||||||
wnd_class.style = CS_DROPSHADOW;
|
wnd_class.style = CS_DROPSHADOW;
|
||||||
wnd_class.cbClsExtra = 0;
|
wnd_class.cbClsExtra = 0;
|
||||||
wnd_class.cbWndExtra = 0;
|
wnd_class.cbWndExtra = 0;
|
||||||
wnd_class.lpszMenuName = nullptr;
|
wnd_class.lpszMenuName = nullptr;
|
||||||
wnd_class.lpfnWndProc = DefWindowProcA;
|
wnd_class.lpfnWndProc = DefWindowProcA;
|
||||||
wnd_class.hInstance = host;
|
wnd_class.hInstance = self;
|
||||||
wnd_class.hIcon = LoadIconA(host, MAKEINTRESOURCEA(1));
|
wnd_class.hIcon = LoadIconA(self, reinterpret_cast<LPCSTR>(102));
|
||||||
wnd_class.hCursor = LoadCursorA(nullptr, IDC_APPSTARTING);
|
wnd_class.hCursor = LoadCursorA(nullptr, IDC_APPSTARTING);
|
||||||
wnd_class.hbrBackground = reinterpret_cast<HBRUSH>(6);
|
wnd_class.hbrBackground = reinterpret_cast<HBRUSH>(6);
|
||||||
wnd_class.lpszClassName = "IW7 Splash Screen";
|
wnd_class.lpszClassName = "IW7 Splash Screen";
|
||||||
@ -156,13 +103,13 @@ namespace splash
|
|||||||
WS_POPUP | WS_SYSMENU,
|
WS_POPUP | WS_SYSMENU,
|
||||||
(x_pixels - 320) / 2, (y_pixels - 100) / 2, 320, 100, nullptr,
|
(x_pixels - 320) / 2, (y_pixels - 100) / 2, 320, 100, nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
host, nullptr);
|
self, nullptr);
|
||||||
|
|
||||||
if (this->window_)
|
if (this->window_)
|
||||||
{
|
{
|
||||||
auto* const image_window = CreateWindowExA(0, "Static", nullptr, WS_CHILD | WS_VISIBLE | 0xEu,
|
auto* const image_window = CreateWindowExA(0, "Static", nullptr, WS_CHILD | WS_VISIBLE | 0xEu,
|
||||||
0, 0,
|
0, 0,
|
||||||
320, 100, this->window_, nullptr, host, nullptr);
|
320, 100, this->window_, nullptr, self, nullptr);
|
||||||
if (image_window)
|
if (image_window)
|
||||||
{
|
{
|
||||||
RECT rect;
|
RECT rect;
|
||||||
@ -181,10 +128,6 @@ namespace splash
|
|||||||
SetWindowPos(this->window_, nullptr, rect.left, rect.top, rect.right - rect.left,
|
SetWindowPos(this->window_, nullptr, rect.left, rect.top, rect.right - rect.left,
|
||||||
rect.bottom - rect.top, SWP_NOZORDER);
|
rect.bottom - rect.top, SWP_NOZORDER);
|
||||||
|
|
||||||
SetWindowRgn(this->window_,
|
|
||||||
CreateRoundRectRgn(0, 0, rect.right - rect.left, rect.bottom - rect.top, 15,
|
|
||||||
15), TRUE);
|
|
||||||
|
|
||||||
ShowWindow(this->window_, SW_SHOW);
|
ShowWindow(this->window_, SW_SHOW);
|
||||||
UpdateWindow(this->window_);
|
UpdateWindow(this->window_);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user