← Back to file list Raw

src/CWindowManager.cpp

#include "CWindowManager.h"
#include "CEngine.h"
#include "CLogger.h"
#include "CWrapable.h"
#include "CStartupArgsManager.h"
#include "U_Macros.h"
#include "boost/bimap.hpp"
#include "boost/assign/list_of.hpp"
#include "CTestRender.h"
CWindowManager::CWindowManager()
{
}
CWindowManager::~CWindowManager()
{
DestructWindow();
SDL_Quit();
}
bool CWindowManager::V_Init()
{
Log::Instance() << "CWindowManager::V_Init\n";
constexpr int init = SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_HAPTIC | SDL_INIT_GAMEPAD | SDL_INIT_SENSOR;
int status = SDL_Init(init); //TODO maybe choose what subsystems we need to use?
if (status < 0)
{
COMPONENT_CALL(CLogger, Err(L"Can't initialize SDL. Not using window manager.\n"));
return false;
}
unsigned int width = 1024, height = 768;
bool windowed = true, noborder = false, fullscreen = false;
COMPONENT_CALL(CStartupArgsManager, GetIfExist<unsigned int>("-width", width));
COMPONENT_CALL(CStartupArgsManager, GetIfExist<unsigned int>("-height", height));
COMPONENT_CALL_GET(windowed, CStartupArgsManager, IsArgumentSet("-windowed"));
COMPONENT_CALL_GET(noborder, CStartupArgsManager, IsArgumentSet("-noborder"));
COMPONENT_CALL_GET(fullscreen, CStartupArgsManager, IsArgumentSet("-fullscreen"));
if(fullscreen)
{
windowed = noborder = false;
}
width = std::clamp<unsigned int>(width, 1, 0x00FFFFFF);
height = std::clamp<unsigned int>(height, 1, 0x00FFFFFF);
std::string RendererType = "gl430";
COMPONENT_CALL_GET(RendererType, CStartupArgsManager, GetArgumentValue("-renderer"));
Renderer = CEngine::GetInstance()->RenderersFactory.create<std::unique_ptr<CRendererBase>>(RendererType);
if(!Renderer)
{
COMPONENT_CALL(CLogger, Err(L"Can't create renderer.\n"));
return false;
}
size_t flags = GetWindowFlags(windowed, noborder, Renderer->GetGenericFlag());
Window = SDL_CreateWindow("EngineGL 4.0", width, height, flags);
if(!Window)
{
COMPONENT_CALL(CLogger, Err(L"Can't create window!\n"));
return false;
}
m_UpdateAspect();
Renderer->Init(Window);
Log::Instance() << "CWindowManager::V_Init END\n";
SDL_SetWindowRelativeMouseMode(Window, true); //TODO temporary
return true;
}
void CWindowManager::m_UpdateAspect()
{
auto size = GetWindowSize();
m_aspect = static_cast<float>(size.x) / static_cast<float>(size.y);
}
float CWindowManager::GetWindowAspect() const
{
return m_aspect;
}
void CWindowManager::HandleEvent(const SDL_Event& event)
{
if (event.type == SDL_EVENT_QUIT)
{
CEngine::GetInstance()->Quit();
}
else if (event.type == SDL_EVENT_WINDOW_RESIZED)
{
m_UpdateAspect();
}
else if (event.type == SDL_EVENT_KEY_DOWN)
{
SDL_Keycode keycode = event.key.key;
if(keycode == SDLK_T)
{
bool toggled = !SDL_GetWindowRelativeMouseMode(Window);
SDL_SetWindowRelativeMouseMode(Window, toggled);
Log::Instance() << "Cursor toggled\n";
}
}
}
void CWindowManager::V_Update()
{
while (SDL_PollEvent(&m_Event) != 0)
{
HandleEvent(m_Event);
OnEventHandle(m_Event);
}
Renderer->Update();
Renderer->ClearWindow();
COMPONENT_CALL(CTestRender, Draw());
OnDraw();
Renderer->Display();
}
void CWindowManager::DestructWindow()
{
if(Renderer)
{
Renderer.reset();
}
if (Window)
{
SDL_DestroyWindow(Window);
Window = nullptr;
}
}
glm::ivec2 CWindowManager::GetWindowSize()
{
int w = 0;
int h = 0;
SDL_GetWindowSizeInPixels(Window, &w, &h);
return glm::ivec2(static_cast<glm::ivec2::value_type>(w), static_cast<glm::ivec2::value_type>(h));
}
size_t CWindowManager::GetWindowFlags(bool windowed, bool noborder, size_t generic_flag)
{
size_t flag = generic_flag | SDL_WINDOW_RESIZABLE;
if (!windowed) { return (flag | SDL_WINDOW_FULLSCREEN); }
if (windowed && !noborder) { return (flag); }
if (windowed && noborder) { return (flag | SDL_WINDOW_BORDERLESS); }
return flag;
}
bool CWindowManager::V_ScriptInit(std::shared_ptr<sol::state> state, sol::table table)
{
static boost::bimap<std::string, SDL_Scancode> stringToCodes =
boost::assign::list_of<boost::bimap<std::string, SDL_Scancode>::value_type>
("a", SDL_SCANCODE_A)
("b", SDL_SCANCODE_B)
("c", SDL_SCANCODE_C)
("d", SDL_SCANCODE_D)
("e", SDL_SCANCODE_E)
("f", SDL_SCANCODE_F)
("g", SDL_SCANCODE_G)
("h", SDL_SCANCODE_H)
("i", SDL_SCANCODE_I)
("j", SDL_SCANCODE_J)
("k", SDL_SCANCODE_K)
("l", SDL_SCANCODE_L)
("m", SDL_SCANCODE_M)
("n", SDL_SCANCODE_N)
("o", SDL_SCANCODE_O)
("p", SDL_SCANCODE_P)
("q", SDL_SCANCODE_Q)
("r", SDL_SCANCODE_R)
("s", SDL_SCANCODE_S)
("t", SDL_SCANCODE_T)
("u", SDL_SCANCODE_U)
("v", SDL_SCANCODE_V)
("w", SDL_SCANCODE_W)
("x", SDL_SCANCODE_X)
("y", SDL_SCANCODE_Y)
("z", SDL_SCANCODE_Z)
("lshift", SDL_SCANCODE_LSHIFT)
("lctrl", SDL_SCANCODE_LCTRL)
("lalt", SDL_SCANCODE_LALT)
("rshift", SDL_SCANCODE_RSHIFT)
("rctrl", SDL_SCANCODE_RCTRL)
("ralt", SDL_SCANCODE_RALT);
table["onEventHandle"] = OnEventHandle.GetScriptTable(state);
table.set_function("getRelativeMouseState", []() -> glm::vec2
{
float dx, dy;
SDL_GetRelativeMouseState(&dx, &dy);
return { dx, dy };
});
table.set_function("setRelativeMouseMode", [this](bool enable) -> void { SDL_SetWindowRelativeMouseMode(Window, enable); });
table.set_function("getRelativeMouseMode", [this]() -> bool { return SDL_GetWindowRelativeMouseMode(Window); });
table.set_function("getKeyState", [](const std::string& name) -> bool
{
const bool* keyboard = SDL_GetKeyboardState(NULL);
auto it = stringToCodes.left.find(name);
if(it == stringToCodes.left.end()) { return false; }
return keyboard[it->second];
});
table.set_function("pumpEvents", []() -> void { SDL_PumpEvents(); });
return true;
}
LINK_SOL_USERTYPE(CWindowManager);
LINK_COMPONENT_TO_CLASS(CWindowManager, windowmanager);