MyCurry/src/gamelib/gamescenebase.cpp

136 lines
3.6 KiB
C++

/*
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
This file is part of MyCurry.
MyCurry is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MyCurry is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gamescenebase.hpp"
#include "inputbag.hpp"
#include "sdlmain.hpp"
#include "rect.hpp"
#include "drawing_queue.hpp"
#include <cassert>
#include <SDL2/SDL.h>
#include <algorithm>
#include <ciso646>
#if !defined(NDEBUG)
# include "compatibility.h"
# include <cmath>
#endif
namespace curry {
namespace {
///---------------------------------------------------------------------
///---------------------------------------------------------------------
bool DoEvents (cloonel::InputBag& parInput, cloonel::SDLMain* parSdlMain) {
using cloonel::InputDevice_Keyboard;
using cloonel::ushort2;
SDL_Event eve;
while (SDL_PollEvent(&eve)) {
switch (eve.type) {
case SDL_KEYDOWN:
//eve.key.keysym.sym
parInput.NotifyKeyAction(InputDevice_Keyboard, eve.key.keysym.scancode, true);
break;
case SDL_KEYUP:
parInput.NotifyKeyAction(InputDevice_Keyboard, eve.key.keysym.scancode, false);
break;
case SDL_QUIT:
return true;
case SDL_WINDOWEVENT:
if (SDL_WINDOWEVENT_RESIZED == eve.window.event) {
parSdlMain->SetResolution(ushort2(static_cast<uint16_t>(eve.window.data1), static_cast<uint16_t>(eve.window.data2)));
}
else if (SDL_WINDOWEVENT_CLOSE == eve.window.event) {
return true;
}
break;
}
}
return false;
}
} //unnamed namespace
GameSceneBase::GameSceneBase (cloonel::SDLMain* parSdlMain) :
m_time0(std::chrono::steady_clock::now()),
m_input(std::make_unique<cloonel::InputBag>()),
m_drawing_queue(std::make_unique<DrawingQueue>(parSdlMain, cloonel::DeferredRegister())),
m_sdlmain(parSdlMain),
m_screen_width(static_cast<float>(m_sdlmain->WidthHeight().x())),
m_screen_height(static_cast<float>(m_sdlmain->WidthHeight().y())),
m_wants_to_quit(false)
{
assert(m_sdlmain);
}
GameSceneBase::~GameSceneBase() noexcept = default;
void GameSceneBase::prepare() {
m_wants_to_quit = false;
this->on_prepare();
m_time0 = std::chrono::steady_clock::now();
}
void GameSceneBase::destroy() noexcept {
set_wants_to_quit();
this->on_destroy();
}
bool GameSceneBase::wants_to_quit() const {
return m_wants_to_quit;
}
void GameSceneBase::set_wants_to_quit() {
m_wants_to_quit = true;
}
void GameSceneBase::exec() {
const auto time1 = std::chrono::steady_clock::now();
const bool quit = DoEvents(*m_input, m_sdlmain);
m_input->KeyStateUpdateFinished();
if (quit)
set_wants_to_quit();
const float delta = std::chrono::duration<float>(time1 - m_time0).count();
m_time0 = time1;
this->on_update(delta);
m_drawing_queue->flush_to_renderer();
SDL_RenderPresent(this->sdl_main()->GetRenderer());
}
cloonel::SDLMain* GameSceneBase::sdl_main() {
return m_sdlmain;
}
cloonel::InputBag& GameSceneBase::input_bag() {
return *m_input;
}
DrawingQueue& GameSceneBase::drawing_queue() {
return *m_drawing_queue;
}
const DrawingQueue& GameSceneBase::drawing_queue() const {
return *m_drawing_queue;
}
} //namespace curry