diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 7d69a24..9023348 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -3,7 +3,7 @@ # # Add source to this project's executable. -add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp") +add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp" "platform/game-dx.cpp") if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET xna PROPERTY CXX_STANDARD 20) diff --git a/framework/forward.hpp b/framework/forward.hpp index 9de662c..2ef39b6 100644 --- a/framework/forward.hpp +++ b/framework/forward.hpp @@ -23,7 +23,16 @@ namespace xna { struct Vector3; struct Vector4; - //Audio + //Game + class DrawableGameComponent; + class Game; + class GameComponent; + class GameComponentCollection; + class GameTime; + class GameWindow; + class IDrawable; + class IGameComponent; + class IUpdatable; //Graphics class BlendState; @@ -35,18 +44,7 @@ namespace xna { class SwapChain; class Texture; class Texture2D; - struct Viewport; - - //Game - class DrawableGameComponent; - class Game; - class GameComponent; - class GameComponentCollection; - class GameTime; - class GameWindow; - class IDrawable; - class IGameComponent; - class IUpdatable; + struct Viewport; using PBoundingBox = std::shared_ptr; using PBoundingFrustum = std::shared_ptr; @@ -64,18 +62,7 @@ namespace xna { using PRectangle = std::shared_ptr; using PVector2 = std::shared_ptr; using PVector3 = std::shared_ptr; - using PVector4 = std::shared_ptr; - - using PBlendState = std::shared_ptr; - using PDisplayMode = std::shared_ptr; - using PDisplayModeCollection = std::shared_ptr; - using PGraphicsAdapter = std::shared_ptr; - using PGraphicsDevice = std::shared_ptr; - using PRenderTarget2D = std::shared_ptr; - using PSwapChain = std::shared_ptr; - using PTexture = std::shared_ptr; - using PTexture2D = std::shared_ptr; - using PViewport = std::shared_ptr; + using PVector4 = std::shared_ptr; using PDrawableGameComponent = std::shared_ptr; using PGame = std::shared_ptr; @@ -86,6 +73,17 @@ namespace xna { using PIDrawable = std::shared_ptr; using PIGameComponent = std::shared_ptr; using PIUpdatable = std::shared_ptr; + + using PBlendState = std::shared_ptr; + using PDisplayMode = std::shared_ptr; + using PDisplayModeCollection = std::shared_ptr; + using PGraphicsAdapter = std::shared_ptr; + using PGraphicsDevice = std::shared_ptr; + using PRenderTarget2D = std::shared_ptr; + using PSwapChain = std::shared_ptr; + using PTexture = std::shared_ptr; + using PTexture2D = std::shared_ptr; + using PViewport = std::shared_ptr; } #endif \ No newline at end of file diff --git a/framework/game/game.hpp b/framework/game/game.hpp new file mode 100644 index 0000000..37e7dd4 --- /dev/null +++ b/framework/game/game.hpp @@ -0,0 +1,25 @@ +#ifndef XNA_GAME_GAME_HPP +#define XNA_GAME_GAME_HPP + +#include "../enums.hpp" +#include "../forward.hpp" +#include "../types.hpp" +#include "time.hpp" +#include "window.hpp" + +namespace xna { + class IGame { + public: + virtual ~IGame(){} + + virtual void Exit() = 0; + virtual int Run() = 0; + + protected: + virtual void Draw(GameTime const& gameTime) = 0; + virtual void Initialize() = 0; + virtual void Update(GameTime const& gameTime) = 0; + }; +} + +#endif \ No newline at end of file diff --git a/framework/game/time.hpp b/framework/game/time.hpp new file mode 100644 index 0000000..295e0c5 --- /dev/null +++ b/framework/game/time.hpp @@ -0,0 +1,37 @@ +#ifndef XNA_GAME_TIME_HPP +#define XNA_GAME_TIME_HPP + +#include "../forward.hpp" +#include "../types.hpp" +#include "../timespan.hpp" + +namespace xna { + class GameTime { + public: + constexpr GameTime() = default; + + constexpr GameTime(const TimeSpan& elapsedGameTime, bool isRunningSlowly, const TimeSpan& totalGameTime) : + _elapsedGameTime(elapsedGameTime), + _isRunningSlowly(isRunningSlowly), + _totalGameTime(totalGameTime) { } + + constexpr TimeSpan ElapsedGameTime() const { + return _elapsedGameTime; + } + + constexpr bool IsRunningSlowly() const { + return _isRunningSlowly; + } + + constexpr TimeSpan TotalGameTime() const { + return _totalGameTime; + } + + private: + TimeSpan _elapsedGameTime{ 0 }; + bool _isRunningSlowly{ false }; + TimeSpan _totalGameTime{ 0 }; + }; +} + +#endif \ No newline at end of file diff --git a/framework/game/window.hpp b/framework/game/window.hpp index 81fcafb..023b728 100644 --- a/framework/game/window.hpp +++ b/framework/game/window.hpp @@ -5,25 +5,14 @@ #include "../common/rectangle.hpp" namespace xna { - class GameWindow { + class IGameWindow { public: - PLATFORM_DEVELOPMENT - GameWindow(); - PLATFORM_DEVELOPMENT - String Title() const; - PLATFORM_DEVELOPMENT - void Title(String const& title); - PLATFORM_DEVELOPMENT - Rectangle ClientBounds() const; - PLATFORM_DEVELOPMENT - intptr_t Handle() const; + virtual ~IGameWindow(){} - private: - class InternalProperty; - friend class InternalProperty; - - public: - sptr ip_GameWindow{ nullptr }; + virtual String Title() const = 0; + virtual void Title(String const& title) = 0; + virtual Rectangle ClientBounds() const = 0; + virtual intptr_t Handle() const = 0; }; } diff --git a/framework/graphics/adapter.hpp b/framework/graphics/adapter.hpp index 09a410b..3c449c4 100644 --- a/framework/graphics/adapter.hpp +++ b/framework/graphics/adapter.hpp @@ -7,64 +7,49 @@ #include "displaymode.hpp" namespace xna { - class GraphicsAdapter { + class IGraphicsAdapter { public: - PLATFORM_DEVELOPMENT - GraphicsAdapter(); + virtual ~IGraphicsAdapter() { + } static PGraphicsAdapter DefaultAdapter() { if (_adaptersList.empty()) return nullptr; - if (_defaultAdapter >= _adaptersList.size()) + if (_defaultAdapterIndex >= _adaptersList.size()) return nullptr; - return _adaptersList[_defaultAdapter]; + return _adaptersList[_defaultAdapterIndex]; } static constexpr void DefaultAdapter(size_t index) { - _defaultAdapter = index; + _defaultAdapterIndex = index; } static constexpr std::vector Adapters() { return _adaptersList; } - PLATFORM_DEVELOPMENT - String Description() const; - PLATFORM_DEVELOPMENT - Uint DeviceId() const; - PLATFORM_DEVELOPMENT - String DeviceName() const; + virtual String Description() const = 0; + virtual Uint DeviceId() const = 0; + virtual String DeviceName() const = 0; - bool IsDefaultAdapter() const { - auto def = DefaultAdapter(); - return this == def.get(); + constexpr bool IsDefaultAdapter() const { + return _index == _defaultAdapterIndex; } - PLATFORM_DEVELOPMENT - intptr_t MonitorHandle() const; - PLATFORM_DEVELOPMENT - Uint Revision() const; - PLATFORM_DEVELOPMENT - Uint SubSystemId() const; - PLATFORM_DEVELOPMENT - Uint VendorId() const; - PLATFORM_DEVELOPMENT - PDisplayModeCollection SupportedDisplayModes() const; - - private: - inline static size_t _defaultAdapter = 0; - - PLATFORM_DEVELOPMENT - static std::vector getAllAdapters(); + virtual intptr_t MonitorHandle() const = 0; + virtual Uint Revision() const = 0; + virtual Uint SubSystemId() const = 0; + virtual Uint VendorId() const = 0; + virtual PDisplayModeCollection SupportedDisplayModes() const = 0; + + protected: + Uint _index{ 0 }; + inline static size_t _defaultAdapterIndex = 0; + static std::vector getAllAdapters(); inline static std::vector _adaptersList = getAllAdapters(); - - public: - class InternalProperty; - friend class InternalProperty; - sptr ip_GraphicsAdapter{ nullptr }; }; } diff --git a/framework/graphics/blendstate.hpp b/framework/graphics/blendstate.hpp index aa0f6f3..39853e8 100644 --- a/framework/graphics/blendstate.hpp +++ b/framework/graphics/blendstate.hpp @@ -6,53 +6,16 @@ #include "../enums.hpp" namespace xna { - class BlendState { + class IBlendState { public: - PLATFORM_DEVELOPMENT - BlendState(GraphicsDevice* device); + virtual ~IBlendState(){} - static PBlendState Opaque() { - auto blendState = New(nullptr); - blendState->_source = Blend::SourceAlpha; - blendState->_sourceAlpha = Blend::SourceAlpha; - blendState->_destination = Blend::Zero; - blendState->_destinationAlpha = Blend::Zero; - - return blendState; - } - - static PBlendState AlphaBlend() { - auto blendState = New(nullptr); - blendState->_source = Blend::One; - blendState->_sourceAlpha = Blend::One; - blendState->_destination = Blend::InverseSourceAlpha; - blendState->_destinationAlpha = Blend::InverseSourceAlpha; - - return blendState; - } - - static PBlendState Additive() { - auto blendState = New(nullptr); - blendState->_source = Blend::SourceAlpha; - blendState->_sourceAlpha = Blend::SourceAlpha; - blendState->_destination = Blend::One; - blendState->_destinationAlpha = Blend::One; - - return blendState; - } - - static PBlendState NonPremultiplied() { - auto blendState = New(nullptr); - blendState->_source = Blend::SourceAlpha; - blendState->_sourceAlpha = Blend::SourceAlpha; - blendState->_destination = Blend::InverseSourceAlpha; - blendState->_destinationAlpha = Blend::InverseSourceAlpha; - - return blendState; - } - - PLATFORM_DEVELOPMENT - bool Apply(GraphicsDevice* device); + static PBlendState Opaque(); + static PBlendState AlphaBlend(); + static PBlendState Additive(); + static PBlendState NonPremultiplied(); + + virtual bool Apply(GraphicsDevice* device) = 0; public: bool _alphaToCoverage{ false }; @@ -64,13 +27,7 @@ namespace xna { Blend _destinationAlpha{ Blend::Zero }; BlendOperation _operationAlpha{ BlendOperation::Add }; ColorWriteChannels _writeMask{ ColorWriteChannels::All }; - GraphicsDevice* _device{nullptr}; - - public: - class InternalProperty; - friend class InternalProperty; - sptr ip_BlendState{ nullptr }; - }; + }; } #endif \ No newline at end of file diff --git a/framework/graphics/device.hpp b/framework/graphics/device.hpp index 14ee551..13d28a4 100644 --- a/framework/graphics/device.hpp +++ b/framework/graphics/device.hpp @@ -12,22 +12,12 @@ #include "blendstate.hpp" namespace xna { - class GraphicsDevice : public std::enable_shared_from_this { + class IGraphicsDevice { public: - PLATFORM_DEVELOPMENT - GraphicsDevice(); - - PLATFORM_DEVELOPMENT - void Clear(); - - PLATFORM_DEVELOPMENT - void Clear(Color const& color); - - PLATFORM_DEVELOPMENT - bool Initialize(GameWindow& gameWindow); - - PLATFORM_DEVELOPMENT - bool Present(); + virtual ~IGraphicsDevice() {} + virtual void Clear() = 0; + virtual bool Initialize(GameWindow& gameWindow) = 0; + virtual bool Present() = 0; PGraphicsAdapter Adapter() const { return _adapter; @@ -35,7 +25,7 @@ namespace xna { void Adapter(PGraphicsAdapter const& adapter) { _adapter = adapter; - } + } constexpr xna::Viewport Viewport() const { return _viewport; @@ -49,17 +39,17 @@ namespace xna { return _swapChain; } - private: + constexpr void UseVSync(bool use) { + _usevsync = use; + } + + protected: PGraphicsAdapter _adapter{ nullptr }; PSwapChain _swapChain{ nullptr }; PRenderTarget2D _renderTarget2D{ nullptr }; xna::Viewport _viewport{}; PBlendState _blendState{ nullptr }; - - public: - class InternalProperty; - friend class InternalProperty; - sptr ip_GraphicsDevice{ nullptr }; + bool _usevsync{ false }; }; } diff --git a/framework/graphics/rendertarget.hpp b/framework/graphics/rendertarget.hpp index fe715c1..1989b0f 100644 --- a/framework/graphics/rendertarget.hpp +++ b/framework/graphics/rendertarget.hpp @@ -5,21 +5,15 @@ namespace xna { - class RenderTarget2D : public Texture2D { + class IRenderTarget2D { public: - RenderTarget2D(GraphicsDevice* device); + virtual ~IRenderTarget2D(){} - PLATFORM_DEVELOPMENT - bool Apply(); + virtual bool Apply() = 0; - private: - GraphicsDevice* _device; - - public: - class InternalProperty; - friend class InternalProperty; - sptr ip_RenderTarget2D{ nullptr }; - }; + protected: + GraphicsDevice* _device{nullptr}; + }; } #endif \ No newline at end of file diff --git a/framework/graphics/swapchain.hpp b/framework/graphics/swapchain.hpp index bc874bf..36c9b33 100644 --- a/framework/graphics/swapchain.hpp +++ b/framework/graphics/swapchain.hpp @@ -7,25 +7,12 @@ #include "../game/window.hpp" namespace xna { - class SwapChain { + class ISwapChain { public: - PLATFORM_DEVELOPMENT - SwapChain(GraphicsDevice* device); - - PLATFORM_DEVELOPMENT - bool Initialize(GameWindow const& gameWindow); - - PLATFORM_DEVELOPMENT - bool Apply(); - - private: - GraphicsDevice* _device{ nullptr }; - - public: - class InternalProperty; - friend class InternalProperty; - sptr ip_SwapChain{ nullptr }; - }; + virtual ~ISwapChain() {} + virtual bool Initialize(GameWindow const& gameWindow) = 0; + virtual bool Apply() = 0; + }; } #endif \ No newline at end of file diff --git a/framework/graphics/texture.hpp b/framework/graphics/texture.hpp index 84c176b..5207d94 100644 --- a/framework/graphics/texture.hpp +++ b/framework/graphics/texture.hpp @@ -9,15 +9,9 @@ namespace xna { class Texture { }; - class Texture2D : public Texture { + class ITexture2D { public: - PLATFORM_DEVELOPMENT - Texture2D(); - - public: - class InternalProperty; - friend class InternalProperty; - sptr ip_Texture2D{ nullptr }; + virtual ~ITexture2D(){} }; } diff --git a/framework/platform/adapter-dx.cpp b/framework/platform/adapter-dx.cpp index a1adab9..5383df0 100644 --- a/framework/platform/adapter-dx.cpp +++ b/framework/platform/adapter-dx.cpp @@ -2,33 +2,26 @@ #include "../helpers.hpp" namespace xna { - GraphicsAdapter::GraphicsAdapter() { - ip_GraphicsAdapter = New(); - } String GraphicsAdapter::Description() const { - auto& p = ip_GraphicsAdapter; DXGI_ADAPTER_DESC1 desc; - p->_adapter->GetDesc1(&desc); + _adapter->GetDesc1(&desc); String description = WStringToString(desc.Description); return description; } Uint GraphicsAdapter::DeviceId() const { - auto& p = ip_GraphicsAdapter; DXGI_ADAPTER_DESC1 desc; - p->_adapter->GetDesc1(&desc); + _adapter->GetDesc1(&desc); return static_cast(desc.DeviceId); } String GraphicsAdapter::DeviceName() const { - auto& p = ip_GraphicsAdapter; - IDXGIOutput* pOutput = nullptr; DXGI_OUTPUT_DESC outputDesc; - if (p->_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { + if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { pOutput->GetDesc(&outputDesc); String deviceName = WStringToString(outputDesc.DeviceName); @@ -42,12 +35,10 @@ namespace xna { } intptr_t GraphicsAdapter::MonitorHandle() const { - auto& p = ip_GraphicsAdapter; - IDXGIOutput* pOutput = nullptr; DXGI_OUTPUT_DESC outputDesc; - if (p->_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { + if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { pOutput->GetDesc(&outputDesc); pOutput->Release(); @@ -60,37 +51,33 @@ namespace xna { } Uint GraphicsAdapter::Revision() const { - auto& p = ip_GraphicsAdapter; DXGI_ADAPTER_DESC1 desc; - p->_adapter->GetDesc1(&desc); + _adapter->GetDesc1(&desc); return static_cast(desc.Revision); } Uint GraphicsAdapter::SubSystemId() const { - auto& p = ip_GraphicsAdapter; DXGI_ADAPTER_DESC1 desc; - p->_adapter->GetDesc1(&desc); + _adapter->GetDesc1(&desc); return static_cast(desc.SubSysId); } Uint GraphicsAdapter::VendorId() const { - auto& p = ip_GraphicsAdapter; DXGI_ADAPTER_DESC1 desc; - p->_adapter->GetDesc1(&desc); + _adapter->GetDesc1(&desc); return static_cast(desc.VendorId); } PDisplayModeCollection GraphicsAdapter::SupportedDisplayModes() const { - auto& p = ip_GraphicsAdapter; IDXGIOutput* pOutput = nullptr; UINT numModes = 0; UINT totalModes = 0; std::vector buffer(250); - if (p->_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { + if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) { const auto currentSurface = static_cast(f); DXGI_FORMAT format = SurfaceFormatMapper::ParseToDXGI(currentSurface); @@ -100,8 +87,8 @@ namespace xna { if (numModes == 0) continue; - if (buffer.size() < totalModes + numModes) - buffer.resize(totalModes * 2); + if (buffer.size() < static_cast(totalModes) + numModes) + buffer.resize(static_cast(totalModes * 2)); pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data() + totalModes); @@ -127,7 +114,7 @@ namespace xna { return New(); } - std::vector GraphicsAdapter::getAllAdapters() { + std::vector IGraphicsAdapter::getAllAdapters() { IDXGIFactory1* pFactory = nullptr; std::vector adapters; @@ -140,9 +127,10 @@ namespace xna { for (; pFactory->EnumAdapters1(count, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++count) { auto adp = New(); - const auto& p = adp->ip_GraphicsAdapter; + + adp->_index = count; + adp->_adapter = pAdapter; - p->_adapter = pAdapter; adapters.push_back(adp); } diff --git a/framework/platform/adapter-dx.hpp b/framework/platform/adapter-dx.hpp index 4762356..fa18145 100644 --- a/framework/platform/adapter-dx.hpp +++ b/framework/platform/adapter-dx.hpp @@ -6,23 +6,29 @@ #include "d3d11.h" namespace xna { - class GraphicsAdapter::InternalProperty { - friend class GraphicsAdapter; - + class GraphicsAdapter : public IGraphicsAdapter { public: - InternalProperty() { - } + GraphicsAdapter() {} - ~InternalProperty() { + virtual ~GraphicsAdapter() override { if (_adapter) { _adapter->Release(); _adapter = nullptr; } } + virtual String Description() const override; + virtual Uint DeviceId() const override; + virtual String DeviceName() const override; + virtual intptr_t MonitorHandle() const override; + virtual Uint Revision() const override; + virtual Uint SubSystemId() const override; + virtual Uint VendorId() const override; + virtual PDisplayModeCollection SupportedDisplayModes() const override; + public: - IDXGIAdapter1* _adapter{ nullptr }; - }; + IDXGIAdapter1* _adapter{ nullptr }; + }; struct SurfaceFormatMapper { static constexpr DXGI_FORMAT ParseToDXGI(SurfaceFormat format) diff --git a/framework/platform/blendstate-dx.cpp b/framework/platform/blendstate-dx.cpp index 8b64c97..c2beabe 100644 --- a/framework/platform/blendstate-dx.cpp +++ b/framework/platform/blendstate-dx.cpp @@ -2,8 +2,8 @@ #include "device-dx.hpp" namespace xna { - BlendState::BlendState(GraphicsDevice* device) : _device(device) { - ip_BlendState = New(); + BlendState::BlendState(GraphicsDevice* device) { + _device = device; } bool BlendState::Apply(GraphicsDevice* device) { @@ -23,12 +23,51 @@ namespace xna { if (_device == nullptr || _device != device) _device = device; - auto& p = _device->ip_GraphicsDevice; - if FAILED(p->_device->CreateBlendState(&blendDesc, &ip_BlendState->_blendState)) + if FAILED(_device->_device->CreateBlendState(&blendDesc, &_blendState)) return false; - p->_context->OMSetBlendState(ip_BlendState->_blendState, nullptr, 0xffffffff); + _device->_context->OMSetBlendState(_blendState, nullptr, 0xffffffff); return true; } + + PBlendState IBlendState::Opaque() { + auto blendState = New(nullptr); + blendState->_source = Blend::SourceAlpha; + blendState->_sourceAlpha = Blend::SourceAlpha; + blendState->_destination = Blend::Zero; + blendState->_destinationAlpha = Blend::Zero; + + return blendState; + } + + PBlendState IBlendState::AlphaBlend() { + auto blendState = New(nullptr); + blendState->_source = Blend::One; + blendState->_sourceAlpha = Blend::One; + blendState->_destination = Blend::InverseSourceAlpha; + blendState->_destinationAlpha = Blend::InverseSourceAlpha; + + return blendState; + } + + PBlendState IBlendState::Additive() { + auto blendState = New(nullptr); + blendState->_source = Blend::SourceAlpha; + blendState->_sourceAlpha = Blend::SourceAlpha; + blendState->_destination = Blend::One; + blendState->_destinationAlpha = Blend::One; + + return blendState; + } + + PBlendState IBlendState::NonPremultiplied() { + auto blendState = New(nullptr); + blendState->_source = Blend::SourceAlpha; + blendState->_sourceAlpha = Blend::SourceAlpha; + blendState->_destination = Blend::InverseSourceAlpha; + blendState->_destinationAlpha = Blend::InverseSourceAlpha; + + return blendState; + } } \ No newline at end of file diff --git a/framework/platform/blendstate-dx.hpp b/framework/platform/blendstate-dx.hpp index f392ad3..83bbb0b 100644 --- a/framework/platform/blendstate-dx.hpp +++ b/framework/platform/blendstate-dx.hpp @@ -6,20 +6,23 @@ #include "d3d11.h" namespace xna { - class BlendState::InternalProperty { - friend class BlendState; - friend class GraphicsDevice; + class BlendState : public IBlendState { public: - ~InternalProperty() { + BlendState(GraphicsDevice* device); + + virtual ~BlendState() override { if (_blendState) { _blendState->Release(); _blendState = nullptr; } } - private: - ID3D11BlendState* _blendState{ nullptr }; - }; + virtual bool Apply(GraphicsDevice* device) override; + + public: + ID3D11BlendState* _blendState{ nullptr }; + GraphicsDevice* _device{ nullptr }; + }; struct BlendMapper { static constexpr D3D11_BLEND ConvertBlend(Blend blend) { diff --git a/framework/platform/device-dx.cpp b/framework/platform/device-dx.cpp index e130a83..eb6cbb7 100644 --- a/framework/platform/device-dx.cpp +++ b/framework/platform/device-dx.cpp @@ -3,28 +3,25 @@ #include "swapchain-dx.hpp" #include "rendertarget-dx.hpp" #include "adapter-dx.hpp" +#include "blendstate-dx.hpp" namespace xna { - GraphicsDevice::GraphicsDevice() { - _adapter = New(); + GraphicsDevice::GraphicsDevice() { _blendState = BlendState::NonPremultiplied(); - _adapter = GraphicsAdapter::DefaultAdapter(); - - ip_GraphicsDevice = New(); + _adapter = GraphicsAdapter::DefaultAdapter(); } - bool GraphicsDevice::Initialize(GameWindow& gameWindow) { - auto& p = ip_GraphicsDevice; - p->_createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; + bool GraphicsDevice::Initialize(GameWindow& gameWindow) { + _createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; - if (p->_device) { - p->_device->Release(); - p->_device = nullptr; + if (_device) { + _device->Release(); + _device = nullptr; } - if (p->_context) { - p->_context->Release(); - p->_context = nullptr; + if (_context) { + _context->Release(); + _context = nullptr; } const auto bounds = gameWindow.ClientBounds(); @@ -33,43 +30,14 @@ namespace xna { static_cast(bounds.Height), 0.0F, 1.F); - if FAILED( - D3D11CreateDevice( - _adapter->ip_GraphicsAdapter->_adapter, // adaptador de vídeo (NULL = adaptador padrão) - D3D_DRIVER_TYPE_HARDWARE, // tipo de driver D3D (Hardware, Reference ou Software) - NULL, // ponteiro para rasterizador em software - p->_createDeviceFlags, // modo de depuração ou modo normal - NULL, // featureLevels do Direct3D (NULL = maior suportada) - 0, // tamanho do vetor featureLevels - D3D11_SDK_VERSION, // versão do SDK do Direct3D - &p->_device, // guarda o dispositivo D3D criado - &p->_featureLevel, // versão do Direct3D utilizada - &p->_context)) // contexto do dispositivo D3D - { - // sistema não suporta dispositivo D3D11 - // fazendo a criação de um WARP Device que - // implementa um rasterizador em software - if FAILED(D3D11CreateDevice( - NULL, - D3D_DRIVER_TYPE_WARP, - NULL, - p->_createDeviceFlags, - NULL, - 0, - D3D11_SDK_VERSION, - &p->_device, - &p->_featureLevel, - &p->_context)) - return false; + if (!createDevice()) + return false; - OutputDebugString("---> Usando Adaptador WARP: não há suporte ao D3D11\n"); - } - - COLORREF color = gameWindow.ip_GameWindow->Color(); - p->_backgroundColor[0] = GetRValue(color) / 255.0f; - p->_backgroundColor[1] = GetGValue(color) / 255.0f; - p->_backgroundColor[2] = GetBValue(color) / 255.0f; - p->_backgroundColor[3] = 1.0f; + COLORREF color = gameWindow.Color(); + _backgroundColor[0] = GetRValue(color) / 255.0f; + _backgroundColor[1] = GetGValue(color) / 255.0f; + _backgroundColor[2] = GetBValue(color) / 255.0f; + _backgroundColor[3] = 1.0f; if (!_swapChain) _swapChain = New(this); @@ -83,7 +51,7 @@ namespace xna { if FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&dxgiFactory)) return false; - if FAILED(dxgiFactory->MakeWindowAssociation(gameWindow.ip_GameWindow->WindowHandle(), DXGI_MWA_NO_ALT_ENTER)) + if FAILED(dxgiFactory->MakeWindowAssociation(gameWindow.WindowHandle(), DXGI_MWA_NO_ALT_ENTER)) return false; if (!_renderTarget2D) { @@ -101,7 +69,7 @@ namespace xna { view.MinDepth = _viewport.MinDetph; view.MaxDepth = _viewport.MaxDepth; - p->_context->RSSetViewports(1, &view); + _context->RSSetViewports(1, &view); _blendState->Apply(this); @@ -109,19 +77,57 @@ namespace xna { } bool GraphicsDevice::Present() { - _swapChain->ip_SwapChain->_swapChain->Present(false, NULL); - auto& p = ip_GraphicsDevice; - auto& pr = _renderTarget2D->ip_RenderTarget2D; - - p->_context->OMSetRenderTargets(1, &pr->_renderTargetView, nullptr); + _swapChain->_swapChain->Present(_usevsync, NULL); + _context->OMSetRenderTargets(1, &_renderTarget2D->_renderTargetView, nullptr); return true; } - void GraphicsDevice::Clear() { - auto& p = ip_GraphicsDevice; - auto& pr = _renderTarget2D->ip_RenderTarget2D; + bool GraphicsDevice::GetSwapChainBackBuffer(ID3D11Texture2D*& texture2D) { + if FAILED(_swapChain->_swapChain->GetBuffer(0, __uuidof(texture2D), (void**)(&texture2D))) + return false; - p->_context->ClearRenderTargetView(pr->_renderTargetView, p->_backgroundColor); + return true; + } + + bool GraphicsDevice::createDevice() { +#if _DEBUG + _createDeviceFlags |= D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_DEBUG; +#endif + + if FAILED( + D3D11CreateDevice( + _adapter->_adapter, + D3D_DRIVER_TYPE_UNKNOWN, + NULL, + _createDeviceFlags, + NULL, + 0, + D3D11_SDK_VERSION, + &_device, + &_featureLevel, + &_context)) { + + if FAILED(D3D11CreateDevice( + NULL, + D3D_DRIVER_TYPE_WARP, + NULL, + _createDeviceFlags, + NULL, + 0, + D3D11_SDK_VERSION, + &_device, + &_featureLevel, + &_context)) + return false; + + OutputDebugString("---> Usando Adaptador WARP: não há suporte ao D3D11\n"); + } + + return true; + } + + void GraphicsDevice::Clear() { + _context->ClearRenderTargetView(_renderTarget2D->_renderTargetView, _backgroundColor); } } \ No newline at end of file diff --git a/framework/platform/device-dx.hpp b/framework/platform/device-dx.hpp index b8b82a8..865a528 100644 --- a/framework/platform/device-dx.hpp +++ b/framework/platform/device-dx.hpp @@ -6,13 +6,11 @@ #include "d3d11.h" namespace xna { - class GraphicsDevice::InternalProperty { - friend class GraphicsDevice; - + class GraphicsDevice : public IGraphicsDevice { public: - InternalProperty() {} + GraphicsDevice(); - ~InternalProperty() { + virtual ~GraphicsDevice() override { if (_device) { _device->Release(); _device = nullptr; @@ -24,6 +22,10 @@ namespace xna { } } + virtual void Clear() override; + virtual bool Initialize(GameWindow& gameWindow) override; + virtual bool Present() override; + constexpr void SetCreateFlags(D3D11_CREATE_DEVICE_FLAG flags) { _createDeviceFlags |= flags; } @@ -32,6 +34,8 @@ namespace xna { _createDeviceFlags = 0; } + bool GetSwapChainBackBuffer(ID3D11Texture2D*& texture2D); + public: ID3D11Device* _device{ nullptr }; ID3D11DeviceContext* _context{ nullptr }; @@ -40,7 +44,9 @@ namespace xna { unsigned int _createDeviceFlags{ 0 }; D3D_FEATURE_LEVEL _featureLevel{ D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_0 }; float _backgroundColor[4] = { 0, 0, 0, 0 }; - }; + + bool createDevice(); + }; } #endif \ No newline at end of file diff --git a/framework/platform/game-dx.cpp b/framework/platform/game-dx.cpp new file mode 100644 index 0000000..189f18a --- /dev/null +++ b/framework/platform/game-dx.cpp @@ -0,0 +1,50 @@ +#include "game-dx.hpp" +#include "window-dx.hpp" +#include "device-dx.hpp" +#include "Windows.h" + +namespace xna { + Game::Game() { + _gameWindow = New(); + _gameWindow->Color(255, 155, 55); + _gameWindow->Title("Teste de título"); + + _graphicsDevice = New(); + } + + int Game::Run() { + if (!_gameWindow->Create()) { + MessageBox(nullptr, "Falha na criação da janela", "Xna Game Engine", MB_OK); + return EXIT_FAILURE; + } + + if (!_graphicsDevice->Initialize(*_gameWindow)) { + MessageBox(nullptr, "Falha na inicialização do dispositivo gráfico", "Xna Game Engine", MB_OK); + return EXIT_FAILURE; + } + + return startLoop(); + } + + int Game::startLoop() { + MSG msg{}; + + do { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + else { + GameTime gt; + this->Update(gt); + _graphicsDevice->Clear(); + this->Draw(gt); + _graphicsDevice->Present(); + } + + } while (msg.message != WM_QUIT); + + return msg.wParam; + } +} diff --git a/framework/platform/game-dx.hpp b/framework/platform/game-dx.hpp new file mode 100644 index 0000000..8a6b327 --- /dev/null +++ b/framework/platform/game-dx.hpp @@ -0,0 +1,32 @@ +#ifndef XNA_PLATFORM_GAME_DX_HPP +#define XNA_PLATFORM_GAME_DX_HPP + +#include "../game/game.hpp" +#include "dxgi.h" +#include "d3d11.h" + +namespace xna { + class Game : public IGame { + public: + Game(); + + virtual ~Game() override { + } + + virtual void Exit() override{} + virtual int Run() override; + + protected: + virtual void Draw(GameTime const& gameTime) override{} + virtual void Initialize() override{} + virtual void Update(GameTime const& gameTime) override{} + + private: + PGameWindow _gameWindow{ nullptr }; + PGraphicsDevice _graphicsDevice{ nullptr }; + + int startLoop(); + }; +} + +#endif \ No newline at end of file diff --git a/framework/platform/rendertarget-dx.cpp b/framework/platform/rendertarget-dx.cpp index 04de000..b75ba07 100644 --- a/framework/platform/rendertarget-dx.cpp +++ b/framework/platform/rendertarget-dx.cpp @@ -4,30 +4,26 @@ #include "device-dx.hpp" namespace xna { - RenderTarget2D::RenderTarget2D(GraphicsDevice* device) : _device(device) { - this->ip_RenderTarget2D = New(); + RenderTarget2D::RenderTarget2D(GraphicsDevice* device) { + _device = device; } bool RenderTarget2D::Apply() { - auto& p1 = this->ip_Texture2D; - auto swapChain = _device->GetSwapChain(); - - if (p1->_texture2D) { - p1->_texture2D->Release(); - p1->_texture2D = nullptr; + if (_texture2D) { + _texture2D->Release(); + _texture2D = nullptr; } - if (!swapChain->ip_SwapChain->GetBackBuffer(p1->_texture2D)) + if (!_device->GetSwapChainBackBuffer(_texture2D)) return false; - auto& device = _device->ip_GraphicsDevice->_device; - auto& p2 = this->ip_RenderTarget2D; + auto& device = _device->_device; - if FAILED(device->CreateRenderTargetView(p1->_texture2D, NULL, &p2->_renderTargetView)) + if FAILED(device->CreateRenderTargetView(_texture2D, NULL, &_renderTargetView)) return false; - auto& context = _device->ip_GraphicsDevice->_context; - context->OMSetRenderTargets(1, &p2->_renderTargetView, nullptr); + auto& context = _device->_context; + context->OMSetRenderTargets(1, &_renderTargetView, nullptr); return true; } diff --git a/framework/platform/rendertarget-dx.hpp b/framework/platform/rendertarget-dx.hpp index 0a913b9..a07fe1f 100644 --- a/framework/platform/rendertarget-dx.hpp +++ b/framework/platform/rendertarget-dx.hpp @@ -7,13 +7,21 @@ #include "d3d11.h" namespace xna { - class RenderTarget2D::InternalProperty { - friend class RenderTarget2D; - friend class GraphicsDevice; + class RenderTarget2D : public IRenderTarget2D, public Texture2D { public: + RenderTarget2D(GraphicsDevice* device); - private: - ID3D11RenderTargetView* _renderTargetView; + virtual ~RenderTarget2D() override { + if (_renderTargetView) { + _renderTargetView->Release(); + _renderTargetView = nullptr; + } + } + + virtual bool Apply() override; + + public: + ID3D11RenderTargetView* _renderTargetView = nullptr; }; } diff --git a/framework/platform/swapchain-dx.cpp b/framework/platform/swapchain-dx.cpp index ab54800..7fba654 100644 --- a/framework/platform/swapchain-dx.cpp +++ b/framework/platform/swapchain-dx.cpp @@ -4,46 +4,41 @@ #include "device-dx.hpp" namespace xna { - SwapChain::SwapChain(GraphicsDevice* device) : - _device(device) { - ip_SwapChain = New(); + SwapChain::SwapChain(GraphicsDevice* device){ + _device = device; } bool SwapChain::Initialize(GameWindow const& gameWindow) { - auto& p = ip_SwapChain; - const auto bounds = gameWindow.ClientBounds(); - p->_swapDescription.BufferDesc.Width = static_cast(bounds.Width); - p->_swapDescription.BufferDesc.Height = static_cast(bounds.Height); - p->_swapDescription.BufferDesc.RefreshRate.Numerator = 60; - p->_swapDescription.BufferDesc.RefreshRate.Denominator = 1; - p->_swapDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - p->_swapDescription.SampleDesc.Count = 1; - p->_swapDescription.SampleDesc.Quality = 0; - p->_swapDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - p->_swapDescription.BufferCount = 2; - p->_swapDescription.OutputWindow = gameWindow.ip_GameWindow->WindowHandle(); - p->_swapDescription.Windowed = gameWindow.ip_GameWindow->Mode() != GameWindowMode::Fullscreen; - p->_swapDescription.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - p->_swapDescription.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + _swapDescription.BufferDesc.Width = static_cast(bounds.Width); + _swapDescription.BufferDesc.Height = static_cast(bounds.Height); + _swapDescription.BufferDesc.RefreshRate.Numerator = 60; + _swapDescription.BufferDesc.RefreshRate.Denominator = 1; + _swapDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + _swapDescription.SampleDesc.Count = 1; + _swapDescription.SampleDesc.Quality = 0; + _swapDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + _swapDescription.BufferCount = 2; + _swapDescription.OutputWindow = gameWindow.WindowHandle(); + _swapDescription.Windowed = gameWindow.Mode() != GameWindowMode::Fullscreen; + _swapDescription.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + _swapDescription.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; return true; } - bool SwapChain::Apply() { - auto& p = ip_SwapChain; - + bool SwapChain::Apply() { auto adapter = _device->Adapter(); - auto dxAdapter = adapter->ip_GraphicsAdapter->_adapter; + auto dxAdapter = adapter->_adapter; IDXGIFactory* dxFactory = nullptr; if FAILED(dxAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxFactory)) return false; - auto dxdevice = _device->ip_GraphicsDevice->_device; + auto dxdevice = _device->_device; - if FAILED(dxFactory->CreateSwapChain(dxdevice, &p->_swapDescription, &p->_swapChain)) + if FAILED(dxFactory->CreateSwapChain(dxdevice, &_swapDescription, &_swapChain)) return false; dxFactory->Release(); diff --git a/framework/platform/swapchain-dx.hpp b/framework/platform/swapchain-dx.hpp index a7d6b2c..f74bc76 100644 --- a/framework/platform/swapchain-dx.hpp +++ b/framework/platform/swapchain-dx.hpp @@ -7,19 +7,20 @@ #include "d3d11.h" namespace xna { - class SwapChain::InternalProperty { - friend class SwapChain; - friend class GraphicsDevice; + class SwapChain : public ISwapChain{ public: - InternalProperty(){} + SwapChain(GraphicsDevice* device); - ~InternalProperty() { + virtual ~SwapChain() override { if (_swapChain) { _swapChain->Release(); _swapChain = nullptr; } } + virtual bool Initialize(GameWindow const& gameWindow) override; + virtual bool Apply() override; + bool GetBackBuffer(ID3D11Texture2D*& texture2D) { if FAILED(_swapChain->GetBuffer(0, __uuidof(texture2D), (void**)(&texture2D))) return false; @@ -27,10 +28,11 @@ namespace xna { return true; } - private: - IDXGISwapChain* _swapChain{nullptr}; - DXGI_SWAP_CHAIN_DESC _swapDescription{}; - }; + public: + IDXGISwapChain* _swapChain{ nullptr }; + DXGI_SWAP_CHAIN_DESC _swapDescription{}; + GraphicsDevice* _device{ nullptr }; + }; } #endif \ No newline at end of file diff --git a/framework/platform/texture-dx.cpp b/framework/platform/texture-dx.cpp index 9e35d9c..93ca7c6 100644 --- a/framework/platform/texture-dx.cpp +++ b/framework/platform/texture-dx.cpp @@ -1,7 +1,6 @@ #include "texture-dx.hpp" namespace xna { - Texture2D::Texture2D() { - ip_Texture2D = New(); + Texture2D::Texture2D() { } } \ No newline at end of file diff --git a/framework/platform/texture-dx.hpp b/framework/platform/texture-dx.hpp index c0ab4d9..7bb8db5 100644 --- a/framework/platform/texture-dx.hpp +++ b/framework/platform/texture-dx.hpp @@ -6,13 +6,18 @@ #include "d3d11.h" namespace xna { - class Texture2D::InternalProperty { - friend class Texture2D; - friend class GraphicsDevice; - friend class RenderTarget2D; - public: + class Texture2D : public ITexture2D { + public: + Texture2D(); - private: + virtual ~Texture2D() override { + if (_texture2D) { + _texture2D->Release(); + _texture2D = nullptr; + } + } + + public: ID3D11Texture2D* _texture2D{nullptr}; }; } diff --git a/framework/platform/window-dx.cpp b/framework/platform/window-dx.cpp index 838b27a..4bdf7fc 100644 --- a/framework/platform/window-dx.cpp +++ b/framework/platform/window-dx.cpp @@ -2,30 +2,27 @@ namespace xna { GameWindow::GameWindow() { - ip_GameWindow = New(this); - auto& p = ip_GameWindow; + _hInstance = GetModuleHandle(NULL); + _windowIcon = LoadIcon(NULL, IDI_APPLICATION); + _windowCursor = LoadCursor(NULL, IDC_ARROW); + _windowStyle = static_cast(GameWindowMode::Windowed); + _windowCenterX = _windowWidth / 2.0F; + _windowCenterY = _windowHeight / 2.0F; - p->_hInstance = GetModuleHandle(NULL); - p->_windowIcon = LoadIcon(NULL, IDI_APPLICATION); - p->_windowCursor = LoadCursor(NULL, IDC_ARROW); - p->_windowStyle = static_cast(GameWindowMode::Windowed); - p->_windowCenterX = p->_windowWidth / 2.0F; - p->_windowCenterY = p->_windowHeight / 2.0F; + } + + void GameWindow::Size(int width, int height) { + _windowWidth = width; + _windowHeight = height; + setPosition(); + setCenter(); } void GameWindow::Title(String const& title) { - ip_GameWindow->_windowTitle = title; - } + _windowTitle = title; + } - void GameWindow::InternalProperty::Size(int width, int height) { - _windowWidth = width; - _windowHeight = height; - - setCenter(); - setPosition(); - } - - bool GameWindow::InternalProperty::Create() { + bool GameWindow::Create() { WNDCLASSEX wndClass{}; wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; @@ -75,27 +72,29 @@ namespace xna { TRUE); return _windowHandle ? true : false; - } + } + + return true; } String GameWindow::Title() const { - return ip_GameWindow->_windowTitle; + return _windowTitle; } Rectangle GameWindow::ClientBounds() const { return Rectangle( - ip_GameWindow->_windowPosX, - ip_GameWindow->_windowPosY, - ip_GameWindow->_windowWidth, - ip_GameWindow->_windowHeight + _windowPosX, + _windowPosY, + _windowWidth, + _windowHeight ); } intptr_t GameWindow::Handle() const { - return reinterpret_cast(ip_GameWindow->_windowHandle); + return reinterpret_cast(_windowHandle); } - LRESULT GameWindow::InternalProperty::WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) + LRESULT GameWindow::WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: diff --git a/framework/platform/window-dx.hpp b/framework/platform/window-dx.hpp index 3786481..32c9891 100644 --- a/framework/platform/window-dx.hpp +++ b/framework/platform/window-dx.hpp @@ -13,11 +13,9 @@ namespace xna { Borderless = WS_EX_TOPMOST | WS_POPUP | WS_VISIBLE, }; - class GameWindow::InternalProperty { - friend class GameWindow; + class GameWindow : public IGameWindow { public: - InternalProperty(GameWindow* gamewindow) : - _gamewindow(gamewindow){} + GameWindow(); constexpr void Mode(GameWindowMode mode) { _windowStyle = static_cast(mode); @@ -52,7 +50,7 @@ namespace xna { inline void Icon(HICON icon) { _windowIcon = icon; } - + inline void Cursor(unsigned int cursor) { _windowCursor = LoadCursor(GetModuleHandle(NULL), MAKEINTRESOURCE(cursor)); } @@ -81,7 +79,7 @@ namespace xna { return _windowColor; } - inline void Color(COLORREF color) { + inline void Color(COLORREF color) { _windowColor = color; } @@ -92,7 +90,12 @@ namespace xna { bool Create(); static LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); - private: + virtual String Title() const override; + virtual void Title(String const& title) override; + virtual Rectangle ClientBounds() const override; + virtual intptr_t Handle() const override; + + private: HINSTANCE _hInstance{ nullptr }; HWND _windowHandle{ nullptr }; int _windowWidth{ 800 }; @@ -108,8 +111,6 @@ namespace xna { float _windowCenterY{ 0 }; private: - GameWindow* _gamewindow = nullptr; - inline void setPosition() { _windowPosX = GetSystemMetrics(SM_CXSCREEN) / 2 - _windowWidth / 2; _windowPosY = GetSystemMetrics(SM_CYSCREEN) / 2 - _windowHeight / 2; @@ -118,7 +119,7 @@ namespace xna { inline void setCenter() { _windowCenterX = _windowWidth / 2.0f; _windowCenterY = _windowHeight / 2.0f; - } + } }; } diff --git a/framework/timespan.hpp b/framework/timespan.hpp new file mode 100644 index 0000000..37bba98 --- /dev/null +++ b/framework/timespan.hpp @@ -0,0 +1,231 @@ +#ifndef XNA_TIMESPAN_HPP +#define XNA_TIMESPAN_HPP + +#include +#include +#include "types.hpp" + +namespace xna { + struct TimeSpan { + static constexpr Long TicksPerMillisecond{ 10000 }; + static constexpr Long TicksPerSecond{ TicksPerMillisecond * 1000 }; + static constexpr Long TicksPerMinute{ TicksPerSecond * 60 }; + static constexpr Long TicksPerHour{ TicksPerMinute * 60 }; + static constexpr Long TicksPerDay{ TicksPerHour * 24 }; + + constexpr TimeSpan() = default; + constexpr TimeSpan(Long ticks) : + _ticks(ticks) {} + constexpr TimeSpan(Int hours, Int minutes, Int seconds) : + _ticks(TimeToTicks(hours, minutes, seconds)) {} + constexpr TimeSpan(Int days, Int hours, Int minutes, Int seconds) : + _ticks(DayToTicks(days, hours, minutes, seconds, 0)) {} + constexpr TimeSpan(Int days, Int hours, Int minutes, Int seconds, Int milliseconds) : + _ticks(DayToTicks(days, hours, minutes, seconds, milliseconds)) {} + + constexpr TimeSpan operator -(TimeSpan const& t) { + return TimeSpan(-t._ticks); + } + + constexpr TimeSpan operator +(TimeSpan const& t) { + return t; + } + + constexpr friend TimeSpan operator +(TimeSpan const& t1, TimeSpan const& t2) { + return t1.Add(t2); + } + + constexpr friend TimeSpan operator -(TimeSpan const& t1, TimeSpan const& t2) { + return t1.Subtract(t2); + } + + constexpr friend bool operator ==(TimeSpan const& t1, TimeSpan const& t2) { + return t1._ticks == t2._ticks; + } + + constexpr friend bool operator !=(TimeSpan const& t1, TimeSpan const& t2) { + return t1._ticks != t2._ticks; + } + + constexpr friend bool operator <(TimeSpan const& t1, TimeSpan const& t2) { + return t1._ticks < t2._ticks; + } + + constexpr friend bool operator <=(TimeSpan const& t1, TimeSpan const& t2) { + return t1._ticks <= t2._ticks; + } + + constexpr friend bool operator >(TimeSpan const& t1, TimeSpan const& t2) { + return t1._ticks > t2._ticks; + } + + constexpr friend bool operator >=(TimeSpan const& t1, TimeSpan const& t2) { + return t1._ticks >= t2._ticks; + } + + static constexpr TimeSpan Zero() { + return TimeSpan(); + } + + static constexpr TimeSpan MaxValue() { + return TimeSpan(std::numeric_limits::max()); + } + + static constexpr TimeSpan MinValue() { + return TimeSpan(std::numeric_limits::min()); + } + + static constexpr Int Compare(TimeSpan const& t1, TimeSpan const& t2) { + if (t1._ticks > t2._ticks) + return 1; + + if (t1._ticks < t2._ticks) + return -1; + + return 0; + } + + static constexpr TimeSpan FromDays(double value) { + return Interval(value, MillisPerDay); + } + + static constexpr TimeSpan FromHours(double value) { + return Interval(value, MillisPerHour); + } + + static constexpr TimeSpan Interval(double value, Int scale) { + double tmp = value * scale; + double millis = tmp + (value >= 0 ? 0.5 : -0.5); + + return TimeSpan(static_cast(millis) * TicksPerMillisecond); + } + + static constexpr TimeSpan FromMilliseconds(double value) { + return Interval(value, 1); + } + + static constexpr TimeSpan FromMinutes(double value) { + return Interval(value, MillisPerMinute); + } + + static constexpr TimeSpan FromSeconds(double value) { + return Interval(value, MillisPerSecond); + } + + static constexpr TimeSpan FromTicks(Long value) { + return TimeSpan(value); + } + + constexpr Long Ticks() const { return _ticks; } + constexpr Int Days() const { return static_cast(_ticks / TicksPerDay); } + constexpr Int Hours() const { return static_cast((_ticks / TicksPerHour) % 24); } + constexpr Int Milliseconds() const { return static_cast((_ticks / TicksPerMillisecond) % 1000); } + constexpr Int Minutes() const { return static_cast((_ticks / TicksPerMinute) % 60); } + constexpr Int Seconds() const { return static_cast((_ticks / TicksPerSecond) % 60); } + constexpr double TotalDays() const { return static_cast(_ticks) * DaysPerTick; } + constexpr double TotalHours() const { return static_cast(_ticks) * HoursPerTick; } + + constexpr double TotalMilliseconds() const { + double temp = static_cast(_ticks) * MillisecondsPerTick; + + if (temp > MaxMilliSeconds) + return static_cast(MaxMilliSeconds); + + if (temp < MinMilliSeconds) + return static_cast(MinMilliSeconds); + + return temp; + } + + constexpr double TotalMinutes() const { return static_cast(_ticks) * MinutesPerTick; } + constexpr double TotalSeconds() const { return static_cast(_ticks) * SecondsPerTick; } + + constexpr TimeSpan Add(TimeSpan const& ts) const { + Long result = _ticks + ts._ticks; + + if ((_ticks >> 63 == ts._ticks >> 63) && (_ticks >> 63 != result >> 63)) { + return TimeSpan(result, true); + } + + return TimeSpan(result); + } + + constexpr TimeSpan Duration() const { + if (Ticks() == TimeSpan::MinValue().Ticks()) { + return TimeSpan(Ticks(), true); + } + + return TimeSpan(_ticks >= 0 ? _ticks : -_ticks); + } + + constexpr bool Equals(TimeSpan other) const { + return _ticks == other._ticks; + } + + constexpr TimeSpan Negate() const { + if (Ticks() == TimeSpan::MinValue().Ticks()) { + return TimeSpan(Ticks(), true); + } + + return TimeSpan(-_ticks); + } + + constexpr TimeSpan Subtract(TimeSpan const& ts) const { + Long result = _ticks - ts._ticks; + + if ((_ticks >> 63 != ts._ticks >> 63) && (_ticks >> 63 != result >> 63)) { + return TimeSpan(result, true); + } + + return TimeSpan(result); + } + + constexpr bool HasOverflowException() { + return hasOverflowException; + } + + private: + constexpr TimeSpan(Long ticks, bool overflow) : + _ticks(ticks), + hasOverflowException(overflow) { + } + + static constexpr double MillisecondsPerTick = 1.0 / TicksPerMillisecond; + static constexpr double SecondsPerTick = 1.0 / TicksPerSecond; + static constexpr double MinutesPerTick = 1.0 / TicksPerMinute; + static constexpr double HoursPerTick = 1.0 / TicksPerHour; + static constexpr double DaysPerTick = 1.0 / TicksPerDay; + static constexpr Int MillisPerSecond = 1000; + static constexpr Int MillisPerMinute = MillisPerSecond * 60; + static constexpr Int MillisPerHour = MillisPerMinute * 60; + static constexpr Int MillisPerDay = MillisPerHour * 24; + static constexpr Long MaxSeconds = std::numeric_limits::max() / TicksPerSecond; + static constexpr Long MinSeconds = std::numeric_limits::min() / TicksPerSecond; + static constexpr Long MaxMilliSeconds = std::numeric_limits::max() / TicksPerMillisecond; + static constexpr Long MinMilliSeconds = std::numeric_limits::min() / TicksPerMillisecond; + static constexpr Long TicksPerTenthSecond = TicksPerMillisecond * 100; + + bool hasOverflowException{ false }; + Long _ticks{ 0 }; + + constexpr static Long TimeToTicks(Int const& hour, Int const& minute, Int const& second) { + Long totalSeconds = + static_cast(hour) * 3600 + + static_cast(minute) * 60 + + static_cast(second); + + return totalSeconds * TicksPerSecond; + } + + constexpr static Long DayToTicks(Int days, Int hours, Int minutes, Int seconds, Int milliseconds) { + Long totalMilliSeconds = + (static_cast(days) * 3600 * 24 + + static_cast(hours) * 3600 + + static_cast(minutes) * 60 + seconds) * 1000 + milliseconds; + + return totalMilliSeconds * TicksPerMillisecond; + } + }; +} + +#endif \ No newline at end of file diff --git a/framework/xna.cpp b/framework/xna.cpp index 12d1f92..5420f38 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -13,28 +13,7 @@ using namespace xna; //} int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { - - GameWindow gw; - MSG msg = { 0 }; - gw.ip_GameWindow->Color(255, 155, 55); - gw.Title("Teste de título"); - gw.ip_GameWindow->Create(); - - GraphicsDevice device; - device.Initialize(gw); - - do { - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - else { - device.Clear(); - device.Present(); - } - - } while (msg.message != WM_QUIT); - + Game game; + game.Run(); return 0; } diff --git a/framework/xna.h b/framework/xna.h index 8f7c93e..4949622 100644 --- a/framework/xna.h +++ b/framework/xna.h @@ -8,6 +8,7 @@ #include "Windows.h" #include "game/window.hpp" #include "platform/window-dx.hpp" -#include "graphics/device.hpp" +#include "platform/device-dx.hpp" +#include "platform/game-dx.hpp" // TODO: Reference additional headers your program requires here.