Finish launcher
This commit is contained in:
parent
a8a609907d
commit
510e02604b
75
src/launcher/image.cpp
Normal file
75
src/launcher/image.cpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include <std_include.hpp>
|
||||||
|
#include "image.hpp"
|
||||||
|
|
||||||
|
image::image(const size_t resource)
|
||||||
|
{
|
||||||
|
this->bitmap_ = LoadBitmapA(GetModuleHandleA(nullptr), MAKEINTRESOURCEA(resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
image::~image()
|
||||||
|
{
|
||||||
|
DeleteBitmap(this->bitmap_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void image::set_position(const POINT& position)
|
||||||
|
{
|
||||||
|
this->position_ = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void image::set_size(const POINT& size)
|
||||||
|
{
|
||||||
|
this->size_ = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool image::is_hovered(const POINT& mouse) const
|
||||||
|
{
|
||||||
|
return mouse.x >= this->position_.x && mouse.x < (this->position_.x + this->size_.x)
|
||||||
|
&& mouse.y >= this->position_.y && mouse.y < (this->position_.y + this->size_.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void image::paint(const HDC hdc, const POINT& mouse) const
|
||||||
|
{
|
||||||
|
BITMAP bitmap;
|
||||||
|
GetObject(this->bitmap_, sizeof(bitmap), &bitmap);
|
||||||
|
|
||||||
|
const auto dc = CreateCompatibleDC(hdc);
|
||||||
|
SelectObject(dc, this->bitmap_);
|
||||||
|
|
||||||
|
const LONG modifier = 1;
|
||||||
|
LONG size_offset = 0;
|
||||||
|
LONG position_offset = 0;
|
||||||
|
if (this->is_hovered(mouse))
|
||||||
|
{
|
||||||
|
size_offset = modifier * 2;
|
||||||
|
position_offset = -modifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetStretchBltMode(hdc, HALFTONE);
|
||||||
|
StretchBlt(hdc, this->position_.x + position_offset, this->position_.y + position_offset,
|
||||||
|
this->size_.x + size_offset, this->size_.y + size_offset, dc, 0, 0, bitmap.bmWidth,
|
||||||
|
bitmap.bmHeight, SRCCOPY);
|
||||||
|
|
||||||
|
DeleteDC(dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void image::set_click_listener(std::function<void()> callback)
|
||||||
|
{
|
||||||
|
this->callback_ = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void image::click(const POINT& mouse, const bool down)
|
||||||
|
{
|
||||||
|
if(down)
|
||||||
|
{
|
||||||
|
this->down_handled_ = this->is_hovered(mouse);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(this->down_handled_ && this->is_hovered(mouse) && this->callback_)
|
||||||
|
{
|
||||||
|
this->callback_();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->down_handled_ = false;
|
||||||
|
}
|
||||||
|
}
|
27
src/launcher/image.hpp
Normal file
27
src/launcher/image.hpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class image final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
image(size_t resource);
|
||||||
|
~image();
|
||||||
|
|
||||||
|
void set_position(const POINT& position);
|
||||||
|
void set_size(const POINT& size);
|
||||||
|
|
||||||
|
bool is_hovered(const POINT& mouse) const;
|
||||||
|
|
||||||
|
void paint(HDC hdc, const POINT& mouse) const;
|
||||||
|
|
||||||
|
void set_click_listener(std::function<void()> callback);
|
||||||
|
|
||||||
|
void click(const POINT& mouse, bool down);
|
||||||
|
|
||||||
|
private:
|
||||||
|
POINT size_{};
|
||||||
|
POINT position_{};
|
||||||
|
HBITMAP bitmap_;
|
||||||
|
|
||||||
|
bool down_handled_ = false;
|
||||||
|
std::function<void()> callback_;
|
||||||
|
};
|
@ -1,12 +1,109 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "launcher.hpp"
|
#include "launcher.hpp"
|
||||||
|
|
||||||
launcher::launcher() : window_("Open-IW5", 300, 400)
|
launcher::launcher() : window_("Open-IW5", 265, 432), image_sp_(IMAGE_SP), image_mp_(IMAGE_MP)
|
||||||
{
|
{
|
||||||
|
this->image_sp_.set_position({75, 50});
|
||||||
|
this->image_mp_.set_position({75, 252});
|
||||||
|
|
||||||
|
this->image_sp_.set_size({100, 100});
|
||||||
|
this->image_mp_.set_size({100, 100});
|
||||||
|
|
||||||
|
this->image_sp_.set_click_listener(std::bind(&launcher::select_mode, this, mode::SINGLEPLAYER));
|
||||||
|
this->image_mp_.set_click_listener(std::bind(&launcher::select_mode, this, mode::MULTIPLAYER));
|
||||||
|
|
||||||
|
this->window_.set_callback(std::bind(&launcher::handler, this, std::placeholders::_1, std::placeholders::_2,
|
||||||
|
std::placeholders::_3));
|
||||||
}
|
}
|
||||||
|
|
||||||
void launcher::run() const
|
launcher::mode launcher::run() const
|
||||||
{
|
{
|
||||||
this->window_.run();
|
this->window_.run();
|
||||||
|
|
||||||
|
return this->mode_;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT launcher::handler(const UINT message, const WPARAM w_param, const LPARAM l_param)
|
||||||
|
{
|
||||||
|
if (message == WM_PAINT)
|
||||||
|
{
|
||||||
|
this->paint();
|
||||||
|
}
|
||||||
|
else if (message == WM_MOUSEMOVE)
|
||||||
|
{
|
||||||
|
this->mouse_move(l_param);
|
||||||
|
}
|
||||||
|
else if (message == WM_LBUTTONDOWN)
|
||||||
|
{
|
||||||
|
this->image_sp_.click(this->mouse_, true);
|
||||||
|
this->image_mp_.click(this->mouse_, true);
|
||||||
|
}
|
||||||
|
else if (message == WM_LBUTTONUP)
|
||||||
|
{
|
||||||
|
this->image_sp_.click(this->mouse_, false);
|
||||||
|
this->image_mp_.click(this->mouse_, false);
|
||||||
|
}
|
||||||
|
else if (message == WM_ERASEBKGND)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefWindowProc(this->window_, message, w_param, l_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
void launcher::select_mode(const mode mode)
|
||||||
|
{
|
||||||
|
this->mode_ = mode;
|
||||||
|
this->window_.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void launcher::draw_text(const HDC hdc)
|
||||||
|
{
|
||||||
|
Gdiplus::Graphics graphics(hdc);
|
||||||
|
Gdiplus::SolidBrush color(Gdiplus::Color(255, 150, 150, 150));
|
||||||
|
Gdiplus::FontFamily font_family(L"Segoe UI");
|
||||||
|
Gdiplus::Font font(&font_family, 18, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel);
|
||||||
|
|
||||||
|
graphics.DrawString(L"Singleplayer", -1, &font, {75, 20}, &color);
|
||||||
|
graphics.DrawString(L"Multiplayer", -1, &font, {75, 222}, &color);
|
||||||
|
|
||||||
|
Gdiplus::Pen pen(Gdiplus::Color(50, 255, 255, 255), 2);
|
||||||
|
graphics.DrawLine(&pen, 0, 200, 500, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void launcher::paint() const
|
||||||
|
{
|
||||||
|
RECT rect;
|
||||||
|
GetClientRect(this->window_, &rect);
|
||||||
|
const int width = rect.right - rect.left;
|
||||||
|
const int height = rect.bottom + rect.left;
|
||||||
|
|
||||||
|
PAINTSTRUCT ps;
|
||||||
|
const auto hdc = BeginPaint(this->window_, &ps);
|
||||||
|
|
||||||
|
const auto hdc_copy = CreateCompatibleDC(hdc);
|
||||||
|
const auto bitmap = CreateCompatibleBitmap(hdc, width, height);
|
||||||
|
SelectObject(hdc_copy, bitmap);
|
||||||
|
|
||||||
|
this->window_.clear(hdc_copy);
|
||||||
|
|
||||||
|
this->draw_text(hdc_copy);
|
||||||
|
|
||||||
|
this->image_sp_.paint(hdc_copy, this->mouse_);
|
||||||
|
this->image_mp_.paint(hdc_copy, this->mouse_);
|
||||||
|
|
||||||
|
BitBlt(hdc, 0, 0, width, height, hdc_copy, 0, 0, SRCCOPY);
|
||||||
|
|
||||||
|
DeleteObject(bitmap);
|
||||||
|
DeleteDC(hdc_copy);
|
||||||
|
|
||||||
|
EndPaint(this->window_, &ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
void launcher::mouse_move(LPARAM l_param)
|
||||||
|
{
|
||||||
|
this->mouse_.x = GET_X_LPARAM(l_param);
|
||||||
|
this->mouse_.y = GET_Y_LPARAM(l_param);
|
||||||
|
|
||||||
|
InvalidateRect(this->window_, nullptr, FALSE);
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,36 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "window.hpp"
|
#include "window.hpp"
|
||||||
|
#include "image.hpp"
|
||||||
|
|
||||||
class launcher
|
class launcher final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum mode
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
SINGLEPLAYER,
|
||||||
|
MULTIPLAYER,
|
||||||
|
};
|
||||||
|
|
||||||
launcher();
|
launcher();
|
||||||
|
|
||||||
void run() const;
|
mode run() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
mode mode_ = NONE;
|
||||||
|
|
||||||
window window_;
|
window window_;
|
||||||
|
|
||||||
|
image image_sp_;
|
||||||
|
image image_mp_;
|
||||||
|
|
||||||
|
POINT mouse_{};
|
||||||
|
|
||||||
|
LRESULT handler(const UINT message, const WPARAM w_param, const LPARAM l_param);
|
||||||
|
|
||||||
|
void select_mode(mode mode);
|
||||||
|
|
||||||
|
static void draw_text(const HDC hdc);
|
||||||
|
void paint() const;
|
||||||
|
void mouse_move(LPARAM l_param);
|
||||||
};
|
};
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "window.hpp"
|
#include "window.hpp"
|
||||||
|
|
||||||
window::window(const std::string& title, int width, int height)
|
window::window(const std::string& title, const int width, const int height)
|
||||||
{
|
{
|
||||||
|
Gdiplus::GdiplusStartupInput input;
|
||||||
|
GdiplusStartup(&this->token_, &input, nullptr);
|
||||||
|
|
||||||
const auto handle = GetModuleHandle(nullptr);
|
const auto handle = GetModuleHandle(nullptr);
|
||||||
|
|
||||||
ZeroMemory(&this->wc_, sizeof(this->wc_));
|
ZeroMemory(&this->wc_, sizeof(this->wc_));
|
||||||
@ -14,14 +17,15 @@ window::window(const std::string& title, int width, int height)
|
|||||||
this->wc_.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
this->wc_.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||||
this->wc_.hIcon = LoadIcon(handle, MAKEINTRESOURCE(102));
|
this->wc_.hIcon = LoadIcon(handle, MAKEINTRESOURCE(102));
|
||||||
this->wc_.hIconSm = this->wc_.hIcon;
|
this->wc_.hIconSm = this->wc_.hIcon;
|
||||||
this->wc_.hbrBackground = CreateSolidBrush(RGB(35, 35, 35));//HBRUSH(COLOR_WINDOW);
|
this->wc_.hbrBackground = CreateSolidBrush(RGB(35, 35, 35)); //HBRUSH(COLOR_WINDOW);
|
||||||
this->wc_.lpszClassName = L"omw3_window";
|
this->wc_.lpszClassName = L"omw3_window";
|
||||||
RegisterClassEx(&this->wc_);
|
RegisterClassEx(&this->wc_);
|
||||||
|
|
||||||
const auto x = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
|
const auto x = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
|
||||||
const auto y = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
|
const auto y = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
|
||||||
|
|
||||||
this->handle_ = CreateWindowExA(NULL, "omw3_window", title.data(), (WS_OVERLAPPEDWINDOW | WS_VISIBLE) & ~(WS_THICKFRAME | WS_MAXIMIZEBOX), x, y, width,
|
this->handle_ = CreateWindowExA(NULL, "omw3_window", title.data(),
|
||||||
|
(WS_OVERLAPPEDWINDOW | WS_VISIBLE) & ~(WS_THICKFRAME | WS_MAXIMIZEBOX), x, y, width,
|
||||||
height, nullptr, nullptr, handle, nullptr);
|
height, nullptr, nullptr, handle, nullptr);
|
||||||
|
|
||||||
SetWindowLongPtrA(*this, GWLP_USERDATA, LONG_PTR(this));
|
SetWindowLongPtrA(*this, GWLP_USERDATA, LONG_PTR(this));
|
||||||
@ -32,6 +36,8 @@ window::~window()
|
|||||||
this->close();
|
this->close();
|
||||||
UnregisterClass(this->wc_.lpszClassName, this->wc_.hInstance);
|
UnregisterClass(this->wc_.lpszClassName, this->wc_.hInstance);
|
||||||
DeleteObject(this->wc_.hbrBackground);
|
DeleteObject(this->wc_.hbrBackground);
|
||||||
|
|
||||||
|
Gdiplus::GdiplusShutdown(this->token_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window::close()
|
void window::close()
|
||||||
@ -59,7 +65,19 @@ void window::run() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK window::processor(UINT message, WPARAM w_param, LPARAM l_param) const
|
void window::clear(const HDC hdc) const
|
||||||
|
{
|
||||||
|
RECT rc;
|
||||||
|
GetClientRect(*this, &rc);
|
||||||
|
FillRect(hdc, &rc, this->wc_.hbrBackground);
|
||||||
|
}
|
||||||
|
|
||||||
|
void window::set_callback(const std::function<LRESULT(UINT, WPARAM, LPARAM)>& callback)
|
||||||
|
{
|
||||||
|
this->callback_ = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK window::processor(const UINT message, const WPARAM w_param, const LPARAM l_param) const
|
||||||
{
|
{
|
||||||
if (message == WM_KILL_WINDOW)
|
if (message == WM_KILL_WINDOW)
|
||||||
{
|
{
|
||||||
@ -67,13 +85,19 @@ LRESULT CALLBACK window::processor(UINT message, WPARAM w_param, LPARAM l_param)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->callback_)
|
||||||
|
{
|
||||||
|
return this->callback_(message, w_param, l_param);
|
||||||
|
}
|
||||||
|
|
||||||
return DefWindowProc(*this, message, w_param, l_param);
|
return DefWindowProc(*this, message, w_param, l_param);
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK window::static_processor(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param)
|
LRESULT CALLBACK window::static_processor(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param)
|
||||||
{
|
{
|
||||||
window* self = reinterpret_cast<window*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
const auto self = reinterpret_cast<window*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
||||||
if (self) return self->processor(message, w_param, l_param);
|
if (self) return self->processor(message, w_param, l_param);
|
||||||
|
|
||||||
return DefWindowProc(hwnd, message, w_param, l_param);
|
return DefWindowProc(hwnd, message, w_param, l_param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,11 +11,17 @@ public:
|
|||||||
void close();
|
void close();
|
||||||
void run() const;
|
void run() const;
|
||||||
|
|
||||||
|
void clear(const HDC hdc) const;
|
||||||
|
|
||||||
|
void set_callback(const std::function<LRESULT(UINT, WPARAM, LPARAM)>& callback);
|
||||||
|
|
||||||
operator HWND() const;
|
operator HWND() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ULONG_PTR token_;
|
||||||
WNDCLASSEX wc_{};
|
WNDCLASSEX wc_{};
|
||||||
HWND handle_ = nullptr;
|
HWND handle_ = nullptr;
|
||||||
|
std::function<LRESULT(UINT, WPARAM, LPARAM)> callback_;
|
||||||
|
|
||||||
LRESULT CALLBACK processor(UINT message, WPARAM w_param, LPARAM l_param) const;
|
LRESULT CALLBACK processor(UINT message, WPARAM w_param, LPARAM l_param) const;
|
||||||
static LRESULT CALLBACK static_processor(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param);
|
static LRESULT CALLBACK static_processor(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param);
|
||||||
|
17
src/main.cpp
17
src/main.cpp
@ -4,5 +4,20 @@
|
|||||||
int CALLBACK WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nCmdShow*/)
|
int CALLBACK WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nCmdShow*/)
|
||||||
{
|
{
|
||||||
launcher launcher;
|
launcher launcher;
|
||||||
launcher.run();
|
const auto mode = launcher.run();
|
||||||
|
|
||||||
|
if(mode == launcher::mode::NONE)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if(mode == launcher::mode::SINGLEPLAYER)
|
||||||
|
{
|
||||||
|
OutputDebugStringA("\n\nSINGLEPLAYER\n\n");
|
||||||
|
}
|
||||||
|
else if(mode == launcher::mode::MULTIPLAYER)
|
||||||
|
{
|
||||||
|
OutputDebugStringA("\n\nMULTIPLAYER\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
4
src/resource.hpp
Normal file
4
src/resource.hpp
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define IMAGE_SP 300
|
||||||
|
#define IMAGE_MP 301
|
@ -8,6 +8,7 @@
|
|||||||
// Generated from the TEXTINCLUDE 2 resource.
|
// Generated from the TEXTINCLUDE 2 resource.
|
||||||
//
|
//
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
|
#include "resource.hpp"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
@ -80,6 +81,15 @@ BEGIN
|
|||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Binary Data
|
||||||
|
//
|
||||||
|
|
||||||
|
IMAGE_SP BITMAP "resources/singleplayer.bmp"
|
||||||
|
IMAGE_MP BITMAP "resources/multiplayer.bmp"
|
||||||
|
|
||||||
|
|
||||||
#endif // English (United States) resources
|
#endif // English (United States) resources
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
BIN
src/resources/multiplayer.bmp
Normal file
BIN
src/resources/multiplayer.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 169 KiB |
BIN
src/resources/singleplayer.bmp
Normal file
BIN
src/resources/singleplayer.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 169 KiB |
@ -1,16 +1,28 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4458)
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <Windowsx.h>
|
||||||
|
#include <objidl.h>
|
||||||
|
#include <gdiplus.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
|
#pragma comment (lib, "gdiplus.lib")
|
||||||
|
|
||||||
#pragma warning(disable: 4100)
|
#pragma warning(disable: 4100)
|
||||||
|
|
||||||
|
#include "resource.hpp"
|
||||||
|
|
||||||
#include "steam/steam.hpp"
|
#include "steam/steam.hpp"
|
||||||
|
Loading…
Reference in New Issue
Block a user