diff --git a/src/core/Application.cpp b/src/core/Application.cpp index a26529df..9a694fad 100644 --- a/src/core/Application.cpp +++ b/src/core/Application.cpp @@ -28,6 +28,7 @@ #include "Transition.h" #include #include +#include #pragma comment (lib ,"imm32.lib") @@ -53,6 +54,40 @@ namespace easy2d { debug_ = options.debug; + // show console if debug mode enabled + HWND console = ::GetConsoleWindow(); + if (debug_ && !console) + { + if (::AllocConsole()) + { + console = ::GetConsoleWindow(); + FILE * dummy; + freopen_s(&dummy, "CONOUT$", "w+t", stdout); + freopen_s(&dummy, "CONIN$", "r+t", stdin); + freopen_s(&dummy, "CONOUT$", "w+t", stderr); + (void)dummy; + + std::cout.clear(); + std::wcout.clear(); + std::cin.clear(); + std::wcin.clear(); + std::cerr.clear(); + std::wcerr.clear(); + } + } + else if (!debug_ && console) + { + ::ShowWindow(console, SW_HIDE); + console = nullptr; + } + + // disable the close button of console + if (console) + { + HMENU hmenu = ::GetSystemMenu(console, FALSE); + ::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); + } + ThrowIfFailed( Factory::Instance()->Init(debug_) ); @@ -95,31 +130,6 @@ namespace easy2d // disable imm ::ImmAssociateContext(hwnd, nullptr); - // show console if debug mode enabled - HWND console = ::GetConsoleWindow(); - if (debug_ && !console) - { - if (::AllocConsole()) - { - console = ::GetConsoleWindow(); - FILE * stdoutStream, *stdinStream, *stderrStream; - freopen_s(&stdoutStream, "conout$", "w+t", stdout); - freopen_s(&stdinStream, "conin$", "r+t", stdin); - freopen_s(&stderrStream, "conout$", "w+t", stderr); - } - } - else if (!debug_ && console) - { - ::ShowWindow(console, SW_HIDE); - } - - // disable the close button of console - if (console) - { - HMENU hmenu = ::GetSystemMenu(console, FALSE); - ::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); - } - // use Application instance in message loop ::SetWindowLongPtr(hwnd, GWLP_USERDATA, PtrToUlong(this)); } @@ -189,8 +199,6 @@ namespace easy2d const auto dt = (now - last) * time_scale_; last = now; - Input::Instance()->Update(); - if (transition_) { transition_->Update(dt); @@ -262,6 +270,8 @@ namespace easy2d { app->Update(); app->Render(hwnd); + + Input::Instance()->Update(); return 0; } break; @@ -269,6 +279,8 @@ namespace easy2d case WM_KEYDOWN: case WM_KEYUP: { + Input::Instance()->UpdateKey((int)wparam, (msg == WM_KEYDOWN) ? true : false); + if (!app->transition_ && app->curr_scene_) { Event evt((msg == WM_KEYDOWN) ? KeyboardEvent::Down : KeyboardEvent::Up); @@ -292,6 +304,10 @@ namespace easy2d case WM_MOUSEMOVE: case WM_MOUSEWHEEL: { + if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP) { Input::Instance()->UpdateKey(VK_LBUTTON, (msg == WM_LBUTTONDOWN) ? true : false); } + else if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONUP) { Input::Instance()->UpdateKey(VK_RBUTTON, (msg == WM_RBUTTONDOWN) ? true : false); } + else if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONUP) { Input::Instance()->UpdateKey(VK_MBUTTON, (msg == WM_MBUTTONDOWN) ? true : false); } + if (!app->transition_ && app->curr_scene_) { Event evt; @@ -301,24 +317,14 @@ namespace easy2d evt.mouse.left_btn_down = !!(wparam & MK_LBUTTON); evt.mouse.left_btn_down = !!(wparam & MK_RBUTTON); - if (msg == WM_MOUSEMOVE) - evt.type = MouseEvent::Move; - else if (msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN || msg == WM_MBUTTONDOWN) - evt.type = MouseEvent::Down; - else if (msg == WM_LBUTTONUP || msg == WM_RBUTTONUP || msg == WM_MBUTTONUP) - evt.type = MouseEvent::Up; - else - { - evt.type = MouseEvent::Wheel; - evt.mouse.wheel_delta = GET_WHEEL_DELTA_WPARAM(wparam) / 120.f; - } + if (msg == WM_MOUSEMOVE) { evt.type = MouseEvent::Move; } + else if (msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN || msg == WM_MBUTTONDOWN) { evt.type = MouseEvent::Down; } + else if (msg == WM_LBUTTONUP || msg == WM_RBUTTONUP || msg == WM_MBUTTONUP) { evt.type = MouseEvent::Up; } + else if (msg == WM_MOUSEWHEEL) { evt.type = MouseEvent::Wheel; evt.mouse.wheel = GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA; } - if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP) - evt.mouse.button = MouseButton::Left; - else if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONUP) - evt.mouse.button = MouseButton::Right; - else if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONUP) - evt.mouse.button = MouseButton::Middle; + if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP) { evt.mouse.button = MouseButton::Left; } + else if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONUP) { evt.mouse.button = MouseButton::Right; } + else if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONUP) { evt.mouse.button = MouseButton::Middle; } app->curr_scene_->Dispatch(evt); } diff --git a/src/core/Application.h b/src/core/Application.h index 8e388a48..8a8f1512 100644 --- a/src/core/Application.h +++ b/src/core/Application.h @@ -62,7 +62,7 @@ namespace easy2d // 初始化 void Init( - Options const& options + Options const& options = Options{} ); // 启动时 diff --git a/src/core/Event.hpp b/src/core/Event.hpp index 3eaf7331..461f89f8 100644 --- a/src/core/Event.hpp +++ b/src/core/Event.hpp @@ -57,7 +57,7 @@ namespace easy2d struct { - float wheel_delta; // 仅当消息类型为 Wheel 时有效 + float wheel; // 仅当消息类型为 Wheel 时有效 }; static inline bool Check(EventType type) diff --git a/src/core/Input.cpp b/src/core/Input.cpp index c421c080..748d9b55 100644 --- a/src/core/Input.cpp +++ b/src/core/Input.cpp @@ -26,9 +26,11 @@ namespace easy2d { Input::Input() : hwnd_(nullptr) + , want_update_(false) { ZeroMemory(keys_, sizeof(keys_)); - ZeroMemory(keys_cache_, sizeof(keys_cache_)); + ZeroMemory(keys_pressed_, sizeof(keys_pressed_)); + ZeroMemory(keys_released_, sizeof(keys_released_)); } Input::~Input() @@ -47,42 +49,55 @@ namespace easy2d void Input::Update() { - memcpy(keys_cache_, keys_, sizeof(keys_cache_)); - ::GetKeyboardState(keys_); + if (want_update_) + { + want_update_ = false; + + ZeroMemory(keys_pressed_, sizeof(keys_pressed_)); + ZeroMemory(keys_released_, sizeof(keys_released_)); + } + } + + void Input::UpdateKey(int key, bool down) + { + if (down && !keys_[key]) + keys_pressed_[key] = true; + if (!down && keys_[key]) + keys_released_[key] = true; + + keys_[key] = down; + + want_update_ = true; } bool Input::IsDown(KeyCode code) { - return !!(keys_[static_cast(code)] & 0x80); + return keys_[static_cast(code)]; } bool Input::IsDown(MouseButton btn) { - return !!(keys_[static_cast(btn)] & 0x80); + return keys_[static_cast(btn)]; } bool Input::WasPressed(KeyCode code) { - return !(keys_cache_[static_cast(code)] & 0x80) - && (keys_[static_cast(code)] & 0x80); + return keys_pressed_[static_cast(code)]; } bool Input::WasPressed(MouseButton btn) { - return !(keys_cache_[static_cast(btn)] & 0x80) - && (keys_[static_cast(btn)] & 0x80); + return keys_pressed_[static_cast(btn)]; } bool Input::WasReleased(KeyCode code) { - return (keys_cache_[static_cast(code)] & 0x80) - && !(keys_[static_cast(code)] & 0x80); + return keys_released_[static_cast(code)]; } bool Input::WasReleased(MouseButton btn) { - return (keys_cache_[static_cast(btn)] & 0x80) - && !(keys_[static_cast(btn)] & 0x80); + return keys_released_[static_cast(btn)]; } float Input::GetMouseX() @@ -97,9 +112,16 @@ namespace easy2d Point Input::GetMousePos() { - POINT pos; - ::GetCursorPos(&pos); - ::ScreenToClient(hwnd_, &pos); - return Point{ static_cast(pos.x), static_cast(pos.y) }; + Point mouse_pos = Point{}; + if (HWND active_window = ::GetForegroundWindow()) + { + if (active_window == hwnd_ || ::IsChild(active_window, hwnd_)) + { + POINT pos; + if (::GetCursorPos(&pos) && ::ScreenToClient(hwnd_, &pos)) + mouse_pos = Point((float)pos.x, (float)pos.y); + } + } + return mouse_pos; } } \ No newline at end of file diff --git a/src/core/Input.h b/src/core/Input.h index 96cb7e79..67df496a 100644 --- a/src/core/Input.h +++ b/src/core/Input.h @@ -31,8 +31,6 @@ namespace easy2d E2D_DECLARE_SINGLETON(Input); public: - HRESULT Init(HWND hwnd, bool debug); - // 检测键盘按键是否正被按下 bool IsDown( KeyCode code @@ -72,16 +70,22 @@ namespace easy2d // 获得鼠标坐标 Point GetMousePos(); + HRESULT Init(HWND hwnd, bool debug); + void Update(); + void UpdateKey(int, bool); + protected: Input(); ~Input(); protected: - HWND hwnd_; - BYTE keys_[256]; - BYTE keys_cache_[256]; + HWND hwnd_; + bool want_update_; + bool keys_[256]; + bool keys_pressed_[256]; + bool keys_released_[256]; }; } diff --git a/src/core/Node.h b/src/core/Node.h index 547320e4..ed9ac65a 100644 --- a/src/core/Node.h +++ b/src/core/Node.h @@ -124,7 +124,7 @@ namespace easy2d // 获取变换 Transform const& GetTransform() const { return transform_; } - // 获取包围盒 + // 获取边框 Rect GetBounds() const; // 获取外切包围盒 diff --git a/src/core/logs.cpp b/src/core/logs.cpp index cf80ea84..3fe6607f 100644 --- a/src/core/logs.cpp +++ b/src/core/logs.cpp @@ -33,35 +33,47 @@ namespace easy2d namespace color { - const wchar_t _reset[] = L"\x1b[0m"; + const WORD _blue = FOREGROUND_BLUE | FOREGROUND_INTENSITY; + const WORD _green = FOREGROUND_GREEN | FOREGROUND_INTENSITY; + const WORD _red = FOREGROUND_RED | FOREGROUND_INTENSITY; + const WORD _yellow = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; + const WORD _white = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; - const wchar_t _black[] = L"\x1b[30m"; - const wchar_t _red[] = L"\x1b[31m"; - const wchar_t _green[] = L"\x1b[32m"; - const wchar_t _yellow[] = L"\x1b[33m"; - const wchar_t _blue[] = L"\x1b[34m"; - const wchar_t _white[] = L"\x1b[37m"; + const WORD _blue_bg = _white | BACKGROUND_BLUE | BACKGROUND_INTENSITY; + const WORD _green_bg = _white | BACKGROUND_GREEN | BACKGROUND_INTENSITY; + const WORD _red_bg = _white | BACKGROUND_RED | BACKGROUND_INTENSITY; + const WORD _yellow_bg = BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY; + const WORD _white_bg = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY; + + const WORD _reset = _white; - const wchar_t _black_bg[] = L"\x1b[40m"; - const wchar_t _red_bg[] = L"\x1b[41m"; - const wchar_t _green_bg[] = L"\x1b[42m"; - const wchar_t _yellow_bg[] = L"\x1b[43m"; - const wchar_t _blue_bg[] = L"\x1b[44m"; - const wchar_t _white_bg[] = L"\x1b[47m"; #define DECLARE_COLOR(COLOR) \ - inline std::wostream& (COLOR)(std::wostream& _out)\ - { _out.write(_##COLOR, 5); return _out; }\ - inline std::wostream& (COLOR##_bg)(std::wostream& _out)\ - { _out.write(_##COLOR##_bg, 5); return _out; } + inline std::wostream& (stdout_##COLOR)(std::wostream& _out)\ + { ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), _##COLOR); return _out; }\ + \ + inline std::wostream& (stderr_##COLOR)(std::wostream& _out)\ + { ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), _##COLOR); return _out; } - inline std::wostream& (reset)(std::wostream& _out) { _out.write(_reset, 4); return _out; } +#define DECLARE_BG_COLOR(COLOR) \ + inline std::wostream& (stdout_##COLOR##_bg)(std::wostream& _out)\ + { ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), _##COLOR##_bg); return _out; }\ + \ + inline std::wostream& (stderr_##COLOR##_bg)(std::wostream& _out)\ + { ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), _##COLOR##_bg); return _out; } DECLARE_COLOR(red); DECLARE_COLOR(green); DECLARE_COLOR(yellow); DECLARE_COLOR(blue); DECLARE_COLOR(white); + DECLARE_COLOR(reset); + + DECLARE_BG_COLOR(red); + DECLARE_BG_COLOR(green); + DECLARE_BG_COLOR(yellow); + DECLARE_BG_COLOR(blue); + DECLARE_BG_COLOR(white); #undef DECLARE_COLOR } @@ -102,7 +114,7 @@ namespace easy2d ss << L"\r\n"; std::wstring output = ss.str(); - os << color << output << color::reset; + os << color << output; ::OutputDebugStringW(output.c_str()); delete[] buffer; @@ -124,7 +136,7 @@ namespace easy2d va_list args = nullptr; va_start(args, format); - Output(std::wcout, color::white, false, nullptr, format, args); + Output(std::wcout, color::stdout_white, false, nullptr, format, args); va_end(args); } @@ -134,7 +146,7 @@ namespace easy2d va_list args = nullptr; va_start(args, format); - Output(std::wcout, color::white, true, nullptr, format, args); + Output(std::wcout, color::stdout_white, true, nullptr, format, args); va_end(args); } @@ -144,7 +156,7 @@ namespace easy2d va_list args = nullptr; va_start(args, format); - Output(std::wcout, color::blue, false, nullptr, format, args); + Output(std::wcout, color::stdout_blue, false, nullptr, format, args); va_end(args); } @@ -154,7 +166,7 @@ namespace easy2d va_list args = nullptr; va_start(args, format); - Output(std::wcout, color::blue, true, nullptr, format, args); + Output(std::wcout, color::stdout_blue, true, nullptr, format, args); va_end(args); } @@ -164,7 +176,7 @@ namespace easy2d va_list args = nullptr; va_start(args, format); - Output(std::wcerr, color::yellow_bg, false, L"Warning: ", format, args); + Output(std::wcerr, color::stdout_yellow_bg, false, L"Warning: ", format, args); va_end(args); } @@ -174,7 +186,7 @@ namespace easy2d va_list args = nullptr; va_start(args, format); - Output(std::wcerr, color::yellow_bg, true, L"Warning: ", format, args); + Output(std::wcerr, color::stdout_yellow_bg, true, L"Warning: ", format, args); va_end(args); } @@ -184,7 +196,7 @@ namespace easy2d va_list args = nullptr; va_start(args, format); - Output(std::wcerr, color::red_bg, false, L"Error: ", format, args); + Output(std::wcerr, color::stderr_red_bg, false, L"Error: ", format, args); va_end(args); } @@ -194,7 +206,7 @@ namespace easy2d va_list args = nullptr; va_start(args, format); - Output(std::wcerr, color::red_bg, true, L"Error: ", format, args); + Output(std::wcerr, color::stderr_red_bg, true, L"Error: ", format, args); va_end(args); }