mirror of
https://github.com/risingPhil/PokeMe64.git
synced 2026-03-21 18:04:15 -05:00
177 lines
4.3 KiB
C++
Executable File
177 lines
4.3 KiB
C++
Executable File
#include "scenes/SceneManager.h"
|
|
#include "scenes/TestScene.h"
|
|
#include "scenes/StatsScene.h"
|
|
#include "scenes/PokeTransporterGBRefScene.h"
|
|
#include "scenes/AboutScene.h"
|
|
#include "scenes/InitTransferPakScene.h"
|
|
#include "scenes/DistributionPokemonListScene.h"
|
|
|
|
#include <libdragon.h>
|
|
|
|
static const uint16_t INPUT_BLOCK_TIME_AFTER_NEW_SCENE_IN_MS = 500;
|
|
|
|
SceneManager::SceneManager(RDPQGraphics& gfx, AnimationManager& animationManager, FontManager& fontManager, TransferPakManager& tpakManager)
|
|
: sceneHistory_()
|
|
, sceneDeps_(SceneDependencies{
|
|
.gfx = gfx,
|
|
.animationManager = animationManager,
|
|
.fontManager = fontManager,
|
|
.tpakManager = tpakManager,
|
|
.sceneManager = (*this),
|
|
.generation = 0,
|
|
.specificGenVersion = 0
|
|
})
|
|
, scene_(nullptr)
|
|
, newSceneType_(SceneType::NONE)
|
|
, newSceneContext_(nullptr)
|
|
, contextToDelete_(nullptr)
|
|
, deleteContextFunc_(nullptr)
|
|
{
|
|
}
|
|
|
|
SceneManager::~SceneManager()
|
|
{
|
|
unloadScene(scene_);
|
|
}
|
|
|
|
void SceneManager::switchScene(SceneType type, void (*deleteContextFunc)(void*), void* sceneContext, bool deleteHistory)
|
|
{
|
|
newSceneType_ = type;
|
|
newSceneContext_ = sceneContext;
|
|
|
|
if(deleteHistory)
|
|
{
|
|
clearHistory();
|
|
}
|
|
|
|
sceneHistory_.push_back(SceneHistorySegment{
|
|
.type = type,
|
|
.context = sceneContext,
|
|
.deleteContextFunc = deleteContextFunc
|
|
});
|
|
|
|
blockInputStartTime_ = get_ticks();
|
|
}
|
|
|
|
void SceneManager::goBackToPreviousScene()
|
|
{
|
|
{
|
|
SceneHistorySegment& curEntry = sceneHistory_.back();
|
|
contextToDelete_ = curEntry.context;
|
|
deleteContextFunc_ = curEntry.deleteContextFunc;
|
|
}
|
|
sceneHistory_.pop_back();
|
|
|
|
{
|
|
SceneHistorySegment& lastEntry = sceneHistory_.back();
|
|
newSceneType_ = lastEntry.type;
|
|
newSceneContext_ = lastEntry.context;
|
|
}
|
|
}
|
|
|
|
void SceneManager::clearHistory()
|
|
{
|
|
for(SceneHistorySegment& entry : sceneHistory_)
|
|
{
|
|
if(entry.context)
|
|
{
|
|
entry.deleteContextFunc(entry.context);
|
|
}
|
|
}
|
|
sceneHistory_.clear();
|
|
}
|
|
|
|
void SceneManager::handleUserInput()
|
|
{
|
|
if(!scene_)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(blockInputStartTime_)
|
|
{
|
|
const uint64_t now = get_ticks();
|
|
if(TICKS_TO_MS(now - blockInputStartTime_) < INPUT_BLOCK_TIME_AFTER_NEW_SCENE_IN_MS)
|
|
{
|
|
return;
|
|
}
|
|
// enough time has passed. reset the blockInputStartTime_
|
|
blockInputStartTime_ = 0;
|
|
}
|
|
|
|
scene_->processUserInput();
|
|
}
|
|
|
|
void SceneManager::render(const Rectangle& sceneBounds)
|
|
{
|
|
if(newSceneType_ != SceneType::NONE)
|
|
{
|
|
loadScene();
|
|
}
|
|
if(!scene_)
|
|
{
|
|
return;
|
|
}
|
|
|
|
scene_->render(sceneDeps_.gfx, sceneBounds);
|
|
}
|
|
|
|
void SceneManager::loadScene()
|
|
{
|
|
IScene* oldScene = scene_;
|
|
|
|
switch(newSceneType_)
|
|
{
|
|
case SceneType::INIT_TRANSFERPAK:
|
|
scene_ = new InitTransferPakScene(sceneDeps_, newSceneContext_);
|
|
break;
|
|
case SceneType::MENU:
|
|
scene_ = new MenuScene(sceneDeps_, newSceneContext_);
|
|
break;
|
|
case SceneType::DISTRIBUTION_POKEMON_LIST:
|
|
scene_ = new DistributionPokemonListScene(sceneDeps_, newSceneContext_);
|
|
break;
|
|
case SceneType::STATS:
|
|
scene_ = new StatsScene(sceneDeps_, newSceneContext_);
|
|
break;
|
|
case SceneType::TEST:
|
|
scene_ = new TestScene(sceneDeps_, newSceneContext_);
|
|
break;
|
|
case SceneType::POKETRANSPORTER_GB_REF:
|
|
scene_ = new PokeTransporterGBRefScene(sceneDeps_, newSceneContext_);
|
|
break;
|
|
case SceneType::ABOUT:
|
|
scene_ = new AboutScene(sceneDeps_, newSceneContext_);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if(!scene_)
|
|
{
|
|
scene_ = oldScene;
|
|
return;
|
|
}
|
|
unloadScene(oldScene);
|
|
|
|
if(contextToDelete_)
|
|
{
|
|
deleteContextFunc_(contextToDelete_);
|
|
contextToDelete_ = nullptr;
|
|
deleteContextFunc_ = nullptr;
|
|
}
|
|
|
|
scene_->init();
|
|
newSceneType_ = SceneType::NONE;
|
|
}
|
|
|
|
void SceneManager::unloadScene(IScene* scene)
|
|
{
|
|
if(!scene)
|
|
{
|
|
return;
|
|
}
|
|
|
|
scene->destroy();
|
|
delete scene;
|
|
} |