Changes
This commit is contained in:
+2
-1
@@ -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)
|
||||||
|
|||||||
@@ -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 {
|
||||||
else {
|
unsigned int i = 0;
|
||||||
while (value) {
|
while (i < 8) {
|
||||||
ret.push_back(table[value & 0xf]);
|
if ((value >> i) & 0xf) break;
|
||||||
value >>= 4;
|
++i;
|
||||||
}
|
}
|
||||||
|
while (i < 8) {
|
||||||
|
ret.push_back(Table16[(value >> i) & 0xf]);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -5,3 +5,4 @@
|
|||||||
#include "Hud.h"
|
#include "Hud.h"
|
||||||
|
|
||||||
void Hud::render() const noexcept {}
|
void Hud::render() const noexcept {}
|
||||||
|
void Hud::tick() noexcept {}
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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 {}
|
||||||
|
|||||||
@@ -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 {}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user