This commit is contained in:
EmsiaetKadosh
2025-02-05 15:13:02 +08:00
parent edcc095979
commit a086558f2d
19 changed files with 388 additions and 56 deletions
+2 -1
View File
@@ -36,7 +36,8 @@ add_executable(${PROJECT_NAME} main.cpp
def.cpp def.cpp
TestCode.h TestCode.h
TextureManager.cpp TextureManager.cpp
TextureManager.h) TextureManager.h
exception.cpp)
set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack) include(CPack)
+48 -11
View File
@@ -15,10 +15,10 @@
ret += *string - L'0'; ret += *string - L'0';
} else if (*string >= L'A' && *string <= L'F') { } else if (*string >= L'A' && *string <= L'F') {
ret <<= 4; ret <<= 4;
ret += *string - 0x41; // L'A' - 10 ret += *string - 0x41;// 'A' - 10
} else if (*string >= L'a' && *string <= L'f') { } else if (*string >= L'a' && *string <= L'f') {
ret <<= 4; ret <<= 4;
ret += *string - 0x61; // L'a' - 10 ret += *string - 0x61;// 'a' - 10
} else return 0xffffffff; } else return 0xffffffff;
++string; ++string;
} }
@@ -35,16 +35,17 @@
ret += string[i] - L'0'; ret += string[i] - L'0';
} else if (string[i] >= L'A' && string[i] <= L'F') { } else if (string[i] >= L'A' && string[i] <= L'F') {
ret <<= 4; ret <<= 4;
ret += string[i] - 0x41; // L'A' - 10 ret += string[i] - 0x41;// L'A' - 10
} else if (string[i] >= L'a' && string[i] <= L'f') { } else if (string[i] >= L'a' && string[i] <= L'f') {
ret <<= 4; ret <<= 4;
ret += string[i] - 0x61; // L'a' - 10 ret += string[i] - 0x61;// L'a' - 10
} else return 0xffffffff; } else return 0xffffffff;
++i; ++i;
} }
return ret; return ret;
} }
static constexpr wchar Table16[17] = L"0123456789ABCDEF";
/** /**
* 将数字转换为字符串 * 将数字转换为字符串
* @param value 要转换的数字 * @param value 要转换的数字
@@ -52,20 +53,56 @@
* @return String类型 * @return String类型
*/ */
[[nodiscard]] inline String uitowb16(unsigned int value, const unsigned int fills = 1) noexcept { [[nodiscard]] inline String uitowb16(unsigned int value, const unsigned int fills = 1) noexcept {
static constexpr const wchar* const table = L"0123456789ABCDEF";
String ret; String ret;
if (value < static_cast<unsigned int>(1) << fills - 1) { if (value < static_cast<unsigned int>(1) << fills - 1) {
ret.assign(fills, L'0'); ret.assign(fills, L'0');
for (unsigned int i = fills - 1; i != 0; --i) { for (unsigned int i = fills - 1; i != 0 && value; --i) {
ret[i] = table[value & 0xf]; ret[i] = Table16[value & 0xf];
value >>= 4; value >>= 4;
} }
} else {
unsigned int i = 0;
while (i < 8) {
if ((value >> i) & 0xf) break;
++i;
} }
else { while (i < 8) {
while (value) { ret.push_back(Table16[(value >> i) & 0xf]);
ret.push_back(table[value & 0xf]); ++i;
value >>= 4;
} }
if (ret.empty()) ret = L"0";
}
return ret;
}
static constexpr wchar Table10[11] = L"0123456789";
static constexpr QWORD Compare10[20] = {
0, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
100000000, 1000000000, 10000000000, 100000000000,
1000000000000, 10000000000000, 100000000000000,
1000000000000000, 10000000000000000, 100000000000000000,
1000000000000000000, 10000000000000000000
};
[[nodiscard]] inline String qwtowb10(QWORD value, const unsigned int fills = 1) noexcept {
String ret;
if (value < Compare10[fills]) {
ret.assign(fills, L'0');
for (unsigned int i = fills - 1; i != 0 && value; --i) {
ret[i] = Table10[value % 10];
value /= 10;
}
} else {
unsigned int i = 0;
while (i < 19) {
if (value >= Compare10[i]) break;
++i;
}
while (i < 19) {
ret.push_back(Table10[value / Compare10[i]]);
value %= Compare10[i];
++i;
}
if (ret.empty()) ret = L"0";
} }
return ret; return ret;
} }
+6
View File
@@ -4,5 +4,11 @@
#include "Game.h" #include "Game.h"
void Game::initialize() noexcept { renderer.setGame(game); } void Game::initialize() noexcept { renderer.setGame(game); }
Game::Game() : floatWindow{ new FloatWindow() } { Logger.put(L"Game created"); }
Game::~Game() { delete floatWindow; }
inline Game game = Game();
+19 -4
View File
@@ -8,15 +8,22 @@
#include "Window.h" #include "Window.h"
class Game : public IRenderable { class Game : public IRenderable {
friend void gameThread();
Hud hud = Hud(); Hud hud = Hud();
Window* window = nullptr; Window* window = nullptr;
FloatWindow* floatWindow;
QWORD currentTick = 0;
public: public:
explicit Game() = default; explicit Game();
~Game() override;
static void initialize() noexcept; static void initialize() noexcept;
void render() const noexcept override { void render() const noexcept override {
if (window) window->render(); renderer.gameStartRender();
hud.render(); hud.render();
if (window) window->render();
if (floatWindow) floatWindow->render();
renderer.gameEndRender();
} }
int setWindow(Window* window) noexcept { int setWindow(Window* window) noexcept {
@@ -31,6 +38,14 @@ public:
} }
[[nodiscard]] Window* getWindow() const noexcept { return window; } [[nodiscard]] Window* getWindow() const noexcept { return window; }
[[nodiscard]] QWORD getTick() const noexcept { return currentTick; }
void tick() noexcept {
++currentTick;
hud.tick();
if (window) window->tick();
if (floatWindow) floatWindow->tick();
}
}; };
inline static Game game = Game(); extern Game game;
+1
View File
@@ -5,3 +5,4 @@
#include "Hud.h" #include "Hud.h"
void Hud::render() const noexcept {} void Hud::render() const noexcept {}
void Hud::tick() noexcept {}
+2 -1
View File
@@ -5,8 +5,9 @@
#pragma once #pragma once
#include "Renderer.h" #include "Renderer.h"
class Hud : public IRenderable { class Hud final : public IRenderable, public ITickable {
public: public:
void render() const noexcept override; void render() const noexcept override;
void tick() noexcept override;
}; };
+19 -1
View File
@@ -21,7 +21,25 @@ struct KeyStatus {
pressTimes = 0; pressTimes = 0;
} }
[[nodiscard]] String toString() const noexcept { return L"KeyStatus: { name = \"" + name + L"\"; pressTimes = " + std::to_wstring(pressTimes) + L"; pressed = " + (pressed ? L"true }" : L"false }"); } [[nodiscard]] String toString() const noexcept { return L"KeyStatus: { name = \"" + name + L"\"; pressTimes = " + std::to_wstring(pressTimes) + L"; pressed = " + (pressed ? L"true; }" : L"false; }"); }
};
struct MouseStatus {
String name;
unsigned int pressTimes = 0;
bool pressed = false;
bool notDealt = false;
bool longHold = false;
[[nodiscard]] bool isPressed() const noexcept { return pressed; }
[[nodiscard]] unsigned int wasPressed() const noexcept { return pressTimes; }
void deals() noexcept {
notDealt = false;
pressTimes = 0;
}
[[nodiscard]] String toString() const noexcept { return L"MouseStatus: { name = \""+ name + L"\"; pressTimes = " + std::to_wstring(pressTimes) + L"; pressed = " + (pressed ? L"true, longHold = " : L"false, longHold = ") + (longHold ? L"true; }" : L"false; }") ; }
}; };
struct KeyBinding; struct KeyBinding;
+6 -1
View File
@@ -7,7 +7,10 @@
#include "Game.h" #include "Game.h"
#include "hbp.h" #include "hbp.h"
void Renderer::initialize() noexcept { MainDC = GetDC(MainWindowHandle); } void Renderer::initialize() noexcept {
MainDC = GetDC(MainWindowHandle);
assistDC = CreateCompatibleDC(MainDC);
}
void Renderer::resize(const int width, const int height) noexcept(false) { void Renderer::resize(const int width, const int height) noexcept(false) {
windowWidth = width; windowWidth = width;
@@ -19,3 +22,5 @@ void Renderer::resize(const int width, const int height) noexcept(false) {
} }
if (game.getWindow()) game.getWindow()->onResize(); if (game.getWindow()) game.getWindow()->onResize();
} }
inline Renderer renderer = Renderer();
+68 -3
View File
@@ -4,7 +4,10 @@
#pragma once #pragma once
#include <thread>
#include "def.h" #include "def.h"
#include "exception.h"
class Game; class Game;
/** /**
@@ -22,18 +25,50 @@ interface ITickable {
virtual void tick() noexcept = 0; virtual void tick() noexcept = 0;
}; };
class Renderer : public ITickable { struct Color {
unsigned int inactive = 0xff777777;
unsigned int active = 0xff000000;
unsigned int hover = 0xff444444;
unsigned int clicked = 0xffeeeeee;
};
inline static constexpr Color TextColor = {
.inactive = 0xff333333,
.active = 0xffeeeeee,
.hover = 0xffeeeeee,
.clicked = 0xff000000
};
class Renderer final : public ITickable {
/** /**
* 后续可能用不到,可能可删 * 后续可能用不到,可能可删
*/ */
Game* pGame = nullptr; Game* pGame = nullptr;
friend class Game;
inline static HDC MainDC; inline static HDC MainDC;
inline static HDC assistDC;
inline static BLENDFUNCTION blendFunction = {
.BlendOp = AC_SRC_OVER,// Only
.BlendFlags = 0,// Must 0
.SourceConstantAlpha = 255,// 预乘
.AlphaFormat = AC_SRC_ALPHA,// Only
};
std::thread::id renderThread = std::this_thread::get_id();
int windowWidth = 0, windowHeight = 0; int windowWidth = 0, windowHeight = 0;
int resizeTime = 0; int resizeTime = 0;
bool isRendering = false;
void gameStartRender() noexcept {
isRendering = true;
renderThread = std::this_thread::get_id();
}
void gameEndRender() noexcept { isRendering = false; }
public: public:
static void initialize() noexcept; static void initialize() noexcept;
explicit Renderer() = default; explicit Renderer() { Logger.put(L"Renderer created"); }
void resize(int width, int height) noexcept(false); void resize(int width, int height) noexcept(false);
void setGame(Game& game) noexcept { pGame = &game; } void setGame(Game& game) noexcept { pGame = &game; }
[[nodiscard]] int getWidth() const noexcept { return windowWidth; } [[nodiscard]] int getWidth() const noexcept { return windowWidth; }
@@ -47,6 +82,36 @@ public:
resizeTime = -1; resizeTime = -1;
} }
} }
/**
* @attention 会忽略A透明度值
* @param argb ARGB式颜色
* @return int BGR式颜色
*/
[[nodiscard]] static unsigned int changeColorFormat(const unsigned int argb) { return (argb & 0xff) << 16 | (argb & 0xff00) | (argb & 0xff0000) >> 16; }
void assertRendering() const noexcept(false) { if (!isRendering) throw InvalidOperationException(L"Operation should be done while rendering"); }
void assertRenderThread() const noexcept(false) { if (std::this_thread::get_id() != renderThread) throw InvalidOperationException(L"Operation should be done in render thread"); }
void fill(const int x, const int y, const int w, const int h, const unsigned int color) const {
assertRendering();
//assertRenderThread();
if (color & 0xff000000 == 0) return;
const RECT rect{
.left = x,
.top = y,
.right = x + w,
.bottom = y + h
};
HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
if ((color & 0xff000000) == 0xff000000) FillRect(MainDC, &rect, clr);
else {
FillRect(assistDC, &rect, clr);
AlphaBlend(MainDC, x, y, w, h, assistDC, x, y, w, h, blendFunction);
}
DeleteObject(clr);
}
}; };
inline static Renderer renderer = Renderer(); extern Renderer renderer;
-16
View File
@@ -4,21 +4,5 @@
#pragma once #pragma once
struct B {
int a = 1;
B() { std::wcout << L"common constructor\n"; }
B(B&) { std::wcout << L"copy constructor\n"; }
// B(B&& other) noexcept { std::wcout << L"move constructor\n"; }
};
struct A {
B b;
explicit A(B&& other) : b(other) {}
};
inline void test() { inline void test() {
B b;
A a{ B() };
a = A(std::move(a.b));
} }
+7 -5
View File
@@ -62,19 +62,21 @@ class TextureManager {
Font* defaultFont = nullptr; Font* defaultFont = nullptr;
using IterFont = Map<int, Font>::const_iterator; using IterFont = Map<int, Font>::const_iterator;
using IterTexture = Map<String, ObjectHolder<ITexture>>::const_iterator; using IterTexture = Map<String, ObjectHolder<ITexture>>::const_iterator;
public: public:
TextureManager() { TextureManager() {
try { try {
fonts.insert(std::make_pair(0, Font(L"Arial"))); fonts.insert(std::make_pair(0, Font(L"Arial")));
defaultFont = &fonts.at(0); defaultFont = &fonts.at(0);
} } catch (const std::out_of_range& e) {
catch (...) {
} catch (const ArrayIndexOutOfBoundException& e){}
} }
}
Font& getFont(const int id) const noexcept { const Font& getFont(const int id) const noexcept {
IterFont iterator = fonts.find(id); IterFont iterator = fonts.find(id);
if (iterator == fonts.cend()) return if (iterator == fonts.cend()) return *defaultFont;
return iterator->second;
} }
}; };
+8
View File
@@ -3,3 +3,11 @@
// //
#include "Window.h" #include "Window.h"
void Window::render() const noexcept {}
void Window::tick() noexcept {}
void Window::onResize() {}
void FloatWindow::render() const noexcept {
renderer.fill(20, 20, 40, 40, 0xffeeeeee);
}
void Button::render() const noexcept {}
+26 -8
View File
@@ -12,13 +12,11 @@ enum class MouseActionCode : char {
MAC_MOVE, MAC_HOVER, MAC_DOWN, MAC_UP, MAC_DOUBLE MAC_MOVE, MAC_HOVER, MAC_DOWN, MAC_UP, MAC_DOUBLE
}; };
class Widget : public IRenderable { class Widget : public IRenderable, public ITickable {
protected: protected:
int left = 0, top = 0, width = 0, height = 0; int left = 0, top = 0, width = 0, height = 0;
mutable bool hasMouse = false;
public: public:
Location location;
using Action = Function<void(int)>; using Action = Function<void(int)>;
double x, y, w, h; double x, y, w, h;
Action hover;// 传入int忽略 Action hover;// 传入int忽略
@@ -27,8 +25,24 @@ public:
Action mouseUp;// 传入int表示变更按键。0左, 1中, 2右 Action mouseUp;// 传入int表示变更按键。0左, 1中, 2右
Action mouseLeave;// 传入int忽略 Action mouseLeave;// 传入int忽略
Action mouseClick;// 传入int表示变更按键。0x0左, 0x1中, 0x2右;0xf表示是否双击 Action mouseClick;// 传入int表示变更按键。0x0左, 0x1中, 0x2右;0xf表示是否双击
Color backgroundColor;
Color foregroundColor;
protected:
mutable bool hasMouse = false;
public:
Location location;
protected:
char unused[6] {};
public:
unsigned int colorSelector(const Color& clr, const Widget& widget) const {
return hasMouse ? clr.hover : clr.inactive;
}
explicit Widget(const double x, const double y, const double w, const double h, Location location) : x(x), y(y), w(w), h(h), location(location) {} explicit Widget(const double x, const double y, const double w, const double h, Location location) : x(x), y(y), w(w), h(h), location(location) {}
void render() const noexcept override {}
virtual void onResize() {} virtual void onResize() {}
virtual bool isMouseIn(int x, int y) noexcept { virtual bool isMouseIn(int x, int y) noexcept {
@@ -44,7 +58,7 @@ public:
virtual void onMouseLeave(const int value) noexcept { if (mouseLeave) mouseLeave(value); } virtual void onMouseLeave(const int value) noexcept { if (mouseLeave) mouseLeave(value); }
virtual void onMouseClick(const int value) noexcept { if (mouseClick) mouseClick(value); } virtual void onMouseClick(const int value) noexcept { if (mouseClick) mouseClick(value); }
virtual void passEvent(int action, int value, int x, int y) noexcept { virtual void passEvent(const int action, const int value, const int x, const int y) noexcept {
if (!isMouseIn(x, y)) { if (!isMouseIn(x, y)) {
if (hasMouse) onMouseLeave(0); if (hasMouse) onMouseLeave(0);
hasMouse = false; hasMouse = false;
@@ -72,7 +86,7 @@ public:
} }
}; };
class Window : public IRenderable { class Window : public IRenderable, public ITickable {
protected: protected:
List<Widget*> widgets; List<Widget*> widgets;
@@ -81,6 +95,8 @@ protected:
~Window() override { for (Widget*& widget : widgets) { delete widget; } } ~Window() override { for (Widget*& widget : widgets) { delete widget; } }
public: public:
void render() const noexcept override;
void tick() noexcept override;
/** /**
* 在Game.setWindow()时,本窗口开启时调用。 * 在Game.setWindow()时,本窗口开启时调用。
* 不应当外部调用。 * 不应当外部调用。
@@ -104,8 +120,10 @@ public:
void onClose() override {} void onClose() override {}
}; };
class Button final : public Widget { class Button : public Widget {
public: public:
ObjectHolder<IText> name; ObjectHolder<IText> name;
explicit Button(const double x, const double y, const double w, const double h, Location location, ObjectHolder<IText> text) : Widget(x, y, w, h, location), name(text) {} explicit Button(const double x, const double y, const double w, const double h, const Location location, const ObjectHolder<IText>& text) : Widget(x, y, w, h, location), name(text) {}
void render() const noexcept override;
void tick() noexcept override {}
}; };
+3
View File
@@ -10,10 +10,12 @@
#include <string> #include <string>
#include <map> #include <map>
#include <atomic> #include <atomic>
#include <thread>
using wchar = wchar_t; using wchar = wchar_t;
using QWORD = unsigned long long int; using QWORD = unsigned long long int;
using String = std::wstring; using String = std::wstring;
using Thread = std::thread;
template<typename K, typename V, typename Cmp = std::less<K>, typename Alloc = std::allocator<std::pair<const K, V>>> using Map = std::map<K, V, Cmp, Alloc>; template<typename K, typename V, typename Cmp = std::less<K>, typename Alloc = std::allocator<std::pair<const K, V>>> using Map = std::map<K, V, Cmp, Alloc>;
template<typename T, typename Alloc = std::allocator<T>> using List = std::list<T, Alloc>; template<typename T, typename Alloc = std::allocator<T>> using List = std::list<T, Alloc>;
template<typename F> using Function = std::function<F>; template<typename F> using Function = std::function<F>;
@@ -48,6 +50,7 @@ template<typename F> using Function = std::function<F>;
#include <iostream> #include <iostream>
#include <dwmapi.h> #include <dwmapi.h>
#pragma comment(lib, "Msimg32.lib")
#pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "dwmapi.lib") #pragma comment(lib, "dwmapi.lib")
#pragma comment(lib, "Uxtheme.lib") #pragma comment(lib, "Uxtheme.lib")
+71
View File
@@ -0,0 +1,71 @@
//
// Created by EmsiaetKadosh on 25-1-22.
//
#pragma once
#include "def.h"
#include "exception.h"
#include "Game.h"
ILogger& PublicLogger::trace(const String& msg) noexcept {
std::wcout << L"T-" + qwtowb10(game.getTick(), 8) + L" [Trace] " + msg + L"\n";
return *this;
}
ILogger& PublicLogger::trace(String&& msg) noexcept {
std::wcout << L"T-" + qwtowb10(game.getTick(), 8) + L" [Trace] " + msg + L"\n";
return *this;
}
ILogger& PublicLogger::debug(const String& msg) noexcept {
std::wcout << L"T-" + qwtowb10(game.getTick(), 8) + L" [Debug] " + msg + L"\n";
return *this;
}
ILogger& PublicLogger::debug(String&& msg) noexcept {
std::wcout << L"T-" + qwtowb10(game.getTick(), 8) + L" [Debug] " + msg + L"\n";
return *this;
}
ILogger& PublicLogger::log(const String& msg) noexcept {
std::wcout << L"T-" + qwtowb10(game.getTick(), 8) + L" [Log] " + msg + L"\n";
return *this;
}
ILogger& PublicLogger::log(String&& msg) noexcept {
std::wcout << L"T-" + qwtowb10(game.getTick(), 8) + L" [Log] " + msg + L"\n";
return *this;
}
ILogger& PublicLogger::info(const String& msg) noexcept {
std::wcout << L"T-" + qwtowb10(game.getTick(), 8) + L" [Info] " + msg + L"\n";
return *this;
}
ILogger& PublicLogger::info(String&& msg) noexcept {
std::wcout << L"T-" + qwtowb10(game.getTick(), 8) + L" [Info] " + msg + L"\n";
return *this;
}
ILogger& PublicLogger::warn(const String& msg) noexcept {
std::wcout << L"T-" + qwtowb10(game.getTick(), 8) + L" [Warn] " + msg + L"\n";
return *this;
}
ILogger& PublicLogger::warn(String&& msg) noexcept {
std::wcout << L"T-" + qwtowb10(game.getTick(), 8) + L" [Warn] " + msg + L"\n";
return *this;
}
ILogger& PublicLogger::error(const String& msg) noexcept {
std::wcout << L"T-" + qwtowb10(game.getTick(), 8) + L" [Error] " + msg + L"\n";
return *this;
}
ILogger& PublicLogger::error(String&& msg) noexcept {
std::wcout << L"T-" + qwtowb10(game.getTick(), 8) + L" [Error] " + msg + L"\n";
return *this;
}
inline PublicLogger Logger{};
+55 -1
View File
@@ -16,7 +16,7 @@ protected:
public: public:
[[nodiscard]] String getMessage() const noexcept { return msg; } [[nodiscard]] String getMessage() const noexcept { return msg; }
[[nodiscard]] const String* getType() const noexcept { return type; } [[nodiscard]] const String* getType() const noexcept { return type; }
[[nodiscard]] const char* what() const override { return "Use Exception::getMessage() instead.";} [[nodiscard]] const char* what() const override { return "Use Exception::getMessage() instead."; }
}; };
class NullPointerException final : public Exception { class NullPointerException final : public Exception {
@@ -34,3 +34,57 @@ public:
explicit ArrayIndexOutOfBoundException(String&& msg) : Exception(std::move(msg), &type) {} explicit ArrayIndexOutOfBoundException(String&& msg) : Exception(std::move(msg), &type) {}
explicit ArrayIndexOutOfBoundException(const String& msg) : Exception(msg, &type) {} explicit ArrayIndexOutOfBoundException(const String& msg) : Exception(msg, &type) {}
}; };
class InvalidOperationException final : public Exception {
inline static const String type = L"InvalidOperationException";
public:
explicit InvalidOperationException(String&& msg) : Exception(std::move(msg), &type) {}
explicit InvalidOperationException(const String& msg) : Exception(msg, &type) {}
};
interface ILogger {
virtual ~ILogger() = default;
virtual ILogger& trace(const String&) noexcept = 0;
virtual ILogger& trace(String&&) noexcept = 0;
virtual ILogger& debug(const String&) noexcept = 0;
virtual ILogger& debug(String&&) noexcept = 0;
virtual ILogger& log(const String&) noexcept = 0;
virtual ILogger& log(String&&) noexcept = 0;
virtual ILogger& info(const String&) noexcept = 0;
virtual ILogger& info(String&&) noexcept = 0;
virtual ILogger& warn(const String&) noexcept = 0;
virtual ILogger& warn(String&&) noexcept = 0;
virtual ILogger& error(const String&) noexcept = 0;
virtual ILogger& error(String&&) noexcept = 0;
};
struct PublicLogger final : ILogger {
PublicLogger() { std::wcout << L"PublicLogger created\n"; }
PublicLogger& put(const String& msg) noexcept {
std::wcout << L"[] [Root] " + msg + L"\n";
return * this;
}
PublicLogger& put(String&& msg) noexcept {
std::wcout << L"[] [Root] " + msg + L"\n";
return *this;
}
ILogger& trace(const String&) noexcept override;
ILogger& trace(String&&) noexcept override;
ILogger& debug(const String&) noexcept override;
ILogger& debug(String&&) noexcept override;
ILogger& log(const String&) noexcept override;
ILogger& log(String&&) noexcept override;
ILogger& info(const String&) noexcept override;
ILogger& info(String&&) noexcept override;
ILogger& warn(const String&) noexcept override;
ILogger& warn(String&&) noexcept override;
ILogger& error(const String&) noexcept override;
ILogger& error(String&&) noexcept override;
};
extern PublicLogger Logger;
+5 -1
View File
@@ -14,14 +14,18 @@ inline BOOL NewProcess(const String& cmdline) noexcept {
inline HRESULT RemoveDefaultCaption(HWND hWnd, const MARGINS* p) noexcept { return DwmExtendFrameIntoClientArea(hWnd, p); } inline HRESULT RemoveDefaultCaption(HWND hWnd, const MARGINS* p) noexcept { return DwmExtendFrameIntoClientArea(hWnd, p); }
inline void ShowConsoleIO() noexcept { inline bool ShowConsoleIO() noexcept {
AllocConsole(); AllocConsole();
FILE* pCout; FILE* pCout;
freopen_s(&pCout, "CONOUT$", "w", stdout); freopen_s(&pCout, "CONOUT$", "w", stdout);
FILE* pCin; FILE* pCin;
freopen_s(&pCin, "CONIN$", "r", stdin); freopen_s(&pCin, "CONIN$", "r", stdin);
return true;
} }
inline const String ApplicationName = L"Hyblud Presher"; inline const String ApplicationName = L"Hyblud Presher";
inline HINSTANCE MainInstance; inline HINSTANCE MainInstance;
inline HWND MainWindowHandle; inline HWND MainWindowHandle;
inline Thread GameThread;
inline Thread RenderThread;
inline static bool isRunning = ShowConsoleIO();
+2
View File
@@ -7,9 +7,11 @@
#include "def.h" #include "def.h"
#include "exception.h" #include "exception.h"
#include "hbp.h" #include "hbp.h"
#include "Chars.h"
#include "Renderer.h" #include "Renderer.h"
#include "InteractManager.h" #include "InteractManager.h"
#include "TextureManager.h" #include "TextureManager.h"
#include "IText.h"
#include "Hud.h" #include "Hud.h"
#include "Window.h" #include "Window.h"
+39 -2
View File
@@ -26,7 +26,7 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (renderer.getWidth() - xPos < 30) { if (renderer.getWidth() - xPos < 30) {
if (yPos < 30) return HTTOPRIGHT; if (yPos < 30) return HTTOPRIGHT;
if (renderer.getHeight() - yPos < 30) return HTBOTTOMRIGHT; if (renderer.getHeight() - yPos < 30) return HTBOTTOMRIGHT;
return HTBOTTOM; return HTRIGHT;
} }
if (yPos < 30) return HTTOP; if (yPos < 30) return HTTOP;
if (renderer.getHeight() - yPos < 30) return HTBOTTOM; if (renderer.getHeight() - yPos < 30) return HTBOTTOM;
@@ -128,6 +128,7 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
_UNLIKELY _UNLIKELY
case WM_DESTROY: case WM_DESTROY:
PostQuitMessage(0); PostQuitMessage(0);
isRunning = false;
return 0; return 0;
_UNLIKELY _UNLIKELY
case WM_CREATE: case WM_CREATE:
@@ -139,8 +140,39 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
return DefWindowProc(hwnd, uMsg, wParam, lParam); return DefWindowProc(hwnd, uMsg, wParam, lParam);
} }
void gameThread() {
using namespace std::chrono;
using Time = time_point<system_clock>;
Time lastTick = system_clock::now();
Time thisTime;
while (isRunning) {
thisTime = system_clock::now();
if (thisTime - lastTick < milliseconds(45)) {
Sleep(1);
continue;
}
game.tick();
lastTick = thisTime;
}
}
void renderThread() {
using namespace std::chrono;
using Time = time_point<system_clock>;
Time lastRender = system_clock::now();
Time thisTime;
while (isRunning) {
thisTime = system_clock::now();
if (thisTime - lastRender < milliseconds(12)) {
Sleep(1);
continue;
}
game.render();
lastRender = thisTime;
}
}
int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) {
ShowConsoleIO();
WNDCLASSEX wc = {}; WNDCLASSEX wc = {};
wc.cbSize = sizeof(WNDCLASSEX); wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW; wc.style = CS_HREDRAW | CS_VREDRAW;
@@ -175,6 +207,8 @@ int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCm
} }
HACCEL hAccelTable = LoadAcceleratorsW(hInstance, MAKEINTRESOURCE(109)); HACCEL hAccelTable = LoadAcceleratorsW(hInstance, MAKEINTRESOURCE(109));
MSG msg = { nullptr }; MSG msg = { nullptr };
GameThread = Thread(gameThread);
RenderThread = Thread(renderThread);
while (GetMessageW(&msg, nullptr, 0, 0)) { while (GetMessageW(&msg, nullptr, 0, 0)) {
if (!TranslateAcceleratorW(msg.hwnd, hAccelTable, &msg)) { if (!TranslateAcceleratorW(msg.hwnd, hAccelTable, &msg)) {
TranslateMessage(&msg); TranslateMessage(&msg);
@@ -182,5 +216,8 @@ int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCm
} }
} }
DestroyAcceleratorTable(hAccelTable); DestroyAcceleratorTable(hAccelTable);
if (GameThread.joinable()) GameThread.join();
if (RenderThread.joinable()) RenderThread.join();
_wsystem(L"pause");
return (int) msg.wParam; return (int) msg.wParam;
} }