Use jpg compressed resources

This commit is contained in:
Maurice Heumann 2022-12-04 12:24:21 +01:00
parent 1614566a9a
commit d1337fc794
14 changed files with 196 additions and 32 deletions

3
.gitmodules vendored
View File

@ -25,3 +25,6 @@
[submodule "deps/discord-rpc"] [submodule "deps/discord-rpc"]
path = deps/discord-rpc path = deps/discord-rpc
url = https://github.com/momo5502/discord-rpc.git url = https://github.com/momo5502/discord-rpc.git
[submodule "deps/stb"]
path = deps/stb
url = https://github.com/nothings/stb.git

19
deps/premake/stb.lua vendored Normal file
View File

@ -0,0 +1,19 @@
stb = {
source = path.join(dependencies.basePath, "stb"),
}
function stb.import()
stb.includes()
end
function stb.includes()
includedirs {
stb.source
}
end
function stb.project()
end
table.insert(dependencies, stb)

1
deps/stb vendored Submodule

@ -0,0 +1 @@
Subproject commit 8b5f1f37b5b75829fc72d38e7b5d4bcbf8a26d55

View File

@ -312,11 +312,15 @@ project "tlsdll"
symbols 'Off' symbols 'Off'
exceptionhandling "Off" exceptionhandling "Off"
flags {"NoRuntimeChecks", "NoBufferSecurityCheck", "OmitDefaultLibrary"} flags {"NoRuntimeChecks", "NoBufferSecurityCheck", "OmitDefaultLibrary"}
buildoptions {"/Zc:threadSafeInit-"} buildoptions {"/Zc:threadSafeInit-"}
removebuildoptions {"/GL"}
linkoptions {"/NODEFAULTLIB", "/IGNORE:4210"} linkoptions {"/NODEFAULTLIB", "/IGNORE:4210"}
removebuildoptions {"/GL"}
removelinkoptions {"/LTCG"}
files {"./src/tlsdll/**.rc", "./src/tlsdll/**.hpp", "./src/tlsdll/**.cpp", "./src/tlsdll/resources/**.*"} files {"./src/tlsdll/**.rc", "./src/tlsdll/**.hpp", "./src/tlsdll/**.cpp", "./src/tlsdll/resources/**.*"}
includedirs {"./src/tlsdll", "%{prj.location}/src"} includedirs {"./src/tlsdll", "%{prj.location}/src"}

View File

@ -7,6 +7,7 @@
#include <utils/thread.hpp> #include <utils/thread.hpp>
#include <utils/hook.hpp> #include <utils/hook.hpp>
#include <utils/concurrency.hpp> #include <utils/concurrency.hpp>
#include <utils/image.hpp>
#define CONSOLE_BUFFER_SIZE 16384 #define CONSOLE_BUFFER_SIZE 16384
#define WINDOW_WIDTH 608 #define WINDOW_WIDTH 608
@ -15,7 +16,7 @@ namespace console
{ {
namespace namespace
{ {
HANDLE logo; utils::image::object logo;
std::atomic_bool started{false}; std::atomic_bool started{false};
std::atomic_bool terminate_runner{false}; std::atomic_bool terminate_runner{false};
utils::concurrency::container<std::queue<std::string>> message_queue{}; utils::concurrency::container<std::queue<std::string>> message_queue{};
@ -79,25 +80,8 @@ namespace console
INT_PTR get_gray_brush() INT_PTR get_gray_brush()
{ {
static struct brush static utils::image::object b(CreateSolidBrush(RGB(50, 50, 50)));
{ return reinterpret_cast<INT_PTR>(b.get());
HBRUSH hbrush;
brush()
: hbrush(CreateSolidBrush(RGB(50, 50, 50)))
{
}
~brush()
{
if (hbrush)
{
DeleteObject(hbrush);
}
}
} b;
return reinterpret_cast<INT_PTR>(b.hbrush);
} }
LRESULT con_wnd_proc(const HWND hwnd, const UINT msg, const WPARAM wparam, const LPARAM lparam) LRESULT con_wnd_proc(const HWND hwnd, const UINT msg, const WPARAM wparam, const LPARAM lparam)
@ -185,7 +169,7 @@ namespace console
utils::hook::set<HWND>(game::s_wcd::codLogo, CreateWindowExA( utils::hook::set<HWND>(game::s_wcd::codLogo, CreateWindowExA(
0, "Static", nullptr, 0x5000000Eu, 5, 5, 0, 0, *game::s_wcd::hWnd, 0, "Static", nullptr, 0x5000000Eu, 5, 5, 0, 0, *game::s_wcd::hWnd,
reinterpret_cast<HMENU>(1), h_instance, nullptr)); reinterpret_cast<HMENU>(1), h_instance, nullptr));
SendMessageA(*game::s_wcd::codLogo, 0x172u, 0, reinterpret_cast<LPARAM>(logo)); SendMessageA(*game::s_wcd::codLogo, STM_SETIMAGE, IMAGE_BITMAP, logo);
} }
// create the input line // create the input line
@ -219,8 +203,12 @@ namespace console
utils::hook::jump(0x1423337F0_g, queue_message); utils::hook::jump(0x1423337F0_g, queue_message);
utils::hook::nop(0x14233380A_g, 2); // Print from every thread utils::hook::nop(0x14233380A_g, 2); // Print from every thread
const auto self = utils::nt::library::get_by_address(sys_create_console_stub); //const auto self = utils::nt::library::get_by_address(sys_create_console_stub);
logo = LoadImageA(self.get_handle(), MAKEINTRESOURCEA(IMAGE_LOGO), 0, 0, 0, LR_COPYFROMRESOURCE); //logo = LoadImageA(self.get_handle(), MAKEINTRESOURCEA(IMAGE_LOGO), 0, 0, 0, LR_COPYFROMRESOURCE);
const auto res = utils::nt::load_resource(IMAGE_LOGO);
const auto img = utils::image::load_image(res);
logo = utils::image::create_bitmap(img);
utils::hook::jump(printf, print_stub); utils::hook::jump(printf, print_stub);

View File

@ -5,20 +5,24 @@
#include "resource.hpp" #include "resource.hpp"
#include <utils/nt.hpp> #include <utils/nt.hpp>
#include <utils/image.hpp>
namespace splash namespace splash
{ {
namespace namespace
{ {
HWND window{}; HWND window{};
HANDLE image{}; utils::image::object image{};
std::thread window_thread{}; std::thread window_thread{};
std::atomic_bool join_safe{false};
HANDLE load_splash_image() utils::image::object load_splash_image()
{ {
const auto self = utils::nt::library::get_by_address(load_splash_image); //const auto self = utils::nt::library::get_by_address(load_splash_image);
return LoadImageA(self, MAKEINTRESOURCE(IMAGE_SPLASH), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); //return LoadImageA(self, MAKEINTRESOURCE(IMAGE_SPLASH), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
const auto res = utils::nt::load_resource(IMAGE_SPLASH);
const auto img = utils::image::load_image(res);
return utils::image::create_bitmap(img);
} }
void enable_dpi_awareness() void enable_dpi_awareness()
@ -93,7 +97,7 @@ namespace splash
if (image_window) if (image_window)
{ {
RECT rect; RECT rect;
SendMessageA(image_window, 0x172u, 0, reinterpret_cast<LPARAM>(image)); SendMessageA(image_window, STM_SETIMAGE, IMAGE_BITMAP, image);
GetWindowRect(image_window, &rect); GetWindowRect(image_window, &rect);
const int width = rect.right - rect.left; const int width = rect.right - rect.left;

View File

@ -92,8 +92,8 @@ END
// //
ID_ICON ICON "resources/icon.ico" ID_ICON ICON "resources/icon.ico"
IMAGE_SPLASH BITMAP "resources/splash.bmp" IMAGE_SPLASH RCDATA "resources/splash.jpg"
IMAGE_LOGO BITMAP "resources/logo.bmp" IMAGE_LOGO RCDATA "resources/logo.jpg"
DW_MOTD RCDATA "resources/dw/experiments_tu32.gz" DW_MOTD RCDATA "resources/dw/experiments_tu32.gz"
DW_CARDS RCDATA "resources/dw/featured_cards-english_tu32.gz" DW_CARDS RCDATA "resources/dw/featured_cards-english_tu32.gz"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

View File

@ -0,0 +1,56 @@
#include "image.hpp"
#include <stdexcept>
#pragma warning(push)
#pragma warning(disable: 4100)
#define STBI_ONLY_JPEG
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#pragma warning(pop)
#include "finally.hpp"
namespace utils::image
{
image load_image(const std::string& data)
{
stbi_uc* buffer{};
const auto _ = finally([&]
{
if (buffer)
{
stbi_image_free(buffer);
}
});
constexpr int channels = 4;
int x, y, channels_in_file;
buffer = stbi_load_from_memory(reinterpret_cast<const uint8_t*>(data.data()),
static_cast<int>(data.size()), &x, &y, &channels_in_file, channels);
if (!buffer)
{
throw std::runtime_error("Failed to load image");
}
image res{};
res.width = static_cast<size_t>(x);
res.height = static_cast<size_t>(y);
res.data.assign(reinterpret_cast<const char*>(buffer), res.width * res.height * channels);
return res;
}
object create_bitmap(const image& img)
{
auto copy = img.data;
for (size_t i = 0; i < (img.width * img.height); ++i)
{
auto& r = copy[i * 4 + 0];
auto& b = copy[i * 4 + 2];
std::swap(r, b);
}
return CreateBitmap(static_cast<int>(img.width), static_cast<int>(img.height), 4, 8, copy.data());
}
}

View File

@ -0,0 +1,89 @@
#pragma once
#include <string>
#include "nt.hpp"
namespace utils::image
{
struct image
{
size_t width;
size_t height;
std::string data;
};
class object
{
public:
object() = default;
object(const HGDIOBJ h)
: handle_(h)
{
}
~object()
{
if (*this)
{
DeleteObject(this->handle_);
this->handle_ = nullptr;
}
}
object(const object&) = delete;
object& operator=(const object&) = delete;
object(object&& obj) noexcept
: object()
{
this->operator=(std::move(obj));
}
object& operator=(object&& obj) noexcept
{
if (this != &obj)
{
this->~object();
this->handle_ = obj.handle_;
obj.handle_ = nullptr;
}
return *this;
}
object& operator=(HANDLE h) noexcept
{
this->~object();
this->handle_ = h;
return *this;
}
HGDIOBJ get() const
{
return this->handle_;
}
operator bool() const
{
return this->handle_ != nullptr;
}
operator HGDIOBJ() const
{
return this->handle_;
}
operator LPARAM() const
{
return reinterpret_cast<LPARAM>(this->handle_);
}
private:
HGDIOBJ handle_{nullptr};
};
image load_image(const std::string& data);
object create_bitmap(const image& img);
}