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>();
|
2024-06-22 11:52:21 -03:00
|
|
|
|
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
|
|
|
|
|
2024-08-01 16:41:50 -03:00
|
|
|
|
gameWindow = snew<GameWindow>();
|
|
|
|
|
gameWindow->impl->Color(146, 150, 154);
|
|
|
|
|
gameWindow->Title("XN65");
|
|
|
|
|
gameWindow->impl->Size(
|
2024-03-30 14:25:08 -03:00
|
|
|
|
GraphicsDeviceManager::DefaultBackBufferWidth,
|
|
|
|
|
GraphicsDeviceManager::DefaultBackBufferHeight, false);
|
2024-04-27 00:10:07 -03:00
|
|
|
|
|
2024-08-01 16:41:50 -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() {
|
2024-08-01 16:41:50 -03:00
|
|
|
|
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);
|
2024-08-01 16:41:50 -03:00
|
|
|
|
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();
|
2024-08-01 16:41:50 -03:00
|
|
|
|
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 {
|
2024-08-01 16:41:50 -03:00
|
|
|
|
if (!gameWindow->impl->Create()) {
|
2024-07-31 16:30:47 -03:00
|
|
|
|
Exception::Throw(Exception::FAILED_TO_CREATE);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Initialize();
|
2024-04-16 16:13:36 -03:00
|
|
|
|
|
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();
|
2024-08-01 16:41:50 -03:00
|
|
|
|
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) {
|
2024-08-01 16:41:50 -03:00
|
|
|
|
if (enabledGameComponents && !drawableGameComponents.empty()) {
|
|
|
|
|
const auto count = drawableGameComponents.size();
|
2024-04-27 15:21:47 -03:00
|
|
|
|
|
2024-08-01 16:41:50 -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) {
|
2024-08-01 16:41:50 -03:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-01 16:41:50 -03:00
|
|
|
|
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) {
|
2024-08-01 16:41:50 -03:00
|
|
|
|
audioEngine->Update();
|
2024-04-27 00:10:07 -03:00
|
|
|
|
|
2024-08-01 16:41:50 -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) {
|
2024-08-01 16:41:50 -03:00
|
|
|
|
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) {
|
2024-08-01 16:41:50 -03:00
|
|
|
|
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
|
|
|
|
|
2024-08-01 16:41:50 -03:00
|
|
|
|
sptr<GameWindow> Game::Window() { return gameWindow; }
|
2024-08-01 16:10:05 -03:00
|
|
|
|
sptr<GraphicsDevice> Game::Device() const { return graphicsDevice; }
|
2024-08-01 16:41:50 -03:00
|
|
|
|
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; }
|
2024-08-01 16:41:50 -03:00
|
|
|
|
void Game::EnableGameComponents(bool value) { enabledGameComponents = value; }
|
2024-07-31 21:42:25 -03:00
|
|
|
|
|
|
|
|
|
void Game::AttachGraphicsDevice(sptr<GraphicsDevice> const& device) {
|
|
|
|
|
graphicsDevice = device;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Game::ResizeWindow(int width, int heigth) {
|
2024-08-01 16:41:50 -03:00
|
|
|
|
const auto windowBounds = gameWindow->ClientBounds();
|
2024-07-31 21:42:25 -03:00
|
|
|
|
|
|
|
|
|
if (windowBounds.Width != width || windowBounds.Height != heigth) {
|
2024-08-01 16:41:50 -03:00
|
|
|
|
gameWindow->impl->Size(
|
2024-07-31 21:42:25 -03:00
|
|
|
|
width,
|
|
|
|
|
heigth);
|
2024-08-01 16:41:50 -03:00
|
|
|
|
gameWindow->impl->Update();
|
2024-07-31 21:42:25 -03:00
|
|
|
|
}
|
|
|
|
|
}
|
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
|
|
|
|
}
|