Changes
This commit is contained in:
+2
-1
@@ -36,7 +36,8 @@ add_executable(${PROJECT_NAME} main.cpp
|
||||
def.cpp
|
||||
TestCode.h
|
||||
TextureManager.cpp
|
||||
TextureManager.h)
|
||||
TextureManager.h
|
||||
exception.cpp)
|
||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
||||
include(CPack)
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
ret += *string - L'0';
|
||||
} else if (*string >= L'A' && *string <= L'F') {
|
||||
ret <<= 4;
|
||||
ret += *string - 0x41; // L'A' - 10
|
||||
ret += *string - 0x41;// 'A' - 10
|
||||
} else if (*string >= L'a' && *string <= L'f') {
|
||||
ret <<= 4;
|
||||
ret += *string - 0x61; // L'a' - 10
|
||||
ret += *string - 0x61;// 'a' - 10
|
||||
} else return 0xffffffff;
|
||||
++string;
|
||||
}
|
||||
@@ -35,16 +35,17 @@
|
||||
ret += string[i] - L'0';
|
||||
} else if (string[i] >= L'A' && string[i] <= L'F') {
|
||||
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') {
|
||||
ret <<= 4;
|
||||
ret += string[i] - 0x61; // L'a' - 10
|
||||
ret += string[i] - 0x61;// L'a' - 10
|
||||
} else return 0xffffffff;
|
||||
++i;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static constexpr wchar Table16[17] = L"0123456789ABCDEF";
|
||||
/**
|
||||
* 将数字转换为字符串
|
||||
* @param value 要转换的数字
|
||||
@@ -52,20 +53,56 @@
|
||||
* @return String类型
|
||||
*/
|
||||
[[nodiscard]] inline String uitowb16(unsigned int value, const unsigned int fills = 1) noexcept {
|
||||
static constexpr const wchar* const table = L"0123456789ABCDEF";
|
||||
String ret;
|
||||
if (value < static_cast<unsigned int>(1) << fills - 1) {
|
||||
ret.assign(fills, L'0');
|
||||
for (unsigned int i = fills - 1; i != 0; --i) {
|
||||
ret[i] = table[value & 0xf];
|
||||
for (unsigned int i = fills - 1; i != 0 && value; --i) {
|
||||
ret[i] = Table16[value & 0xf];
|
||||
value >>= 4;
|
||||
}
|
||||
} else {
|
||||
unsigned int i = 0;
|
||||
while (i < 8) {
|
||||
if ((value >> i) & 0xf) break;
|
||||
++i;
|
||||
}
|
||||
else {
|
||||
while (value) {
|
||||
ret.push_back(table[value & 0xf]);
|
||||
value >>= 4;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -4,5 +4,11 @@
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
|
||||
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"
|
||||
|
||||
class Game : public IRenderable {
|
||||
friend void gameThread();
|
||||
Hud hud = Hud();
|
||||
Window* window = nullptr;
|
||||
|
||||
FloatWindow* floatWindow;
|
||||
QWORD currentTick = 0;
|
||||
public:
|
||||
explicit Game() = default;
|
||||
explicit Game();
|
||||
~Game() override;
|
||||
static void initialize() noexcept;
|
||||
|
||||
void render() const noexcept override {
|
||||
if (window) window->render();
|
||||
renderer.gameStartRender();
|
||||
hud.render();
|
||||
if (window) window->render();
|
||||
if (floatWindow) floatWindow->render();
|
||||
renderer.gameEndRender();
|
||||
}
|
||||
|
||||
int setWindow(Window* window) noexcept {
|
||||
@@ -31,6 +38,14 @@ public:
|
||||
}
|
||||
|
||||
[[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"
|
||||
|
||||
void Hud::render() const noexcept {}
|
||||
void Hud::tick() noexcept {}
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
#pragma once
|
||||
#include "Renderer.h"
|
||||
|
||||
class Hud : public IRenderable {
|
||||
class Hud final : public IRenderable, public ITickable {
|
||||
public:
|
||||
void render() const noexcept override;
|
||||
void tick() noexcept override;
|
||||
};
|
||||
|
||||
|
||||
+19
-1
@@ -21,7 +21,25 @@ struct KeyStatus {
|
||||
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;
|
||||
|
||||
+6
-1
@@ -7,7 +7,10 @@
|
||||
#include "Game.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) {
|
||||
windowWidth = width;
|
||||
@@ -19,3 +22,5 @@ void Renderer::resize(const int width, const int height) noexcept(false) {
|
||||
}
|
||||
if (game.getWindow()) game.getWindow()->onResize();
|
||||
}
|
||||
|
||||
inline Renderer renderer = Renderer();
|
||||
|
||||
+68
-3
@@ -4,7 +4,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "def.h"
|
||||
#include "exception.h"
|
||||
|
||||
class Game;
|
||||
/**
|
||||
@@ -22,18 +25,50 @@ interface ITickable {
|
||||
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;
|
||||
|
||||
friend class Game;
|
||||
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 resizeTime = 0;
|
||||
bool isRendering = false;
|
||||
|
||||
void gameStartRender() noexcept {
|
||||
isRendering = true;
|
||||
renderThread = std::this_thread::get_id();
|
||||
}
|
||||
|
||||
void gameEndRender() noexcept { isRendering = false; }
|
||||
|
||||
public:
|
||||
static void initialize() noexcept;
|
||||
explicit Renderer() = default;
|
||||
explicit Renderer() { Logger.put(L"Renderer created"); }
|
||||
void resize(int width, int height) noexcept(false);
|
||||
void setGame(Game& game) noexcept { pGame = &game; }
|
||||
[[nodiscard]] int getWidth() const noexcept { return windowWidth; }
|
||||
@@ -47,6 +82,36 @@ public:
|
||||
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
|
||||
|
||||
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() {
|
||||
B b;
|
||||
A a{ B() };
|
||||
a = A(std::move(a.b));
|
||||
}
|
||||
|
||||
+7
-5
@@ -62,19 +62,21 @@ class TextureManager {
|
||||
Font* defaultFont = nullptr;
|
||||
using IterFont = Map<int, Font>::const_iterator;
|
||||
using IterTexture = Map<String, ObjectHolder<ITexture>>::const_iterator;
|
||||
|
||||
public:
|
||||
TextureManager() {
|
||||
try {
|
||||
fonts.insert(std::make_pair(0, Font(L"Arial")));
|
||||
defaultFont = &fonts.at(0);
|
||||
}
|
||||
catch (...) {
|
||||
} catch (const std::out_of_range& e) {
|
||||
|
||||
} catch (const ArrayIndexOutOfBoundException& e){}
|
||||
}
|
||||
}
|
||||
Font& getFont(const int id) const noexcept {
|
||||
|
||||
const Font& getFont(const int id) const noexcept {
|
||||
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"
|
||||
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
|
||||
};
|
||||
|
||||
class Widget : public IRenderable {
|
||||
class Widget : public IRenderable, public ITickable {
|
||||
protected:
|
||||
int left = 0, top = 0, width = 0, height = 0;
|
||||
mutable bool hasMouse = false;
|
||||
|
||||
public:
|
||||
Location location;
|
||||
using Action = Function<void(int)>;
|
||||
double x, y, w, h;
|
||||
Action hover;// 传入int忽略
|
||||
@@ -27,8 +25,24 @@ public:
|
||||
Action mouseUp;// 传入int表示变更按键。0左, 1中, 2右
|
||||
Action mouseLeave;// 传入int忽略
|
||||
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) {}
|
||||
void render() const noexcept override {}
|
||||
virtual void onResize() {}
|
||||
|
||||
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 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 (hasMouse) onMouseLeave(0);
|
||||
hasMouse = false;
|
||||
@@ -72,7 +86,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class Window : public IRenderable {
|
||||
class Window : public IRenderable, public ITickable {
|
||||
protected:
|
||||
List<Widget*> widgets;
|
||||
|
||||
@@ -81,6 +95,8 @@ protected:
|
||||
~Window() override { for (Widget*& widget : widgets) { delete widget; } }
|
||||
|
||||
public:
|
||||
void render() const noexcept override;
|
||||
void tick() noexcept override;
|
||||
/**
|
||||
* 在Game.setWindow()时,本窗口开启时调用。
|
||||
* 不应当外部调用。
|
||||
@@ -104,8 +120,10 @@ public:
|
||||
void onClose() override {}
|
||||
};
|
||||
|
||||
class Button final : public Widget {
|
||||
class Button : public Widget {
|
||||
public:
|
||||
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 <map>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
using wchar = wchar_t;
|
||||
using QWORD = unsigned long long int;
|
||||
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 T, typename Alloc = std::allocator<T>> using List = std::list<T, Alloc>;
|
||||
template<typename F> using Function = std::function<F>;
|
||||
@@ -48,6 +50,7 @@ template<typename F> using Function = std::function<F>;
|
||||
#include <iostream>
|
||||
#include <dwmapi.h>
|
||||
|
||||
#pragma comment(lib, "Msimg32.lib")
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#pragma comment(lib, "dwmapi.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:
|
||||
[[nodiscard]] String getMessage() const noexcept { return msg; }
|
||||
[[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 {
|
||||
@@ -34,3 +34,57 @@ public:
|
||||
explicit ArrayIndexOutOfBoundException(String&& msg) : Exception(std::move(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 void ShowConsoleIO() noexcept {
|
||||
inline bool ShowConsoleIO() noexcept {
|
||||
AllocConsole();
|
||||
FILE* pCout;
|
||||
freopen_s(&pCout, "CONOUT$", "w", stdout);
|
||||
FILE* pCin;
|
||||
freopen_s(&pCin, "CONIN$", "r", stdin);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline const String ApplicationName = L"Hyblud Presher";
|
||||
inline HINSTANCE MainInstance;
|
||||
inline HWND MainWindowHandle;
|
||||
inline Thread GameThread;
|
||||
inline Thread RenderThread;
|
||||
inline static bool isRunning = ShowConsoleIO();
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
#include "def.h"
|
||||
#include "exception.h"
|
||||
#include "hbp.h"
|
||||
#include "Chars.h"
|
||||
#include "Renderer.h"
|
||||
#include "InteractManager.h"
|
||||
#include "TextureManager.h"
|
||||
#include "IText.h"
|
||||
|
||||
#include "Hud.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 (yPos < 30) return HTTOPRIGHT;
|
||||
if (renderer.getHeight() - yPos < 30) return HTBOTTOMRIGHT;
|
||||
return HTBOTTOM;
|
||||
return HTRIGHT;
|
||||
}
|
||||
if (yPos < 30) return HTTOP;
|
||||
if (renderer.getHeight() - yPos < 30) return HTBOTTOM;
|
||||
@@ -128,6 +128,7 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
_UNLIKELY
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
isRunning = false;
|
||||
return 0;
|
||||
_UNLIKELY
|
||||
case WM_CREATE:
|
||||
@@ -139,8 +140,39 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM 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) {
|
||||
ShowConsoleIO();
|
||||
WNDCLASSEX wc = {};
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
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));
|
||||
MSG msg = { nullptr };
|
||||
GameThread = Thread(gameThread);
|
||||
RenderThread = Thread(renderThread);
|
||||
while (GetMessageW(&msg, nullptr, 0, 0)) {
|
||||
if (!TranslateAcceleratorW(msg.hwnd, hAccelTable, &msg)) {
|
||||
TranslateMessage(&msg);
|
||||
@@ -182,5 +216,8 @@ int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCm
|
||||
}
|
||||
}
|
||||
DestroyAcceleratorTable(hAccelTable);
|
||||
if (GameThread.joinable()) GameThread.join();
|
||||
if (RenderThread.joinable()) RenderThread.join();
|
||||
_wsystem(L"pause");
|
||||
return (int) msg.wParam;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user