Temporary Platform objects were registering themselves. The move ctor would then initialize the final object in the circular buffer (see PlatformSystem), but it would leave the address of the temporary object registered in the ObserversManager.
154 lines
5.8 KiB
C++
154 lines
5.8 KiB
C++
/*
|
|
Copyright 2014 Michele "King_DuckZ" Santullo
|
|
|
|
This file is part of CloonelJump.
|
|
|
|
CloonelJump 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.
|
|
|
|
CloonelJump 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 CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "sdlmain.hpp"
|
|
#include "observersmanager.hpp"
|
|
#include "sizenotifiable.hpp"
|
|
#include "sizeratio.hpp"
|
|
#include <SDL2/SDL.h>
|
|
#include <stdexcept>
|
|
#include <sstream>
|
|
|
|
namespace cloonel {
|
|
struct SDLMain::LocalData {
|
|
SDL_Window* window;
|
|
SDL_Renderer* renderer;
|
|
SizeRatio sizeratio;
|
|
ObserversManager<SizeNotifiableBase*> resChangeNotifList;
|
|
bool initialized;
|
|
};
|
|
|
|
///------------------------------------------------------------------------
|
|
///------------------------------------------------------------------------
|
|
SDLMain::SDLMain (const char* parGameName, ushort2 parRes, ushort2 parReferenceRes) :
|
|
m_gameName(parGameName),
|
|
m_localData(new LocalData)
|
|
{
|
|
m_localData->sizeratio.SetOriginal(static_cast<float2>(parReferenceRes), static_cast<float2>(parRes));
|
|
}
|
|
|
|
///------------------------------------------------------------------------
|
|
///------------------------------------------------------------------------
|
|
SDLMain::~SDLMain() noexcept {
|
|
ClearIFN(*m_localData);
|
|
}
|
|
|
|
///------------------------------------------------------------------------
|
|
///------------------------------------------------------------------------
|
|
void SDLMain::Init() {
|
|
if (not m_localData->initialized)
|
|
InitSDL(*m_localData);
|
|
}
|
|
|
|
///------------------------------------------------------------------------
|
|
///------------------------------------------------------------------------
|
|
void SDLMain::InitSDL (LocalData& parInitSDL) {
|
|
parInitSDL.window = nullptr;
|
|
parInitSDL.renderer = nullptr;
|
|
parInitSDL.initialized = false;
|
|
|
|
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
|
|
throw std::runtime_error(SDL_GetError());
|
|
parInitSDL.initialized = true;
|
|
|
|
const float2 wh(m_localData->sizeratio.Resolution());
|
|
SDL_Window* const win = SDL_CreateWindow(m_gameName.c_str(), 100, 100, static_cast<int>(wh.x()), static_cast<int>(wh.y()), SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
|
if (!win)
|
|
throw std::runtime_error(SDL_GetError());
|
|
parInitSDL.window = win;
|
|
|
|
SDL_Renderer* const renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
|
if (!renderer)
|
|
throw std::runtime_error(SDL_GetError());
|
|
parInitSDL.renderer = renderer;
|
|
}
|
|
|
|
///------------------------------------------------------------------------
|
|
///------------------------------------------------------------------------
|
|
void SDLMain::ClearIFN (LocalData& parInitSDL) noexcept {
|
|
if (parInitSDL.renderer)
|
|
SDL_DestroyRenderer(parInitSDL.renderer);
|
|
if (parInitSDL.window)
|
|
SDL_DestroyWindow(parInitSDL.window);
|
|
if (parInitSDL.initialized)
|
|
SDL_Quit();
|
|
}
|
|
|
|
///------------------------------------------------------------------------
|
|
///------------------------------------------------------------------------
|
|
SDL_Renderer* SDLMain::GetRenderer() {
|
|
if (m_localData->initialized)
|
|
return m_localData->renderer;
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
///------------------------------------------------------------------------
|
|
///------------------------------------------------------------------------
|
|
void SDLMain::SetResolution (ushort2 parRes) {
|
|
m_localData->sizeratio.UpdateResolution(static_cast<float2>(parRes));
|
|
{
|
|
SDL_Renderer* const renderer = GetRenderer();
|
|
assert(renderer);
|
|
const int retVal = SDL_RenderSetLogicalSize(renderer, parRes.x(), parRes.y());
|
|
if (retVal) {
|
|
std::ostringstream oss;
|
|
oss << "Error setting logical size to renderer to " << parRes.x() << "x" << parRes.y() << ": " << SDL_GetError();
|
|
throw std::runtime_error(oss.str());
|
|
}
|
|
|
|
const SDL_Rect area = { 0, 0, parRes.x(), parRes.y() };
|
|
const int retValViewport = SDL_RenderSetViewport(renderer, &area);
|
|
if (retValViewport) {
|
|
std::ostringstream oss;
|
|
oss << "Error setting viewport to renderer to " << parRes.x() << "x" << parRes.y() << ": " << SDL_GetError();
|
|
throw std::runtime_error(oss.str());
|
|
}
|
|
}
|
|
|
|
for (auto currNotifiable : m_localData->resChangeNotifList) {
|
|
currNotifiable->NotifyResChanged(m_localData->sizeratio);
|
|
}
|
|
}
|
|
|
|
///------------------------------------------------------------------------
|
|
///------------------------------------------------------------------------
|
|
size_t SDLMain::RegisterForResChange (SizeNotifiableBase* parNotif) {
|
|
parNotif->NotifyResChanged(m_localData->sizeratio);
|
|
return m_localData->resChangeNotifList.Add(parNotif);
|
|
}
|
|
|
|
///------------------------------------------------------------------------
|
|
///------------------------------------------------------------------------
|
|
void SDLMain::UnregisterForResChange (size_t parID) noexcept {
|
|
m_localData->resChangeNotifList.Remove(parID);
|
|
}
|
|
|
|
///------------------------------------------------------------------------
|
|
///------------------------------------------------------------------------
|
|
void SDLMain::SwapRegisteredForResChange (size_t parID, SizeNotifiableBase* parNotif) {
|
|
m_localData->resChangeNotifList.Update(parID, parNotif);
|
|
}
|
|
|
|
///------------------------------------------------------------------------
|
|
///------------------------------------------------------------------------
|
|
ushort2 SDLMain::WidthHeight() const noexcept {
|
|
return static_cast<ushort2>(m_localData->sizeratio.Resolution());
|
|
}
|
|
} //namespace cloonel
|