Removing most of legacy functionality

This commit is contained in:
emb
2015-10-31 23:21:52 -05:00
parent b8b93e0bed
commit afc59c22fd
23 changed files with 226 additions and 1447 deletions

View File

@@ -12,6 +12,7 @@ list(APPEND CMAKE_MODULE_PATH "${RETROFE_DIR}/CMake")
set(SQLITE3_ROOT "${RETROFE_THIRD_PARTY_DIR}/sqlite3")
set(RAPIDXML_ROOT "${RETROFE_THIRD_PARTY_DIR}/rapidxml-1.13")
set(LUA_ROOT "${RETROFE_THIRD_PARTY_DIR}/lua-5.3.0/src")
if(WIN32)
if(MSVC)
@@ -66,6 +67,8 @@ set(RETROFE_INCLUDE_DIRS
"${ZLIB_INCLUDE_DIRS}"
"${SQLITE3_ROOT}"
"${RAPIDXML_ROOT}"
"${LUA_ROOT}"
)
if(MSVC)
@@ -80,6 +83,7 @@ set(RETROFE_LIBRARIES
${SDL2_MIXER_LIBRARIES}
${SDL2_TTF_LIBRARIES}
${ZLIB_LIBRARIES}
LUA
)
if(NOT WIN32)
@@ -87,103 +91,26 @@ if(NOT WIN32)
endif()
set(RETROFE_HEADERS
"${RETROFE_DIR}/Source/Collection/CollectionInfo.h"
"${RETROFE_DIR}/Source/Collection/CollectionInfoBuilder.h"
"${RETROFE_DIR}/Source/Collection/Item.h"
"${RETROFE_DIR}/Source/Collection/MenuParser.h"
"${RETROFE_DIR}/Source/Control/UserInput.h"
"${RETROFE_DIR}/Source/Control/InputHandler.h"
"${RETROFE_DIR}/Source/Control/JoyAxisHandler.h"
"${RETROFE_DIR}/Source/Control/JoyButtonHandler.h"
"${RETROFE_DIR}/Source/Control/JoyHatHandler.h"
"${RETROFE_DIR}/Source/Control/KeyboardHandler.h"
"${RETROFE_DIR}/Source/Control/MouseButtonHandler.h"
"${RETROFE_DIR}/Source/Database/Configuration.h"
"${RETROFE_DIR}/Source/Database/DB.h"
"${RETROFE_DIR}/Source/Database/MetadataDatabase.h"
"${RETROFE_DIR}/Source/Execute/AttractMode.h"
"${RETROFE_DIR}/Source/Execute/Launcher.h"
"${RETROFE_DIR}/Source/Graphics/Animate/Tween.h"
"${RETROFE_DIR}/Source/Graphics/Animate/TweenTypes.h"
"${RETROFE_DIR}/Source/Graphics/Animate/TweenSet.h"
"${RETROFE_DIR}/Source/Graphics/Animate/Animation.h"
"${RETROFE_DIR}/Source/Graphics/Animate/AnimationEvents.h"
"${RETROFE_DIR}/Source/Graphics/ComponentItemBinding.h"
"${RETROFE_DIR}/Source/Graphics/Component/Container.h"
"${RETROFE_DIR}/Source/Graphics/Component/Component.h"
"${RETROFE_DIR}/Source/Graphics/Component/Image.h"
"${RETROFE_DIR}/Source/Graphics/Component/ImageBuilder.h"
"${RETROFE_DIR}/Source/Graphics/Component/ReloadableMedia.h"
"${RETROFE_DIR}/Source/Graphics/Component/ReloadableText.h"
"${RETROFE_DIR}/Source/Graphics/Component/ScrollingList.h"
"${RETROFE_DIR}/Source/Graphics/Component/Text.h"
"${RETROFE_DIR}/Source/Graphics/Component/VideoComponent.h"
"${RETROFE_DIR}/Source/Graphics/Component/VideoBuilder.h"
"${RETROFE_DIR}/Source/Graphics/Font.h"
"${RETROFE_DIR}/Source/Graphics/FontCache.h"
"${RETROFE_DIR}/Source/Graphics/PageBuilder.h"
"${RETROFE_DIR}/Source/Graphics/MenuNotifierInterface.h"
"${RETROFE_DIR}/Source/Graphics/Page.h"
"${RETROFE_DIR}/Source/Sound/Sound.h"
"${RETROFE_DIR}/Source/Utility/Log.h"
"${RETROFE_DIR}/Source/Utility/Utils.h"
"${RETROFE_DIR}/Source/Video/IVideo.h"
"${RETROFE_DIR}/Source/Video/GStreamerVideo.h"
"${RETROFE_DIR}/Source/Video/VideoFactory.h"
"${RETROFE_DIR}/Source/Graphics/ComponentItemBindingBuilder.h"
"${RETROFE_DIR}/Source/Graphics/ViewInfo.h"
"${RETROFE_DIR}/Source/Graphics/Component/Component.h"
"${RETROFE_DIR}/Source/Lua.h"
"${RETROFE_DIR}/Source/RetroFE.h"
"${RETROFE_DIR}/Source/SDL.h"
"${RETROFE_DIR}/Source/Version.h"
)
set(RETROFE_SOURCES
"${RETROFE_DIR}/Source/Collection/CollectionInfo.cpp"
"${RETROFE_DIR}/Source/Collection/CollectionInfoBuilder.cpp"
"${RETROFE_DIR}/Source/Collection/Item.cpp"
"${RETROFE_DIR}/Source/Collection/MenuParser.cpp"
"${RETROFE_DIR}/Source/Control/UserInput.cpp"
"${RETROFE_DIR}/Source/Control/JoyAxisHandler.cpp"
"${RETROFE_DIR}/Source/Control/JoyButtonHandler.cpp"
"${RETROFE_DIR}/Source/Control/JoyHatHandler.cpp"
"${RETROFE_DIR}/Source/Control/KeyboardHandler.cpp"
"${RETROFE_DIR}/Source/Control/MouseButtonHandler.cpp"
"${RETROFE_DIR}/Source/Database/Configuration.cpp"
"${RETROFE_DIR}/Source/Database/DB.cpp"
"${RETROFE_DIR}/Source/Database/MetadataDatabase.cpp"
"${RETROFE_DIR}/Source/Execute/AttractMode.cpp"
"${RETROFE_DIR}/Source/Execute/Launcher.cpp"
"${RETROFE_DIR}/Source/Graphics/Font.cpp"
"${RETROFE_DIR}/Source/Graphics/FontCache.cpp"
"${RETROFE_DIR}/Source/Graphics/PageBuilder.cpp"
"${RETROFE_DIR}/Source/Graphics/Page.cpp"
"${RETROFE_DIR}/Source/Graphics/ViewInfo.cpp"
"${RETROFE_DIR}/Source/Graphics/Animate/Animation.cpp"
"${RETROFE_DIR}/Source/Graphics/Animate/AnimationEvents.cpp"
"${RETROFE_DIR}/Source/Graphics/Animate/Tween.cpp"
"${RETROFE_DIR}/Source/Graphics/Animate/TweenSet.cpp"
"${RETROFE_DIR}/Source/Graphics/ComponentItemBindingBuilder.cpp"
"${RETROFE_DIR}/Source/Graphics/ComponentItemBinding.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/Container.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/Component.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/Image.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/ImageBuilder.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/Text.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/ReloadableMedia.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/ReloadableText.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/ScrollingList.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/VideoBuilder.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/VideoComponent.cpp"
"${RETROFE_DIR}/Source/Sound/Sound.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/Component.cpp"
"${RETROFE_DIR}/Source/Utility/Log.cpp"
"${RETROFE_DIR}/Source/Utility/Utils.cpp"
"${RETROFE_DIR}/Source/Video/GStreamerVideo.cpp"
"${RETROFE_DIR}/Source/Video/VideoFactory.cpp"
"${RETROFE_DIR}/Source/Lua.cpp"
"${RETROFE_DIR}/Source/Main.cpp"
"${RETROFE_DIR}/Source/RetroFE.cpp"
"${RETROFE_DIR}/Source/SDL.cpp"
"${RETROFE_DIR}/Source/Version.cpp"
"${SQLITE3_ROOT}/sqlite3.c"
)
@@ -199,6 +126,9 @@ if(MINGW)
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -lmingw32 -mwindows")
endif()
file(GLOB LUA_SRC ${LUA_ROOT}/*.c)
add_library( LUA STATIC ${LUA_SRC})
add_definitions(-DRETROFE_VERSION_MAJOR=${VERSION_MAJOR})
add_definitions(-DRETROFE_VERSION_MINOR=${VERSION_MINOR})
add_definitions(-DRETROFE_VERSION_BUILD=${VERSION_BUILD})

View File

@@ -40,6 +40,8 @@ Configuration::~Configuration()
void Configuration::initialize()
{
absolutePath = "C:/Users/Don/Downloads/RetroFE-FTP";
return;
const char *environment = std::getenv("RETROFE_PATH");
std::string environmentStr;
if (environment != NULL)

View File

@@ -14,7 +14,6 @@
* along with RetroFE. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AttractMode.h"
#include "../Graphics/Page.h"
#include <cstdlib>
@@ -33,7 +32,7 @@ void AttractMode::reset()
activeTime_ = 0;
}
void AttractMode::update(float dt, Page &page)
void AttractMode::update(float dt)
{
elapsedTime_ += dt;
@@ -47,13 +46,13 @@ void AttractMode::update(float dt, Page &page)
if(isActive_)
{
page.setScrolling(Page::ScrollDirectionForward);
//todo: enable scrolling
if(elapsedTime_ > activeTime_)
{
elapsedTime_ = 0;
isActive_ = false;
page.setScrolling(Page::ScrollDirectionIdle);
//todo: go to idle
}
}
}

View File

@@ -15,14 +15,12 @@
*/
#pragma once
class Page;
class AttractMode
{
public:
AttractMode();
void reset();
void update(float dt, Page &page);
void update(float dt);
float idleTime;
private:

View File

@@ -14,447 +14,7 @@
* along with RetroFE. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Component.h"
#include "../Animate/Tween.h"
#include "../../Graphics/ViewInfo.h"
#include "../../Utility/Log.h"
#include "../../SDL.h"
Component::Component(Page &p)
: page(p)
{
tweens_ = NULL;
newItemSelectedSinceEnter = false;
backgroundTexture_ = NULL;
freeGraphicsMemory();
}
Component::Component(const Component &copy)
: page(copy.page)
{
tweens_ = NULL;
newItemSelectedSinceEnter = false;
backgroundTexture_ = NULL;
freeGraphicsMemory();
if(copy.tweens_)
{
AnimationEvents *tweens = new AnimationEvents(*copy.tweens_);
setTweens(tweens);
}
}
Component::~Component()
{
freeGraphicsMemory();
}
void Component::freeGraphicsMemory()
{
currentAnimationState = HIDDEN;
enterRequested = false;
exitRequested = false;
menuEnterRequested = false;
menuEnterIndex = -1;
menuScrollRequested = false;
menuExitRequested = false;
menuExitIndex = -1;
newItemSelected = false;
playlistChanged = false;
highlightExitComplete = false;
currentTweens_ = NULL;
currentTweenIndex_ = 0;
currentTweenComplete_ = false;
elapsedTweenTime_ = 0;
scrollActive = false;
if(backgroundTexture_)
{
SDL_LockMutex(SDL::getMutex());
SDL_DestroyTexture(backgroundTexture_);
SDL_UnlockMutex(SDL::getMutex());
backgroundTexture_ = NULL;
}
}
void Component::allocateGraphicsMemory()
{
if(!backgroundTexture_)
{
// make a 4x4 pixel wide surface to be stretched during rendering, make it a white background so we can use
// color later
SDL_Surface *surface = SDL_CreateRGBSurface(0, 4, 4, 32, 0, 0, 0, 0);
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 255, 255, 255));
SDL_LockMutex(SDL::getMutex());
backgroundTexture_ = SDL_CreateTextureFromSurface(SDL::getRenderer(), surface);
SDL_UnlockMutex(SDL::getMutex());
SDL_FreeSurface(surface);
SDL_SetTextureBlendMode(backgroundTexture_, SDL_BLENDMODE_BLEND);
}
}
void Component::triggerEnterEvent()
{
enterRequested = true;
}
void Component::triggerExitEvent()
{
exitRequested = true;
}
void Component::triggerMenuEnterEvent(int menuIndex)
{
menuEnterRequested = true;
menuEnterIndex = menuIndex;
}
void Component::triggerMenuScrollEvent()
{
menuScrollRequested = true;
}
void Component::triggerMenuExitEvent(int menuIndex)
{
menuExitRequested = true;
menuExitIndex = menuIndex;
}
void Component::triggerHighlightEvent()
{
newItemSelected = true;
}
void Component::triggerPlaylistChangeEvent(std::string name)
{
playlistChanged = true;
this->playlistName = name;
}
bool Component::isIdle()
{
return (currentAnimationState == IDLE);
}
bool Component::isHidden()
{
return (currentAnimationState == HIDDEN);
}
bool Component::isWaiting()
{
return (currentAnimationState == HIGHLIGHT_WAIT);
}
bool Component::isMenuScrolling()
{
return (currentAnimationState == MENU_ENTER || currentAnimationState == MENU_SCROLL || currentAnimationState == MENU_EXIT || menuScrollRequested);
}
void Component::setTweens(AnimationEvents *set)
{
tweens_ = set;
forceIdle();
}
void Component::forceIdle()
{
currentAnimationState = IDLE;
currentTweenIndex_ = 0;
currentTweenComplete_ = false;
elapsedTweenTime_ = 0;
currentTweens_ = NULL;
}
void Component::update(float dt)
{
elapsedTweenTime_ += dt;
highlightExitComplete = false;
if(isHidden() || isWaiting() || (isIdle() && exitRequested))
{
currentTweenComplete_ = true;
}
if(currentTweenComplete_)
{
currentTweens_ = NULL;
// There was no request to override our state path. Continue on as normal.
std::stringstream ss;
switch(currentAnimationState)
{
case MENU_ENTER:
currentTweens_ = NULL;
currentAnimationState = IDLE;
break;
case MENU_SCROLL:
currentTweens_ = NULL;
currentAnimationState = IDLE;
break;
case MENU_EXIT:
currentTweens_ = NULL;
currentAnimationState = IDLE;
break;
case ENTER:
currentTweens_ = tweens_->getAnimation("enter", menuEnterIndex);
currentAnimationState = HIGHLIGHT_ENTER;
break;
case EXIT:
currentTweens_ = NULL;
currentAnimationState = HIDDEN;
break;
case HIGHLIGHT_ENTER:
currentTweens_ = tweens_->getAnimation("idle", menuEnterIndex);
currentAnimationState = IDLE;
break;
case IDLE:
// prevent us from automatically jumping to the exit tween upon enter
if(enterRequested)
{
enterRequested = false;
newItemSelected = false;
}
else if(menuExitRequested && (!menuEnterRequested || menuExitRequested <= menuEnterRequested))
{
currentTweens_ = tweens_->getAnimation("menuExit", menuExitIndex);
currentAnimationState = MENU_EXIT;
menuExitRequested = false;
}
else if(menuEnterRequested && (!menuExitRequested || menuExitRequested > menuEnterRequested))
{
currentTweens_ = tweens_->getAnimation("menuEnter", menuEnterIndex);
currentAnimationState = MENU_ENTER;
menuEnterRequested = false;
}
else if(menuScrollRequested)
{
menuScrollRequested = false;
currentTweens_ = tweens_->getAnimation("menuScroll", menuEnterIndex);
currentAnimationState = MENU_SCROLL;
}
else if(scrollActive || newItemSelected || exitRequested)
{
currentTweens_ = tweens_->getAnimation("highlightExit", menuEnterIndex);
currentAnimationState = HIGHLIGHT_EXIT;
}
else
{
currentTweens_ = tweens_->getAnimation("idle", menuEnterIndex);
currentAnimationState = IDLE;
}
break;
case HIGHLIGHT_EXIT:
// intentionally break down
case HIGHLIGHT_WAIT:
if(exitRequested && (currentAnimationState == HIGHLIGHT_WAIT))
{
currentTweens_ = tweens_->getAnimation("highlightExit", menuEnterIndex);
currentAnimationState = HIGHLIGHT_EXIT;
}
else if(exitRequested && (currentAnimationState == HIGHLIGHT_EXIT))
{
currentTweens_ = tweens_->getAnimation("exit", menuEnterIndex);
currentAnimationState = EXIT;
exitRequested = false;
}
else if(scrollActive)
{
currentTweens_ = NULL;
currentAnimationState = HIGHLIGHT_WAIT;
}
else if(newItemSelected)
{
currentTweens_ = tweens_->getAnimation("highlightEnter", menuEnterIndex);
currentAnimationState = HIGHLIGHT_ENTER;
highlightExitComplete = true;
newItemSelected = false;
}
else
{
currentTweens_ = NULL;
currentAnimationState = HIGHLIGHT_WAIT;
}
break;
case HIDDEN:
if(enterRequested || exitRequested)
{
currentTweens_ = tweens_->getAnimation("enter", menuEnterIndex);
currentAnimationState = ENTER;
}
else if(menuExitRequested && (!menuEnterRequested || menuExitRequested <= menuEnterRequested))
{
currentTweens_ = tweens_->getAnimation("menuExit", menuExitIndex);
currentAnimationState = MENU_EXIT;
menuExitRequested = false;
}
else if(menuEnterRequested && (!menuExitRequested || menuExitRequested > menuEnterRequested))
{
currentTweens_ = tweens_->getAnimation("menuEnter", menuEnterIndex);
currentAnimationState = MENU_ENTER;
menuEnterRequested = false;
}
else if(menuScrollRequested)
{
menuScrollRequested = false;
currentTweens_ = tweens_->getAnimation("menuScroll", menuEnterIndex);
currentAnimationState = MENU_SCROLL;
}
else
{
currentTweens_ = NULL;
currentAnimationState = HIDDEN;
}
}
currentTweenIndex_ = 0;
currentTweenComplete_ = false;
elapsedTweenTime_ = 0;
}
currentTweenComplete_ = animate(isIdle());
}
void Component::draw()
{
if(backgroundTexture_)
{
SDL_Rect rect;
rect.h = static_cast<int>(baseViewInfo.ScaledHeight());
rect.w = static_cast<int>(baseViewInfo.ScaledWidth());
rect.x = static_cast<int>(baseViewInfo.XRelativeToOrigin());
rect.y = static_cast<int>(baseViewInfo.YRelativeToOrigin());
SDL_SetTextureColorMod(backgroundTexture_,
static_cast<char>(baseViewInfo.BackgroundRed*255),
static_cast<char>(baseViewInfo.BackgroundGreen*255),
static_cast<char>(baseViewInfo.BackgroundBlue*255));
SDL::renderCopy(backgroundTexture_, static_cast<char>(baseViewInfo.BackgroundAlpha*255), NULL, &rect, baseViewInfo.Angle);
}
}
bool Component::animate(bool loop)
{
bool completeDone = false;
if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->size())
{
completeDone = true;
}
else if(currentTweens_)
{
bool currentDone = true;
TweenSet *tweens = currentTweens_->tweenSet(currentTweenIndex_);
for(unsigned int i = 0; i < tweens->size(); i++)
{
Tween *tween = tweens->tweens()->at(i);
double elapsedTime = elapsedTweenTime_;
//todo: too many levels of nesting
if(elapsedTime < tween->duration)
{
currentDone = false;
}
else
{
elapsedTime = static_cast<float>(tween->duration);
}
float value = tween->animate(elapsedTime);
switch(tween->property)
{
case TWEEN_PROPERTY_X:
baseViewInfo.X = value;
break;
case TWEEN_PROPERTY_Y:
baseViewInfo.Y = value;
break;
case TWEEN_PROPERTY_HEIGHT:
baseViewInfo.Height = value;
break;
case TWEEN_PROPERTY_WIDTH:
baseViewInfo.Width = value;
break;
case TWEEN_PROPERTY_ANGLE:
baseViewInfo.Angle = value;
break;
case TWEEN_PROPERTY_ALPHA:
baseViewInfo.Alpha = value;
break;
case TWEEN_PROPERTY_X_ORIGIN:
baseViewInfo.XOrigin = value;
break;
case TWEEN_PROPERTY_Y_ORIGIN:
baseViewInfo.YOrigin = value;
break;
case TWEEN_PROPERTY_X_OFFSET:
baseViewInfo.XOffset = value;
break;
case TWEEN_PROPERTY_Y_OFFSET:
baseViewInfo.YOffset = value;
break;
case TWEEN_PROPERTY_FONT_SIZE:
baseViewInfo.FontSize = value;
break;
case TWEEN_PROPERTY_BACKGROUND_ALPHA:
baseViewInfo.BackgroundAlpha = value;
break;
}
}
if(currentDone)
{
currentTweenIndex_++;
elapsedTweenTime_ = 0;
}
}
if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->tweenSets()->size())
{
if(loop)
{
currentTweenIndex_ = 0;
}
completeDone = true;
}
return completeDone;
}

View File

@@ -15,85 +15,9 @@
*/
#pragma once
#include <vector>
#include "../../SDL.h"
#include "../MenuNotifierInterface.h"
#include "../Page.h"
#include "../ViewInfo.h"
#include "../Animate/Tween.h"
#include "../Animate/AnimationEvents.h"
#include "../../Collection/Item.h"
class Component
{
public:
Component(Page &p);
Component(const Component &copy);
virtual ~Component();
virtual void freeGraphicsMemory();
virtual void allocateGraphicsMemory();
virtual void launchEnter() {}
virtual void launchExit() {}
void triggerEnterEvent();
void triggerExitEvent();
void triggerMenuEnterEvent(int menuIndex = -1);
void triggerMenuExitEvent(int menuIndex = -1);
void triggerMenuScrollEvent();
void triggerHighlightEvent();
void triggerPlaylistChangeEvent(std::string name);
bool isIdle();
bool isHidden();
bool isWaiting();
bool isMenuScrolling();
virtual void update(float dt);
virtual void draw();
void setTweens(AnimationEvents *set);
void forceIdle();
ViewInfo baseViewInfo;
std::string collectionName;
bool scrollActive;
protected:
Page &page;
enum AnimationState
{
IDLE,
ENTER,
HIGHLIGHT_EXIT,
HIGHLIGHT_WAIT,
HIGHLIGHT_ENTER,
EXIT,
MENU_ENTER,
MENU_SCROLL,
MENU_EXIT,
HIDDEN
};
AnimationState currentAnimationState;
bool enterRequested;
bool exitRequested;
bool menuEnterRequested;
int menuEnterIndex;
bool menuScrollRequested;
bool menuExitRequested;
int menuExitIndex;
bool newItemSelected;
bool playlistChanged;
std::string playlistName;
bool highlightExitComplete;
bool newItemSelectedSinceEnter;
private:
bool animate(bool loop);
bool tweenSequencingComplete();
AnimationEvents *tweens_;
Animation *currentTweens_;
SDL_Texture *backgroundTexture_;
unsigned int currentTweenIndex_;
bool currentTweenComplete_;
float elapsedTweenTime_;
virtual void update(float dt) = 0;
virtual void draw() = 0;
};

View File

@@ -18,8 +18,8 @@
#include "../ViewInfo.h"
#include "../../SDL.h"
Container::Container(Page &p)
: Component(p)
Container::Container()
: Component()
{
allocateGraphicsMemory();
}

View File

@@ -22,7 +22,7 @@
class Container : public Component
{
public:
Container(Page &p);
Container();
virtual ~Container();
void freeGraphicsMemory();
void allocateGraphicsMemory();

View File

@@ -14,46 +14,26 @@
* along with RetroFE. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Image.h"
#include "../ViewInfo.h"
#include "../../SDL.h"
#include "../../Utility/Log.h"
#include <SDL2/SDL_image.h>
Image::Image(std::string file, Page &p, float scaleX, float scaleY)
: Component(p)
, texture_(NULL)
Image::Image(std::string file)
: texture_(NULL)
, file_(file)
, scaleX_(scaleX)
, scaleY_(scaleY)
, width(0)
, height(0)
, x(0)
, y(0)
, alpha(1)
{
allocateGraphicsMemory();
}
Image::~Image()
{
freeGraphicsMemory();
}
void Image::freeGraphicsMemory()
void Image::Initialize()
{
Component::freeGraphicsMemory();
SDL_LockMutex(SDL::getMutex());
if (texture_ != NULL)
{
SDL_DestroyTexture(texture_);
texture_ = NULL;
}
SDL_UnlockMutex(SDL::getMutex());
}
void Image::allocateGraphicsMemory()
{
int width;
int height;
Component::allocateGraphicsMemory();
if(!texture_)
{
SDL_LockMutex(SDL::getMutex());
@@ -63,27 +43,47 @@ void Image::allocateGraphicsMemory()
{
SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND);
SDL_QueryTexture(texture_, NULL, NULL, &width, &height);
baseViewInfo.ImageWidth = width * scaleX_;
baseViewInfo.ImageHeight = height * scaleY_;
}
SDL_UnlockMutex(SDL::getMutex());
}
}
void Image::DeInitialize()
{
if(texture_)
{
SDL_DestroyTexture(texture_);
texture_ = NULL;
}
}
void Image::update(float dt)
{
if(!texture_)
{
SDL_LockMutex(SDL::getMutex());
texture_ = IMG_LoadTexture(SDL::getRenderer(), file_.c_str());
if (texture_ != NULL)
{
SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND);
SDL_QueryTexture(texture_, NULL, NULL, &width, &height);
}
SDL_UnlockMutex(SDL::getMutex());
}
}
void Image::draw()
{
Component::draw();
if(texture_)
{
SDL_Rect rect;
rect.x = static_cast<int>(baseViewInfo.XRelativeToOrigin());
rect.y = static_cast<int>(baseViewInfo.YRelativeToOrigin());
rect.h = static_cast<int>(baseViewInfo.ScaledHeight());
rect.w = static_cast<int>(baseViewInfo.ScaledWidth());
rect.x = x;
rect.y = y;
rect.h = width;
rect.w = height;
SDL::renderCopy(texture_, static_cast<char>((baseViewInfo.Alpha * 255)), NULL, &rect, baseViewInfo.Angle);
SDL::renderCopy(texture_, (unsigned char)(alpha*255), NULL, &rect, 45);
}
}

View File

@@ -22,15 +22,20 @@
class Image : public Component
{
public:
Image(std::string file, Page &p, float scaleX, float scaleY);
Image(std::string file);
virtual ~Image();
void freeGraphicsMemory();
void allocateGraphicsMemory();
void Initialize();
void DeInitialize();
void update(float dt);
void draw();
int width;
int height;
int x;
int y;
int rotate;
float alpha;
protected:
SDL_Texture *texture_;
std::string file_;
float scaleX_;
float scaleY_;
};

View File

@@ -18,7 +18,7 @@
#include "../../Utility/Log.h"
#include <fstream>
Image * ImageBuilder::CreateImage(std::string path, Page &p, std::string name, float scaleX, float scaleY)
Image * ImageBuilder::CreateImage(std::string path, std::string name)
{
Image *image = NULL;
std::vector<std::string> extensions;
@@ -35,7 +35,7 @@ Image * ImageBuilder::CreateImage(std::string path, Page &p, std::string name, f
if(Utils::findMatchingFile(prefix, extensions, file))
{
image = new Image(file, p, scaleX, scaleY);
image = new Image(file);
}
return image;

View File

@@ -15,7 +15,6 @@
*/
#pragma once
#include "../Page.h"
#include "Image.h"
#include "VideoComponent.h"
#include "../../Video/VideoFactory.h"
@@ -24,5 +23,5 @@
class ImageBuilder
{
public:
Image * CreateImage(std::string path, Page &p, std::string name, float scaleX, float scaleY);
Image * CreateImage(std::string path, std::string name);
};

View File

@@ -51,9 +51,6 @@ private:
Font *FfntInst_;
bool textFallback_;
std::string type_;
float scaleX_;
float scaleY_;
std::string currentCollection_;
Page *page_;
int displayOffset_;
};

View File

@@ -17,7 +17,6 @@
#include "Component.h"
#include "Text.h"
#include "../Font.h"
#include "../Page.h"
#include "../../Collection/Item.h"
#include <SDL2/SDL.h>
#include <string>
@@ -25,7 +24,7 @@
class ReloadableText : public Component
{
public:
ReloadableText(std::string type, Page &page, Font *font, std::string layoutKey, float scaleX, float scaleY);
ReloadableText(std::string type, Font *font, std::string layoutKey);
virtual ~ReloadableText();
void update(float dt);
void draw();
@@ -58,7 +57,4 @@ private:
bool reloadRequested_;
bool firstLoad_;
Font *fontInst_;
float scaleX_;
float scaleY_;
};

View File

@@ -340,8 +340,8 @@ void ScrollingList::letterChange(bool increment)
// check if we are changing characters from a-z, or changing from alpha character to non-alpha character
if(isalpha(startname[0]) ^ isalpha(endname[0]))
{
break;
itemIndex_ = index;
break;
}
else if(isalpha(startname[0]) && isalpha(endname[0]) && startname[0] != endname[0])
{

View File

@@ -18,7 +18,6 @@
#include <vector>
#include "Component.h"
#include "../Animate/Tween.h"
#include "../Page.h"
#include "../MenuNotifierInterface.h"
#include "../ViewInfo.h"
#include "../../Database/Configuration.h"
@@ -44,9 +43,6 @@ public:
};
ScrollingList(Configuration &c,
Page &p,
float scaleX,
float scaleY,
Font *font,
std::string layoutKey,
std::string imageType);
@@ -124,8 +120,6 @@ private:
float scrollPeriod_;
Configuration &config_;
float scaleX_;
float scaleY_;
Font *fontInst_;
std::string layoutKey_;
std::string imageType_;

View File

@@ -20,12 +20,10 @@
#include "../Font.h"
#include <sstream>
Text::Text(std::string text, Page &p, Font *font, float scaleX, float scaleY)
: Component(p)
Text::Text(std::string text, Font *font)
: Component()
, textData_(text)
, fontInst_(font)
, scaleX_(scaleX)
, scaleY_(scaleY)
{
allocateGraphicsMemory();
}
@@ -86,7 +84,7 @@ void Text::draw()
baseViewInfo.Width = imageWidth*scale;
baseViewInfo.Height = baseViewInfo.FontSize;
baseViewInfo.ImageWidth = imageWidth;
baseViewInfo.ImageWidth = imageWidth;
baseViewInfo.ImageHeight = imageHeight;
float xOrigin = baseViewInfo.XRelativeToOrigin();

View File

@@ -16,7 +16,6 @@
#pragma once
#include "Component.h"
#include "../Page.h"
#include <SDL2/SDL.h>
#include <vector>
@@ -26,7 +25,7 @@ class Text : public Component
{
public:
//todo: should have a Font flass that references fontcache, pass that in as an argument
Text(std::string text, Page &p, Font *font, float scaleX, float scaleY);
Text(std::string text, Font *font);
virtual ~Text();
void setText(std::string text);
void allocateGraphicsMemory();
@@ -36,6 +35,4 @@ public:
private:
std::string textData_;
Font *fontInst_;
float scaleX_;
float scaleY_;
};

View File

@@ -17,14 +17,13 @@
#include "Image.h"
#include "VideoComponent.h"
#include "../Page.h"
#include "../../Video/VideoFactory.h"
//todo: this is more of a factory than a builder
class VideoBuilder
{
public:
VideoComponent * createVideo(std::string path, Page &page, std::string name, float scaleX, float scaleY);
VideoComponent * createVideo(std::string path, std::string name);
private:
VideoFactory factory_;

View File

@@ -16,7 +16,6 @@
#pragma once
#include "Component.h"
#include "Image.h"
#include "../Page.h"
#include "../../Collection/Item.h"
#include "../../Video/IVideo.h"
#include <SDL2/SDL.h>
@@ -25,7 +24,7 @@
class VideoComponent : public Component
{
public:
VideoComponent(IVideo *videoInst, Page &p, std::string videoFile, float scaleX, float scaleY);
VideoComponent(IVideo *videoInst, std::string videoFile);
virtual ~VideoComponent();
void update(float dt);
void draw();
@@ -38,7 +37,5 @@ private:
std::string videoFile_;
std::string name_;
IVideo *videoInst_;
float scaleX_;
float scaleY_;
bool isPlaying_;
};

View File

@@ -15,8 +15,6 @@
*/
#include "Database/Configuration.h"
#include "Collection/CollectionInfoBuilder.h"
#include "Execute/Launcher.h"
#include "Utility/Log.h"
#include "Utility/Utils.h"
#include "RetroFE.h"
@@ -31,135 +29,23 @@ static bool StartLogging();
int main(int argc, char **argv)
{
Configuration::initialize();
Configuration config;
config.import("", "C:/Users/Don/Downloads/RetroFE-FTP/settings.conf");
if(!StartLogging())
{
return -1;
}
// check to see if createcollection was requested
if(argc == 3)
{
std::string param = argv[1];
std::string value = argv[2];
if(param == "-createcollection")
{
CollectionInfoBuilder::createCollectionDirectory(value);
}
return 0;
}
if(!ImportConfiguration(&config))
{
return -1;
}
RetroFE p(config);
p.run();
p.deInitialize();
Logger::deInitialize();
return 0;
}
bool ImportConfiguration(Configuration *c)
{
std::string configPath = Configuration::absolutePath;
std::string launchersPath = Utils::combinePath(Configuration::absolutePath, "launchers");
std::string collectionsPath = Utils::combinePath(Configuration::absolutePath, "collections");
DIR *dp;
struct dirent *dirp;
std::string settingsConfPath = Utils::combinePath(configPath, "settings.conf");
if(!c->import("", settingsConfPath))
{
Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + settingsConfPath + "\"");
return false;
}
std::string controlsConfPath = Utils::combinePath(configPath, "controls.conf");
if(!c->import("controls", controlsConfPath))
{
Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + controlsConfPath + "\"");
return false;
}
dp = opendir(launchersPath.c_str());
if(dp == NULL)
{
Logger::write(Logger::ZONE_NOTICE, "RetroFE", "Could not read directory \"" + launchersPath + "\"");
return false;
}
while((dirp = readdir(dp)) != NULL)
{
if (dirp->d_type != DT_DIR && std::string(dirp->d_name) != "." && std::string(dirp->d_name) != "..")
{
std::string basename = dirp->d_name;
std::string extension = basename.substr(basename.find_last_of("."), basename.size()-1);
basename = basename.substr(0, basename.find_last_of("."));
if(extension == ".conf")
{
std::string prefix = "launchers." + basename;
std::string importFile = Utils::combinePath(launchersPath, std::string(dirp->d_name));
if(!c->import(prefix, importFile))
{
Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + importFile + "\"");
closedir(dp);
return false;
}
}
}
}
closedir(dp);
dp = opendir(collectionsPath.c_str());
if(dp == NULL)
{
Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not read directory \"" + collectionsPath + "\"");
return false;
}
while((dirp = readdir(dp)) != NULL)
{
std::string collection = (dirp->d_name);
if (dirp->d_type == DT_DIR && collection != "." && collection != ".." && collection.length() > 0 && collection[0] != '_')
{
std::string prefix = "collections." + collection;
std::string settingsFile = Utils::combinePath(collectionsPath, collection, "settings.conf");
if(!c->import(collection, prefix, settingsFile))
{
Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + settingsFile + "\"");
closedir(dp);
return false;
}
}
}
closedir(dp);
Logger::write(Logger::ZONE_INFO, "RetroFE", "Imported configuration");
return true;
}
bool StartLogging()
{
std::string logFile = Utils::combinePath(Configuration::absolutePath, "log.txt");

View File

@@ -15,30 +15,19 @@
*/
#include "RetroFE.h"
#include "Collection/CollectionInfoBuilder.h"
#include "Collection/CollectionInfo.h"
#include "Database/Configuration.h"
#include "Collection/Item.h"
#include "Execute/Launcher.h"
#include "Utility/Log.h"
#include "Utility/Utils.h"
#include "Collection/MenuParser.h"
#include "SDL.h"
#include "Control/UserInput.h"
#include "Graphics/PageBuilder.h"
#include "Graphics/Page.h"
#include "Graphics/Component/ScrollingList.h"
#include "Video/VideoFactory.h"
#include "Graphics/Component/Image.h"
#include "Graphics/Component/Component.h"
#include <vector>
#include <string>
#include <sstream>
#include <dirent.h>
#ifdef __linux
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <cstring>
#endif
#ifdef WIN32
@@ -47,600 +36,162 @@
#include <SDL2/SDL_thread.h>
#endif
std::map<Component *, Component *> components;
static int lua_getCenter(lua_State *l)
{
int x = SDL::getWindowWidth() / 2;
int y = SDL::getWindowHeight() / 2;
lua_pushnumber(l, x);
lua_pushnumber(l, y);
return 2;
}
static int lua_getDimensions(lua_State *l)
{
int x = SDL::getWindowWidth();
int y = SDL::getWindowHeight();
lua_pushnumber(l, x);
lua_pushnumber(l, y);
return 2;
}
Image *i = NULL;
static int lua_imageCreate(lua_State *l)
{
std::string filename = lua_tostring(l, 1);
i = new Image(filename);
i->Initialize();
lua_pushinteger(l, (int)i);
components[i] = i;
return 1;
}
static int lua_imageDelete(lua_State *l)
{
Image *i = (Image *)lua_tointeger(l, 1);
if(components.find(i) != components.end()) {
components.erase(i);
}
i->DeInitialize();
delete i;
return 0;
}
static int lua_imageSetSize(lua_State *l)
{
Image *i = (Image *)lua_tointeger(l, 1);
i->width = (int)lua_tointeger(l, 2);
i->height = (int)lua_tointeger(l, 3);
return 0;
}
static int lua_imageSetPosition(lua_State *l)
{
Image *i = (Image *)lua_tointeger(l, 1);
i->x = (int)lua_tointeger(l, 2);
i->y = (int)lua_tointeger(l, 3);
return 0;
}
static int lua_imageSetRotate(lua_State *l)
{
Image *i = (Image *)lua_tointeger(l, 1);
i->rotate = (int)lua_tointeger(l, 2);
return 0;
}
static int lua_imageSetAlpha(lua_State *l)
{
Image *i = (Image *)lua_tointeger(l, 1);
i->alpha = (float)lua_tonumber(l, 2);
return 0;
}
static const luaL_Reg luaDisplayFuncs[] = {
// Creation
{"getCenter", lua_getCenter},
{"getDimensions", lua_getDimensions},
{NULL, NULL}
};
static const luaL_Reg luaImageFuncs[] = {
// Creation
{"create", lua_imageCreate},
{"delete", lua_imageDelete},
{"setSize", lua_imageSetSize},
{"setRotate", lua_imageSetRotate},
{"setPosition", lua_imageSetPosition},
{"setAlpha", lua_imageSetAlpha},
{NULL, NULL}
};
void RetroFE::initializeLua()
{
lua_.initialize();
lua_newtable(lua_.state);
luaL_setfuncs (lua_.state, luaDisplayFuncs, 0);
lua_pushvalue(lua_.state,-1); // pluck these lines out if they offend you
lua_setglobal(lua_.state,"display"); // for they clobber the Holy _G
lua_newtable(lua_.state);
luaL_setfuncs (lua_.state, luaImageFuncs, 0);
lua_pushvalue(lua_.state,-1); // pluck these lines out if they offend you
lua_setglobal(lua_.state,"image"); // for they clobber the Holy _G
}
void RetroFE::reloadLuaScripts()
{
luaL_loadfile(lua_.state, "C:/Users/Don/Downloads/RetroFE-FTP/layouts/LUATest/Page.lua");
lua_pcall(lua_.state, 0, LUA_MULTRET, 0);
}
RetroFE::RetroFE(Configuration &c)
: initialized(false)
, initializeError(false)
, initializeThread(NULL)
, config_(c)
, db_(NULL)
, metadb_(NULL)
, input_(config_)
, currentPage_(NULL)
, keyInputDisable_(0)
, currentTime_(0)
, lastLaunchReturnTime_(0)
, keyLastTime_(0)
, keyDelayTime_(.3f)
: config_(c)
{
}
RetroFE::~RetroFE()
{
deInitialize();
}
void RetroFE::render()
{
SDL_LockMutex(SDL::getMutex());
SDL_SetRenderDrawColor(SDL::getRenderer(), 0x0, 0x0, 0x00, 0xFF);
SDL_RenderClear(SDL::getRenderer());
if(currentPage_)
{
currentPage_->draw();
}
SDL_RenderPresent(SDL::getRenderer());
SDL_UnlockMutex(SDL::getMutex());
}
int RetroFE::initialize(void *context)
{
RetroFE *instance = static_cast<RetroFE *>(context);
Logger::write(Logger::ZONE_INFO, "RetroFE", "Initializing");
if(!instance->input_.initialize())
{
Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not initialize user controls");
instance->initializeError = true;
return -1;
}
instance->db_ = new DB(Utils::combinePath(Configuration::absolutePath, "meta.db"));
if(!instance->db_->initialize())
{
Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not initialize database");
instance->initializeError = true;
return -1;
}
instance->metadb_ = new MetadataDatabase(*(instance->db_), instance->config_);
if(!instance->metadb_->initialize())
{
Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not initialize meta database");
instance->initializeError = true;
return -1;
}
instance->initialized = true;
return 0;
}
void RetroFE::launchEnter()
{
if(currentPage_)
{
currentPage_->launchEnter();
}
SDL_SetWindowGrab(SDL::getWindow(), SDL_FALSE);
}
void RetroFE::launchExit()
{
SDL_RestoreWindow(SDL::getWindow());
SDL_RaiseWindow(SDL::getWindow());
SDL_SetWindowGrab(SDL::getWindow(), SDL_TRUE);
input_.resetStates();
attract_.reset();
currentTime_ = static_cast<float>(SDL_GetTicks()) / 1000;
if(currentPage_)
{
currentPage_->launchExit();
}
lastLaunchReturnTime_ = currentTime_;
}
void RetroFE::freeGraphicsMemory()
{
if(currentPage_)
{
currentPage_->freeGraphicsMemory();
}
fontcache_.deInitialize();
SDL::deInitialize();
}
void RetroFE::allocateGraphicsMemory()
{
SDL::initialize(config_);
fontcache_.initialize();
if(currentPage_)
{
currentPage_->allocateGraphicsMemory();
currentPage_->start();
}
}
bool RetroFE::deInitialize()
{
bool retVal = true;
freeGraphicsMemory();
if(currentPage_)
{
currentPage_->DeInitialize();
delete currentPage_;
currentPage_ = NULL;
}
if(metadb_)
{
delete metadb_;
metadb_ = NULL;
}
if(db_)
{
delete db_;
db_ = NULL;
}
initialized = false;
//todo: handle video deallocation
Logger::write(Logger::ZONE_INFO, "RetroFE", "Exiting");
return retVal;
}
void RetroFE::run()
{
if(!SDL::initialize(config_)) return;
fontcache_.initialize();
float preloadTime = 0;
bool videoEnable = true;
int videoLoop = 0;
config_.getProperty("videoEnable", videoEnable);
config_.getProperty("videoLoop", videoLoop);
initializeLua();
VideoFactory::setEnabled(videoEnable);
VideoFactory::setNumLoops(videoLoop);
VideoFactory::createVideo(); // pre-initialize the gstreamer engine
reloadLuaScripts();
bool quit = false;
initializeThread = SDL_CreateThread(initialize, "RetroFEInit", (void *)this);
while(!quit) {
SDL_LockMutex(SDL::getMutex());
SDL_SetRenderDrawColor(SDL::getRenderer(), 0x0, 0x0, 0x00, 0xFF);
SDL_RenderClear(SDL::getRenderer());
for(std::map<Component *, Component *>::iterator it = components.begin(); it != components.end(); it++)
{
it->second->update(0);
}
for(std::map<Component *, Component *>::iterator it = components.begin(); it != components.end(); it++)
{
it->second->draw();
}
SDL_RenderPresent(SDL::getRenderer());
SDL_UnlockMutex(SDL::getMutex());
if(!initializeThread)
{
Logger::write(Logger::ZONE_INFO, "RetroFE", "Could not initialize RetroFE");
return;
}
int attractModeTime = 0;
std::string firstCollection = "Main";
bool running = true;
RETROFE_STATE state = RETROFE_NEW;
config_.getProperty("attractModeTime", attractModeTime);
config_.getProperty("firstCollection", firstCollection);
attract_.idleTime = static_cast<float>(attractModeTime);
int initializeStatus = 0;
// load the initial splash screen, unload it once it is complete
currentPage_ = loadSplashPage();
bool splashMode = true;
Launcher l(*this, config_);
preloadTime = static_cast<float>(SDL_GetTicks()) / 1000;
while (running)
{
float lastTime = 0;
float deltaTime = 0;
SDL_Event e;
if (SDL_PollEvent(&e))
{
if(input_.update(e))
{
attract_.reset();
}
}
if(!currentPage_)
{
Logger::write(Logger::ZONE_WARNING, "RetroFE", "Could not load page");
running = false;
break;
}
switch(state)
{
case RETROFE_IDLE:
if(currentPage_ && !splashMode)
{
// account for when returning from a menu and the previous key was still "stuck"
if(lastLaunchReturnTime_ == 0 || (currentTime_ - lastLaunchReturnTime_ > .3))
{
state = processUserInput(currentPage_);
lastLaunchReturnTime_ = 0;
}
}
if((initialized || initializeError) && splashMode && currentPage_->getMinShowTime() <= (currentTime_ - preloadTime))
{
SDL_WaitThread(initializeThread, &initializeStatus);
if(initializeError)
{
state = RETROFE_QUIT_REQUEST;
break;
}
// delete the splash screen and use the standard menu
currentPage_->DeInitialize();
delete currentPage_;
currentPage_ = loadPage();
splashMode = false;
if(currentPage_)
{
std::string firstCollection = "Main";
bool menuSort = true;
config_.getProperty("firstCollection", firstCollection);
config_.getProperty("collections." + firstCollection + ".list.menuSort", menuSort);
currentPage_->start();
config_.setProperty("currentCollection", firstCollection);
CollectionInfo *info = getCollection(firstCollection);
MenuParser mp;
mp.buildMenuItems(info, menuSort);
currentPage_->pushCollection(info);
}
else
{
state = RETROFE_QUIT_REQUEST;
}
}
break;
case RETROFE_NEXT_PAGE_REQUEST:
if(currentPage_->isIdle())
{
state = RETROFE_NEW;
}
break;
case RETROFE_LAUNCH_REQUEST:
nextPageItem_ = currentPage_->getSelectedItem();
l.run(nextPageItem_->collectionInfo->name, nextPageItem_);
state = RETROFE_IDLE;
break;
case RETROFE_BACK_REQUEST:
lastMenuOffsets_[currentPage_->getCollectionName()] = currentPage_->getScrollOffsetIndex();
currentPage_->popCollection();
config_.setProperty("currentCollection", currentPage_->getCollectionName());
state = RETROFE_NEW;
break;
case RETROFE_NEW:
if(currentPage_->isIdle())
{
state = RETROFE_IDLE;
}
break;
case RETROFE_QUIT_REQUEST:
currentPage_->stop();
state = RETROFE_QUIT;
break;
case RETROFE_QUIT:
if(currentPage_->isHidden())
{
running = false;
}
break;
}
// the logic below could be done in a helper method
if(running)
{
lastTime = currentTime_;
currentTime_ = static_cast<float>(SDL_GetTicks()) / 1000;
if (currentTime_ < lastTime)
{
currentTime_ = lastTime;
}
deltaTime = currentTime_ - lastTime;
double sleepTime = 1000.0/60.0 - deltaTime*1000;
if(sleepTime > 0)
{
SDL_Delay(static_cast<unsigned int>(sleepTime));
}
if(currentPage_)
{
attract_.update(deltaTime, *currentPage_);
currentPage_->update(deltaTime);
}
render();
}
}
}
bool RetroFE::back(bool &exit)
{
bool canGoBack = false;
bool exitOnBack = false;
config_.getProperty("exitOnFirstPageBack", exitOnBack);
exit = false;
if(currentPage_->getMenuDepth() <= 1)
{
exit = exitOnBack;
}
else
{
canGoBack = true;
}
return canGoBack;
}
RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
{
bool exit = false;
RETROFE_STATE state = RETROFE_IDLE;
bool rememberMenu = false;
config_.getProperty("rememberMenu", rememberMenu);
if(page->isHorizontalScroll())
{
if (input_.keystate(UserInput::KeyCodeLeft))
{
page->setScrolling(Page::ScrollDirectionBack);
}
if (input_.keystate(UserInput::KeyCodeRight))
{
page->setScrolling(Page::ScrollDirectionForward);
}
}
else
{
if (input_.keystate(UserInput::KeyCodeUp))
{
page->setScrolling(Page::ScrollDirectionBack);
}
if (input_.keystate(UserInput::KeyCodeDown))
{
page->setScrolling(Page::ScrollDirectionForward);
}
}
if (!input_.keystate(UserInput::KeyCodePageUp) &&
!input_.keystate(UserInput::KeyCodePageDown) &&
!input_.keystate(UserInput::KeyCodeLetterUp) &&
!input_.keystate(UserInput::KeyCodeLetterDown) &&
!input_.keystate(UserInput::KeyCodeNextPlaylist) &&
!input_.keystate(UserInput::KeyCodeAddPlaylist) &&
!input_.keystate(UserInput::KeyCodeRemovePlaylist) &&
!input_.keystate(UserInput::KeyCodeRandom))
{
keyLastTime_ = 0;
keyDelayTime_= 0.3f;
}
else if((currentTime_ - keyLastTime_) > keyDelayTime_ || keyLastTime_ == 0)
{
keyLastTime_ = currentTime_;
keyDelayTime_-= .05f;
if(keyDelayTime_< 0.1f) keyDelayTime_= 0.1f;
if (input_.keystate(UserInput::KeyCodePageUp))
{
page->pageScroll(Page::ScrollDirectionBack);
}
if (input_.keystate(UserInput::KeyCodePageDown))
{
page->pageScroll(Page::ScrollDirectionForward);
}
if (input_.keystate(UserInput::KeyCodeLetterUp))
{
page->letterScroll(Page::ScrollDirectionBack);
}
if (input_.keystate(UserInput::KeyCodeLetterDown))
{
page->letterScroll(Page::ScrollDirectionForward);
}
if(input_.newKeyPressed(UserInput::KeyCodeNextPlaylist))
{
page->nextPlaylist();
}
if(input_.newKeyPressed(UserInput::KeyCodeRemovePlaylist))
{
page->removePlaylist();
}
if(input_.newKeyPressed(UserInput::KeyCodeAddPlaylist))
{
page->addPlaylist();
}
if(input_.keystate(UserInput::KeyCodeRandom))
{
page->selectRandom();
}
}
if (input_.keystate(UserInput::KeyCodeAdminMode))
{
//todo: add admin mode support
}
if (input_.keystate(UserInput::KeyCodeSelect) && page->isMenuIdle())
{
nextPageItem_ = page->getSelectedItem();
if(nextPageItem_)
{
if(nextPageItem_->leaf)
{
state = RETROFE_LAUNCH_REQUEST;
}
else
{
bool menuSort = true;
config_.setProperty("currentCollection", nextPageItem_->name);
config_.getProperty("collections." + nextPageItem_->name + ".list.menuSort", menuSort);
CollectionInfo *info = getCollection(nextPageItem_->name);
MenuParser mp;
mp.buildMenuItems(info, menuSort);
page->pushCollection(info);
if(rememberMenu && lastMenuOffsets_.find(nextPageItem_->name) != lastMenuOffsets_.end())
{
page->setScrollOffsetIndex(lastMenuOffsets_[nextPageItem_->name]);
}
state = RETROFE_NEXT_PAGE_REQUEST;
}
}
}
if (input_.keystate(UserInput::KeyCodeBack) && page->isMenuIdle())
{
if(back(exit) || exit)
{
state = (exit) ? RETROFE_QUIT_REQUEST : RETROFE_BACK_REQUEST;
}
}
if (input_.keystate(UserInput::KeyCodeQuit))
{
state = RETROFE_QUIT_REQUEST;
}
if(!input_.keystate(UserInput::KeyCodeUp) &&
!input_.keystate(UserInput::KeyCodeLeft) &&
!input_.keystate(UserInput::KeyCodeDown) &&
!input_.keystate(UserInput::KeyCodeRight) &&
!input_.keystate(UserInput::KeyCodePageUp) &&
!input_.keystate(UserInput::KeyCodePageDown))
{
page->setScrolling(Page::ScrollDirectionIdle);
}
return state;
}
Page *RetroFE::loadPage()
{
std::string layoutName;
config_.getProperty("layout", layoutName);
PageBuilder pb(layoutName, "layout", config_, &fontcache_);
Page *page = pb.buildPage();
if(!page)
{
Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not create page");
}
else
{
page->start();
}
return page;
}
Page *RetroFE::loadSplashPage()
{
std::string layoutName;
config_.getProperty("layout", layoutName);
PageBuilder pb(layoutName, "splash", config_, &fontcache_);
Page * page = pb.buildPage();
page->start();
return page;
}
CollectionInfo *RetroFE::getCollection(std::string collectionName)
{
// the page will deallocate this once its done
CollectionInfoBuilder cib(config_, *metadb_);
CollectionInfo *collection = cib.buildCollection(collectionName);
DIR *dp;
struct dirent *dirp;
std::string path = Utils::combinePath(Configuration::absolutePath, "collections", collectionName);
dp = opendir(path.c_str());
while((dirp = readdir(dp)) != NULL)
{
std::string file = dirp->d_name;
size_t position = file.find_last_of(".");
std::string basename = (std::string::npos == position)? file : file.substr(0, position);
std::string comparator = ".sub";
int start = file.length() - comparator.length();
if(start >= 0)
{
if(file.compare(start, comparator.length(), comparator) == 0)
{
Logger::write(Logger::ZONE_INFO, "RetroFE", "Loading subcollection into menu: " + basename);
CollectionInfo *subcollection = cib.buildCollection(basename, collectionName);
collection->addSubcollection(subcollection);
}
}
}
collection->sortItems();
return collection;
}
std::string RetroFE::getLayout(std::string collectionName)
{
std::string layoutKeyName = "collections." + collectionName + ".layout";
std::string layoutName = "Default 16x9";
if(!config_.getProperty(layoutKeyName, layoutName))
{
config_.getProperty("layout", layoutName);
}
return layoutName;
}

View File

@@ -15,73 +15,20 @@
*/
#pragma once
#include "Collection/Item.h"
#include "Control/UserInput.h"
#include "Database/DB.h"
#include "Database/MetadataDatabase.h"
#include "Execute/AttractMode.h"
#include "Graphics/FontCache.h"
#include "Video/IVideo.h"
#include "Video/VideoFactory.h"
#include "Lua.h"
#include "Database/Configuration.h"
#include <SDL2/SDL.h>
#include <list>
#include <vector>
#include <map>
class CollectionInfo;
class Configuration;
class Page;
class RetroFE
{
public:
RetroFE(Configuration &c);
virtual ~RetroFE();
bool deInitialize();
void run();
void freeGraphicsMemory();
void allocateGraphicsMemory();
void launchEnter();
void launchExit();
private:
volatile bool initialized;
volatile bool initializeError;
SDL_Thread *initializeThread;
static int initialize(void *context);
enum RETROFE_STATE
{
RETROFE_IDLE,
RETROFE_NEXT_PAGE_REQUEST,
RETROFE_LAUNCH_REQUEST,
RETROFE_BACK_REQUEST,
RETROFE_NEW,
RETROFE_QUIT_REQUEST,
RETROFE_QUIT,
};
void render();
bool back(bool &exit);
void quit();
Page *loadPage();
Page *loadSplashPage();
RETROFE_STATE processUserInput(Page *page);
void update(float dt, bool scrollActive);
std::string getLayout(std::string collectionName);
CollectionInfo *getCollection(std::string collectionName);
void initializeLua();
void reloadLuaScripts();
Configuration &config_;
DB *db_;
MetadataDatabase *metadb_;
UserInput input_;
Page *currentPage_;
float keyInputDisable_;
float currentTime_;
float lastLaunchReturnTime_;
float keyLastTime_;
float keyDelayTime_;
Item *nextPageItem_;
FontCache fontcache_;
AttractMode attract_;
std::map<std::string, unsigned int> lastMenuOffsets_;
Lua lua_;
};