1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00

213 lines
5.1 KiB
C++
Raw Permalink Normal View History

2024-07-13 22:55:36 -03:00
#include "xna/xna-dx.hpp"
2024-03-21 16:01:47 -03:00
namespace xna {
Game::Game() {
2024-05-24 22:57:41 -03:00
impl = unew<PlatformImplementation>();
services = snew<GameServiceContainer>();
2024-05-27 16:44:01 -03:00
auto iservice = reinterpret_pointer_cast<IServiceProvider>(services);
2024-08-01 16:10:05 -03:00
contentManager = snew<ContentManager>(services, "");
contentManager->mainGameService = iservice;
2024-05-06 10:32:17 -03:00
gameWindow = snew<GameWindow>();
gameWindow->impl->Color(146, 150, 154);
gameWindow->Title("XN65");
gameWindow->impl->Size(
GraphicsDeviceManager::DefaultBackBufferWidth,
GraphicsDeviceManager::DefaultBackBufferHeight, false);
2024-04-27 00:10:07 -03:00
gameComponents = snew<GameComponentCollection>();
2024-08-01 16:10:05 -03:00
IsFixedTimeStep(isFixedTimeStep);
TargetElapsedTime(targetElapsedTime);
2024-04-24 10:11:53 -03:00
}
2024-04-20 13:39:19 -03:00
2024-05-06 14:54:13 -03:00
void Game::Exit() {
gameWindow->impl->Close();
2024-04-22 16:14:55 -03:00
}
2024-05-24 22:57:41 -03:00
int Game::StartGameLoop() {
MSG msg{};
2024-08-01 16:33:06 -03:00
impl->_stepTimer = xna::StepTimer();
2024-05-24 22:57:41 -03:00
do {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
2024-08-01 16:10:05 -03:00
Tick();
2024-05-24 22:57:41 -03:00
}
} while (msg.message != WM_QUIT);
2024-08-01 16:33:06 -03:00
EndRun();
2024-05-24 22:57:41 -03:00
return static_cast<int>(msg.wParam);
}
2024-08-01 16:10:05 -03:00
void Game::Tick()
2024-05-24 22:57:41 -03:00
{
impl->_stepTimer.Tick([&]()
{
const auto elapsed = impl->_stepTimer.GetElapsedSeconds();
const auto total = impl->_stepTimer.GetTotalSeconds();
const auto elapsedTimeSpan = TimeSpan::FromSeconds(elapsed);
const auto totalTimeSpan = TimeSpan::FromSeconds(total);
currentGameTime.ElapsedGameTime = elapsedTimeSpan;
currentGameTime.TotalGameTime = totalTimeSpan;
Update(currentGameTime);
2024-05-24 22:57:41 -03:00
});
2024-08-01 16:33:06 -03:00
BeginDraw();
Draw(currentGameTime);
2024-08-01 16:33:06 -03:00
EndDraw();
2024-05-24 22:57:41 -03:00
}
2024-04-22 16:14:55 -03:00
int Game::Run() {
2024-08-01 16:10:05 -03:00
if (isRunning)
return EXIT_FAILURE;
2024-05-28 14:43:56 -03:00
try {
if (!gameWindow->impl->Create()) {
Exception::Throw(Exception::FAILED_TO_CREATE);
return false;
}
Initialize();
2024-05-28 14:43:56 -03:00
if (graphicsDevice == nullptr) {
MessageBox(nullptr, "O dispositivo gr<67>fico n<>o foi inicializado corretamente", "XN65", MB_OK);
return EXIT_FAILURE;
}
2024-03-21 16:01:47 -03:00
2024-08-01 16:10:05 -03:00
isRunning = true;
2024-08-01 16:33:06 -03:00
BeginRun();
2024-05-28 14:43:56 -03:00
return StartGameLoop();
}
catch (std::exception& e) {
MessageBox(nullptr, e.what(), "XN65", MB_OK);
2024-05-28 16:59:03 -03:00
return EXIT_FAILURE;
2024-05-28 14:43:56 -03:00
}
2024-04-27 15:21:47 -03:00
}
2024-04-23 16:11:17 -03:00
2024-05-27 21:12:46 -03:00
void Game::Initialize() {
2024-07-31 22:31:08 -03:00
Keyboard::Initialize();
Mouse::Initialize(gameWindow->Handle());
2024-05-21 16:21:01 -03:00
GamePad::Initialize();
2024-05-27 21:12:46 -03:00
AudioEngine::Initialize();
2024-04-24 10:11:53 -03:00
2024-04-20 13:39:19 -03:00
LoadContent();
}
2024-04-27 15:21:47 -03:00
void Game::Draw(GameTime const& gameTime) {
if (enabledGameComponents && !drawableGameComponents.empty()) {
const auto count = drawableGameComponents.size();
2024-04-27 15:21:47 -03:00
if (count != drawableGameComponentsCount && gameComponents->AutoSort) {
GameComponentCollection::DrawSort(drawableGameComponents);
drawableGameComponentsCount = count;
2024-04-27 15:21:47 -03:00
}
for (size_t i = 0; i < count; ++i) {
auto& component = drawableGameComponents[i];
2024-04-27 15:21:47 -03:00
if (!component) continue;
auto drawable = reinterpret_pointer_cast<IDrawable>(component);
if (drawable && drawable->Visible())
drawable->Draw(gameTime);
}
drawableGameComponents.clear();
2024-04-27 15:21:47 -03:00
}
2024-05-06 14:54:13 -03:00
graphicsDevice->Present();
2024-04-27 15:21:47 -03:00
}
2024-04-20 13:39:19 -03:00
void Game::Update(GameTime const& gameTime) {
audioEngine->Update();
2024-04-27 00:10:07 -03:00
if (enabledGameComponents && gameComponents->Count() > 0) {
const auto count = gameComponents->Count();
2024-04-27 15:21:47 -03:00
for (size_t i = 0; i < count; ++i) {
auto component = gameComponents->At(i);
2024-04-27 00:10:07 -03:00
if (!component) continue;
2024-04-27 15:21:47 -03:00
if (component->Type() == GameComponentType::Drawable) {
drawableGameComponents.push_back(component);
2024-04-27 15:21:47 -03:00
}
2024-04-27 00:10:07 -03:00
auto updatable = reinterpret_pointer_cast<IUpdateable>(component);
if(updatable && updatable->Enabled())
updatable->Update(gameTime);
2024-04-27 15:21:47 -03:00
}
2024-04-27 00:10:07 -03:00
}
2024-04-20 13:39:19 -03:00
}
2024-04-23 16:11:17 -03:00
sptr<GameWindow> Game::Window() { return gameWindow; }
2024-08-01 16:10:05 -03:00
sptr<GraphicsDevice> Game::Device() const { return graphicsDevice; }
sptr<GameComponentCollection> Game::Components() const { return gameComponents; }
2024-05-24 22:57:41 -03:00
sptr<GameServiceContainer> Game::Services() { return services; }
2024-08-01 16:10:05 -03:00
sptr<ContentManager> Game::Content() const { return contentManager; }
void Game::EnableGameComponents(bool value) { enabledGameComponents = value; }
void Game::AttachGraphicsDevice(sptr<GraphicsDevice> const& device) {
graphicsDevice = device;
}
void Game::ResizeWindow(int width, int heigth) {
const auto windowBounds = gameWindow->ClientBounds();
if (windowBounds.Width != width || windowBounds.Height != heigth) {
gameWindow->impl->Size(
width,
heigth);
gameWindow->impl->Update();
}
}
2024-08-01 16:10:05 -03:00
void Game::Content(sptr<ContentManager> const& value) {
contentManager = value;
auto iservice = reinterpret_pointer_cast<IServiceProvider>(services);
contentManager->mainGameService = iservice;
}
void Game::IsFixedTimeStep(bool value) {
isFixedTimeStep = value;
impl->_stepTimer.SetFixedTimeStep(value);
}
bool Game::IsMouseVisible() const {
if (!Mouse::impl)
return false;
return Mouse::impl->_dxMouse->IsVisible();
}
void Game::IsMouseVisible(bool value) {
if (!Mouse::impl)
return;
Mouse::impl->_dxMouse->SetVisible(value);
}
void Game::TargetElapsedTime(TimeSpan const& value) {
if (!isFixedTimeStep)
return;
const auto ticks = targetElapsedTime.Ticks();
impl->_stepTimer.SetTargetElapsedTicks(ticks);
}
void Game::ResetElapsedTime() const {
impl->_stepTimer.ResetElapsedTime();
}
void Game::RunOneFrame() {
Tick();
}
2024-03-21 16:01:47 -03:00
}