mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-17 22:55:38 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
e809414558
13
.gitignore
vendored
13
.gitignore
vendored
|
@ -14,13 +14,18 @@
|
|||
# Dependency makefiles
|
||||
*.d
|
||||
|
||||
#Compiled executable
|
||||
# Compiled executable
|
||||
emulationstation
|
||||
|
||||
#build directory
|
||||
EmulationStation_vs2010
|
||||
# build directory
|
||||
build
|
||||
Debug
|
||||
Release
|
||||
MinSizeRel
|
||||
RelWithDebInfo
|
||||
RelWithDebInfo
|
||||
|
||||
# CMake
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
cmake_install.cmake
|
||||
Makefile
|
||||
|
|
|
@ -117,7 +117,7 @@ set(ES_HEADERS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/FolderData.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Font.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/GameData.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Gui.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/GuiComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ImageIO.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/InputConfig.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/InputManager.h
|
||||
|
@ -125,21 +125,28 @@ set(ES_HEADERS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/MathExp.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/platform.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Settings.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Sound.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/SystemData.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Vector2.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/VolumeControl.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Window.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/XMLReader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiAnimation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/AnimationComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ComponentListComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/SliderComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/SwitchComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/TextComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/TextListComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ThemeComponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiBox.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiDetectDevice.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiFastSelect.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiGameList.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiImage.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiInputConfig.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiList.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMenu.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiTheme.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiSettingsMenu.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugiconfig.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugixml.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/data/Resources.h
|
||||
|
@ -149,7 +156,7 @@ set(ES_SOURCES
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/FolderData.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Font.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/GameData.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Gui.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/GuiComponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ImageIO.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/InputConfig.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/InputManager.cpp
|
||||
|
@ -159,21 +166,26 @@ set(ES_SOURCES
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/platform.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer_draw_gl.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer_init.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Settings.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Sound.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/SystemData.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/VolumeControl.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Window.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/XMLReader.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiAnimation.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/AnimationComponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ComponentListComponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageComponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/SliderComponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/SwitchComponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/TextComponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ThemeComponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiBox.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiDetectDevice.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiFastSelect.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiGameList.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiImage.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiInputConfig.cpp
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiList.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMenu.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiTheme.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiSettingsMenu.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugixml.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/data/logo/ES_logo_16.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/data/logo/ES_logo_32.cpp
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual C++ Express 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EmulationStation_vs2010", "EmulationStation_vs2010\EmulationStation_vs2010.vcxproj", "{0AB5C397-7B64-4AAD-92AD-E6B72FEDE8C3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0AB5C397-7B64-4AAD-92AD-E6B72FEDE8C3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{0AB5C397-7B64-4AAD-92AD-E6B72FEDE8C3}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{0AB5C397-7B64-4AAD-92AD-E6B72FEDE8C3}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{0AB5C397-7B64-4AAD-92AD-E6B72FEDE8C3}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -1,128 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{0AB5C397-7B64-4AAD-92AD-E6B72FEDE8C3}</ProjectGuid>
|
||||
<RootNamespace>EmulationStation_vs2010</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="lib_paths.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="lib_paths.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>USE_OPENGL_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\AudioManager.cpp" />
|
||||
<ClCompile Include="..\..\src\components\GuiAnimation.cpp" />
|
||||
<ClCompile Include="..\..\src\components\GuiBox.cpp" />
|
||||
<ClCompile Include="..\..\src\components\GuiDetectDevice.cpp" />
|
||||
<ClCompile Include="..\..\src\components\GuiFastSelect.cpp" />
|
||||
<ClCompile Include="..\..\src\components\GuiGameList.cpp" />
|
||||
<ClCompile Include="..\..\src\components\GuiImage.cpp" />
|
||||
<ClCompile Include="..\..\src\components\GuiInputConfig.cpp" />
|
||||
<ClCompile Include="..\..\src\components\GuiMenu.cpp" />
|
||||
<ClCompile Include="..\..\src\components\GuiTheme.cpp" />
|
||||
<ClCompile Include="..\..\src\FolderData.cpp" />
|
||||
<ClCompile Include="..\..\src\Font.cpp" />
|
||||
<ClCompile Include="..\..\src\GameData.cpp" />
|
||||
<ClCompile Include="..\..\src\Gui.cpp" />
|
||||
<ClCompile Include="..\..\src\InputConfig.cpp" />
|
||||
<ClCompile Include="..\..\src\InputManager.cpp" />
|
||||
<ClCompile Include="..\..\src\Log.cpp" />
|
||||
<ClCompile Include="..\..\src\main.cpp" />
|
||||
<ClCompile Include="..\..\src\MathExp.cpp" />
|
||||
<ClCompile Include="..\..\src\platform.cpp" />
|
||||
<ClCompile Include="..\..\src\pugiXML\pugixml.cpp" />
|
||||
<ClCompile Include="..\..\src\Renderer_draw_gl.cpp" />
|
||||
<ClCompile Include="..\..\src\Renderer_init.cpp" />
|
||||
<ClCompile Include="..\..\src\Renderer_init_sdlgl.cpp" />
|
||||
<ClCompile Include="..\..\src\Sound.cpp" />
|
||||
<ClCompile Include="..\..\src\SystemData.cpp" />
|
||||
<ClCompile Include="..\..\src\Window.cpp" />
|
||||
<ClCompile Include="..\..\src\XMLReader.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\AudioManager.h" />
|
||||
<ClInclude Include="..\..\src\components\GuiAnimation.h" />
|
||||
<ClInclude Include="..\..\src\components\GuiBox.h" />
|
||||
<ClInclude Include="..\..\src\components\GuiDetectDevice.h" />
|
||||
<ClInclude Include="..\..\src\components\GuiFastSelect.h" />
|
||||
<ClInclude Include="..\..\src\components\GuiGameList.h" />
|
||||
<ClInclude Include="..\..\src\components\GuiImage.h" />
|
||||
<ClInclude Include="..\..\src\components\GuiInputConfig.h" />
|
||||
<ClInclude Include="..\..\src\components\GuiList.h" />
|
||||
<ClInclude Include="..\..\src\components\GuiMenu.h" />
|
||||
<ClInclude Include="..\..\src\components\GuiTheme.h" />
|
||||
<ClInclude Include="..\..\src\FileData.h" />
|
||||
<ClInclude Include="..\..\src\FolderData.h" />
|
||||
<ClInclude Include="..\..\src\Font.h" />
|
||||
<ClInclude Include="..\..\src\GameData.h" />
|
||||
<ClInclude Include="..\..\src\Gui.h" />
|
||||
<ClInclude Include="..\..\src\InputConfig.h" />
|
||||
<ClInclude Include="..\..\src\InputManager.h" />
|
||||
<ClInclude Include="..\..\src\Log.h" />
|
||||
<ClInclude Include="..\..\src\MathExp.h" />
|
||||
<ClInclude Include="..\..\src\platform.h" />
|
||||
<ClInclude Include="..\..\src\pugiXML\pugiconfig.hpp" />
|
||||
<ClInclude Include="..\..\src\pugiXML\pugixml.hpp" />
|
||||
<ClInclude Include="..\..\src\Renderer.h" />
|
||||
<ClInclude Include="..\..\src\Sound.h" />
|
||||
<ClInclude Include="..\..\src\SystemData.h" />
|
||||
<ClInclude Include="..\..\src\Window.h" />
|
||||
<ClInclude Include="..\..\src\XMLReader.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -1,195 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="components">
|
||||
<UniqueIdentifier>{31a8e8d1-9795-42bf-99fd-500e57ac87d4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="PugiXML">
|
||||
<UniqueIdentifier>{bec1ca52-69f2-42eb-b134-57016057661a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\AudioManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\FolderData.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Font.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\GameData.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Gui.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\InputConfig.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\InputManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Log.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\MathExp.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Renderer_draw_gl.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Renderer_init.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Sound.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\SystemData.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Window.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\XMLReader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\components\GuiAnimation.cpp">
|
||||
<Filter>components</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\components\GuiTheme.cpp">
|
||||
<Filter>components</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\components\GuiBox.cpp">
|
||||
<Filter>components</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\components\GuiDetectDevice.cpp">
|
||||
<Filter>components</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\components\GuiFastSelect.cpp">
|
||||
<Filter>components</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\components\GuiGameList.cpp">
|
||||
<Filter>components</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\components\GuiImage.cpp">
|
||||
<Filter>components</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\components\GuiInputConfig.cpp">
|
||||
<Filter>components</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\components\GuiMenu.cpp">
|
||||
<Filter>components</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\pugiXML\pugixml.cpp">
|
||||
<Filter>PugiXML</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\platform.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Renderer_init_sdlgl.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\AudioManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\FileData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\FolderData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Font.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\GameData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Gui.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\InputConfig.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\InputManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Log.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\MathExp.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\platform.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Renderer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Sound.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\SystemData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Window.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\XMLReader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\components\GuiTheme.h">
|
||||
<Filter>components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\components\GuiAnimation.h">
|
||||
<Filter>components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\components\GuiBox.h">
|
||||
<Filter>components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\components\GuiDetectDevice.h">
|
||||
<Filter>components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\components\GuiFastSelect.h">
|
||||
<Filter>components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\components\GuiGameList.h">
|
||||
<Filter>components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\components\GuiImage.h">
|
||||
<Filter>components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\components\GuiInputConfig.h">
|
||||
<Filter>components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\components\GuiList.h">
|
||||
<Filter>components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\components\GuiMenu.h">
|
||||
<Filter>components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\pugiXML\pugiconfig.hpp">
|
||||
<Filter>PugiXML</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\pugiXML\pugixml.hpp">
|
||||
<Filter>PugiXML</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_DESKTOP_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>SDLmain.lib;SDL.lib;FreeImage.lib;freetype.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup />
|
||||
</Project>
|
4
Makefile
4
Makefile
|
@ -1,4 +0,0 @@
|
|||
CPPFLAGS=-I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -I/usr/include/freetype2 -I/usr/include/SDL -D_RPI_
|
||||
LIBS=-L/opt/vc/lib -lbcm_host -lEGL -lGLESv2 -lfreetype -lSDL -lboost_system -lboost_filesystem -lfreeimage -lSDL_mixer
|
||||
|
||||
include Makefile.common
|
|
@ -1,25 +0,0 @@
|
|||
CXX=g++
|
||||
CXXFLAGS=-Wall -g -O2
|
||||
LDFLAGS=
|
||||
|
||||
SRC_SOURCES=platform.cpp AudioManager.cpp Window.cpp InputConfig.cpp Log.cpp FolderData.cpp Font.cpp GameData.cpp Gui.cpp InputManager.cpp main.cpp MathExp.cpp Renderer_draw_gl.cpp Renderer_init.cpp Sound.cpp SystemData.cpp XMLReader.cpp components/GuiAnimation.cpp components/GuiBox.cpp components/GuiFastSelect.cpp components/GuiGameList.cpp components/GuiImage.cpp components/GuiMenu.cpp components/GuiTheme.cpp components/GuiInputConfig.cpp components/GuiDetectDevice.cpp pugiXML/pugixml.cpp
|
||||
SOURCES=$(addprefix src/,$(SRC_SOURCES))
|
||||
OBJECTS=$(SOURCES:.cpp=.o)
|
||||
DEPS=$(SOURCES:.cpp=.d)
|
||||
EXECUTABLE=emulationstation
|
||||
|
||||
all: $(EXECUTABLE)
|
||||
|
||||
$(EXECUTABLE): $(DEPS) $(OBJECTS)
|
||||
$(CXX) -o $@ $(LDFLAGS) $(OBJECTS) $(LIBS)
|
||||
|
||||
include $(wildcard src/*.d src/components/*.d src/pugiXML/*.d)
|
||||
|
||||
%.d: %.cpp
|
||||
$(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $< | tr -d "\\\\\n" | sed -e "s|$(*F).o|$(*D)/& $@|" -e "s|: \(.*\)|: \$$\(wildcard \1\)|" > $@'
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f src/*.[do] src/components/*.[do] src/pugiXML/*.[do] $(EXECUTABLE)
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
CPPFLAGS=-I/usr/include/freetype2 -I/usr/include/SDL -D_DESKTOP_
|
||||
LIBS=-lGL -lfreetype -lSDL -lboost_system -lboost_filesystem -lfreeimage -lSDL_mixer
|
||||
|
||||
include Makefile.common
|
54
README.md
54
README.md
|
@ -1,44 +1,54 @@
|
|||
EmulationStation
|
||||
================
|
||||
|
||||
A graphical front-end for emulators with controller navigation. Developed for the Raspbery Pi, but runs on most Linux systems.
|
||||
A cross-platform graphical front-end for emulators with controller navigation.
|
||||
|
||||
A cool guy named petrockblog made a script which automatically installs RetroArch, its cores, and ES. It also includes options for configuring your RPi and setting it up to boot directly into ES. You can find it here: https://github.com/petrockblog/RetroPie-Setup
|
||||
**Raspberry Pi users:**
|
||||
A cool guy named petrockblog made a script which automatically installs many emulators and ES. It also includes options for configuring your RPi and setting it up to boot directly into ES. You can find it here: https://github.com/petrockblog/RetroPie-Setup
|
||||
|
||||
Building
|
||||
========
|
||||
|
||||
**On the Raspberry Pi:**
|
||||
EmulationStation uses some C++11 code, which means you'll need to install at least g++-4.7 on Linux, or VS2010 on Windows.
|
||||
|
||||
EmulationStation has a few dependencies. For building, you'll need SDL 1.2, SDL_mixer, FreeImage, FreeType, and Boost.Filesystem, which can easily be obtained with apt-get:
|
||||
EmulationStation has a few dependencies. For building, you'll need SDL 1.2, Boost.System, Boost.Filesystem, FreeImage, FreeType, and the DejaVu TrueType font.
|
||||
|
||||
**On Linux:**
|
||||
All of this be easily installed with apt-get:
|
||||
```
|
||||
sudo apt-get install libsdl1.2-dev libboost-system-dev libboost-filesystem-dev libfreeimage-dev libfreetype6-dev ttf-dejavu
|
||||
```
|
||||
|
||||
There are also a few libraries already on the RPi (located in /opt/vc/, like the Broadcom libraries, EGL, and GLES). You can build EmulationStation by simply running `make`.
|
||||
|
||||
|
||||
**On something else (desktop):**
|
||||
|
||||
EmulationStation can also be built on a "normal" Linux system. You'll need the same libraries listed above:
|
||||
```
|
||||
sudo apt-get install libsdl1.2-dev libboost-system-dev libboost-filesystem-dev libfreeimage-dev libfreetype6-dev ttf-dejavu
|
||||
```
|
||||
|
||||
You'll also need OpenGL. I you don't have `/usr/include/GL/gl.h` and `libGL` try installing the MESA development package with:
|
||||
On "desktop" Linux (that is, *not* the Raspberry Pi), you'll also need OpenGL. Try installing the MESA development package with:
|
||||
```
|
||||
sudo apt-get libgl1-mesa-dev
|
||||
```
|
||||
|
||||
You can build with `make -f Makefile.x86` (badly named Makefile, I know). For some reason it doesn't seem to run with X closed on desktop.
|
||||
On the Raspberry Pi, there are also a few special libraries, located in /opt/vc/: the Broadcom libraries, libEGL, and GLES. You shouldn't need to install them.
|
||||
|
||||
|
||||
**Via CMake:**
|
||||
<pre>
|
||||
**Generate and Build Makefile with CMake:**
|
||||
```
|
||||
cd EmulationStation
|
||||
cmake .
|
||||
make
|
||||
</pre>
|
||||
```
|
||||
|
||||
**On Windows:**
|
||||
|
||||
[Boost](http://www.boost.org/users/download/) (you'll need to compile for Boost.Filesystem)
|
||||
|
||||
[FreeImage](http://downloads.sourceforge.net/freeimage/FreeImage3154Win32.zip)
|
||||
|
||||
[FreeType2](http://download.savannah.gnu.org/releases/freetype/freetype-2.4.9.tar.bz2) (you'll need to compile)
|
||||
|
||||
[SDL-1.2](http://www.libsdl.org/release/SDL-devel-1.2.15-VC.zip)
|
||||
|
||||
(remember to copy necessary .DLLs into the same folder as the executable: FreeImage.dll, freetype6.dll, SDL.dll, and zlib1.dll)
|
||||
|
||||
[CMake](http://www.cmake.org/cmake/resources/software.html) (this is used for generating the Visual Studio project)
|
||||
|
||||
(If you don't know how to use CMake, here are some hints: run CMake-gui and point it at your EmulationStation folder. Point the "build" directory somewhere - I use EmulationStation/build. Click configure, choose "Visual Studio 2010 Project", fill in red fields as they appear, then click Generate.)
|
||||
|
||||
|
||||
Configuring
|
||||
===========
|
||||
|
@ -97,10 +107,12 @@ The COMMAND is the shell command ES will execute to start your emulator. As it i
|
|||
|
||||
The following "tags" are replaced by ES in COMMANDs:
|
||||
|
||||
`%ROM%` - Replaced with absolute path to the selected ROM.
|
||||
`%ROM%` - Replaced with absolute path to the selected ROM, with most Bash special characters escaped with a backslash.
|
||||
|
||||
`%BASENAME%` - Replaced with the "base" name of the path to the selected ROM. For example, a path of "/foo/bar.rom", this tag would be "bar". This tag is useful for setting up AdvanceMAME.
|
||||
|
||||
`%ROM_RAW%` - Replaced with the unescaped absolute path to the selected ROM. If your emulator is picky about paths, you might want to use this instead of %ROM%, but enclosed in quotes.
|
||||
|
||||
gamelist.xml
|
||||
============
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ void AudioManager::mixAudio(void *unused, Uint8 *stream, int len)
|
|||
{
|
||||
//calculate rest length of current sample
|
||||
Uint32 restLength = (sound->getLength() - sound->getPosition());
|
||||
if (restLength > len) {
|
||||
if (restLength > (Uint32)len) {
|
||||
//if stream length is smaller than smaple lenght, clip it
|
||||
restLength = len;
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
// Do this version number update as the very last commit for the new release version.
|
||||
#define PROGRAM_VERSION_MAJOR 1
|
||||
#define PROGRAM_VERSION_MINOR 0
|
||||
#define PROGRAM_VERSION_MAINTENANCE 0
|
||||
#define PROGRAM_VERSION_MAINTENANCE 1
|
||||
#define PROGRAM_VERSION_REVISION 0
|
||||
#define PROGRAM_VERSION_STRING "1.0.0.0 - built " __DATE__ " - " __TIME__
|
||||
#define RESOURCE_VERSION_STRING "1,0,0,0\0"
|
||||
#define PROGRAM_VERSION_STRING "1.0.1.0 - built " __DATE__ " - " __TIME__
|
||||
#define RESOURCE_VERSION_STRING "1,0,1,0\0"
|
||||
|
||||
#define RESOURCE_VERSION PROGRAM_VERSION_MAJOR,PROGRAM_VERSION_MINOR,PROGRAM_VERSION_MAINTENANCE,PROGRAM_VERSION_REVISION
|
||||
|
|
|
@ -37,7 +37,9 @@ bool filesort(FileData* file1, FileData* file2)
|
|||
std::string name1 = file1->getName();
|
||||
std::string name2 = file2->getName();
|
||||
|
||||
for(unsigned int i = 0; i < name1.length(); i++)
|
||||
//min of name1/name2 .length()s
|
||||
unsigned int count = name1.length() > name2.length() ? name2.length() : name1.length();
|
||||
for(unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if(toupper(name1[i]) != toupper(name2[i]))
|
||||
{
|
||||
|
|
111
src/Font.cpp
111
src/Font.cpp
|
@ -5,6 +5,7 @@
|
|||
#include "Renderer.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "Log.h"
|
||||
#include "Vector2.h"
|
||||
|
||||
FT_Library Font::sLibrary;
|
||||
bool Font::libraryInitialized = false;
|
||||
|
@ -199,7 +200,7 @@ void Font::buildAtlas()
|
|||
if((y + maxHeight) >= textureHeight)
|
||||
{
|
||||
//failed to create a proper font texture
|
||||
LOG(LogError) << "Error - font with size " << mSize << " exceeded texture size! Trying again...";
|
||||
LOG(LogWarning) << "Font with size " << mSize << " exceeded max texture size! Trying again...";
|
||||
//try a 3/4th smaller size and redo initialization
|
||||
fontScale *= 1.25f;
|
||||
mSize = (int)(mSize * (1.0f / fontScale));
|
||||
|
@ -207,10 +208,8 @@ void Font::buildAtlas()
|
|||
init();
|
||||
}
|
||||
else {
|
||||
LOG(LogInfo) << "Created font with size " << mSize << std::endl;
|
||||
LOG(LogInfo) << "Created font with size " << mSize << ".";
|
||||
}
|
||||
|
||||
//std::cout << "generated texture \"" << textureID << "\" (w: " << w << " h: " << h << ")" << std::endl;
|
||||
}
|
||||
|
||||
Font::~Font()
|
||||
|
@ -220,33 +219,10 @@ Font::~Font()
|
|||
}
|
||||
|
||||
|
||||
|
||||
//why these aren't in an array:
|
||||
//openGL reads these in the order they are in memory
|
||||
//if I use an array, it will be 4 x values then 4 y values
|
||||
//it'll read XX, XX, YY instead of XY, XY, XY
|
||||
//...
|
||||
//that was the thinking at the time and honestly an array would have been smarter wow I'm dumb
|
||||
struct point {
|
||||
GLfloat pos0x;
|
||||
GLfloat pos0y;
|
||||
|
||||
GLfloat pos1x;
|
||||
GLfloat pos1y;
|
||||
|
||||
GLfloat pos2x;
|
||||
GLfloat pos2y;
|
||||
};
|
||||
|
||||
struct tex {
|
||||
GLfloat tex0x;
|
||||
GLfloat tex0y;
|
||||
|
||||
GLfloat tex1x;
|
||||
GLfloat tex1y;
|
||||
|
||||
GLfloat tex2x;
|
||||
GLfloat tex2y;
|
||||
struct Vertex
|
||||
{
|
||||
Vector2<GLfloat> pos;
|
||||
Vector2<GLfloat> tex;
|
||||
};
|
||||
|
||||
void Font::drawText(std::string text, int startx, int starty, int color)
|
||||
|
@ -257,10 +233,9 @@ void Font::drawText(std::string text, int startx, int starty, int color)
|
|||
return;
|
||||
}
|
||||
|
||||
int pointCount = text.length() * 2;
|
||||
point* points = new point[pointCount];
|
||||
tex* texs = new tex[pointCount];
|
||||
GLubyte* colors = new GLubyte[pointCount * 3 * 4];
|
||||
const int triCount = text.length() * 2;
|
||||
Vertex* vert = new Vertex[triCount * 3];
|
||||
GLubyte* colors = new GLubyte[triCount * 3 * 4];
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
@ -274,58 +249,51 @@ void Font::drawText(std::string text, int startx, int starty, int color)
|
|||
float x = (float)startx;
|
||||
float y = starty + mMaxGlyphHeight * 1.1f * fontScale; //padding (another 0.5% is added to the bottom through the sizeText function)
|
||||
|
||||
int p = 0;
|
||||
for(int i = 0; p < pointCount; i++, p++)
|
||||
int charNum = 0;
|
||||
for(int i = 0; i < triCount * 3; i += 6, charNum++)
|
||||
{
|
||||
unsigned char letter = text[i];
|
||||
unsigned char letter = text[charNum];
|
||||
|
||||
if(letter < 32 || letter >= 128)
|
||||
letter = 127; //print [X] if character is not standard ASCII
|
||||
|
||||
points[p].pos0x = x;
|
||||
points[p].pos0y = y + (charData[letter].texH - charData[letter].bearingY) * fontScale;
|
||||
points[p].pos1x = x + charData[letter].texW * fontScale;
|
||||
points[p].pos1y = y - charData[letter].bearingY * fontScale;
|
||||
points[p].pos2x = x;
|
||||
points[p].pos2y = points[p].pos1y;
|
||||
//order is bottom left, top right, top left
|
||||
vert[i + 0].pos = Vector2<GLfloat>(x, y + (charData[letter].texH - charData[letter].bearingY) * fontScale);
|
||||
vert[i + 1].pos = Vector2<GLfloat>(x + charData[letter].texW * fontScale, y - charData[letter].bearingY * fontScale);
|
||||
vert[i + 2].pos = Vector2<GLfloat>(x, vert[i + 1].pos.y);
|
||||
|
||||
texs[p].tex0x = charData[letter].texX / tw;
|
||||
texs[p].tex0y = (charData[letter].texY + charData[letter].texH) / th;
|
||||
texs[p].tex1x = (charData[letter].texX + charData[letter].texW) / tw;
|
||||
texs[p].tex1y = charData[letter].texY / th;
|
||||
texs[p].tex2x = texs[p].tex0x;
|
||||
texs[p].tex2y = texs[p].tex1y;
|
||||
Vector2<int> charTexCoord(charData[letter].texX, charData[letter].texY);
|
||||
Vector2<int> charTexSize(charData[letter].texW, charData[letter].texH);
|
||||
|
||||
p++;
|
||||
vert[i + 0].tex = Vector2<GLfloat>(charTexCoord.x / tw, (charTexCoord.y + charTexSize.y) / th);
|
||||
vert[i + 1].tex = Vector2<GLfloat>((charTexCoord.x + charTexSize.x) / tw, charTexCoord.y / th);
|
||||
vert[i + 2].tex = Vector2<GLfloat>(vert[i + 0].tex.x, vert[i + 1].tex.y);
|
||||
|
||||
points[p].pos0x = points[p-1].pos0x;
|
||||
points[p].pos0y = points[p-1].pos0y;
|
||||
points[p].pos1x = points[p-1].pos1x;
|
||||
points[p].pos1y = points[p-1].pos1y;
|
||||
points[p].pos2x = points[p-1].pos1x;
|
||||
points[p].pos2y = points[p-1].pos0y;
|
||||
//next triangle (second half of the quad)
|
||||
vert[i + 3].pos = vert[i + 0].pos;
|
||||
vert[i + 4].pos = vert[i + 1].pos;
|
||||
vert[i + 5].pos.x = vert[i + 1].pos.x;
|
||||
vert[i + 5].pos.y = vert[i + 0].pos.y;
|
||||
|
||||
texs[p].tex0x = texs[p-1].tex0x;
|
||||
texs[p].tex0y = texs[p-1].tex0y;
|
||||
texs[p].tex1x = texs[p-1].tex1x;
|
||||
texs[p].tex1y = texs[p-1].tex1y;
|
||||
texs[p].tex2x = texs[p-1].tex1x;
|
||||
texs[p].tex2y = texs[p-1].tex0y;
|
||||
vert[i + 3].tex = vert[i + 0].tex;
|
||||
vert[i + 4].tex = vert[i + 1].tex;
|
||||
vert[i + 5].tex.x = vert[i + 1].tex.x;
|
||||
vert[i + 5].tex.y = vert[i + 0].tex.y;
|
||||
|
||||
x += charData[letter].advX * fontScale;
|
||||
}
|
||||
|
||||
Renderer::buildGLColorArray(colors, color, pointCount * 3);
|
||||
Renderer::buildGLColorArray(colors, color, triCount * 3);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
glVertexPointer(2, GL_FLOAT, 0, points);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, texs);
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &vert[0].pos);
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vert[0].tex);
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, pointCount * 3);
|
||||
glDrawArrays(GL_TRIANGLES, 0, triCount * 3);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
@ -334,14 +302,13 @@ void Font::drawText(std::string text, int startx, int starty, int color)
|
|||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
delete[] points;
|
||||
delete[] texs;
|
||||
delete[] vert;
|
||||
delete[] colors;
|
||||
}
|
||||
|
||||
void Font::sizeText(std::string text, int* w, int* h)
|
||||
{
|
||||
int cwidth = 0;
|
||||
float cwidth = 0.0f;
|
||||
for(unsigned int i = 0; i < text.length(); i++)
|
||||
{
|
||||
unsigned char letter = text[i];
|
||||
|
@ -352,10 +319,10 @@ void Font::sizeText(std::string text, int* w, int* h)
|
|||
}
|
||||
|
||||
if(w != NULL)
|
||||
*w = cwidth;
|
||||
*w = (int)cwidth;
|
||||
|
||||
if(h != NULL)
|
||||
*h = (int)(mMaxGlyphHeight * 1.5f * fontScale);
|
||||
*h = getHeight();
|
||||
}
|
||||
|
||||
int Font::getHeight()
|
||||
|
|
|
@ -22,6 +22,7 @@ std::string GameData::getBashPath()
|
|||
{
|
||||
//a quick and dirty way to insert a backslash before most characters that would mess up a bash path
|
||||
std::string path = mPath;
|
||||
|
||||
const char* invalidChars = " '\"\\!$^&*(){}[]?;<>";
|
||||
for(unsigned int i = 0; i < path.length(); i++)
|
||||
{
|
||||
|
|
17
src/Gui.cpp
17
src/Gui.cpp
|
@ -1,17 +0,0 @@
|
|||
#include "Gui.h"
|
||||
#include "Window.h"
|
||||
|
||||
Gui::Gui(Window* window) : mWindow(window)
|
||||
{
|
||||
}
|
||||
|
||||
Gui::~Gui()
|
||||
{
|
||||
mWindow->removeGui(this);
|
||||
}
|
||||
|
||||
void Gui::setOffset(int x, int y) { mOffsetX = x; mOffsetY = y; }
|
||||
void Gui::setOffsetX(int x) { mOffsetX = x; }
|
||||
void Gui::setOffsetY(int y) { mOffsetY = y; }
|
||||
int Gui::getOffsetX() { return mOffsetX; }
|
||||
int Gui::getOffsetY() { return mOffsetY; }
|
33
src/Gui.h
33
src/Gui.h
|
@ -1,33 +0,0 @@
|
|||
#ifndef _GUI_H_
|
||||
#define _GUI_H_
|
||||
|
||||
#include "InputConfig.h"
|
||||
|
||||
class Window;
|
||||
|
||||
class Gui
|
||||
{
|
||||
public:
|
||||
Gui(Window* window);
|
||||
virtual ~Gui();
|
||||
|
||||
virtual void input(InputConfig* config, Input input) { };
|
||||
virtual void update(int deltaTime) { };
|
||||
virtual void render() { };
|
||||
|
||||
virtual void init() { };
|
||||
virtual void deinit() { };
|
||||
|
||||
void setOffsetX(int x);
|
||||
void setOffsetY(int y);
|
||||
void setOffset(int x, int y);
|
||||
int getOffsetX();
|
||||
int getOffsetY();
|
||||
protected:
|
||||
int mOffsetX;
|
||||
int mOffsetY;
|
||||
|
||||
Window* mWindow;
|
||||
};
|
||||
|
||||
#endif
|
158
src/GuiComponent.cpp
Normal file
158
src/GuiComponent.cpp
Normal file
|
@ -0,0 +1,158 @@
|
|||
#include "GuiComponent.h"
|
||||
#include "Window.h"
|
||||
#include "Log.h"
|
||||
#include "Renderer.h"
|
||||
|
||||
GuiComponent::GuiComponent(Window* window) : mWindow(window), mParent(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
GuiComponent::~GuiComponent()
|
||||
{
|
||||
mWindow->removeGui(this);
|
||||
|
||||
if(mParent)
|
||||
mParent->removeChild(this);
|
||||
|
||||
for(unsigned int i = 0; i < getChildCount(); i++)
|
||||
getChild(i)->setParent(NULL);
|
||||
}
|
||||
|
||||
bool GuiComponent::input(InputConfig* config, Input input)
|
||||
{
|
||||
for(unsigned int i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
if(getChild(i)->input(config, input))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GuiComponent::update(int deltaTime)
|
||||
{
|
||||
for(unsigned int i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
getChild(i)->update(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiComponent::render()
|
||||
{
|
||||
Renderer::translate(mOffset);
|
||||
|
||||
onRender();
|
||||
|
||||
Renderer::translate(-mOffset);
|
||||
}
|
||||
|
||||
void GuiComponent::onRender()
|
||||
{
|
||||
for(unsigned int i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
getChild(i)->render();
|
||||
}
|
||||
}
|
||||
|
||||
void GuiComponent::init()
|
||||
{
|
||||
for(unsigned int i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
getChild(i)->init();
|
||||
}
|
||||
}
|
||||
|
||||
void GuiComponent::deinit()
|
||||
{
|
||||
for(unsigned int i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
getChild(i)->deinit();
|
||||
}
|
||||
}
|
||||
|
||||
//Offset stuff.
|
||||
Vector2i GuiComponent::getGlobalOffset()
|
||||
{
|
||||
if(mParent)
|
||||
return mParent->getGlobalOffset() + mOffset;
|
||||
else
|
||||
return mOffset;
|
||||
}
|
||||
|
||||
Vector2i GuiComponent::getOffset()
|
||||
{
|
||||
return mOffset;
|
||||
}
|
||||
|
||||
void GuiComponent::setOffset(Vector2i offset)
|
||||
{
|
||||
setOffset(offset.x, offset.y);
|
||||
onOffsetChanged();
|
||||
}
|
||||
|
||||
void GuiComponent::setOffset(int x, int y)
|
||||
{
|
||||
mOffset.x = x;
|
||||
mOffset.y = y;
|
||||
onOffsetChanged();
|
||||
}
|
||||
|
||||
Vector2u GuiComponent::getSize()
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
//Children stuff.
|
||||
void GuiComponent::addChild(GuiComponent* cmp)
|
||||
{
|
||||
mChildren.push_back(cmp);
|
||||
|
||||
if(cmp->getParent())
|
||||
cmp->getParent()->removeChild(cmp);
|
||||
|
||||
cmp->setParent(this);
|
||||
}
|
||||
|
||||
void GuiComponent::removeChild(GuiComponent* cmp)
|
||||
{
|
||||
if(cmp->getParent() != this)
|
||||
{
|
||||
LOG(LogError) << "Tried to remove child from incorrect parent!";
|
||||
}
|
||||
|
||||
cmp->setParent(NULL);
|
||||
|
||||
for(auto i = mChildren.begin(); i != mChildren.end(); i++)
|
||||
{
|
||||
if(*i == cmp)
|
||||
{
|
||||
mChildren.erase(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuiComponent::clearChildren()
|
||||
{
|
||||
mChildren.clear();
|
||||
}
|
||||
|
||||
unsigned int GuiComponent::getChildCount()
|
||||
{
|
||||
return mChildren.size();
|
||||
}
|
||||
|
||||
GuiComponent* GuiComponent::getChild(unsigned int i)
|
||||
{
|
||||
return mChildren.at(i);
|
||||
}
|
||||
|
||||
void GuiComponent::setParent(GuiComponent* parent)
|
||||
{
|
||||
mParent = parent;
|
||||
}
|
||||
|
||||
GuiComponent* GuiComponent::getParent()
|
||||
{
|
||||
return mParent;
|
||||
}
|
60
src/GuiComponent.h
Normal file
60
src/GuiComponent.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
#ifndef _GUICOMPONENT_H_
|
||||
#define _GUICOMPONENT_H_
|
||||
|
||||
#include "InputConfig.h"
|
||||
#include "Vector2.h"
|
||||
|
||||
class Window;
|
||||
|
||||
class GuiComponent
|
||||
{
|
||||
public:
|
||||
GuiComponent(Window* window);
|
||||
virtual ~GuiComponent();
|
||||
|
||||
//Called when input is received.
|
||||
//Return true if the input is consumed, false if it should continue to be passed to other children.
|
||||
virtual bool input(InputConfig* config, Input input);
|
||||
|
||||
//Called when time passes. Default implementation also calls update(deltaTime) on children - so you should probably call GuiComponent::update(deltaTime) at some point.
|
||||
virtual void update(int deltaTime);
|
||||
|
||||
//Called when it's time to render. Translates the OpenGL matrix, calls onRender() (which renders children), then un-translates the OpenGL matrix.
|
||||
//You probably don't need to override this, and should use the protected method onRender.
|
||||
virtual void render();
|
||||
|
||||
//Called when the Renderer initializes. Passes to children.
|
||||
virtual void init();
|
||||
|
||||
//Called when the Renderer deinitializes. Passes to children.
|
||||
virtual void deinit();
|
||||
|
||||
virtual Vector2i getGlobalOffset();
|
||||
Vector2i getOffset();
|
||||
void setOffset(Vector2i offset);
|
||||
void setOffset(int x, int y);
|
||||
virtual void onOffsetChanged() {};
|
||||
|
||||
Vector2u getSize();
|
||||
|
||||
void setParent(GuiComponent* parent);
|
||||
GuiComponent* getParent();
|
||||
|
||||
void addChild(GuiComponent* cmp);
|
||||
void removeChild(GuiComponent* cmp);
|
||||
void clearChildren();
|
||||
unsigned int getChildCount();
|
||||
GuiComponent* getChild(unsigned int i);
|
||||
|
||||
protected:
|
||||
//Default implementation just renders children - you should probably always call GuiComponent::onRender at some point in your custom onRender.
|
||||
virtual void onRender();
|
||||
|
||||
Window* mWindow;
|
||||
GuiComponent* mParent;
|
||||
Vector2i mOffset;
|
||||
Vector2u mSize;
|
||||
std::vector<GuiComponent*> mChildren;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -3,6 +3,7 @@
|
|||
#include <algorithm>
|
||||
#include <SDL.h>
|
||||
#include <iostream>
|
||||
#include "Log.h"
|
||||
|
||||
//some util functions
|
||||
std::string inputTypeToString(InputType type)
|
||||
|
@ -138,7 +139,7 @@ void InputConfig::loadFromXML(pugi::xml_node node, int playerNum)
|
|||
|
||||
if(typeEnum == TYPE_COUNT)
|
||||
{
|
||||
std::cout << "ERROR - input type \"" << type << "\" is invalid! Skipping input \"" << name << "\".\n";
|
||||
LOG(LogError) << "InputConfig load error - input of type \"" << type << "\" is invalid! Skipping input \"" << name << "\".\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -146,7 +147,7 @@ void InputConfig::loadFromXML(pugi::xml_node node, int playerNum)
|
|||
int value = input.attribute("value").as_int();
|
||||
|
||||
if(value == 0)
|
||||
std::cout << "WARNING: InputConfig value is 0 for " << type << " " << id << "!\n";
|
||||
LOG(LogWarning) << "WARNING: InputConfig value is 0 for " << type << " " << id << "!\n";
|
||||
|
||||
mNameMap[toLower(name)] = Input(mDeviceId, typeEnum, id, value, true);
|
||||
}
|
||||
|
@ -167,6 +168,9 @@ void InputConfig::writeToXML(pugi::xml_node parent)
|
|||
typedef std::map<std::string, Input>::iterator it_type;
|
||||
for(it_type iterator = mNameMap.begin(); iterator != mNameMap.end(); iterator++)
|
||||
{
|
||||
if(!iterator->second.configured)
|
||||
continue;
|
||||
|
||||
pugi::xml_node input = cfg.append_child("input");
|
||||
input.append_attribute("name") = iterator->first.c_str();
|
||||
input.append_attribute("type") = inputTypeToString(iterator->second.type).c_str();
|
||||
|
|
|
@ -72,7 +72,7 @@ std::vector<InputDevice> InputManager::getInputDevices() const
|
|||
if (GetRawInputDeviceList(deviceList, &nrOfDevices, sizeof(RAWINPUTDEVICELIST)) != -1)
|
||||
{
|
||||
//loop through input devices
|
||||
for (int i = 0; i < nrOfDevices; i++)
|
||||
for (unsigned int i = 0; i < nrOfDevices; i++)
|
||||
{
|
||||
//get device name
|
||||
char * rawName = new char[2048];
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "Vector2.h"
|
||||
#include "platform.h"
|
||||
#include GLHEADER
|
||||
//#include "Font.h"
|
||||
|
@ -28,8 +29,16 @@ namespace Renderer
|
|||
Font* getDefaultFont(FontSize size);
|
||||
void buildGLColorArray(GLubyte* ptr, unsigned int color, unsigned int vertCount);
|
||||
|
||||
//drawing commands
|
||||
//graphics commands
|
||||
void swapBuffers();
|
||||
|
||||
void translatef(float x, float y);
|
||||
void translate(Vector2i offset);
|
||||
|
||||
void pushClipRect(int x, int y, unsigned int w, unsigned int h);
|
||||
void pushClipRect(Vector2i offset, Vector2u size);
|
||||
void popClipRect();
|
||||
|
||||
void drawRect(int x, int y, int w, int h, unsigned int color);
|
||||
void drawText(std::string text, int x, int y, unsigned int color, Font* font);
|
||||
void drawCenteredText(std::string text, int xOffset, int y, unsigned int color, Font* font);
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
#include "Font.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "Log.h"
|
||||
#include <stack>
|
||||
|
||||
namespace Renderer {
|
||||
bool loadedFonts = false;
|
||||
|
||||
std::stack<Rect> clipStack;
|
||||
|
||||
void setColor4bArray(GLubyte* array, unsigned int color)
|
||||
{
|
||||
array[0] = (color & 0xff000000) / 0x1000000;
|
||||
|
@ -26,6 +29,56 @@ namespace Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
void translatef(float x, float y)
|
||||
{
|
||||
glTranslatef(x, y, 0);
|
||||
}
|
||||
|
||||
void translate(Vector2i offset)
|
||||
{
|
||||
translatef((float)offset.x, (float)offset.y);
|
||||
}
|
||||
|
||||
void pushClipRect(int x, int y, unsigned int w, unsigned int h)
|
||||
{
|
||||
Rect rect(x, y, w, h);
|
||||
if(rect.size.x == 0)
|
||||
rect.size.x = Renderer::getScreenWidth() - rect.pos.x;
|
||||
if(rect.size.y == 0)
|
||||
rect.size.y = Renderer::getScreenHeight() - rect.pos.y;
|
||||
|
||||
//glScissor starts at the bottom left of the window
|
||||
//so (0, 0, 1, 1) is the bottom left pixel
|
||||
//everything else uses y+ = down, so flip it to be consistent
|
||||
rect.pos.y = Renderer::getScreenHeight() - rect.pos.y - rect.size.y;
|
||||
|
||||
clipStack.push(rect);
|
||||
glScissor(rect.pos.x, rect.pos.y, rect.size.x, rect.size.y);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
void pushClipRect(Vector2i pos, Vector2u size)
|
||||
{
|
||||
pushClipRect(pos.x, pos.y, size.x, size.y);
|
||||
}
|
||||
|
||||
void popClipRect()
|
||||
{
|
||||
if(clipStack.empty())
|
||||
{
|
||||
LOG(LogError) << "Tried to popClipRect while the stack was empty!";
|
||||
return;
|
||||
}
|
||||
clipStack.pop();
|
||||
if(clipStack.empty())
|
||||
{
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}else{
|
||||
Rect top = clipStack.top();
|
||||
glScissor(top.pos.x, top.pos.y, top.size.x, top.size.y);
|
||||
}
|
||||
}
|
||||
|
||||
void drawRect(int x, int y, int w, int h, unsigned int color)
|
||||
{
|
||||
#ifdef USE_OPENGL_ES
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
#include "ImageIO.h"
|
||||
#include "../data/Resources.h"
|
||||
#include "EmulationStation.h"
|
||||
|
||||
extern bool WINDOWED;
|
||||
#include "Settings.h"
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
|
@ -71,7 +70,8 @@ namespace Renderer
|
|||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
sdlScreen = SDL_SetVideoMode(display_width, display_height, 16, SDL_OPENGL | (WINDOWED ? 0 : SDL_FULLSCREEN) | SDL_DOUBLEBUF);
|
||||
//SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); //vsync
|
||||
sdlScreen = SDL_SetVideoMode(display_width, display_height, 16, SDL_OPENGL | (Settings::getInstance()->getBool("WINDOWED") ? 0 : SDL_FULLSCREEN));
|
||||
|
||||
if(sdlScreen == NULL)
|
||||
{
|
||||
|
@ -88,7 +88,7 @@ namespace Renderer
|
|||
LOG(LogInfo) << "Created surface successfully.";
|
||||
|
||||
//hide mouse cursor
|
||||
initialCursorState = SDL_ShowCursor(0);
|
||||
initialCursorState = SDL_ShowCursor(0) == 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
101
src/Settings.cpp
Normal file
101
src/Settings.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include "Settings.h"
|
||||
#include "Log.h"
|
||||
#include "pugiXML/pugixml.hpp"
|
||||
#include "platform.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
Settings* Settings::sInstance = NULL;
|
||||
|
||||
Settings::Settings()
|
||||
{
|
||||
setDefaults();
|
||||
loadFile();
|
||||
}
|
||||
|
||||
Settings* Settings::getInstance()
|
||||
{
|
||||
if(sInstance == NULL)
|
||||
sInstance = new Settings();
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
void Settings::setDefaults()
|
||||
{
|
||||
mBoolMap.clear();
|
||||
mIntMap.clear();
|
||||
|
||||
mBoolMap["PARSEGAMELISTONLY"] = false;
|
||||
mBoolMap["IGNOREGAMELIST"] = false;
|
||||
mBoolMap["DRAWFRAMERATE"] = false;
|
||||
mBoolMap["DONTSHOWEXIT"] = false;
|
||||
mBoolMap["DEBUG"] = false;
|
||||
mBoolMap["WINDOWED"] = false;
|
||||
|
||||
mIntMap["DIMTIME"] = 30*1000;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void saveMap(pugi::xml_document& doc, std::map<K, V>& map, const char* type)
|
||||
{
|
||||
for(auto iter = map.begin(); iter != map.end(); iter++)
|
||||
{
|
||||
pugi::xml_node node = doc.append_child(type);
|
||||
node.append_attribute("name").set_value(iter->first.c_str());
|
||||
node.append_attribute("value").set_value(iter->second);
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::saveFile()
|
||||
{
|
||||
const std::string path = getHomePath() + "/.emulationstation/es_settings.cfg";
|
||||
|
||||
pugi::xml_document doc;
|
||||
|
||||
saveMap<std::string, bool>(doc, mBoolMap, "bool");
|
||||
saveMap<std::string, int>(doc, mIntMap, "int");
|
||||
saveMap<std::string, float>(doc, mFloatMap, "float");
|
||||
|
||||
doc.save_file(path.c_str());
|
||||
}
|
||||
|
||||
void Settings::loadFile()
|
||||
{
|
||||
const std::string path = getHomePath() + "/.emulationstation/es_settings.cfg";
|
||||
|
||||
if(!boost::filesystem::exists(path))
|
||||
return;
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result = doc.load_file(path.c_str());
|
||||
if(!result)
|
||||
{
|
||||
LOG(LogError) << "Could not parse Settings file!\n " << result.description();
|
||||
return;
|
||||
}
|
||||
|
||||
for(pugi::xml_node node = doc.child("bool"); node; node = node.next_sibling())
|
||||
setBool(node.attribute("name").as_string(), node.attribute("value").as_bool());
|
||||
for(pugi::xml_node node = doc.child("int"); node; node = node.next_sibling())
|
||||
setInt(node.attribute("name").as_string(), node.attribute("value").as_int());
|
||||
for(pugi::xml_node node = doc.child("float"); node; node = node.next_sibling())
|
||||
setFloat(node.attribute("name").as_string(), node.attribute("value").as_float());
|
||||
}
|
||||
|
||||
//Print a warning message if the setting we're trying to get doesn't already exist in the map, then return the value in the map.
|
||||
#define SETTINGS_GETSET(type, mapName, getMethodName, setMethodName) type Settings::getMethodName(const std::string& name) \
|
||||
{ \
|
||||
if(mapName.find(name) == mapName.end()) \
|
||||
{ \
|
||||
LOG(LogError) << "Tried to use unset setting " << name << "!"; \
|
||||
} \
|
||||
return mapName[name]; \
|
||||
} \
|
||||
void Settings::setMethodName(const std::string& name, type value) \
|
||||
{ \
|
||||
mapName[name] = value; \
|
||||
}
|
||||
|
||||
SETTINGS_GETSET(bool, mBoolMap, getBool, setBool);
|
||||
SETTINGS_GETSET(int, mIntMap, getInt, setInt);
|
||||
SETTINGS_GETSET(float, mFloatMap, getFloat, setFloat);
|
38
src/Settings.h
Normal file
38
src/Settings.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#ifndef _SETTINGS_H_
|
||||
#define _SETTINGS_H_
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
//This is a singleton for storing settings.
|
||||
class Settings
|
||||
{
|
||||
public:
|
||||
static Settings* getInstance();
|
||||
|
||||
void loadFile();
|
||||
void saveFile();
|
||||
|
||||
//You will get a warning if you try a get on a key that is not already present.
|
||||
bool getBool(const std::string& name);
|
||||
int getInt(const std::string& name);
|
||||
float getFloat(const std::string& name);
|
||||
|
||||
void setBool(const std::string& name, bool value);
|
||||
void setInt(const std::string& name, int value);
|
||||
void setFloat(const std::string& name, float value);
|
||||
|
||||
private:
|
||||
static Settings* sInstance;
|
||||
|
||||
Settings();
|
||||
|
||||
//Clear everything and load default values.
|
||||
void setDefaults();
|
||||
|
||||
std::map<std::string, bool> mBoolMap;
|
||||
std::map<std::string, int> mIntMap;
|
||||
std::map<std::string, float> mFloatMap;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -11,14 +11,12 @@
|
|||
#include "Log.h"
|
||||
#include "InputManager.h"
|
||||
#include <iostream>
|
||||
#include "Settings.h"
|
||||
|
||||
std::vector<SystemData*> SystemData::sSystemVector;
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
extern bool PARSEGAMELISTONLY;
|
||||
extern bool IGNOREGAMELIST;
|
||||
|
||||
std::string SystemData::getStartPath() { return mStartPath; }
|
||||
std::string SystemData::getExtension() { return mSearchExtension; }
|
||||
|
||||
|
@ -41,10 +39,10 @@ SystemData::SystemData(std::string name, std::string descName, std::string start
|
|||
|
||||
mRootFolder = new FolderData(this, mStartPath, "Search Root");
|
||||
|
||||
if(!PARSEGAMELISTONLY)
|
||||
if(!Settings::getInstance()->getBool("PARSEGAMELISTONLY"))
|
||||
populateFolder(mRootFolder);
|
||||
|
||||
if(!IGNOREGAMELIST)
|
||||
if(!Settings::getInstance()->getBool("IGNOREGAMELIST"))
|
||||
parseGamelist(this);
|
||||
|
||||
mRootFolder->sort();
|
||||
|
@ -77,6 +75,7 @@ void SystemData::launchGame(Window* window, GameData* game)
|
|||
|
||||
command = strreplace(command, "%ROM%", game->getBashPath());
|
||||
command = strreplace(command, "%BASENAME%", game->getBaseName());
|
||||
command = strreplace(command, "%ROM_RAW%", game->getPath());
|
||||
|
||||
LOG(LogInfo) << " " << command;
|
||||
std::cout << "==============================================\n";
|
||||
|
@ -120,7 +119,37 @@ void SystemData::populateFolder(FolderData* folder)
|
|||
if(filePath.stem().string().empty())
|
||||
continue;
|
||||
|
||||
if(fs::is_directory(filePath))
|
||||
//this is a little complicated because we allow a list of extensions to be defined (delimited with a space)
|
||||
//we first get the extension of the file itself:
|
||||
std::string extension = filePath.extension().string();
|
||||
std::string chkExt;
|
||||
size_t extPos = 0;
|
||||
|
||||
//folders *can* also match the extension and be added as games - this is mostly just to support higan
|
||||
//see issue #75: https://github.com/Aloshi/EmulationStation/issues/75
|
||||
bool isGame = false;
|
||||
do {
|
||||
//now we loop through every extension in the list
|
||||
size_t cpos = extPos;
|
||||
extPos = mSearchExtension.find(" ", extPos);
|
||||
chkExt = mSearchExtension.substr(cpos, ((extPos == std::string::npos) ? mSearchExtension.length() - cpos: extPos - cpos));
|
||||
|
||||
//if it matches, add it
|
||||
if(chkExt == extension)
|
||||
{
|
||||
GameData* newGame = new GameData(this, filePath.string(), filePath.stem().string());
|
||||
folder->pushFileData(newGame);
|
||||
isGame = true;
|
||||
break;
|
||||
}else if(extPos != std::string::npos) //if not, add one to the "next position" marker to skip the space when reading the next extension
|
||||
{
|
||||
extPos++;
|
||||
}
|
||||
|
||||
} while(extPos != std::string::npos && chkExt != "" && chkExt.find(".") != std::string::npos);
|
||||
|
||||
//add directories that also do not match an extension as folders
|
||||
if(!isGame && fs::is_directory(filePath))
|
||||
{
|
||||
FolderData* newFolder = new FolderData(this, filePath.string(), filePath.stem().string());
|
||||
populateFolder(newFolder);
|
||||
|
@ -130,31 +159,6 @@ void SystemData::populateFolder(FolderData* folder)
|
|||
delete newFolder;
|
||||
else
|
||||
folder->pushFileData(newFolder);
|
||||
}else{
|
||||
//this is a little complicated because we allow a list of extensions to be defined (delimited with a space)
|
||||
//we first get the extension of the file itself:
|
||||
std::string extension = filePath.extension().string();
|
||||
std::string chkExt;
|
||||
size_t extPos = 0;
|
||||
|
||||
do {
|
||||
//now we loop through every extension in the list
|
||||
size_t cpos = extPos;
|
||||
extPos = mSearchExtension.find(" ", extPos);
|
||||
chkExt = mSearchExtension.substr(cpos, ((extPos == std::string::npos) ? mSearchExtension.length() - cpos: extPos - cpos));
|
||||
|
||||
//if it matches, add it
|
||||
if(chkExt == extension)
|
||||
{
|
||||
GameData* newGame = new GameData(this, filePath.string(), filePath.stem().string());
|
||||
folder->pushFileData(newGame);
|
||||
break;
|
||||
}else if(extPos != std::string::npos) //if not, add one to the "next position" marker to skip the space when reading the next extension
|
||||
{
|
||||
extPos++;
|
||||
}
|
||||
|
||||
} while(extPos != std::string::npos && chkExt != "" && chkExt.find(".") != std::string::npos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -316,8 +320,8 @@ FolderData* SystemData::getRootFolder()
|
|||
return mRootFolder;
|
||||
}
|
||||
|
||||
std::string SystemData::getGamelistPath(){
|
||||
|
||||
std::string SystemData::getGamelistPath()
|
||||
{
|
||||
std::string filePath;
|
||||
|
||||
filePath = mRootFolder->getPath() + "/gamelist.xml";
|
||||
|
|
107
src/Vector2.h
Normal file
107
src/Vector2.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
#ifndef _VECTOR2_H_
|
||||
#define _VECTOR2_H_
|
||||
|
||||
//Taken from the SFML Vector2 class:
|
||||
//https://github.com/LaurentGomila/SFML/blob/master/include/SFML/System/Vector2.hpp
|
||||
//https://github.com/LaurentGomila/SFML/blob/master/include/SFML/System/Vector2.inl
|
||||
|
||||
template <typename T>
|
||||
class Vector2
|
||||
{
|
||||
public:
|
||||
Vector2() : x(0), y(0)
|
||||
{
|
||||
}
|
||||
|
||||
Vector2(T X, T Y) : x(X), y(Y)
|
||||
{
|
||||
}
|
||||
|
||||
//convert between vector types
|
||||
template <typename U>
|
||||
explicit Vector2(const Vector2<U>& vector) : x(static_cast<T>(vector.x)), y(static_cast<T>(vector.y))
|
||||
{
|
||||
}
|
||||
|
||||
T x;
|
||||
T y;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Vector2<T> operator -(const Vector2<T>& right)
|
||||
{
|
||||
return Vector2<T>(-right.x, -right.y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vector2<T>& operator +=(Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
left.x += right.x;
|
||||
left.y += right.y;
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vector2<T>& operator -=(Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
left.x -= right.x;
|
||||
left.y -= right.y;
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vector2<T> operator +(const Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
return Vector2<T>(left.x + right.x, left.y + right.y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vector2<T> operator -(const Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
return Vector2<T>(left.x - right.x, left.y - right.y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vector2<T> operator *(const Vector2<T>& left, T right)
|
||||
{
|
||||
return Vector2<T>(left.x * right, left.y * right);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Vector2<T>& operator *=(Vector2<T>& left, T right)
|
||||
{
|
||||
left.x *= right;
|
||||
left.y *= right;
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator ==(const Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
return (left.x == right.x && left.y == right.y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator !=(const Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
return (left.x != right.x) || (left.y != right.y);
|
||||
}
|
||||
|
||||
typedef Vector2<int> Vector2i;
|
||||
typedef Vector2<unsigned int> Vector2u;
|
||||
typedef Vector2<float> Vector2f;
|
||||
|
||||
class Rect
|
||||
{
|
||||
public:
|
||||
Vector2i pos;
|
||||
Vector2u size;
|
||||
|
||||
Rect() {};
|
||||
Rect(int x, int y, unsigned int w, unsigned int h) : pos(x, y), size(w, h) {};
|
||||
};
|
||||
|
||||
#endif
|
|
@ -14,24 +14,24 @@ Window::~Window()
|
|||
delete mInputManager;
|
||||
}
|
||||
|
||||
void Window::pushGui(Gui* gui)
|
||||
void Window::pushGui(GuiComponent* gui)
|
||||
{
|
||||
mGuiStack.push_back(gui);
|
||||
}
|
||||
|
||||
void Window::removeGui(Gui* gui)
|
||||
void Window::removeGui(GuiComponent* gui)
|
||||
{
|
||||
for(unsigned int i = 0; i < mGuiStack.size(); i++)
|
||||
for(auto i = mGuiStack.begin(); i != mGuiStack.end(); i++)
|
||||
{
|
||||
if(mGuiStack.at(i) == gui)
|
||||
if(*i == gui)
|
||||
{
|
||||
mGuiStack.erase(mGuiStack.begin() + i);
|
||||
break;
|
||||
mGuiStack.erase(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Gui* Window::peekGui()
|
||||
GuiComponent* Window::peekGui()
|
||||
{
|
||||
if(mGuiStack.size() == 0)
|
||||
return NULL;
|
||||
|
@ -41,6 +41,7 @@ Gui* Window::peekGui()
|
|||
|
||||
void Window::render()
|
||||
{
|
||||
//there's nothing to render, which should pretty much never happen
|
||||
if(mGuiStack.size() == 0)
|
||||
std::cout << "guistack empty\n";
|
||||
|
||||
|
|
10
src/Window.h
10
src/Window.h
|
@ -1,7 +1,7 @@
|
|||
#ifndef _WINDOW_H_
|
||||
#define _WINDOW_H_
|
||||
|
||||
#include "Gui.h"
|
||||
#include "GuiComponent.h"
|
||||
#include "InputManager.h"
|
||||
#include <vector>
|
||||
|
||||
|
@ -11,9 +11,9 @@ public:
|
|||
Window();
|
||||
~Window();
|
||||
|
||||
void pushGui(Gui* gui);
|
||||
void removeGui(Gui* gui);
|
||||
Gui* peekGui();
|
||||
void pushGui(GuiComponent* gui);
|
||||
void removeGui(GuiComponent* gui);
|
||||
GuiComponent* peekGui();
|
||||
|
||||
void input(InputConfig* config, Input input);
|
||||
void update(int deltaTime);
|
||||
|
@ -26,7 +26,7 @@ public:
|
|||
|
||||
private:
|
||||
InputManager* mInputManager;
|
||||
std::vector<Gui*> mGuiStack;
|
||||
std::vector<GuiComponent*> mGuiStack;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,14 +33,12 @@ GameData* createGameFromPath(std::string gameAbsPath, SystemData* system)
|
|||
std::string sysPath = system->getStartPath();
|
||||
|
||||
//strip out the system path stuff so it's relative to the system root folder
|
||||
for(unsigned int i = 0; i < gamePath.length(); i++)
|
||||
{
|
||||
if(gamePath[i] != sysPath[i])
|
||||
{
|
||||
gamePath = gamePath.substr(i, gamePath.length() - i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
unsigned int i = 0;
|
||||
while(i < gamePath.length() && i < sysPath.length() && gamePath[i] == sysPath[i])
|
||||
i++;
|
||||
|
||||
gamePath = gamePath.substr(i, gamePath.length() - i);
|
||||
|
||||
|
||||
if(gamePath[0] != '/')
|
||||
gamePath.insert(0, "/");
|
||||
|
|
100
src/components/AnimationComponent.cpp
Normal file
100
src/components/AnimationComponent.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
#include "AnimationComponent.h"
|
||||
|
||||
AnimationComponent::AnimationComponent()
|
||||
{
|
||||
mMoveX = 0;
|
||||
mMoveY = 0;
|
||||
mMoveSpeed = 0;
|
||||
mFadeRate = 0;
|
||||
mOpacity = 0;
|
||||
mAccumulator = 0;
|
||||
}
|
||||
|
||||
void AnimationComponent::move(int x, int y, int speed)
|
||||
{
|
||||
mMoveX = x;
|
||||
mMoveY = y;
|
||||
mMoveSpeed = speed;
|
||||
}
|
||||
|
||||
void AnimationComponent::fadeIn(int time)
|
||||
{
|
||||
mOpacity = 0;
|
||||
setChildrenOpacity(0);
|
||||
|
||||
mFadeRate = time;
|
||||
}
|
||||
|
||||
void AnimationComponent::fadeOut(int time)
|
||||
{
|
||||
mOpacity = 255;
|
||||
setChildrenOpacity(255);
|
||||
|
||||
mFadeRate = -time;
|
||||
}
|
||||
|
||||
//this should really be fixed at the system loop level...
|
||||
void AnimationComponent::update(int deltaTime)
|
||||
{
|
||||
mAccumulator += deltaTime;
|
||||
while(mAccumulator >= ANIMATION_TICK_SPEED)
|
||||
{
|
||||
mAccumulator -= ANIMATION_TICK_SPEED;
|
||||
|
||||
if(mMoveX != 0 || mMoveY != 0)
|
||||
{
|
||||
Vector2i offset(mMoveX, mMoveY);
|
||||
if(abs(offset.x) > mMoveSpeed)
|
||||
offset.x = mMoveSpeed * (offset.x > 0 ? 1 : -1);
|
||||
if(abs(offset.y) > mMoveSpeed)
|
||||
offset.y = mMoveSpeed * (offset.y > 0 ? 1 : -1);
|
||||
|
||||
moveChildren(offset.x, offset.y);
|
||||
|
||||
mMoveX -= offset.x;
|
||||
mMoveY -= offset.y;
|
||||
}
|
||||
|
||||
if(mFadeRate != 0)
|
||||
{
|
||||
int opacity = (int)mOpacity + mFadeRate;
|
||||
if(opacity > 255)
|
||||
{
|
||||
mFadeRate = 0;
|
||||
opacity = 255;
|
||||
}
|
||||
|
||||
if(opacity < 0)
|
||||
{
|
||||
mFadeRate = 0;
|
||||
opacity = 0;
|
||||
}
|
||||
|
||||
mOpacity = (unsigned char)opacity;
|
||||
setChildrenOpacity((unsigned char)opacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationComponent::addChild(ImageComponent* gui)
|
||||
{
|
||||
mChildren.push_back(gui);
|
||||
}
|
||||
|
||||
void AnimationComponent::moveChildren(int offsetx, int offsety)
|
||||
{
|
||||
Vector2i move(offsetx, offsety);
|
||||
for(unsigned int i = 0; i < mChildren.size(); i++)
|
||||
{
|
||||
ImageComponent* comp = mChildren.at(i);
|
||||
comp->setOffset(comp->getOffset() + move);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationComponent::setChildrenOpacity(unsigned char opacity)
|
||||
{
|
||||
for(unsigned int i = 0; i < mChildren.size(); i++)
|
||||
{
|
||||
mChildren.at(i)->setOpacity(opacity);
|
||||
}
|
||||
}
|
|
@ -1,14 +1,16 @@
|
|||
#ifndef _GUIANIMATION_H_
|
||||
#define _GUIANIMATION_H_
|
||||
#ifndef _ANIMATIONCOMPONENT_H_
|
||||
#define _ANIMATIONCOMPONENT_H_
|
||||
|
||||
#include "../Gui.h"
|
||||
#include "GuiImage.h"
|
||||
#include "../GuiComponent.h"
|
||||
#include "ImageComponent.h"
|
||||
#include <vector>
|
||||
|
||||
class GuiAnimation
|
||||
#define ANIMATION_TICK_SPEED 16
|
||||
|
||||
class AnimationComponent
|
||||
{
|
||||
public:
|
||||
GuiAnimation();
|
||||
AnimationComponent();
|
||||
|
||||
void move(int x, int y, int speed);
|
||||
void fadeIn(int time);
|
||||
|
@ -16,18 +18,20 @@ public:
|
|||
|
||||
void update(int deltaTime);
|
||||
|
||||
void addChild(GuiImage* gui);
|
||||
void addChild(ImageComponent* gui);
|
||||
|
||||
private:
|
||||
unsigned char mOpacity;
|
||||
|
||||
std::vector<GuiImage*> mChildren;
|
||||
std::vector<ImageComponent*> mChildren;
|
||||
|
||||
void moveChildren(int offsetx, int offsety);
|
||||
void setChildrenOpacity(unsigned char opacity);
|
||||
|
||||
int mFadeRate;
|
||||
int mMoveX, mMoveY, mMoveSpeed;
|
||||
|
||||
int mAccumulator;
|
||||
};
|
||||
|
||||
#endif
|
319
src/components/ComponentListComponent.cpp
Normal file
319
src/components/ComponentListComponent.cpp
Normal file
|
@ -0,0 +1,319 @@
|
|||
#include "ComponentListComponent.h"
|
||||
#include "../Log.h"
|
||||
#include "../Renderer.h"
|
||||
|
||||
#define INITIAL_CELL_SIZE 12
|
||||
|
||||
ComponentListComponent::ComponentListComponent(Window* window, Vector2u gridDimensions) : GuiComponent(window), mGrid(NULL), mColumnWidths(NULL), mRowHeights(NULL)
|
||||
{
|
||||
mEntries.reserve(gridDimensions.x*gridDimensions.y);
|
||||
makeCells(gridDimensions);
|
||||
}
|
||||
|
||||
void ComponentListComponent::makeCells(Vector2u size)
|
||||
{
|
||||
if(mGrid)
|
||||
delete[] mGrid;
|
||||
if(mColumnWidths)
|
||||
delete[] mColumnWidths;
|
||||
if(mRowHeights)
|
||||
delete[] mRowHeights;
|
||||
|
||||
mGridSize = size;
|
||||
mGrid = new ComponentEntry*[size.x * size.y];
|
||||
std::fill(mGrid, mGrid + (size.x * size.y), (ComponentEntry*)NULL);
|
||||
|
||||
mColumnWidths = new unsigned int[size.x];
|
||||
std::fill(mColumnWidths, mColumnWidths + size.x, INITIAL_CELL_SIZE);
|
||||
|
||||
mRowHeights = new unsigned int[size.y];
|
||||
std::fill(mRowHeights, mRowHeights + size.y, INITIAL_CELL_SIZE);
|
||||
|
||||
updateSize();
|
||||
resetCursor();
|
||||
}
|
||||
|
||||
void ComponentListComponent::setEntry(Vector2u pos, Vector2u size, GuiComponent* component, bool canFocus, AlignmentType align,
|
||||
Vector2<bool> autoFit, UpdateBehavior updateType)
|
||||
{
|
||||
if(pos.x > mGridSize.x || pos.y > mGridSize.y)
|
||||
{
|
||||
LOG(LogError) << "Tried to set entry beyond grid size!";
|
||||
return;
|
||||
}
|
||||
|
||||
if(component == NULL)
|
||||
{
|
||||
LOG(LogError) << "Tried to add NULL component to ComponentList!";
|
||||
return;
|
||||
}
|
||||
|
||||
ComponentEntry entry(Rect(pos.x, pos.y, size.x, size.y), component, updateType, canFocus, align);
|
||||
|
||||
mEntries.push_back(entry);
|
||||
|
||||
for(unsigned int y = pos.y; y < pos.y + size.y; y++)
|
||||
{
|
||||
for(unsigned int x = pos.x; x < pos.x + size.x; x++)
|
||||
{
|
||||
setCell(x, y, &mEntries.back());
|
||||
}
|
||||
}
|
||||
|
||||
if(component->getParent() != NULL)
|
||||
LOG(LogError) << "ComponentListComponent ruining an existing parent-child relationship! Call a social worker!";
|
||||
component->setParent(this);
|
||||
|
||||
if(!cursorValid() && canFocus)
|
||||
mCursor = (Vector2i)pos;
|
||||
|
||||
//update the column width and row height
|
||||
if(autoFit.x && getColumnWidth(pos.x) < component->getSize().x)
|
||||
setColumnWidth(pos.x, component->getSize().x);
|
||||
if(autoFit.y && getRowHeight(pos.y) < component->getSize().y)
|
||||
setRowHeight(pos.y, component->getSize().y);
|
||||
|
||||
component->setOffset(getCellOffset(pos));
|
||||
}
|
||||
|
||||
void ComponentListComponent::setRowHeight(int row, unsigned int size)
|
||||
{
|
||||
mRowHeights[row] = size;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void ComponentListComponent::setColumnWidth(int col, unsigned int size)
|
||||
{
|
||||
mColumnWidths[col] = size;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
unsigned int ComponentListComponent::getRowHeight(int row) { return mRowHeights[row]; }
|
||||
unsigned int ComponentListComponent::getColumnWidth(int col) { return mColumnWidths[col]; }
|
||||
|
||||
Vector2i ComponentListComponent::getCellOffset(Vector2u pos)
|
||||
{
|
||||
Vector2i offset;
|
||||
|
||||
for(unsigned int y = 0; y < pos.y; y++)
|
||||
offset.y += getRowHeight(y);
|
||||
|
||||
for(unsigned int x = 0; x < pos.x; x++)
|
||||
offset.x += getColumnWidth(x);
|
||||
|
||||
ComponentEntry* entry = getCell(pos.x, pos.y);
|
||||
|
||||
Vector2u gridSize;
|
||||
for(unsigned int x = pos.x; x < pos.x + entry->box.size.x; x++)
|
||||
gridSize.x += getColumnWidth(x);
|
||||
for(unsigned int y = pos.y; y < pos.y + entry->box.size.y; y++)
|
||||
gridSize.y += getRowHeight(y);
|
||||
|
||||
//if AlignCenter, add half of cell width - half of control width
|
||||
if(entry->alignment == AlignCenter)
|
||||
offset.x += gridSize.x / 2 - entry->component->getSize().x / 2;
|
||||
|
||||
//if AlignRight, add cell width - control width
|
||||
if(entry->alignment == AlignRight)
|
||||
offset.x += gridSize.x - entry->component->getSize().x;
|
||||
|
||||
//always center on the Y axis
|
||||
offset.y += gridSize.y / 2 - entry->component->getSize().y / 2;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
void ComponentListComponent::setCell(unsigned int x, unsigned int y, ComponentEntry* entry)
|
||||
{
|
||||
if(x < 0 || y < 0 || x >= mGridSize.x || y >= mGridSize.y)
|
||||
{
|
||||
LOG(LogError) << "Invalid setCell - position " << x << ", " << y << " out of bounds!";
|
||||
return;
|
||||
}
|
||||
|
||||
mGrid[y * mGridSize.x + x] = entry;
|
||||
}
|
||||
|
||||
ComponentListComponent::ComponentEntry* ComponentListComponent::getCell(unsigned int x, unsigned int y)
|
||||
{
|
||||
if(x < 0 || y < 0 || x >= mGridSize.x || y >= mGridSize.y)
|
||||
{
|
||||
LOG(LogError) << "Invalid getCell - position " << x << ", " << y << " out of bounds!";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mGrid[y * mGridSize.x + x];
|
||||
}
|
||||
|
||||
void ComponentListComponent::updateSize()
|
||||
{
|
||||
mSize = Vector2u(0, 0);
|
||||
for(unsigned int x = 0; x < mGridSize.x; x++)
|
||||
mSize.x += getColumnWidth(x);
|
||||
for(unsigned int y = 0; y < mGridSize.y; y++)
|
||||
mSize.y += getRowHeight(y);
|
||||
}
|
||||
|
||||
void ComponentListComponent::updateComponentOffsets()
|
||||
{
|
||||
for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++)
|
||||
{
|
||||
iter->component->setOffset(getCellOffset((Vector2u)iter->box.pos));
|
||||
}
|
||||
}
|
||||
|
||||
bool ComponentListComponent::input(InputConfig* config, Input input)
|
||||
{
|
||||
if(cursorValid() && getCell(mCursor.x, mCursor.y)->component->input(config, input))
|
||||
return true;
|
||||
|
||||
if(!input.value)
|
||||
return false;
|
||||
|
||||
if(config->isMappedTo("down", input))
|
||||
{
|
||||
moveCursor(Vector2i(0, 1));
|
||||
return true;
|
||||
}
|
||||
if(config->isMappedTo("up", input))
|
||||
{
|
||||
moveCursor(Vector2i(0, -1));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ComponentListComponent::resetCursor()
|
||||
{
|
||||
if(mEntries.size() == 0)
|
||||
{
|
||||
mCursor = Vector2i(-1, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
mCursor = mEntries.at(0).box.pos;
|
||||
}
|
||||
|
||||
void ComponentListComponent::moveCursor(Vector2i dir)
|
||||
{
|
||||
if(dir.x != 0 && dir.y != 0)
|
||||
{
|
||||
LOG(LogError) << "Invalid cursor move dir!";
|
||||
return;
|
||||
}
|
||||
|
||||
if(!cursorValid())
|
||||
{
|
||||
resetCursor();
|
||||
if(!cursorValid())
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2i origCursor = mCursor;
|
||||
|
||||
Vector2i searchAxis(dir.x == 0, dir.y == 0);
|
||||
|
||||
while(mCursor.x >= 0 && mCursor.y >= 0 && mCursor.x < (int)mGridSize.x && mCursor.y < (int)mGridSize.y)
|
||||
{
|
||||
mCursor = mCursor + dir;
|
||||
|
||||
Vector2i curDirPos = mCursor;
|
||||
|
||||
//spread out on search axis+
|
||||
while(mCursor.x < (int)mGridSize.x && mCursor.y < (int)mGridSize.y)
|
||||
{
|
||||
if(cursorValid() && getCell(mCursor.x, mCursor.y)->canFocus)
|
||||
return;
|
||||
|
||||
mCursor += searchAxis;
|
||||
}
|
||||
|
||||
//now again on search axis-
|
||||
mCursor = curDirPos;
|
||||
while(mCursor.x >= 0 && mCursor.y >= 0)
|
||||
{
|
||||
if(cursorValid() && getCell(mCursor.x, mCursor.y)->canFocus)
|
||||
return;
|
||||
|
||||
mCursor -= searchAxis;
|
||||
}
|
||||
}
|
||||
|
||||
//failed to find another focusable element in this direction
|
||||
mCursor = origCursor;
|
||||
}
|
||||
|
||||
bool ComponentListComponent::cursorValid()
|
||||
{
|
||||
if(mCursor.x < 0 || mCursor.y < 0 || mCursor.x >= (int)mGridSize.x || mCursor.y >= (int)mGridSize.y)
|
||||
return false;
|
||||
|
||||
return getCell(mCursor.x, mCursor.y) != NULL;
|
||||
}
|
||||
|
||||
void ComponentListComponent::update(int deltaTime)
|
||||
{
|
||||
for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++)
|
||||
{
|
||||
if(iter->updateType == UpdateAlways)
|
||||
{
|
||||
iter->component->update(deltaTime);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(iter->updateType == UpdateFocused && cursorValid() && getCell(mCursor.x, mCursor.y)->component == iter->component)
|
||||
{
|
||||
iter->component->update(deltaTime);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentListComponent::onRender()
|
||||
{
|
||||
Renderer::drawRect(0, 0, getSize().x, getSize().y, 0xFFFFFFAA);
|
||||
|
||||
for(auto iter = mEntries.begin(); iter != mEntries.end(); iter++)
|
||||
{
|
||||
iter->component->render();
|
||||
}
|
||||
|
||||
//draw cell outlines
|
||||
/*Vector2i pos;
|
||||
for(unsigned int x = 0; x < mGridSize.x; x++)
|
||||
{
|
||||
for(unsigned int y = 0; y < mGridSize.y; y++)
|
||||
{
|
||||
Renderer::drawRect(pos.x, pos.y, getColumnWidth(x), 2, 0x000000AA);
|
||||
Renderer::drawRect(pos.x, pos.y, 2, getRowHeight(y), 0x000000AA);
|
||||
Renderer::drawRect(pos.x + getColumnWidth(x), pos.y, 2, getRowHeight(y), 0x000000AA);
|
||||
Renderer::drawRect(pos.x, pos.y + getRowHeight(y) - 2, getColumnWidth(x), 2, 0x000000AA);
|
||||
|
||||
pos.y += getRowHeight(y);
|
||||
}
|
||||
|
||||
pos.y = 0;
|
||||
pos.x += getColumnWidth(x);
|
||||
}*/
|
||||
|
||||
//draw cursor
|
||||
if(cursorValid())
|
||||
{
|
||||
ComponentEntry* entry = getCell(mCursor.x, mCursor.y);
|
||||
Renderer::drawRect(entry->component->getOffset().x, entry->component->getOffset().y, 4, 4, 0xFF0000FF);
|
||||
Renderer::drawRect(entry->component->getOffset().x, entry->component->getOffset().y, entry->component->getSize().x, entry->component->getSize().y, 0x0000AA88);
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentListComponent::onOffsetChanged()
|
||||
{
|
||||
updateComponentOffsets();
|
||||
}
|
||||
|
||||
GuiComponent* ComponentListComponent::getSelectedComponent()
|
||||
{
|
||||
if(!cursorValid())
|
||||
return NULL;
|
||||
return getCell(mCursor.x, mCursor.y)->component;
|
||||
}
|
131
src/components/ComponentListComponent.h
Normal file
131
src/components/ComponentListComponent.h
Normal file
|
@ -0,0 +1,131 @@
|
|||
#pragma once
|
||||
|
||||
#include "../GuiComponent.h"
|
||||
|
||||
class ComponentListComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
ComponentListComponent(Window* window, Vector2u gridDimensions);
|
||||
|
||||
enum UpdateBehavior
|
||||
{
|
||||
UpdateAlways, UpdateFocused
|
||||
};
|
||||
|
||||
enum AlignmentType
|
||||
{
|
||||
AlignLeft, AlignRight, AlignCenter
|
||||
};
|
||||
|
||||
void setEntry(Vector2u pos, Vector2u size, GuiComponent* component, bool canFocus, AlignmentType align, Vector2<bool> autoFit, UpdateBehavior updateType = UpdateAlways);
|
||||
|
||||
void onOffsetChanged() override;
|
||||
|
||||
bool input(InputConfig* config, Input input) override;
|
||||
void update(int deltaTime) override;
|
||||
void onRender() override;
|
||||
|
||||
void setColumnWidth(int col, unsigned int size);
|
||||
void setRowHeight(int row, unsigned int size);
|
||||
|
||||
void resetCursor();
|
||||
bool cursorValid();
|
||||
|
||||
GuiComponent* getSelectedComponent();
|
||||
|
||||
private:
|
||||
class ComponentEntry
|
||||
{
|
||||
public:
|
||||
Rect box;
|
||||
GuiComponent* component;
|
||||
UpdateBehavior updateType;
|
||||
AlignmentType alignment;
|
||||
bool canFocus;
|
||||
|
||||
ComponentEntry() : component(NULL), updateType(UpdateAlways), canFocus(true), alignment(AlignCenter) {};
|
||||
ComponentEntry(Rect b, GuiComponent* comp, UpdateBehavior update, bool focus, AlignmentType align) : box(b), component(comp), updateType(update), canFocus(focus), alignment(align) {};
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return component != NULL;
|
||||
}
|
||||
};
|
||||
|
||||
//Offset we render components by (for scrolling).
|
||||
Vector2i mComponentOffset;
|
||||
|
||||
Vector2u mGridSize;
|
||||
ComponentEntry** mGrid;
|
||||
std::vector<ComponentEntry> mEntries;
|
||||
void makeCells(Vector2u size);
|
||||
void setCell(unsigned int x, unsigned int y, ComponentEntry* entry);
|
||||
ComponentEntry* getCell(unsigned int x, unsigned int y);
|
||||
|
||||
Vector2u mSelectedCellIndex;
|
||||
|
||||
unsigned int getColumnWidth(int col);
|
||||
unsigned int getRowHeight(int row);
|
||||
|
||||
unsigned int* mColumnWidths;
|
||||
unsigned int* mRowHeights;
|
||||
|
||||
Vector2i getCellOffset(Vector2u gridPos);
|
||||
void updateSize();
|
||||
|
||||
void moveCursor(Vector2i dir);
|
||||
Vector2i mCursor;
|
||||
|
||||
void updateComponentOffsets();
|
||||
};
|
||||
|
||||
//ability to define a list of components in terms of a grid
|
||||
|
||||
//input
|
||||
//pass to selected component
|
||||
// if returns true, stop
|
||||
// else, process:
|
||||
// if input == up/down
|
||||
// scroll to prev/next selectable component in grid Y
|
||||
// if input == left/right
|
||||
// scroll to prev/next selectable component in grid X
|
||||
// if input == accept
|
||||
// call registered function?
|
||||
|
||||
//entry struct/class
|
||||
// GuiComponent* component - component to work with
|
||||
// bool canFocus - can we pass input to this? (necessary for labels to not be selectable)
|
||||
// Function* selectFunc?
|
||||
// UpdateBehavior update - how to handle updates (all the time or only when focused)
|
||||
|
||||
//update
|
||||
//animate component offset to display selected component within the bounds
|
||||
//pass update to all entries with appropriate update behavior
|
||||
|
||||
//render
|
||||
//clip rect to our size
|
||||
//render a "selected" effect behind component with focus somehow
|
||||
// an edge filter would be cool, but we can't really do that without shader support
|
||||
// a transparent rect will work for now, but it's kind of ugly...maybe a GuiBox
|
||||
//glTranslatef by our render offset
|
||||
// doesn't handle getGlobalOffset for our components...would need parenting for that
|
||||
|
||||
//methods
|
||||
//List::setEntry(Vector2i gridPos, GuiComponent* component, bool canFocus, AlignmentType align,
|
||||
// Function* selectFunc = NULL, UpdateBehavior updateType = UpdateAlways);
|
||||
|
||||
//example of setting up the SettingsMenu list:
|
||||
//ComponentListComponent list;
|
||||
//int row = 0;
|
||||
//TextComponent* label = new TextComponent(Vector2i(0, 0), "Debug:", font, lblColor, etc);
|
||||
//
|
||||
//list.setEntry(Vector2i(-1, row), label, false, AlignRight);
|
||||
//list.setEntry(Vector2i(0, row++), &mDebugSwitch, true, AlignLeft);
|
||||
//...
|
||||
//list.setEntry(Rect(-1, row, 2, 1), &mSaveButton, true, AlignCenter);
|
||||
|
||||
//example of setting up GameGrid list:
|
||||
//ComponentListComponent list;
|
||||
//for(int y = 0; y < yMax; y++)
|
||||
// for(int x = 0; x < xMax; x++)
|
||||
// list.setEntry(Vector2i(x, y), getGameImage(x, y), true, AlignCenter, &this->onSelectGame);
|
|
@ -1,92 +0,0 @@
|
|||
#include "GuiAnimation.h"
|
||||
|
||||
GuiAnimation::GuiAnimation()
|
||||
{
|
||||
mMoveX = 0;
|
||||
mMoveY = 0;
|
||||
mMoveSpeed = 0;
|
||||
mFadeRate = 0;
|
||||
}
|
||||
|
||||
void GuiAnimation::move(int x, int y, int speed)
|
||||
{
|
||||
mMoveX = x;
|
||||
mMoveY = y;
|
||||
mMoveSpeed = speed;
|
||||
}
|
||||
|
||||
void GuiAnimation::fadeIn(int time)
|
||||
{
|
||||
mOpacity = 0;
|
||||
setChildrenOpacity(0);
|
||||
|
||||
mFadeRate = time;
|
||||
}
|
||||
|
||||
void GuiAnimation::fadeOut(int time)
|
||||
{
|
||||
mOpacity = 255;
|
||||
setChildrenOpacity(255);
|
||||
|
||||
mFadeRate = -time;
|
||||
}
|
||||
|
||||
void GuiAnimation::update(int deltaTime)
|
||||
{
|
||||
float mult = deltaTime * 0.05f;
|
||||
|
||||
if(mMoveX != 0 || mMoveY != 0)
|
||||
{
|
||||
int offsetx = (mMoveX > mMoveSpeed) ? mMoveSpeed : mMoveX;
|
||||
int offsety = (mMoveY > mMoveSpeed) ? mMoveSpeed : mMoveY;
|
||||
|
||||
offsetx = (int)(offsetx * mult);
|
||||
offsety = (int)(offsety * mult);
|
||||
|
||||
moveChildren(offsetx, offsety);
|
||||
|
||||
mMoveX -= offsetx;
|
||||
mMoveY -= offsety;
|
||||
}
|
||||
|
||||
if(mFadeRate != 0)
|
||||
{
|
||||
int opacity = (int)mOpacity + mFadeRate;
|
||||
if(opacity > 255)
|
||||
{
|
||||
mFadeRate = 0;
|
||||
opacity = 255;
|
||||
}
|
||||
|
||||
if(opacity < 0)
|
||||
{
|
||||
mFadeRate = 0;
|
||||
opacity = 0;
|
||||
}
|
||||
|
||||
mOpacity = (unsigned char)opacity;
|
||||
setChildrenOpacity((unsigned char)opacity);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiAnimation::addChild(GuiImage* gui)
|
||||
{
|
||||
mChildren.push_back(gui);
|
||||
}
|
||||
|
||||
void GuiAnimation::moveChildren(int offsetx, int offsety)
|
||||
{
|
||||
for(unsigned int i = 0; i < mChildren.size(); i++)
|
||||
{
|
||||
GuiImage* comp = mChildren.at(i);
|
||||
comp->setOffset(comp->getOffsetX() + offsetx, comp->getOffsetY() + offsety);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiAnimation::setChildrenOpacity(unsigned char opacity)
|
||||
{
|
||||
for(unsigned int i = 0; i < mChildren.size(); i++)
|
||||
{
|
||||
mChildren.at(i)->setOpacity(opacity);
|
||||
}
|
||||
}
|
|
@ -1,13 +1,11 @@
|
|||
#include "GuiBox.h"
|
||||
|
||||
GuiBox::GuiBox(Window* window, int offsetX, int offsetY, unsigned int width, unsigned int height) : Gui(window), mBackgroundImage(window),
|
||||
GuiBox::GuiBox(Window* window, int offsetX, int offsetY, unsigned int width, unsigned int height) : GuiComponent(window), mBackgroundImage(window),
|
||||
mHorizontalImage(window), mVerticalImage(window), mCornerImage(window)
|
||||
{
|
||||
setOffsetX(offsetX);
|
||||
setOffsetY(offsetY);
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
setOffset(Vector2i(offsetX, offsetY));
|
||||
|
||||
mSize = Vector2u(width, height);
|
||||
}
|
||||
|
||||
void GuiBox::setData(GuiBoxData data)
|
||||
|
@ -24,7 +22,7 @@ void GuiBox::setHorizontalImage(std::string path, bool tiled)
|
|||
mHorizontalImage.setOrigin(0, 0);
|
||||
|
||||
mHorizontalImage.setImage(path);
|
||||
mHorizontalImage.setResize(mHorizontalImage.getHeight(), mHeight, true);
|
||||
mHorizontalImage.setResize(getHorizontalBorderWidth(), mSize.y, true);
|
||||
}
|
||||
|
||||
void GuiBox::setVerticalImage(std::string path, bool tiled)
|
||||
|
@ -33,16 +31,15 @@ void GuiBox::setVerticalImage(std::string path, bool tiled)
|
|||
mVerticalImage.setOrigin(0, 0);
|
||||
|
||||
mVerticalImage.setImage(path);
|
||||
mVerticalImage.setResize(mWidth, mVerticalImage.getHeight(), true);
|
||||
mVerticalImage.setResize(mSize.x, getVerticalBorderWidth(), true);
|
||||
}
|
||||
|
||||
void GuiBox::setBackgroundImage(std::string path, bool tiled)
|
||||
{
|
||||
mBackgroundImage.setOrigin(0, 0);
|
||||
mBackgroundImage.setResize(mWidth, mHeight, true);
|
||||
mBackgroundImage.setResize(mSize.x, mSize.y, true);
|
||||
mBackgroundImage.setTiling(tiled);
|
||||
mBackgroundImage.setOffsetX(getOffsetX());
|
||||
mBackgroundImage.setOffsetY(getOffsetY());
|
||||
mBackgroundImage.setOffset(0, 0);
|
||||
|
||||
mBackgroundImage.setImage(path);
|
||||
}
|
||||
|
@ -55,60 +52,53 @@ void GuiBox::setCornerImage(std::string path)
|
|||
mCornerImage.setImage(path);
|
||||
}
|
||||
|
||||
void GuiBox::render()
|
||||
void GuiBox::onRender()
|
||||
{
|
||||
mBackgroundImage.render();
|
||||
|
||||
//left border
|
||||
mHorizontalImage.setOffsetX(getOffsetX() - getHorizontalBorderWidth());
|
||||
mHorizontalImage.setOffsetY(getOffsetY());
|
||||
mHorizontalImage.setOffset(-getHorizontalBorderWidth(), 0);
|
||||
mHorizontalImage.setFlipX(false);
|
||||
mHorizontalImage.render();
|
||||
//Renderer::drawRect(getOffsetX() - getHorizontalBorderWidth(), getOffsetY(), getHorizontalBorderWidth(), mHeight, 0xFF0000);
|
||||
|
||||
|
||||
//right border
|
||||
mHorizontalImage.setOffsetX(getOffsetX() + mWidth);
|
||||
//same Y
|
||||
mHorizontalImage.setOffset(mSize.x, 0);
|
||||
mHorizontalImage.setFlipX(true);
|
||||
mHorizontalImage.render();
|
||||
//Renderer::drawRect(getOffsetX() + mWidth, getOffsetY(), getHorizontalBorderWidth(), mHeight, 0xFF0000);
|
||||
|
||||
|
||||
//top border
|
||||
mVerticalImage.setOffsetX(getOffsetX());
|
||||
mVerticalImage.setOffsetY(getOffsetY() - getVerticalBorderWidth());
|
||||
mVerticalImage.setOffset(0, -getVerticalBorderWidth());
|
||||
mVerticalImage.setFlipY(false);
|
||||
mVerticalImage.render();
|
||||
//Renderer::drawRect(getOffsetX(), getOffsetY() - getVerticalBorderWidth(), mWidth, getVerticalBorderWidth(), 0x00FF00);
|
||||
|
||||
|
||||
//bottom border
|
||||
//same X
|
||||
mVerticalImage.setOffsetY(getOffsetY() + mHeight);
|
||||
mVerticalImage.setOffset(0, mSize.y);
|
||||
mVerticalImage.setFlipY(true);
|
||||
mVerticalImage.render();
|
||||
//Renderer::drawRect(getOffsetX(), getOffsetY() + mHeight, mWidth, getVerticalBorderWidth(), 0x00FF00);
|
||||
|
||||
|
||||
//corner top left
|
||||
mCornerImage.setOffsetX(getOffsetX() - getHorizontalBorderWidth());
|
||||
mCornerImage.setOffsetY(getOffsetY() - getVerticalBorderWidth());
|
||||
mCornerImage.setOffset(-getHorizontalBorderWidth(), -getVerticalBorderWidth());
|
||||
mCornerImage.setFlipX(false);
|
||||
mCornerImage.setFlipY(false);
|
||||
mCornerImage.render();
|
||||
|
||||
//top right
|
||||
mCornerImage.setOffsetX(getOffsetX() + mWidth);
|
||||
mCornerImage.setOffset(mSize.x, mCornerImage.getOffset().y);
|
||||
mCornerImage.setFlipX(true);
|
||||
mCornerImage.render();
|
||||
|
||||
//bottom right
|
||||
mCornerImage.setOffsetY(getOffsetY() + mHeight);
|
||||
mCornerImage.setOffset(mCornerImage.getOffset().x, mSize.y);
|
||||
mCornerImage.setFlipY(true);
|
||||
mCornerImage.render();
|
||||
|
||||
//bottom left
|
||||
mCornerImage.setOffsetX(getOffsetX() - getHorizontalBorderWidth());
|
||||
mCornerImage.setOffset(-getHorizontalBorderWidth(), mCornerImage.getOffset().y);
|
||||
mCornerImage.setFlipX(false);
|
||||
mCornerImage.render();
|
||||
|
||||
GuiComponent::onRender();
|
||||
}
|
||||
|
||||
void GuiBox::init()
|
||||
|
@ -116,6 +106,8 @@ void GuiBox::init()
|
|||
mVerticalImage.init();
|
||||
mHorizontalImage.init();
|
||||
mCornerImage.init();
|
||||
|
||||
GuiComponent::init();
|
||||
}
|
||||
|
||||
void GuiBox::deinit()
|
||||
|
@ -123,16 +115,18 @@ void GuiBox::deinit()
|
|||
mVerticalImage.deinit();
|
||||
mHorizontalImage.deinit();
|
||||
mCornerImage.deinit();
|
||||
|
||||
GuiComponent::deinit();
|
||||
}
|
||||
|
||||
int GuiBox::getHorizontalBorderWidth()
|
||||
{
|
||||
return mHorizontalImage.getWidth();
|
||||
return mHorizontalImage.getTextureSize().x;
|
||||
}
|
||||
|
||||
int GuiBox::getVerticalBorderWidth()
|
||||
{
|
||||
return mVerticalImage.getHeight();
|
||||
return mVerticalImage.getTextureSize().y;
|
||||
}
|
||||
|
||||
bool GuiBox::hasBackground()
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef _GUIBOX_H_
|
||||
#define _GUIBOX_H_
|
||||
|
||||
#include "../Gui.h"
|
||||
#include "GuiImage.h"
|
||||
#include "../GuiComponent.h"
|
||||
#include "ImageComponent.h"
|
||||
#include <string>
|
||||
|
||||
struct GuiBoxData
|
||||
|
@ -16,7 +16,7 @@ struct GuiBoxData
|
|||
std::string cornerPath;
|
||||
};
|
||||
|
||||
class GuiBox : public Gui
|
||||
class GuiBox : public GuiComponent
|
||||
{
|
||||
public:
|
||||
GuiBox(Window* window, int offsetX, int offsetY, unsigned int width, unsigned int height);
|
||||
|
@ -30,17 +30,17 @@ public:
|
|||
|
||||
bool hasBackground();
|
||||
|
||||
void render();
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
|
||||
protected:
|
||||
void onRender();
|
||||
|
||||
private:
|
||||
GuiImage mBackgroundImage, mHorizontalImage, mVerticalImage, mCornerImage;
|
||||
ImageComponent mBackgroundImage, mHorizontalImage, mVerticalImage, mCornerImage;
|
||||
|
||||
int getHorizontalBorderWidth();
|
||||
int getVerticalBorderWidth();
|
||||
|
||||
unsigned int mWidth, mHeight;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
GuiDetectDevice::GuiDetectDevice(Window* window) : Gui(window)
|
||||
GuiDetectDevice::GuiDetectDevice(Window* window) : GuiComponent(window)
|
||||
{
|
||||
//clear any player information from the InputManager
|
||||
for(int i = 0; i < mWindow->getInputManager()->getNumPlayers(); i++)
|
||||
|
@ -22,7 +22,7 @@ GuiDetectDevice::GuiDetectDevice(Window* window) : Gui(window)
|
|||
mHoldingFinish = false;
|
||||
}
|
||||
|
||||
void GuiDetectDevice::input(InputConfig* config, Input input)
|
||||
bool GuiDetectDevice::input(InputConfig* config, Input input)
|
||||
{
|
||||
if((input.type == TYPE_BUTTON || input.type == TYPE_KEY))
|
||||
{
|
||||
|
@ -38,11 +38,11 @@ void GuiDetectDevice::input(InputConfig* config, Input input)
|
|||
mHoldingFinish = false;
|
||||
}
|
||||
}
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!input.value)
|
||||
return;
|
||||
return false;
|
||||
|
||||
config->setPlayerNum(mCurrentPlayer);
|
||||
mWindow->getInputManager()->setNumPlayers(mWindow->getInputManager()->getNumPlayers() + 1); //inc total number of players
|
||||
|
@ -53,7 +53,11 @@ void GuiDetectDevice::input(InputConfig* config, Input input)
|
|||
{
|
||||
done();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GuiDetectDevice::done()
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#ifndef _GUIDETECTDEVICE_H_
|
||||
#define _GUIDETECTDEVICE_H_
|
||||
|
||||
#include "../Gui.h"
|
||||
#include "../GuiComponent.h"
|
||||
|
||||
class GuiDetectDevice : public Gui
|
||||
class GuiDetectDevice : public GuiComponent
|
||||
{
|
||||
public:
|
||||
GuiDetectDevice(Window* window);
|
||||
|
||||
void input(InputConfig* config, Input input);
|
||||
bool input(InputConfig* config, Input input);
|
||||
void update(int deltaTime);
|
||||
void render();
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ const std::string GuiFastSelect::LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|||
const int GuiFastSelect::SCROLLSPEED = 100;
|
||||
const int GuiFastSelect::SCROLLDELAY = 507;
|
||||
|
||||
GuiFastSelect::GuiFastSelect(Window* window, GuiGameList* parent, GuiList<FileData*>* list, char startLetter, GuiBoxData data,
|
||||
int textcolor, std::shared_ptr<Sound> & scrollsound, Font* font) : Gui(window)
|
||||
GuiFastSelect::GuiFastSelect(Window* window, GuiGameList* parent, TextListComponent<FileData*>* list, char startLetter, GuiBoxData data,
|
||||
int textcolor, std::shared_ptr<Sound> & scrollsound, Font* font) : GuiComponent(window)
|
||||
{
|
||||
mLetterID = LETTERS.find(toupper(startLetter));
|
||||
if(mLetterID == std::string::npos)
|
||||
|
@ -48,18 +48,20 @@ void GuiFastSelect::render()
|
|||
Renderer::drawCenteredText(LETTERS.substr(mLetterID, 1), 0, (int)(sh * 0.5f - (mFont->getHeight() * 0.5f)), mTextColor, mFont);
|
||||
}
|
||||
|
||||
void GuiFastSelect::input(InputConfig* config, Input input)
|
||||
bool GuiFastSelect::input(InputConfig* config, Input input)
|
||||
{
|
||||
if(config->isMappedTo("up", input) && input.value != 0)
|
||||
{
|
||||
mScrollOffset = -1;
|
||||
scroll();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(config->isMappedTo("down", input) && input.value != 0)
|
||||
{
|
||||
mScrollOffset = 1;
|
||||
scroll();
|
||||
return true;
|
||||
}
|
||||
|
||||
if((config->isMappedTo("up", input) || config->isMappedTo("down", input)) && input.value == 0)
|
||||
|
@ -67,14 +69,17 @@ void GuiFastSelect::input(InputConfig* config, Input input)
|
|||
mScrolling = false;
|
||||
mScrollTimer = 0;
|
||||
mScrollOffset = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(config->isMappedTo("select", input) && input.value == 0)
|
||||
{
|
||||
setListPos();
|
||||
delete this;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GuiFastSelect::update(int deltaTime)
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
#ifndef _GUIFASTSELECT_H_
|
||||
#define _GUIFASTSELECT_H_
|
||||
|
||||
#include "../Gui.h"
|
||||
#include "../GuiComponent.h"
|
||||
#include "../SystemData.h"
|
||||
#include "../FolderData.h"
|
||||
#include "../Sound.h"
|
||||
#include "GuiList.h"
|
||||
#include "TextListComponent.h"
|
||||
#include "GuiBox.h"
|
||||
|
||||
class GuiGameList;
|
||||
|
||||
class GuiFastSelect : public Gui
|
||||
class GuiFastSelect : public GuiComponent
|
||||
{
|
||||
public:
|
||||
GuiFastSelect(Window* window, GuiGameList* parent, GuiList<FileData*>* list, char startLetter, GuiBoxData data, int textcolor, std::shared_ptr<Sound> & scrollsound, Font* font);
|
||||
GuiFastSelect(Window* window, GuiGameList* parent, TextListComponent<FileData*>* list, char startLetter, GuiBoxData data,
|
||||
int textcolor, std::shared_ptr<Sound> & scrollsound, Font* font);
|
||||
~GuiFastSelect();
|
||||
|
||||
void input(InputConfig* config, Input input);
|
||||
bool input(InputConfig* config, Input input);
|
||||
void update(int deltaTime);
|
||||
void render();
|
||||
private:
|
||||
|
@ -28,7 +29,7 @@ private:
|
|||
void scroll();
|
||||
void setLetterID(int id);
|
||||
|
||||
GuiList<FileData*>* mList;
|
||||
TextListComponent<FileData*>* mList;
|
||||
|
||||
size_t mLetterID;
|
||||
GuiGameList* mParent;
|
||||
|
|
|
@ -5,44 +5,65 @@
|
|||
#include "GuiFastSelect.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "../Log.h"
|
||||
#include "../Settings.h"
|
||||
|
||||
GuiGameList::GuiGameList(Window* window, bool useDetail) : Gui(window)
|
||||
Vector2i GuiGameList::getImagePos()
|
||||
{
|
||||
return Vector2i((int)(Renderer::getScreenWidth() * mTheme->getFloat("gameImageOffsetX")), (int)(Renderer::getScreenHeight() * mTheme->getFloat("gameImageOffsetY")));
|
||||
}
|
||||
|
||||
GuiGameList::GuiGameList(Window* window, bool useDetail) : GuiComponent(window),
|
||||
mDescription(window), mTransitionImage(window, 0, 0, "", Renderer::getScreenWidth(), Renderer::getScreenHeight(), true)
|
||||
{
|
||||
mDetailed = useDetail;
|
||||
|
||||
mTheme = new GuiTheme(mWindow, mDetailed);
|
||||
mTheme = new ThemeComponent(mWindow, mDetailed);
|
||||
|
||||
//The GuiGameList can use the older, simple game list if so desired.
|
||||
//The old view only shows a list in the center of the screen; the new view can display an image and description.
|
||||
//Those with smaller displays may prefer the older view.
|
||||
if(mDetailed)
|
||||
{
|
||||
mList = new GuiList<FileData*>(mWindow, (int)(Renderer::getScreenWidth() * mTheme->getFloat("listOffsetX")), Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::MEDIUM));
|
||||
mList = new TextListComponent<FileData*>(mWindow, (int)(Renderer::getScreenWidth() * mTheme->getFloat("listOffsetX")), Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::MEDIUM));
|
||||
|
||||
mScreenshot = new GuiImage(mWindow, (int)(Renderer::getScreenWidth() * mTheme->getFloat("gameImageOffsetX")), (int)(Renderer::getScreenHeight() * mTheme->getFloat("gameImageOffsetY")), "", (unsigned int)mTheme->getFloat("gameImageWidth"), (unsigned int)mTheme->getFloat("gameImageHeight"), false);
|
||||
mScreenshot->setOrigin(mTheme->getFloat("gameImageOriginX"), mTheme->getFloat("gameImageOriginY"));
|
||||
|
||||
mImageAnimation = new GuiAnimation();
|
||||
mImageAnimation = new AnimationComponent();
|
||||
mImageAnimation->addChild(mScreenshot);
|
||||
}else{
|
||||
mList = new GuiList<FileData*>(mWindow, 0, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::MEDIUM));
|
||||
mScreenshot = NULL;
|
||||
mImageAnimation = NULL;
|
||||
mList = new TextListComponent<FileData*>(mWindow, 0, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::MEDIUM));
|
||||
}
|
||||
|
||||
mScreenshot = new ImageComponent(mWindow, getImagePos().x, getImagePos().y, "", (unsigned int)mTheme->getFloat("gameImageWidth"), (unsigned int)mTheme->getFloat("gameImageHeight"), false);
|
||||
mScreenshot->setOrigin(mTheme->getFloat("gameImageOriginX"), mTheme->getFloat("gameImageOriginY"));
|
||||
|
||||
mDescription.setOffset(Vector2i((int)(Renderer::getScreenWidth() * 0.03), mScreenshot->getOffset().y + mScreenshot->getSize().y + 12));
|
||||
mDescription.setExtent(Vector2u((int)(Renderer::getScreenWidth() * (mTheme->getFloat("listOffsetX") - 0.03)), 0));
|
||||
|
||||
mTransitionImage.setOffset(Renderer::getScreenWidth(), 0);
|
||||
mTransitionImage.setOrigin(0, 0);
|
||||
mTransitionAnimation.addChild(&mTransitionImage);
|
||||
|
||||
//a hack! the GuiGameList doesn't use the children system right now because I haven't redone it to do so yet.
|
||||
//the list depends on knowing it's final window coordinates (getGlobalOffset), which requires knowing the where the GuiGameList is.
|
||||
//the GuiGameList now moves during screen transitions, so we have to let it know somehow.
|
||||
//this should be removed in favor of using real children soon.
|
||||
mList->setParent(this);
|
||||
|
||||
setSystemId(0);
|
||||
}
|
||||
|
||||
GuiGameList::~GuiGameList()
|
||||
{
|
||||
//undo the parenting hack because otherwise it's not really a child and will try to remove itself on delete
|
||||
mList->setParent(NULL);
|
||||
delete mList;
|
||||
|
||||
if(mDetailed)
|
||||
{
|
||||
delete mImageAnimation;
|
||||
delete mScreenshot;
|
||||
delete mTheme;
|
||||
}
|
||||
|
||||
delete mTheme;
|
||||
}
|
||||
|
||||
void GuiGameList::setSystemId(int id)
|
||||
|
@ -74,6 +95,13 @@ void GuiGameList::setSystemId(int id)
|
|||
|
||||
void GuiGameList::render()
|
||||
{
|
||||
if(mTransitionImage.getOffset().x > 0) //transitioning in from the left
|
||||
mOffset.x = mTransitionImage.getOffset().x - Renderer::getScreenWidth();
|
||||
else //transitioning in from the right
|
||||
mOffset.x = mTransitionImage.getOffset().x + Renderer::getScreenWidth();
|
||||
|
||||
Renderer::translate(mOffset);
|
||||
|
||||
if(mTheme)
|
||||
mTheme->render();
|
||||
|
||||
|
@ -86,24 +114,24 @@ void GuiGameList::render()
|
|||
//divider
|
||||
if(!mTheme->getBool("hideDividers"))
|
||||
Renderer::drawRect((int)(Renderer::getScreenWidth() * mTheme->getFloat("listOffsetX")) - 4, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, 8, Renderer::getScreenHeight(), 0x0000FFFF);
|
||||
|
||||
//if we're not scrolling and we have selected a non-folder
|
||||
if(!mList->isScrolling() && mList->getSelectedObject() && !mList->getSelectedObject()->isFolder())
|
||||
{
|
||||
GameData* game = (GameData*)mList->getSelectedObject();
|
||||
|
||||
std::string desc = game->getDescription();
|
||||
if(!desc.empty())
|
||||
Renderer::drawWrappedText(desc, (int)(Renderer::getScreenWidth() * 0.03), mScreenshot->getOffsetY() + mScreenshot->getHeight() + 12, (int)(Renderer::getScreenWidth() * (mTheme->getFloat("listOffsetX") - 0.03)), mTheme->getColor("description"), mTheme->getDescriptionFont());
|
||||
}
|
||||
|
||||
|
||||
mScreenshot->render();
|
||||
|
||||
//if we're not scrolling and we have selected a non-folder
|
||||
if(!mList->isScrolling() && !mList->getSelectedObject()->isFolder())
|
||||
{
|
||||
mDescription.render();
|
||||
}
|
||||
}
|
||||
|
||||
mList->render();
|
||||
|
||||
Renderer::translate(-mOffset);
|
||||
|
||||
mTransitionImage.render();
|
||||
}
|
||||
|
||||
void GuiGameList::input(InputConfig* config, Input input)
|
||||
bool GuiGameList::input(InputConfig* config, Input input)
|
||||
{
|
||||
mList->input(config, input);
|
||||
|
||||
|
@ -118,6 +146,8 @@ void GuiGameList::input(InputConfig* config, Input input)
|
|||
mFolderStack.push(mFolder);
|
||||
mFolder = (FolderData*)file;
|
||||
updateList();
|
||||
updateDetailData();
|
||||
return true;
|
||||
}else{
|
||||
mList->stopScrolling();
|
||||
|
||||
|
@ -125,7 +155,7 @@ void GuiGameList::input(InputConfig* config, Input input)
|
|||
while(mTheme->getSound("menuSelect")->isPlaying());
|
||||
|
||||
mSystem->launchGame(mWindow, (GameData*)file);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,6 +169,8 @@ void GuiGameList::input(InputConfig* config, Input input)
|
|||
|
||||
//play the back sound
|
||||
mTheme->getSound("menuBack")->play();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//only allow switching systems if more than one exists (otherwise it'll reset your position when you switch and it's annoying)
|
||||
|
@ -147,10 +179,14 @@ void GuiGameList::input(InputConfig* config, Input input)
|
|||
if(config->isMappedTo("right", input))
|
||||
{
|
||||
setSystemId(mSystemId + 1);
|
||||
doTransition(-1);
|
||||
return true;
|
||||
}
|
||||
if(config->isMappedTo("left", input))
|
||||
{
|
||||
setSystemId(mSystemId - 1);
|
||||
doTransition(1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,12 +194,14 @@ void GuiGameList::input(InputConfig* config, Input input)
|
|||
if(config->isMappedTo("menu", input) && input.value != 0)
|
||||
{
|
||||
mWindow->pushGui(new GuiMenu(mWindow, this));
|
||||
return true;
|
||||
}
|
||||
|
||||
//open the fast select menu
|
||||
if(config->isMappedTo("select", input) && input.value != 0)
|
||||
{
|
||||
mWindow->pushGui(new GuiFastSelect(mWindow, this, mList, mList->getSelectedObject()->getName()[0], mTheme->getBoxData(), mTheme->getColor("fastSelect"), mTheme->getSound("menuScroll"), mTheme->getFastSelectFont()));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(mDetailed)
|
||||
|
@ -175,7 +213,10 @@ void GuiGameList::input(InputConfig* config, Input input)
|
|||
else
|
||||
clearDetailData();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GuiGameList::updateList()
|
||||
|
@ -235,13 +276,15 @@ void GuiGameList::updateTheme()
|
|||
{
|
||||
mList->setCentered(mTheme->getBool("listCentered"));
|
||||
|
||||
mList->setOffsetX((int)(mTheme->getFloat("listOffsetX") * Renderer::getScreenWidth()));
|
||||
mList->setOffset((int)(mTheme->getFloat("listOffsetX") * Renderer::getScreenWidth()), mList->getOffset().y);
|
||||
mList->setTextOffsetX((int)(mTheme->getFloat("listTextOffsetX") * Renderer::getScreenWidth()));
|
||||
|
||||
mScreenshot->setOffsetX((int)(mTheme->getFloat("gameImageOffsetX") * Renderer::getScreenWidth()));
|
||||
mScreenshot->setOffsetY((int)(mTheme->getFloat("gameImageOffsetY") * Renderer::getScreenHeight()));
|
||||
mScreenshot->setOffset((int)(mTheme->getFloat("gameImageOffsetX") * Renderer::getScreenWidth()), (int)(mTheme->getFloat("gameImageOffsetY") * Renderer::getScreenHeight()));
|
||||
mScreenshot->setOrigin(mTheme->getFloat("gameImageOriginX"), mTheme->getFloat("gameImageOriginY"));
|
||||
mScreenshot->setResize((int)mTheme->getFloat("gameImageWidth"), (int)mTheme->getFloat("gameImageHeight"), false);
|
||||
|
||||
mDescription.setColor(mTheme->getColor("description"));
|
||||
mDescription.setFont(mTheme->getDescriptionFont());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,15 +295,19 @@ void GuiGameList::updateDetailData()
|
|||
|
||||
if(mList->getSelectedObject() && !mList->getSelectedObject()->isFolder())
|
||||
{
|
||||
mScreenshot->setOffset((int)((mTheme->getFloat("gameImageOffsetX") - 0.05) * Renderer::getScreenWidth()), (int)(mTheme->getFloat("gameImageOffsetY") * Renderer::getScreenHeight()));
|
||||
|
||||
if(((GameData*)mList->getSelectedObject())->getImagePath().empty())
|
||||
mScreenshot->setImage(mTheme->getString("imageNotFoundPath"));
|
||||
else
|
||||
mScreenshot->setImage(((GameData*)mList->getSelectedObject())->getImagePath());
|
||||
|
||||
mImageAnimation->fadeIn(15);
|
||||
mImageAnimation->move((int)(0.05 * Renderer::getScreenWidth()), 0, 5);
|
||||
Vector2i imgOffset = Vector2i((int)(Renderer::getScreenWidth() * 0.10f), 0);
|
||||
mScreenshot->setOffset(getImagePos() - imgOffset);
|
||||
|
||||
mImageAnimation->fadeIn(35);
|
||||
mImageAnimation->move(imgOffset.x, imgOffset.y, 20);
|
||||
|
||||
mDescription.setOffset(Vector2i((int)(Renderer::getScreenWidth() * 0.03), mScreenshot->getOffset().y + mScreenshot->getSize().y + 12));
|
||||
mDescription.setText(((GameData*)mList->getSelectedObject())->getDescription());
|
||||
}else{
|
||||
mScreenshot->setImage("");
|
||||
}
|
||||
|
@ -296,12 +343,11 @@ void GuiGameList::init()
|
|||
}
|
||||
}
|
||||
|
||||
extern bool IGNOREGAMELIST; //defined in main.cpp (as a command line argument)
|
||||
GuiGameList* GuiGameList::create(Window* window)
|
||||
{
|
||||
bool detailed = false;
|
||||
|
||||
if(!IGNOREGAMELIST)
|
||||
if(!Settings::getInstance()->getBool("IGNOREGAMELIST"))
|
||||
{
|
||||
for(unsigned int i = 0; i < SystemData::sSystemVector.size(); i++)
|
||||
{
|
||||
|
@ -323,5 +369,15 @@ void GuiGameList::update(int deltaTime)
|
|||
if(mDetailed)
|
||||
mImageAnimation->update(deltaTime);
|
||||
|
||||
mTransitionAnimation.update(deltaTime);
|
||||
|
||||
mList->update(deltaTime);
|
||||
}
|
||||
|
||||
void GuiGameList::doTransition(int dir)
|
||||
{
|
||||
mTransitionImage.copyScreen();
|
||||
mTransitionImage.setOpacity(255);
|
||||
mTransitionImage.setOffset(0, 0);
|
||||
mTransitionAnimation.move(Renderer::getScreenWidth() * dir, 0, 50);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#ifndef _GUIGAMELIST_H_
|
||||
#define _GUIGAMELIST_H_
|
||||
|
||||
#include "../Gui.h"
|
||||
#include "GuiList.h"
|
||||
#include "GuiImage.h"
|
||||
#include "GuiTheme.h"
|
||||
#include "GuiAnimation.h"
|
||||
#include "../GuiComponent.h"
|
||||
#include "TextListComponent.h"
|
||||
#include "ImageComponent.h"
|
||||
#include "ThemeComponent.h"
|
||||
#include "AnimationComponent.h"
|
||||
#include "TextComponent.h"
|
||||
#include <string>
|
||||
#include <stack>
|
||||
#include "../SystemData.h"
|
||||
|
@ -13,16 +14,16 @@
|
|||
#include "../FolderData.h"
|
||||
|
||||
//This is where the magic happens - GuiGameList is the parent of almost every graphical element in ES at the moment.
|
||||
//It has a GuiList child that handles the game list, a GuiTheme that handles the theming system, and a GuiImage for game images.
|
||||
class GuiGameList : public Gui
|
||||
//It has a TextListComponent child that handles the game list, a ThemeComponent that handles the theming system, and an ImageComponent for game images.
|
||||
class GuiGameList : public GuiComponent
|
||||
{
|
||||
public:
|
||||
GuiGameList(Window* window, bool useDetail = false);
|
||||
~GuiGameList();
|
||||
virtual ~GuiGameList();
|
||||
|
||||
void setSystemId(int id);
|
||||
|
||||
void input(InputConfig* config, Input input);
|
||||
bool input(InputConfig* config, Input input);
|
||||
void update(int deltaTime);
|
||||
void render();
|
||||
|
||||
|
@ -38,6 +39,8 @@ private:
|
|||
void updateList();
|
||||
void updateTheme();
|
||||
void clearDetailData();
|
||||
void doTransition(int dir);
|
||||
|
||||
std::string getThemeFile();
|
||||
|
||||
SystemData* mSystem;
|
||||
|
@ -46,10 +49,16 @@ private:
|
|||
int mSystemId;
|
||||
bool mDetailed;
|
||||
|
||||
GuiList<FileData*>* mList;
|
||||
GuiImage* mScreenshot;
|
||||
GuiAnimation* mImageAnimation;
|
||||
GuiTheme* mTheme;
|
||||
TextListComponent<FileData*>* mList;
|
||||
ImageComponent* mScreenshot;
|
||||
TextComponent mDescription;
|
||||
AnimationComponent* mImageAnimation;
|
||||
ThemeComponent* mTheme;
|
||||
|
||||
ImageComponent mTransitionImage;
|
||||
AnimationComponent mTransitionAnimation;
|
||||
|
||||
Vector2i getImagePos();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,11 +5,14 @@
|
|||
#include "GuiGameList.h"
|
||||
#include "../Log.h"
|
||||
|
||||
static int inputCount = 12;
|
||||
static std::string inputName[12] = { "Up", "Down", "Left", "Right", "A", "B", "Menu", "Select", "PageUp", "PageDown", "MasterVolUp", "MasterVolDown" };
|
||||
static std::string inputDispName[12] = { "Up", "Down", "Left", "Right", "Accept", "Back", "Menu", "Jump to Letter", "Page Up", "Page Down", "Master volume up", "Master volume down" };
|
||||
static const int inputCount = 10;
|
||||
static std::string inputName[inputCount] = { "Up", "Down", "Left", "Right", "A", "B", "Menu", "Select", "PageUp", "PageDown"};
|
||||
static std::string inputDispName[inputCount] = { "Up", "Down", "Left", "Right", "Accept", "Back", "Menu", "Jump to Letter", "Page Up", "Page Down"};
|
||||
|
||||
GuiInputConfig::GuiInputConfig(Window* window, InputConfig* target) : Gui(window), mTargetConfig(target)
|
||||
//MasterVolUp and MasterVolDown are also hooked up, but do not appear on this screen.
|
||||
//If you want, you can manually add them to es_input.cfg.
|
||||
|
||||
GuiInputConfig::GuiInputConfig(Window* window, InputConfig* target) : GuiComponent(window), mTargetConfig(target), mCanSkip(false)
|
||||
{
|
||||
mCurInputId = 0;
|
||||
LOG(LogInfo) << "Configuring device " << target->getDeviceId();
|
||||
|
@ -20,10 +23,10 @@ void GuiInputConfig::update(int deltaTime)
|
|||
|
||||
}
|
||||
|
||||
void GuiInputConfig::input(InputConfig* config, Input input)
|
||||
bool GuiInputConfig::input(InputConfig* config, Input input)
|
||||
{
|
||||
if(config != mTargetConfig || input.value == 0)
|
||||
return;
|
||||
return false;
|
||||
|
||||
if(mCurInputId >= inputCount)
|
||||
{
|
||||
|
@ -38,12 +41,19 @@ void GuiInputConfig::input(InputConfig* config, Input input)
|
|||
GuiGameList::create(mWindow);
|
||||
}
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
}else{
|
||||
if(mCanSkip && config->isMappedTo("a", input))
|
||||
{
|
||||
mCurInputId++;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(config->getMappedTo(input).size() > 0)
|
||||
{
|
||||
mErrorMsg = "Already mapped!";
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
input.configured = true;
|
||||
|
@ -53,12 +63,15 @@ void GuiInputConfig::input(InputConfig* config, Input input)
|
|||
mCurInputId++;
|
||||
mErrorMsg = "";
|
||||
|
||||
//if the controller doesn't have enough buttons for Page Up/Page Down, skip to done
|
||||
if(mWindow->getInputManager()->getButtonCountByDevice(config->getDeviceId()) <= 4 && mCurInputId >= 8)
|
||||
//for buttons with not enough buttons, press A to skip
|
||||
if(mCurInputId >= 7)
|
||||
{
|
||||
mCurInputId = inputCount;
|
||||
mCanSkip = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GuiInputConfig::render()
|
||||
|
@ -78,10 +91,21 @@ void GuiInputConfig::render()
|
|||
|
||||
if(mCurInputId >= inputCount)
|
||||
{
|
||||
Renderer::drawCenteredText("Basic config done!", 0, (int)(Renderer::getScreenHeight() * 0.6), 0x00CC00FF, font);
|
||||
Renderer::drawCenteredText("Press any button to continue.", 0, (int)(Renderer::getScreenHeight() * 0.6) + font->getHeight() + 4, 0x000000FF, font);
|
||||
Renderer::drawCenteredText("Basic config done!", 0, (int)(Renderer::getScreenHeight() * 0.4), 0x00CC00FF, font);
|
||||
Renderer::drawCenteredText("Press any button to continue.", 0, (int)(Renderer::getScreenHeight() * 0.4) + font->getHeight() + 4, 0x000000FF, font);
|
||||
}else{
|
||||
Renderer::drawText(inputDispName[mCurInputId], 10, y, 0x000000FF, font);
|
||||
if(mCanSkip)
|
||||
{
|
||||
int textWidth = 0;
|
||||
font->sizeText(inputDispName[mCurInputId], &textWidth, NULL);
|
||||
textWidth += 14;
|
||||
|
||||
if(Renderer::getScreenWidth() / 2.5f > textWidth)
|
||||
textWidth = (int)(Renderer::getScreenWidth() / 2.5f);
|
||||
|
||||
Renderer::drawText("press Accept to skip", textWidth, y, 0x0000AAFF, font);
|
||||
}
|
||||
}
|
||||
|
||||
if(!mErrorMsg.empty())
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
#ifndef _GUIINPUTCONFIG_H_
|
||||
#define _GUIINPUTCONFIG_H_
|
||||
|
||||
#include "../Gui.h"
|
||||
#include "../GuiComponent.h"
|
||||
#include <string>
|
||||
|
||||
class GuiInputConfig : public Gui
|
||||
class GuiInputConfig : public GuiComponent
|
||||
{
|
||||
public:
|
||||
GuiInputConfig(Window* window, InputConfig* target);
|
||||
|
||||
void input(InputConfig* config, Input input);
|
||||
bool input(InputConfig* config, Input input);
|
||||
void update(int deltaTime);
|
||||
void render();
|
||||
|
||||
|
@ -17,6 +17,7 @@ private:
|
|||
std::string mErrorMsg;
|
||||
InputConfig* mTargetConfig;
|
||||
int mCurInputId;
|
||||
bool mCanSkip;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,293 +0,0 @@
|
|||
//This is *actually* part of the GuiList header and not meant to be compiled.
|
||||
|
||||
#include "GuiList.h"
|
||||
#include <iostream>
|
||||
|
||||
template <typename listType>
|
||||
GuiList<listType>::GuiList(Window* window, int offsetX, int offsetY, Font* font) : Gui(window)
|
||||
{
|
||||
mSelection = 0;
|
||||
mScrollDir = 0;
|
||||
mScrolling = 0;
|
||||
mScrollAccumulator = 0;
|
||||
|
||||
mOffsetX = offsetX;
|
||||
mOffsetY = offsetY;
|
||||
|
||||
mTextOffsetX = 0;
|
||||
|
||||
mFont = font;
|
||||
mSelectorColor = 0x000000FF;
|
||||
mSelectedTextColorOverride = 0;
|
||||
mScrollSound = NULL;
|
||||
mDrawCentered = true;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
GuiList<listType>::~GuiList()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
void GuiList<listType>::render()
|
||||
{
|
||||
const int cutoff = getOffsetY();
|
||||
const int entrySize = mFont->getHeight() + 5;
|
||||
|
||||
int startEntry = 0;
|
||||
|
||||
//number of entries that can fit on the screen simultaniously
|
||||
int screenCount = (Renderer::getScreenHeight() - cutoff) / entrySize;
|
||||
//screenCount -= 1;
|
||||
|
||||
if((int)mRowVector.size() >= screenCount)
|
||||
{
|
||||
startEntry = mSelection - (int)(screenCount * 0.5);
|
||||
if(startEntry < 0)
|
||||
startEntry = 0;
|
||||
if(startEntry >= (int)mRowVector.size() - screenCount)
|
||||
startEntry = mRowVector.size() - screenCount;
|
||||
}
|
||||
|
||||
int y = cutoff;
|
||||
|
||||
if(mRowVector.size() == 0)
|
||||
{
|
||||
Renderer::drawCenteredText("The list is empty.", 0, y, 0xFF0000FF, mFont);
|
||||
return;
|
||||
}
|
||||
|
||||
int listCutoff = startEntry + screenCount;
|
||||
if(listCutoff > (int)mRowVector.size())
|
||||
listCutoff = mRowVector.size();
|
||||
|
||||
for(int i = startEntry; i < listCutoff; i++)
|
||||
{
|
||||
//draw selector bar
|
||||
if(mSelection == i)
|
||||
{
|
||||
Renderer::drawRect(getOffsetX(), y, Renderer::getScreenWidth(), mFont->getHeight(), mSelectorColor);
|
||||
}
|
||||
|
||||
ListRow row = mRowVector.at((unsigned int)i);
|
||||
|
||||
if(mDrawCentered)
|
||||
Renderer::drawCenteredText(row.name, getOffsetX(), y, (mSelection == i && mSelectedTextColorOverride != 0) ? mSelectedTextColorOverride : row.color, mFont);
|
||||
else
|
||||
Renderer::drawText(row.name, getOffsetX() + mTextOffsetX, y, (mSelection == i && mSelectedTextColorOverride != 0) ? mSelectedTextColorOverride : row.color, mFont);
|
||||
|
||||
y += entrySize;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
void GuiList<listType>::input(InputConfig* config, Input input)
|
||||
{
|
||||
if(mRowVector.size() > 0)
|
||||
{
|
||||
if(input.value != 0)
|
||||
{
|
||||
if(config->isMappedTo("down", input))
|
||||
{
|
||||
mScrollDir = 1;
|
||||
scroll();
|
||||
}
|
||||
|
||||
if(config->isMappedTo("up", input))
|
||||
{
|
||||
mScrollDir = -1;
|
||||
scroll();
|
||||
}
|
||||
if(config->isMappedTo("pagedown", input))
|
||||
{
|
||||
mScrollDir = 10;
|
||||
scroll();
|
||||
}
|
||||
|
||||
if(config->isMappedTo("pageup", input))
|
||||
{
|
||||
mScrollDir = -10;
|
||||
scroll();
|
||||
}
|
||||
}else{
|
||||
//if((button == InputManager::DOWN && mScrollDir > 0) || (button == InputManager::PAGEDOWN && mScrollDir > 0) || (button == InputManager::UP && mScrollDir < 0) || (button == InputManager::PAGEUP && mScrollDir < 0))
|
||||
if(config->isMappedTo("down", input) || config->isMappedTo("up", input) || config->isMappedTo("pagedown", input) || config->isMappedTo("pageup", input))
|
||||
{
|
||||
stopScrolling();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
void GuiList<listType>::stopScrolling()
|
||||
{
|
||||
mScrollAccumulator = 0;
|
||||
mScrolling = false;
|
||||
mScrollDir = 0;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
void GuiList<listType>::update(int deltaTime)
|
||||
{
|
||||
if(mScrollDir != 0)
|
||||
{
|
||||
mScrollAccumulator += deltaTime;
|
||||
|
||||
if(!mScrolling)
|
||||
{
|
||||
if(mScrollAccumulator >= SCROLLDELAY)
|
||||
{
|
||||
mScrollAccumulator = SCROLLTIME;
|
||||
mScrolling = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(mScrolling)
|
||||
{
|
||||
mScrollAccumulator += deltaTime;
|
||||
|
||||
while(mScrollAccumulator >= SCROLLTIME)
|
||||
{
|
||||
mScrollAccumulator -= SCROLLTIME;
|
||||
|
||||
scroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
void GuiList<listType>::scroll()
|
||||
{
|
||||
mSelection += mScrollDir;
|
||||
|
||||
if(mSelection < 0)
|
||||
{
|
||||
if(mScrollDir < -1)
|
||||
mSelection = 0;
|
||||
else
|
||||
mSelection += mRowVector.size();
|
||||
}
|
||||
if(mSelection >= (int)mRowVector.size())
|
||||
{
|
||||
if(mScrollDir > 1)
|
||||
mSelection = (int)mRowVector.size() - 1;
|
||||
else
|
||||
mSelection -= mRowVector.size();
|
||||
}
|
||||
|
||||
if(mScrollSound)
|
||||
mScrollSound->play();
|
||||
}
|
||||
|
||||
//list management stuff
|
||||
template <typename listType>
|
||||
void GuiList<listType>::addObject(std::string name, listType obj, unsigned int color)
|
||||
{
|
||||
ListRow row = {name, obj, color};
|
||||
mRowVector.push_back(row);
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
void GuiList<listType>::clear()
|
||||
{
|
||||
mRowVector.clear();
|
||||
mSelection = 0;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
std::string GuiList<listType>::getSelectedName()
|
||||
{
|
||||
if((int)mRowVector.size() > mSelection)
|
||||
return mRowVector.at(mSelection).name;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
listType GuiList<listType>::getSelectedObject()
|
||||
{
|
||||
if((int)mRowVector.size() > mSelection)
|
||||
return mRowVector.at(mSelection).object;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
int GuiList<listType>::getSelection()
|
||||
{
|
||||
return mSelection;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
bool GuiList<listType>::isScrolling()
|
||||
{
|
||||
return mScrollDir != 0;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
void GuiList<listType>::setSelectorColor(unsigned int selectorColor)
|
||||
{
|
||||
mSelectorColor = selectorColor;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
void GuiList<listType>::setSelectedTextColor(unsigned int selectedColor)
|
||||
{
|
||||
mSelectedTextColorOverride = selectedColor;
|
||||
}
|
||||
|
||||
template<typename listType>
|
||||
void GuiList<listType>::setCentered(bool centered)
|
||||
{
|
||||
mDrawCentered = centered;
|
||||
}
|
||||
|
||||
template<typename listType>
|
||||
void GuiList<listType>::setTextOffsetX(int textoffsetx)
|
||||
{
|
||||
mTextOffsetX = textoffsetx;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
int GuiList<listType>::getObjectCount()
|
||||
{
|
||||
return mRowVector.size();
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
listType GuiList<listType>::getObject(int i)
|
||||
{
|
||||
return mRowVector.at(i).object;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
void GuiList<listType>::setSelection(int i)
|
||||
{
|
||||
mSelection = i;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
void GuiList<listType>::setScrollSound(std::shared_ptr<Sound> & sound)
|
||||
{
|
||||
mScrollSound = sound;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
void GuiList<listType>::setFont(Font* font)
|
||||
{
|
||||
mFont = font;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
int GuiList<listType>::getOffsetX()
|
||||
{
|
||||
return mOffsetX;
|
||||
}
|
||||
|
||||
template <typename listType>
|
||||
int GuiList<listType>::getOffsetY()
|
||||
{
|
||||
return mOffsetY;
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
#ifndef _GUILIST_H_
|
||||
#define _GUILIST_H_
|
||||
|
||||
#include "../Renderer.h"
|
||||
#include "../Font.h"
|
||||
#include "../Gui.h"
|
||||
#include "../InputManager.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "../Sound.h"
|
||||
|
||||
//A graphical list. Supports multiple colors for rows and scrolling.
|
||||
//TODO - add truncation to text rendering if name exceeds a maximum width (a trailing elipses, perhaps).
|
||||
template <typename listType>
|
||||
class GuiList : public Gui
|
||||
{
|
||||
public:
|
||||
GuiList(Window* window, int offsetX, int offsetY, Font* font);
|
||||
~GuiList();
|
||||
|
||||
void input(InputConfig* config, Input input);
|
||||
void update(int deltaTime);
|
||||
void render();
|
||||
|
||||
void addObject(std::string name, listType obj, unsigned int color = 0xFF0000);
|
||||
void clear();
|
||||
|
||||
std::string getSelectedName();
|
||||
listType getSelectedObject();
|
||||
int getSelection();
|
||||
void stopScrolling();
|
||||
bool isScrolling();
|
||||
|
||||
void setSelectorColor(unsigned int selectorColor);
|
||||
void setSelectedTextColor(unsigned int selectedColor);
|
||||
void setCentered(bool centered);
|
||||
void setScrollSound(std::shared_ptr<Sound> & sound);
|
||||
void setTextOffsetX(int textoffsetx);
|
||||
|
||||
int getObjectCount();
|
||||
listType getObject(int i);
|
||||
void setSelection(int i);
|
||||
|
||||
void setFont(Font* f);
|
||||
|
||||
int getOffsetX();
|
||||
int getOffsetY();
|
||||
private:
|
||||
static const int SCROLLDELAY = 507;
|
||||
static const int SCROLLTIME = 200;
|
||||
|
||||
int mOffsetX, mOffsetY;
|
||||
|
||||
void scroll(); //helper method, scrolls in whatever direction scrollDir is
|
||||
|
||||
int mScrollDir, mScrollAccumulator;
|
||||
bool mScrolling;
|
||||
|
||||
Font* mFont;
|
||||
unsigned int mSelectorColor, mSelectedTextColorOverride;
|
||||
bool mDrawCentered;
|
||||
|
||||
int mTextOffsetX;
|
||||
|
||||
struct ListRow
|
||||
{
|
||||
std::string name;
|
||||
listType object;
|
||||
unsigned int color;
|
||||
};
|
||||
|
||||
std::vector<ListRow> mRowVector;
|
||||
int mSelection;
|
||||
std::shared_ptr<Sound> mScrollSound;
|
||||
};
|
||||
|
||||
#include "GuiList.cpp"
|
||||
|
||||
#endif
|
|
@ -4,15 +4,14 @@
|
|||
#include "../Log.h"
|
||||
#include "../SystemData.h"
|
||||
#include "GuiGameList.h"
|
||||
#include "../Settings.h"
|
||||
#include "GuiSettingsMenu.h"
|
||||
|
||||
//defined in main.cpp
|
||||
extern bool DONTSHOWEXIT;
|
||||
|
||||
GuiMenu::GuiMenu(Window* window, GuiGameList* parent) : Gui(window)
|
||||
GuiMenu::GuiMenu(Window* window, GuiGameList* parent) : GuiComponent(window)
|
||||
{
|
||||
mParent = parent;
|
||||
|
||||
mList = new GuiList<std::string>(mWindow, 0, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::LARGE));
|
||||
mList = new TextListComponent<std::string>(mWindow, 0, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::LARGE));
|
||||
mList->setSelectedTextColor(0x0000FFFF);
|
||||
populateList();
|
||||
}
|
||||
|
@ -22,20 +21,23 @@ GuiMenu::~GuiMenu()
|
|||
delete mList;
|
||||
}
|
||||
|
||||
void GuiMenu::input(InputConfig* config, Input input)
|
||||
bool GuiMenu::input(InputConfig* config, Input input)
|
||||
{
|
||||
mList->input(config, input);
|
||||
|
||||
if(config->isMappedTo("menu", input) && input.value != 0)
|
||||
{
|
||||
delete this;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(config->isMappedTo("a", input) && input.value != 0)
|
||||
{
|
||||
executeCommand(mList->getSelectedObject());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GuiMenu::executeCommand(std::string command)
|
||||
|
@ -51,6 +53,10 @@ void GuiMenu::executeCommand(std::string command)
|
|||
//reload the game list
|
||||
SystemData::loadConfig();
|
||||
mParent->setSystemId(0);
|
||||
}else if(command == "es_settings")
|
||||
{
|
||||
mWindow->pushGui(new GuiSettingsMenu(mWindow));
|
||||
delete this;
|
||||
}else{
|
||||
if(system(command.c_str()) != 0)
|
||||
{
|
||||
|
@ -68,12 +74,15 @@ void GuiMenu::populateList()
|
|||
//the method is GuiList::addObject(std::string displayString, std::string commandString, unsigned int displayHexColor);
|
||||
//the list will automatically adjust as items are added to it, this should be the only area you need to change
|
||||
//if you want to do something special within ES, override your command in the executeComand() method
|
||||
|
||||
mList->addObject("Settings", "es_settings", 0x0000FFFF);
|
||||
|
||||
mList->addObject("Restart", "sudo shutdown -r now", 0x0000FFFF);
|
||||
mList->addObject("Shutdown", "sudo shutdown -h now", 0x0000FFFF);
|
||||
|
||||
mList->addObject("Reload", "es_reload", 0x0000FFFF);
|
||||
|
||||
if(!DONTSHOWEXIT)
|
||||
if(!Settings::getInstance()->getBool("DONTSHOWEXIT"))
|
||||
mList->addObject("Exit", "exit", 0xFF0000FF); //a special case; pushes an SDL quit event to the event stack instead of being called by system()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
#ifndef _GUIMENU_H_
|
||||
#define _GUIMENU_H_
|
||||
|
||||
#include "../Gui.h"
|
||||
#include "GuiList.h"
|
||||
#include "../GuiComponent.h"
|
||||
#include "TextListComponent.h"
|
||||
|
||||
class GuiGameList;
|
||||
|
||||
class GuiMenu : public Gui
|
||||
class GuiMenu : public GuiComponent
|
||||
{
|
||||
public:
|
||||
GuiMenu(Window* window, GuiGameList* parent);
|
||||
~GuiMenu();
|
||||
virtual ~GuiMenu();
|
||||
|
||||
void input(InputConfig* config, Input input);
|
||||
bool input(InputConfig* config, Input input);
|
||||
void update(int deltaTime);
|
||||
void render();
|
||||
|
||||
private:
|
||||
GuiGameList* mParent;
|
||||
GuiList<std::string>* mList;
|
||||
TextListComponent<std::string>* mList;
|
||||
|
||||
void populateList();
|
||||
void executeCommand(std::string command);
|
||||
|
|
89
src/components/GuiSettingsMenu.cpp
Normal file
89
src/components/GuiSettingsMenu.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
#include "GuiSettingsMenu.h"
|
||||
#include "../Renderer.h"
|
||||
#include "../Settings.h"
|
||||
#include "../VolumeControl.h"
|
||||
|
||||
GuiSettingsMenu::GuiSettingsMenu(Window* window) : GuiComponent(window),
|
||||
mList(window, Vector2u(2, 3)),
|
||||
mDrawFramerateSwitch(window),
|
||||
mVolumeSlider(window, 0, 100, 1),
|
||||
mSaveLabel(window)
|
||||
{
|
||||
loadStates();
|
||||
|
||||
addChild(&mList);
|
||||
|
||||
mList.setOffset(Renderer::getScreenWidth() / 4, 0);
|
||||
|
||||
TextComponent* label = new TextComponent(mWindow);
|
||||
label->setText("Draw Framerate: ");
|
||||
label->setColor(0x0000FFFF);
|
||||
mList.setEntry(Vector2u(0, 0), Vector2u(1, 1), label, false, ComponentListComponent::AlignRight, Vector2<bool>(true, true));
|
||||
mLabels.push_back(label);
|
||||
|
||||
//drawFramerate switch
|
||||
mList.setEntry(Vector2u(1, 0), Vector2u(1, 1), &mDrawFramerateSwitch, true, ComponentListComponent::AlignCenter, Vector2<bool>(true, true));
|
||||
|
||||
label = new TextComponent(mWindow);
|
||||
label->setText("System volume: ");
|
||||
label->setColor(0x0000FFFF);
|
||||
mList.setEntry(Vector2u(0, 1), Vector2u(1, 1), label, false, ComponentListComponent::AlignRight, Vector2<bool>(true, true));
|
||||
|
||||
//volume slider
|
||||
mList.setEntry(Vector2u(1, 1), Vector2u(1, 1), &mVolumeSlider, true, ComponentListComponent::AlignCenter, Vector2<bool>(true, true));
|
||||
|
||||
//save label
|
||||
mSaveLabel.setText("SAVE");
|
||||
mSaveLabel.setColor(0x000000FF);
|
||||
mList.setEntry(Vector2u(0, 2), Vector2u(2, 1), &mSaveLabel, true, ComponentListComponent::AlignCenter, Vector2<bool>(false, true));
|
||||
|
||||
mList.setOffset(Renderer::getScreenWidth() / 2 - mList.getSize().x / 2, 0);
|
||||
}
|
||||
|
||||
GuiSettingsMenu::~GuiSettingsMenu()
|
||||
{
|
||||
for(auto iter = mLabels.begin(); iter != mLabels.end(); iter++)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
}
|
||||
|
||||
bool GuiSettingsMenu::input(InputConfig* config, Input input)
|
||||
{
|
||||
//let our children (read: list) go first
|
||||
if(GuiComponent::input(config, input))
|
||||
return true;
|
||||
|
||||
if(config->isMappedTo("b", input) && input.value)
|
||||
{
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(config->isMappedTo("a", input) && mList.getSelectedComponent() == &mSaveLabel && input.value)
|
||||
{
|
||||
applyStates();
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GuiSettingsMenu::loadStates()
|
||||
{
|
||||
Settings* s = Settings::getInstance();
|
||||
mDrawFramerateSwitch.setState(s->getBool("DRAWFRAMERATE"));
|
||||
|
||||
mVolumeSlider.setValue((float)VolumeControl::getInstance()->getVolume());
|
||||
}
|
||||
|
||||
void GuiSettingsMenu::applyStates()
|
||||
{
|
||||
Settings* s = Settings::getInstance();
|
||||
s->setBool("DRAWFRAMERATE", mDrawFramerateSwitch.getState());
|
||||
|
||||
VolumeControl::getInstance()->setVolume((int)mVolumeSlider.getValue());
|
||||
|
||||
s->saveFile();
|
||||
}
|
32
src/components/GuiSettingsMenu.h
Normal file
32
src/components/GuiSettingsMenu.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef _SETTINGSMENU_H_
|
||||
#define _SETTINGSMENU_H_
|
||||
|
||||
#include "../GuiComponent.h"
|
||||
#include "ComponentListComponent.h"
|
||||
#include <vector>
|
||||
#include "SwitchComponent.h"
|
||||
#include "SliderComponent.h"
|
||||
#include "TextComponent.h"
|
||||
|
||||
class GuiSettingsMenu : public GuiComponent
|
||||
{
|
||||
public:
|
||||
GuiSettingsMenu(Window* window);
|
||||
~GuiSettingsMenu();
|
||||
|
||||
bool input(InputConfig* config, Input input) override;
|
||||
|
||||
private:
|
||||
void loadStates();
|
||||
void applyStates();
|
||||
|
||||
ComponentListComponent mList;
|
||||
|
||||
SwitchComponent mDrawFramerateSwitch;
|
||||
SliderComponent mVolumeSlider;
|
||||
TextComponent mSaveLabel;
|
||||
|
||||
std::vector<GuiComponent*> mLabels;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,33 +1,30 @@
|
|||
#include "GuiImage.h"
|
||||
#include "ImageComponent.h"
|
||||
#include <iostream>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <math.h>
|
||||
#include "../Log.h"
|
||||
#include "../Renderer.h"
|
||||
|
||||
unsigned int GuiImage::getWidth() { return mDrawWidth; }
|
||||
unsigned int GuiImage::getHeight() { return mDrawHeight; }
|
||||
Vector2u ImageComponent::getTextureSize() { return mTextureSize; }
|
||||
|
||||
GuiImage::GuiImage(Window* window, int offsetX, int offsetY, std::string path, unsigned int resizeWidth, unsigned int resizeHeight, bool resizeExact) : Gui(window)
|
||||
ImageComponent::ImageComponent(Window* window, int offsetX, int offsetY, std::string path, unsigned int resizeWidth, unsigned int resizeHeight, bool allowUpscale) : GuiComponent(window)
|
||||
{
|
||||
mTextureID = 0;
|
||||
|
||||
setOffset(offsetX, offsetY);
|
||||
setOffset(Vector2i(offsetX, offsetY));
|
||||
|
||||
//default origin is the center of image
|
||||
mOriginX = 0.5;
|
||||
mOriginY = 0.5;
|
||||
mOpacity = 255;
|
||||
mOrigin.x = 0.5;
|
||||
mOrigin.y = 0.5;
|
||||
|
||||
mWidth = mDrawWidth = 0;
|
||||
mHeight = mDrawHeight = 0;
|
||||
mOpacity = 255;
|
||||
|
||||
mTiled = false;
|
||||
|
||||
mResizeWidth = resizeWidth;
|
||||
mResizeHeight = resizeHeight;
|
||||
mTargetSize.x = resizeWidth;
|
||||
mTargetSize.y = resizeHeight;
|
||||
|
||||
mResizeExact = resizeExact;
|
||||
mAllowUpscale = allowUpscale;
|
||||
|
||||
mFlipX = false;
|
||||
mFlipY = false;
|
||||
|
@ -36,17 +33,17 @@ GuiImage::GuiImage(Window* window, int offsetX, int offsetY, std::string path, u
|
|||
setImage(path);
|
||||
}
|
||||
|
||||
GuiImage::~GuiImage()
|
||||
ImageComponent::~ImageComponent()
|
||||
{
|
||||
unloadImage();
|
||||
}
|
||||
|
||||
void GuiImage::loadImage(std::string path)
|
||||
void ImageComponent::loadImage(std::string path)
|
||||
{
|
||||
//make sure the file *exists*
|
||||
if(!boost::filesystem::exists(path))
|
||||
{
|
||||
LOG(LogError) << "File \"" << path << "\" not found!";
|
||||
LOG(LogError) << "Image \"" << path << "\" not found!";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -112,29 +109,6 @@ void GuiImage::loadImage(std::string path)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
//set width/height to powers of 2 for OpenGL
|
||||
for(unsigned int i = 0; i < 22; i++)
|
||||
{
|
||||
unsigned int pwrOf2 = pow(2, i);
|
||||
if(!widthPwrOf2 && pwrOf2 >= width)
|
||||
widthPwrOf2 = pwrOf2;
|
||||
if(!heightPwrOf2 && pwrOf2 >= height)
|
||||
heightPwrOf2 = pwrOf2;
|
||||
|
||||
if(widthPwrOf2 && heightPwrOf2)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!widthPwrOf2 || !heightPwrOf2)
|
||||
{
|
||||
LOG(LogError) << "Error assigning power of two for width or height of image!";
|
||||
FreeImage_Unload(image);
|
||||
return;
|
||||
}*/
|
||||
|
||||
|
||||
//convert from BGRA to RGBA
|
||||
GLubyte* imageRGBA = new GLubyte[4*width*height];
|
||||
for(unsigned int i = 0; i < width*height; i++)
|
||||
|
@ -159,8 +133,8 @@ void GuiImage::loadImage(std::string path)
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mTextureSize.x = width;
|
||||
mTextureSize.y = height;
|
||||
|
||||
//free the image data
|
||||
FreeImage_Unload(image);
|
||||
|
@ -171,42 +145,43 @@ void GuiImage::loadImage(std::string path)
|
|||
resize();
|
||||
}
|
||||
|
||||
void GuiImage::resize()
|
||||
void ImageComponent::resize()
|
||||
{
|
||||
mDrawWidth = mWidth;
|
||||
mDrawHeight = mHeight;
|
||||
mSize.x = mTextureSize.x;
|
||||
mSize.y = mTextureSize.y;
|
||||
|
||||
//(we don't resize tiled images)
|
||||
if(!mTiled)
|
||||
if(!mTiled && (mTargetSize.x || mTargetSize.y))
|
||||
{
|
||||
float resizeScaleX = 0, resizeScaleY = 0;
|
||||
if(mResizeExact)
|
||||
{
|
||||
if(mResizeWidth)
|
||||
resizeScaleX = (float)mResizeWidth / mWidth;
|
||||
if(mResizeHeight)
|
||||
resizeScaleY = (float)mResizeHeight / mHeight;
|
||||
}else{
|
||||
if(mResizeWidth && mWidth > mResizeWidth)
|
||||
resizeScaleX = (float)mResizeWidth / mWidth;
|
||||
Vector2f resizeScale;
|
||||
|
||||
if(mResizeHeight && mHeight > mResizeHeight)
|
||||
resizeScaleY = (float)mResizeHeight / mHeight;
|
||||
if(mTargetSize.x && (mAllowUpscale || mSize.x > mTargetSize.x))
|
||||
{
|
||||
resizeScale.x = (float)mTargetSize.x / mSize.x;
|
||||
}
|
||||
if(mTargetSize.y && (mAllowUpscale || mSize.y > mTargetSize.y))
|
||||
{
|
||||
resizeScale.y = (float)mTargetSize.y / mSize.y;
|
||||
}
|
||||
|
||||
if(resizeScaleX && !resizeScaleY)
|
||||
resizeScaleY = resizeScaleX;
|
||||
if(resizeScaleY && !resizeScaleX)
|
||||
resizeScaleX = resizeScaleY;
|
||||
if(resizeScale.x && !resizeScale.y)
|
||||
resizeScale.y = resizeScale.x;
|
||||
if(resizeScale.y && !resizeScale.x)
|
||||
resizeScale.x = resizeScale.y;
|
||||
|
||||
if(resizeScaleX)
|
||||
mDrawWidth = (int)(mDrawWidth * resizeScaleX);
|
||||
if(resizeScaleY)
|
||||
mDrawHeight = (int)(mDrawHeight * resizeScaleY);
|
||||
if(resizeScale.x)
|
||||
mSize.x = (int)(mSize.x * resizeScale.x);
|
||||
if(resizeScale.y)
|
||||
mSize.y = (int)(mSize.y * resizeScale.y);
|
||||
}
|
||||
|
||||
if(mTiled)
|
||||
{
|
||||
mSize = mTargetSize;
|
||||
}
|
||||
}
|
||||
|
||||
void GuiImage::unloadImage()
|
||||
void ImageComponent::unloadImage()
|
||||
{
|
||||
if(mTextureID)
|
||||
{
|
||||
|
@ -216,7 +191,7 @@ void GuiImage::unloadImage()
|
|||
}
|
||||
}
|
||||
|
||||
void GuiImage::setImage(std::string path)
|
||||
void ImageComponent::setImage(std::string path)
|
||||
{
|
||||
if(mPath == path)
|
||||
return;
|
||||
|
@ -229,39 +204,41 @@ void GuiImage::setImage(std::string path)
|
|||
|
||||
}
|
||||
|
||||
void GuiImage::setOrigin(float originX, float originY)
|
||||
void ImageComponent::setOrigin(float originX, float originY)
|
||||
{
|
||||
mOriginX = originX;
|
||||
mOriginY = originY;
|
||||
mOrigin.x = originX;
|
||||
mOrigin.y = originY;
|
||||
}
|
||||
|
||||
void GuiImage::setTiling(bool tile)
|
||||
void ImageComponent::setTiling(bool tile)
|
||||
{
|
||||
mTiled = tile;
|
||||
|
||||
if(mTiled)
|
||||
mResizeExact = false;
|
||||
}
|
||||
mAllowUpscale = false;
|
||||
|
||||
void GuiImage::setResize(unsigned int width, unsigned int height, bool resizeExact)
|
||||
{
|
||||
mResizeWidth = width;
|
||||
mResizeHeight = height;
|
||||
mResizeExact = resizeExact;
|
||||
resize();
|
||||
}
|
||||
|
||||
void GuiImage::setFlipX(bool flip)
|
||||
void ImageComponent::setResize(unsigned int width, unsigned int height, bool allowUpscale)
|
||||
{
|
||||
mTargetSize.x = width;
|
||||
mTargetSize.y = height;
|
||||
mAllowUpscale = allowUpscale;
|
||||
resize();
|
||||
}
|
||||
|
||||
void ImageComponent::setFlipX(bool flip)
|
||||
{
|
||||
mFlipX = flip;
|
||||
}
|
||||
|
||||
void GuiImage::setFlipY(bool flip)
|
||||
void ImageComponent::setFlipY(bool flip)
|
||||
{
|
||||
mFlipY = flip;
|
||||
}
|
||||
|
||||
void GuiImage::render()
|
||||
void ImageComponent::onRender()
|
||||
{
|
||||
if(mTextureID && getOpacity() > 0)
|
||||
{
|
||||
|
@ -270,29 +247,31 @@ void GuiImage::render()
|
|||
|
||||
if(mTiled)
|
||||
{
|
||||
float xCount = ((float)mResizeWidth/mWidth);
|
||||
float yCount = ((float)mResizeHeight/mHeight);
|
||||
|
||||
float xCount = (float)mSize.x / mTextureSize.x;
|
||||
float yCount = (float)mSize.y / mTextureSize.y;
|
||||
|
||||
Renderer::buildGLColorArray(colors, 0xFFFFFF00 | (getOpacity()), 6);
|
||||
buildImageArray(getOffsetX(), getOffsetY(), points, texs, xCount, yCount);
|
||||
buildImageArray(0, 0, points, texs, xCount, yCount);
|
||||
}else{
|
||||
Renderer::buildGLColorArray(colors, 0xFFFFFF00 | (getOpacity()), 6);
|
||||
buildImageArray(getOffsetX(), getOffsetY(), points, texs);
|
||||
buildImageArray(0, 0, points, texs);
|
||||
}
|
||||
|
||||
drawImageArray(points, texs, colors, 6);
|
||||
}
|
||||
|
||||
GuiComponent::onRender();
|
||||
}
|
||||
|
||||
void GuiImage::buildImageArray(int posX, int posY, GLfloat* points, GLfloat* texs, float px, float py)
|
||||
void ImageComponent::buildImageArray(int posX, int posY, GLfloat* points, GLfloat* texs, float px, float py)
|
||||
{
|
||||
points[0] = posX - (mDrawWidth * mOriginX) * px; points[1] = posY - (mDrawHeight * mOriginY) * py;
|
||||
points[2] = posX - (mDrawWidth * mOriginX) * px; points[3] = posY + (mDrawHeight * (1 - mOriginY)) * py;
|
||||
points[4] = posX + (mDrawWidth * (1 - mOriginX)) * px; points[5] = posY - (mDrawHeight * mOriginY) * py;
|
||||
points[0] = posX - (mSize.x * mOrigin.x); points[1] = posY - (mSize.y * mOrigin.y);
|
||||
points[2] = posX - (mSize.x * mOrigin.x); points[3] = posY + (mSize.y * (1 - mOrigin.y));
|
||||
points[4] = posX + (mSize.x * (1 - mOrigin.x)); points[5] = posY - (mSize.y * mOrigin.y);
|
||||
|
||||
points[6] = posX + (mDrawWidth * (1 - mOriginX)) * px; points[7] = posY - (mDrawHeight * mOriginY) * py;
|
||||
points[8] = posX - (mDrawWidth * mOriginX) * px; points[9] = posY + (mDrawHeight * (1 - mOriginY)) * py;
|
||||
points[10] = posX + (mDrawWidth * (1 -mOriginX)) * px; points[11] = posY + (mDrawHeight * (1 - mOriginY)) * py;
|
||||
points[6] = posX + (mSize.x * (1 - mOrigin.x)); points[7] = posY - (mSize.y * mOrigin.y);
|
||||
points[8] = posX - (mSize.x * mOrigin.x); points[9] = posY + (mSize.y * (1 - mOrigin.y));
|
||||
points[10] = posX + (mSize.x * (1 -mOrigin.x)); points[11] = posY + (mSize.y * (1 - mOrigin.y));
|
||||
|
||||
|
||||
|
||||
|
@ -322,14 +301,13 @@ void GuiImage::buildImageArray(int posX, int posY, GLfloat* points, GLfloat* tex
|
|||
}
|
||||
}
|
||||
|
||||
void GuiImage::drawImageArray(GLfloat* points, GLfloat* texs, GLubyte* colors, unsigned int numArrays)
|
||||
void ImageComponent::drawImageArray(GLfloat* points, GLfloat* texs, GLubyte* colors, unsigned int numArrays)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
|
@ -354,21 +332,57 @@ void GuiImage::drawImageArray(GLfloat* points, GLfloat* texs, GLubyte* colors, u
|
|||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void GuiImage::init()
|
||||
void ImageComponent::init()
|
||||
{
|
||||
if(!mPath.empty())
|
||||
loadImage(mPath);
|
||||
|
||||
GuiComponent::init();
|
||||
}
|
||||
|
||||
void GuiImage::deinit()
|
||||
void ImageComponent::deinit()
|
||||
{
|
||||
unloadImage();
|
||||
|
||||
GuiComponent::deinit();
|
||||
}
|
||||
|
||||
bool GuiImage::hasImage()
|
||||
bool ImageComponent::hasImage()
|
||||
{
|
||||
return !mPath.empty();
|
||||
}
|
||||
|
||||
unsigned char GuiImage::getOpacity() { return mOpacity; }
|
||||
void GuiImage::setOpacity(unsigned char opacity) { mOpacity = opacity; }
|
||||
unsigned char ImageComponent::getOpacity() { return mOpacity; }
|
||||
void ImageComponent::setOpacity(unsigned char opacity) { mOpacity = opacity; }
|
||||
|
||||
void ImageComponent::copyScreen()
|
||||
{
|
||||
unloadImage();
|
||||
|
||||
int width = Renderer::getScreenWidth();
|
||||
int height = Renderer::getScreenHeight();
|
||||
|
||||
//glReadBuffer(GL_FRONT);
|
||||
|
||||
/*char* data = new char[width*height*3];
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);*/
|
||||
|
||||
glGenTextures(1, &mTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
|
||||
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
//delete[] data;
|
||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, width, height, 0);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
mTextureSize.x = height;
|
||||
mTextureSize.y = height;
|
||||
|
||||
resize();
|
||||
}
|
|
@ -1,50 +1,56 @@
|
|||
#ifndef _GUIIMAGE_H_
|
||||
#define _GUIIMAGE_H_
|
||||
#ifndef _IMAGECOMPONENT_H_
|
||||
#define _IMAGECOMPONENT_H_
|
||||
|
||||
#include "../platform.h"
|
||||
#include GLHEADER
|
||||
|
||||
#include "../Gui.h"
|
||||
#include "../GuiComponent.h"
|
||||
#include <string>
|
||||
#include <FreeImage.h>
|
||||
|
||||
|
||||
class GuiImage : public Gui
|
||||
class ImageComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
//Creates a new GuiImage at the given location. If given an image, it will be loaded. If maxWidth and/or maxHeight are nonzero, the image will be
|
||||
//resized to fix. If only one axis is specified, the other will be resized in accordance with the image's aspect ratio. If resizeExact is false,
|
||||
//resized to fit. If only one axis is specified, the other will be set in accordance with the image's aspect ratio. If allowUpscale is false,
|
||||
//the image will only be downscaled, never upscaled (the image's size must surpass at least one nonzero bound).
|
||||
GuiImage(Window* window, int offsetX = 0, int offsetY = 0, std::string path = "", unsigned int maxWidth = 0, unsigned int maxHeight = 0, bool resizeExact = false);
|
||||
~GuiImage();
|
||||
ImageComponent(Window* window, int offsetX = 0, int offsetY = 0, std::string path = "", unsigned int maxWidth = 0, unsigned int maxHeight = 0, bool allowUpscale = false);
|
||||
virtual ~ImageComponent();
|
||||
|
||||
//Copy the entire screen into a texture for us to use.
|
||||
void copyScreen();
|
||||
void setImage(std::string path); //Loads the image at the given filepath.
|
||||
void setOrigin(float originX, float originY); //Sets the origin as a percentage of this image (e.g. (0, 0) is top left, (0.5, 0.5) is the center)
|
||||
void setTiling(bool tile); //Enables or disables tiling. Must be called before loading an image or resizing will be weird.
|
||||
void setResize(unsigned int width, unsigned int height, bool resizeExact);
|
||||
void setResize(unsigned int width, unsigned int height, bool allowUpscale);
|
||||
|
||||
void setFlipX(bool flip);
|
||||
void setFlipY(bool flip);
|
||||
|
||||
unsigned int getWidth(); //Returns render width in pixels. May be different than actual texture width.
|
||||
unsigned int getHeight(); //Returns render height in pixels. May be different than actual texture height.
|
||||
//You can get the rendered size of the ImageComponent with getSize().
|
||||
Vector2u getTextureSize();
|
||||
|
||||
|
||||
bool hasImage();
|
||||
|
||||
void render();
|
||||
|
||||
//Image textures will be deleted on renderer deinitialization, and recreated on reinitialization (if mPath is not empty).
|
||||
void init();
|
||||
void deinit();
|
||||
|
||||
unsigned char getOpacity();
|
||||
void setOpacity(unsigned char opacity);
|
||||
private:
|
||||
unsigned int mResizeWidth, mResizeHeight;
|
||||
float mOriginX, mOriginY;
|
||||
bool mResizeExact, mTiled, mFlipX, mFlipY;
|
||||
|
||||
int mOffsetX, mOffsetY;
|
||||
protected:
|
||||
void onRender();
|
||||
|
||||
private:
|
||||
Vector2u mTargetSize;
|
||||
Vector2u mTextureSize;
|
||||
Vector2f mOrigin;
|
||||
|
||||
bool mAllowUpscale, mTiled, mFlipX, mFlipY;
|
||||
|
||||
unsigned char mOpacity;
|
||||
|
||||
void loadImage(std::string path);
|
||||
|
@ -55,9 +61,6 @@ private:
|
|||
|
||||
std::string mPath;
|
||||
|
||||
unsigned int mWidth, mHeight; //Our rendered size.
|
||||
unsigned int mDrawWidth, mDrawHeight;
|
||||
|
||||
GLuint mTextureID;
|
||||
};
|
||||
|
101
src/components/SliderComponent.cpp
Normal file
101
src/components/SliderComponent.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include "SliderComponent.h"
|
||||
#include <assert.h>
|
||||
#include "../Renderer.h"
|
||||
|
||||
SliderComponent::SliderComponent(Window* window, float min, float max, float increment) : GuiComponent(window),
|
||||
mMin(min), mMax(max), mIncrement(increment), mMoveRate(0), mRepeatWaitTimer(0)
|
||||
{
|
||||
assert((min - max) != 0);
|
||||
|
||||
mValue = (max + min) / 2;
|
||||
|
||||
//calculate move scale
|
||||
mMoveScale = ((max - min) * 0.0007f) / increment;
|
||||
|
||||
setSize(Vector2u(128, 32));
|
||||
}
|
||||
|
||||
bool SliderComponent::input(InputConfig* config, Input input)
|
||||
{
|
||||
if(config->isMappedTo("left", input))
|
||||
{
|
||||
if(input.value)
|
||||
mMoveRate = -mIncrement;
|
||||
else
|
||||
mMoveRate = 0;
|
||||
|
||||
//setting mRepeatWaitTimer to 0 will trigger an initial move in our update method
|
||||
mRepeatWaitTimer = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
if(config->isMappedTo("right", input))
|
||||
{
|
||||
if(input.value)
|
||||
mMoveRate = mIncrement;
|
||||
else
|
||||
mMoveRate = 0;
|
||||
|
||||
mRepeatWaitTimer = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return GuiComponent::input(config, input);
|
||||
}
|
||||
|
||||
void SliderComponent::update(int deltaTime)
|
||||
{
|
||||
if(mMoveRate != 0)
|
||||
{
|
||||
if(mRepeatWaitTimer == 0)
|
||||
mValue += mMoveRate;
|
||||
else if(mRepeatWaitTimer >= 450)
|
||||
mValue += mMoveRate * deltaTime * mMoveScale;
|
||||
|
||||
if(mValue < mMin)
|
||||
mValue = mMin;
|
||||
if(mValue > mMax)
|
||||
mValue = mMax;
|
||||
|
||||
if(mRepeatWaitTimer < 450)
|
||||
mRepeatWaitTimer += deltaTime;
|
||||
}
|
||||
|
||||
GuiComponent::update(deltaTime);
|
||||
}
|
||||
|
||||
void SliderComponent::onRender()
|
||||
{
|
||||
//render line
|
||||
const int lineWidth = 2;
|
||||
Renderer::drawRect(0, mSize.y / 2 - lineWidth / 2, mSize.x, lineWidth, 0x000000CC);
|
||||
|
||||
//render left end
|
||||
const int capWidth = (int)(mSize.x * 0.03f);
|
||||
Renderer::drawRect(0, 0, capWidth, mSize.y, 0x000000CC);
|
||||
|
||||
//render right end
|
||||
Renderer::drawRect(mSize.x - capWidth, 0, capWidth, mSize.y, 0x000000CC);
|
||||
|
||||
//render our value
|
||||
const int lineLength = mSize.x - capWidth;
|
||||
Renderer::drawRect((int)(((mValue + mMin) / mMax) * lineLength), 0, capWidth, mSize.y, 0x0000FFFF);
|
||||
|
||||
GuiComponent::onRender();
|
||||
}
|
||||
|
||||
void SliderComponent::setSize(Vector2u size)
|
||||
{
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
void SliderComponent::setValue(float value)
|
||||
{
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
float SliderComponent::getValue()
|
||||
{
|
||||
return mValue;
|
||||
}
|
28
src/components/SliderComponent.h
Normal file
28
src/components/SliderComponent.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include "../GuiComponent.h"
|
||||
|
||||
class SliderComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
//Minimum value (far left of the slider), maximum value (far right of the slider), increment size (how much just pressing L/R moves by).
|
||||
SliderComponent(Window* window, float min, float max, float increment);
|
||||
|
||||
void setValue(float val);
|
||||
float getValue();
|
||||
|
||||
bool input(InputConfig* config, Input input) override;
|
||||
void update(int deltaTime) override;
|
||||
void onRender() override;
|
||||
|
||||
void setSize(Vector2u size);
|
||||
|
||||
private:
|
||||
float mMin, mMax;
|
||||
float mValue;
|
||||
float mIncrement;
|
||||
float mMoveScale;
|
||||
int mRepeatWaitTimer;
|
||||
|
||||
float mMoveRate;
|
||||
};
|
43
src/components/SwitchComponent.cpp
Normal file
43
src/components/SwitchComponent.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include "SwitchComponent.h"
|
||||
#include "../Renderer.h"
|
||||
#include "../Font.h"
|
||||
|
||||
SwitchComponent::SwitchComponent(Window* window, bool state) : GuiComponent(window), mState(state)
|
||||
{
|
||||
//mSize = Vector2u((unsigned int)(Renderer::getScreenWidth() * 0.05),
|
||||
// (unsigned int)(Renderer::getScreenHeight() * 0.05));
|
||||
|
||||
Renderer::getDefaultFont(Renderer::MEDIUM)->sizeText("OFF", (int*)&mSize.x, (int*)&mSize.y);
|
||||
}
|
||||
|
||||
bool SwitchComponent::input(InputConfig* config, Input input)
|
||||
{
|
||||
if(config->isMappedTo("a", input) && input.value)
|
||||
{
|
||||
mState = !mState;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SwitchComponent::onRender()
|
||||
{
|
||||
Renderer::pushClipRect(getGlobalOffset(), getSize());
|
||||
|
||||
Renderer::drawText(mState ? "ON" : "OFF", 0, 0, mState ? 0x00FF00FF : 0xFF0000FF, Renderer::getDefaultFont(Renderer::MEDIUM));
|
||||
|
||||
Renderer::popClipRect();
|
||||
|
||||
GuiComponent::onRender();
|
||||
}
|
||||
|
||||
bool SwitchComponent::getState()
|
||||
{
|
||||
return mState;
|
||||
}
|
||||
|
||||
void SwitchComponent::setState(bool state)
|
||||
{
|
||||
mState = state;
|
||||
}
|
18
src/components/SwitchComponent.h
Normal file
18
src/components/SwitchComponent.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "../GuiComponent.h"
|
||||
|
||||
class SwitchComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
SwitchComponent(Window* window, bool state = false);
|
||||
|
||||
bool input(InputConfig* config, Input input) override;
|
||||
void onRender() override;
|
||||
|
||||
bool getState();
|
||||
void setState(bool state);
|
||||
|
||||
private:
|
||||
bool mState;
|
||||
};
|
84
src/components/TextComponent.cpp
Normal file
84
src/components/TextComponent.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include "TextComponent.h"
|
||||
#include "../Renderer.h"
|
||||
#include "../Log.h"
|
||||
|
||||
TextComponent::TextComponent(Window* window) : GuiComponent(window), mFont(NULL), mColor(0x000000FF), mAutoCalcExtent(true)
|
||||
{
|
||||
}
|
||||
|
||||
TextComponent::TextComponent(Window* window, const std::string& text, Font* font, Vector2i pos, Vector2u size) : GuiComponent(window),
|
||||
mFont(NULL), mColor(0x000000FF), mAutoCalcExtent(true)
|
||||
{
|
||||
setText(text);
|
||||
setFont(font);
|
||||
setBox(pos, size);
|
||||
}
|
||||
|
||||
void TextComponent::setBox(Vector2i pos, Vector2u size)
|
||||
{
|
||||
setOffset(pos);
|
||||
setExtent(size);
|
||||
}
|
||||
|
||||
void TextComponent::setExtent(Vector2u size)
|
||||
{
|
||||
if(size == Vector2u(0, 0))
|
||||
{
|
||||
mAutoCalcExtent = true;
|
||||
calculateExtent();
|
||||
}else{
|
||||
mAutoCalcExtent = false;
|
||||
mSize = size;
|
||||
}
|
||||
}
|
||||
|
||||
void TextComponent::setFont(Font* font)
|
||||
{
|
||||
mFont = font;
|
||||
|
||||
if(mAutoCalcExtent)
|
||||
calculateExtent();
|
||||
}
|
||||
|
||||
void TextComponent::setColor(unsigned int color)
|
||||
{
|
||||
mColor = color;
|
||||
}
|
||||
|
||||
void TextComponent::setText(const std::string& text)
|
||||
{
|
||||
mText = text;
|
||||
|
||||
if(mAutoCalcExtent)
|
||||
calculateExtent();
|
||||
}
|
||||
|
||||
void TextComponent::onRender()
|
||||
{
|
||||
Font* font = (mFont ? mFont : Renderer::getDefaultFont(Renderer::MEDIUM));
|
||||
if(font == NULL)
|
||||
{
|
||||
LOG(LogError) << "TextComponent can't get a valid font!";
|
||||
return;
|
||||
}
|
||||
|
||||
Renderer::pushClipRect(getGlobalOffset(), getSize());
|
||||
|
||||
Renderer::drawWrappedText(mText, 0, 0, mSize.x, mColor, font);
|
||||
|
||||
Renderer::popClipRect();
|
||||
|
||||
GuiComponent::onRender();
|
||||
}
|
||||
|
||||
void TextComponent::calculateExtent()
|
||||
{
|
||||
Font* font = (mFont ? mFont : Renderer::getDefaultFont(Renderer::MEDIUM));
|
||||
if(font == NULL)
|
||||
{
|
||||
LOG(LogError) << "TextComponent can't get a valid font!";
|
||||
return;
|
||||
}
|
||||
|
||||
font->sizeText(mText, (int*)&mSize.x, (int*)&mSize.y);
|
||||
}
|
30
src/components/TextComponent.h
Normal file
30
src/components/TextComponent.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef _TEXTCOMPONENT_H_
|
||||
#define _TEXTCOMPONENT_H_
|
||||
|
||||
#include "../GuiComponent.h"
|
||||
#include "../Font.h"
|
||||
|
||||
class TextComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
TextComponent(Window* window);
|
||||
TextComponent(Window* window, const std::string& text, Font* font, Vector2i pos, Vector2u size);
|
||||
|
||||
void setFont(Font* font);
|
||||
void setBox(Vector2i pos, Vector2u size);
|
||||
void setExtent(Vector2u size); //Use Vector2u(0, 0) to automatically generate extent.
|
||||
void setText(const std::string& text);
|
||||
void setColor(unsigned int color);
|
||||
|
||||
void onRender();
|
||||
|
||||
private:
|
||||
void calculateExtent();
|
||||
|
||||
unsigned int mColor;
|
||||
Font* mFont;
|
||||
bool mAutoCalcExtent;
|
||||
std::string mText;
|
||||
};
|
||||
|
||||
#endif
|
405
src/components/TextListComponent.h
Normal file
405
src/components/TextListComponent.h
Normal file
|
@ -0,0 +1,405 @@
|
|||
#ifndef _TEXTLISTCOMPONENT_H_
|
||||
#define _TEXTLISTCOMPONENT_H_
|
||||
|
||||
#include "../Renderer.h"
|
||||
#include "../Font.h"
|
||||
#include "../GuiComponent.h"
|
||||
#include "../InputManager.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "../Sound.h"
|
||||
|
||||
#define MARQUEE_DELAY 900
|
||||
#define MARQUEE_SPEED 16
|
||||
#define MARQUEE_RATE 3
|
||||
|
||||
//A graphical list. Supports multiple colors for rows and scrolling.
|
||||
template <typename T>
|
||||
class TextListComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
TextListComponent(Window* window, int offsetX, int offsetY, Font* font);
|
||||
virtual ~TextListComponent();
|
||||
|
||||
bool input(InputConfig* config, Input input);
|
||||
void update(int deltaTime);
|
||||
|
||||
void addObject(std::string name, T obj, unsigned int color = 0xFF0000);
|
||||
void clear();
|
||||
|
||||
std::string getSelectedName();
|
||||
T getSelectedObject();
|
||||
int getSelection();
|
||||
void stopScrolling();
|
||||
bool isScrolling();
|
||||
|
||||
void setSelectorColor(unsigned int selectorColor);
|
||||
void setSelectedTextColor(unsigned int selectedColor);
|
||||
void setCentered(bool centered);
|
||||
void setScrollSound(std::shared_ptr<Sound> & sound);
|
||||
void setTextOffsetX(int textoffsetx);
|
||||
|
||||
int getObjectCount();
|
||||
T getObject(int i);
|
||||
void setSelection(int i);
|
||||
|
||||
void setFont(Font* f);
|
||||
|
||||
protected:
|
||||
void onRender();
|
||||
|
||||
private:
|
||||
static const int SCROLLDELAY = 507;
|
||||
static const int SCROLLTIME = 200;
|
||||
|
||||
void scroll(); //helper method, scrolls in whatever direction scrollDir is
|
||||
void setScrollDir(int val); //helper method, set mScrollDir as well as reset marquee stuff
|
||||
|
||||
int mScrollDir, mScrollAccumulator;
|
||||
bool mScrolling;
|
||||
|
||||
int mMarqueeOffset;
|
||||
int mMarqueeTime;
|
||||
|
||||
Font* mFont;
|
||||
unsigned int mSelectorColor, mSelectedTextColorOverride;
|
||||
bool mDrawCentered;
|
||||
|
||||
int mTextOffsetX;
|
||||
|
||||
struct ListRow
|
||||
{
|
||||
std::string name;
|
||||
T object;
|
||||
unsigned int color;
|
||||
};
|
||||
|
||||
std::vector<ListRow> mRowVector;
|
||||
int mSelection;
|
||||
std::shared_ptr<Sound> mScrollSound;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
TextListComponent<T>::TextListComponent(Window* window, int offsetX, int offsetY, Font* font) : GuiComponent(window)
|
||||
{
|
||||
mSelection = 0;
|
||||
mScrollDir = 0;
|
||||
mScrolling = 0;
|
||||
mScrollAccumulator = 0;
|
||||
|
||||
setOffset(Vector2i(offsetX, offsetY));
|
||||
|
||||
mSize = Vector2u(Renderer::getScreenWidth() - getOffset().x, Renderer::getScreenHeight() - getOffset().y);
|
||||
mMarqueeOffset = 0;
|
||||
mMarqueeTime = -MARQUEE_DELAY;
|
||||
mTextOffsetX = 0;
|
||||
|
||||
mFont = font;
|
||||
mSelectorColor = 0x000000FF;
|
||||
mSelectedTextColorOverride = 0;
|
||||
mScrollSound = NULL;
|
||||
mDrawCentered = true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TextListComponent<T>::~TextListComponent()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TextListComponent<T>::onRender()
|
||||
{
|
||||
const int cutoff = 0;
|
||||
const int entrySize = mFont->getHeight() + 5;
|
||||
|
||||
int startEntry = 0;
|
||||
|
||||
//number of entries that can fit on the screen simultaniously
|
||||
int screenCount = (Renderer::getScreenHeight() - cutoff) / entrySize;
|
||||
//screenCount -= 1;
|
||||
|
||||
if((int)mRowVector.size() >= screenCount)
|
||||
{
|
||||
startEntry = mSelection - (int)(screenCount * 0.5);
|
||||
if(startEntry < 0)
|
||||
startEntry = 0;
|
||||
if(startEntry >= (int)mRowVector.size() - screenCount)
|
||||
startEntry = mRowVector.size() - screenCount;
|
||||
}
|
||||
|
||||
int y = cutoff;
|
||||
|
||||
if(mRowVector.size() == 0)
|
||||
{
|
||||
Renderer::drawCenteredText("The list is empty.", 0, y, 0xFF0000FF, mFont);
|
||||
return;
|
||||
}
|
||||
|
||||
int listCutoff = startEntry + screenCount;
|
||||
if(listCutoff > (int)mRowVector.size())
|
||||
listCutoff = mRowVector.size();
|
||||
|
||||
Renderer::pushClipRect(getGlobalOffset(), getSize());
|
||||
|
||||
for(int i = startEntry; i < listCutoff; i++)
|
||||
{
|
||||
//draw selector bar
|
||||
if(mSelection == i)
|
||||
{
|
||||
Renderer::drawRect(0, y, getSize().x, mFont->getHeight(), mSelectorColor);
|
||||
}
|
||||
|
||||
ListRow row = mRowVector.at((unsigned int)i);
|
||||
|
||||
int x = mTextOffsetX - (mSelection == i ? mMarqueeOffset : 0);
|
||||
unsigned int color = (mSelection == i && mSelectedTextColorOverride != 0) ? mSelectedTextColorOverride : row.color;
|
||||
|
||||
if(mDrawCentered)
|
||||
Renderer::drawCenteredText(row.name, x, y, color, mFont);
|
||||
else
|
||||
Renderer::drawText(row.name, x, y, color, mFont);
|
||||
|
||||
y += entrySize;
|
||||
}
|
||||
|
||||
Renderer::popClipRect();
|
||||
|
||||
GuiComponent::onRender();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool TextListComponent<T>::input(InputConfig* config, Input input)
|
||||
{
|
||||
if(mRowVector.size() > 0)
|
||||
{
|
||||
if(input.value != 0)
|
||||
{
|
||||
if(config->isMappedTo("down", input))
|
||||
{
|
||||
setScrollDir(1);
|
||||
scroll();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(config->isMappedTo("up", input))
|
||||
{
|
||||
setScrollDir(-1);
|
||||
scroll();
|
||||
return true;
|
||||
}
|
||||
if(config->isMappedTo("pagedown", input))
|
||||
{
|
||||
setScrollDir(10);
|
||||
scroll();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(config->isMappedTo("pageup", input))
|
||||
{
|
||||
setScrollDir(-10);
|
||||
scroll();
|
||||
return true;
|
||||
}
|
||||
}else{
|
||||
//if((button == InputManager::DOWN && mScrollDir > 0) || (button == InputManager::PAGEDOWN && mScrollDir > 0) || (button == InputManager::UP && mScrollDir < 0) || (button == InputManager::PAGEUP && mScrollDir < 0))
|
||||
if(config->isMappedTo("down", input) || config->isMappedTo("up", input) || config->isMappedTo("pagedown", input) || config->isMappedTo("pageup", input))
|
||||
{
|
||||
stopScrolling();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GuiComponent::input(config, input);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TextListComponent<T>::setScrollDir(int val)
|
||||
{
|
||||
mScrollDir = val;
|
||||
mMarqueeOffset = 0;
|
||||
mMarqueeTime = -MARQUEE_DELAY;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TextListComponent<T>::stopScrolling()
|
||||
{
|
||||
mScrollAccumulator = 0;
|
||||
mScrolling = false;
|
||||
mScrollDir = 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TextListComponent<T>::update(int deltaTime)
|
||||
{
|
||||
if(mScrollDir != 0)
|
||||
{
|
||||
mScrollAccumulator += deltaTime;
|
||||
|
||||
if(!mScrolling)
|
||||
{
|
||||
if(mScrollAccumulator >= SCROLLDELAY)
|
||||
{
|
||||
mScrollAccumulator = SCROLLTIME;
|
||||
mScrolling = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(mScrolling)
|
||||
{
|
||||
mScrollAccumulator += deltaTime;
|
||||
|
||||
while(mScrollAccumulator >= SCROLLTIME)
|
||||
{
|
||||
mScrollAccumulator -= SCROLLTIME;
|
||||
|
||||
scroll();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//if we're not scrolling and this object's text goes outside our size, marquee it!
|
||||
std::string text = getSelectedName();
|
||||
int w;
|
||||
mFont->sizeText(text, &w, NULL);
|
||||
|
||||
//it's long enough to marquee
|
||||
if(w - mMarqueeOffset > (int)getSize().x - 12)
|
||||
{
|
||||
mMarqueeTime += deltaTime;
|
||||
while(mMarqueeTime > MARQUEE_SPEED)
|
||||
{
|
||||
mMarqueeOffset += MARQUEE_RATE;
|
||||
mMarqueeTime -= MARQUEE_SPEED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GuiComponent::update(deltaTime);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TextListComponent<T>::scroll()
|
||||
{
|
||||
mSelection += mScrollDir;
|
||||
|
||||
if(mSelection < 0)
|
||||
{
|
||||
if(mScrollDir < -1)
|
||||
mSelection = 0;
|
||||
else
|
||||
mSelection += mRowVector.size();
|
||||
}
|
||||
if(mSelection >= (int)mRowVector.size())
|
||||
{
|
||||
if(mScrollDir > 1)
|
||||
mSelection = (int)mRowVector.size() - 1;
|
||||
else
|
||||
mSelection -= mRowVector.size();
|
||||
}
|
||||
|
||||
if(mScrollSound)
|
||||
mScrollSound->play();
|
||||
}
|
||||
|
||||
//list management stuff
|
||||
template <typename T>
|
||||
void TextListComponent<T>::addObject(std::string name, T obj, unsigned int color)
|
||||
{
|
||||
ListRow row = {name, obj, color};
|
||||
mRowVector.push_back(row);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TextListComponent<T>::clear()
|
||||
{
|
||||
mRowVector.clear();
|
||||
mSelection = 0;
|
||||
mMarqueeOffset = 0;
|
||||
mMarqueeTime = -MARQUEE_DELAY;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string TextListComponent<T>::getSelectedName()
|
||||
{
|
||||
if((int)mRowVector.size() > mSelection)
|
||||
return mRowVector.at(mSelection).name;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T TextListComponent<T>::getSelectedObject()
|
||||
{
|
||||
if((int)mRowVector.size() > mSelection)
|
||||
return mRowVector.at(mSelection).object;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int TextListComponent<T>::getSelection()
|
||||
{
|
||||
return mSelection;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool TextListComponent<T>::isScrolling()
|
||||
{
|
||||
return mScrollDir != 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TextListComponent<T>::setSelectorColor(unsigned int selectorColor)
|
||||
{
|
||||
mSelectorColor = selectorColor;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TextListComponent<T>::setSelectedTextColor(unsigned int selectedColor)
|
||||
{
|
||||
mSelectedTextColorOverride = selectedColor;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void TextListComponent<T>::setCentered(bool centered)
|
||||
{
|
||||
mDrawCentered = centered;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void TextListComponent<T>::setTextOffsetX(int textoffsetx)
|
||||
{
|
||||
mTextOffsetX = textoffsetx;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int TextListComponent<T>::getObjectCount()
|
||||
{
|
||||
return mRowVector.size();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T TextListComponent<T>::getObject(int i)
|
||||
{
|
||||
return mRowVector.at(i).object;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TextListComponent<T>::setSelection(int i)
|
||||
{
|
||||
mSelection = i;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TextListComponent<T>::setScrollSound(std::shared_ptr<Sound> & sound)
|
||||
{
|
||||
mScrollSound = sound;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TextListComponent<T>::setFont(Font* font)
|
||||
{
|
||||
mFont = font;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,41 +1,41 @@
|
|||
#include "GuiTheme.h"
|
||||
#include "ThemeComponent.h"
|
||||
#include "../MathExp.h"
|
||||
#include <iostream>
|
||||
#include "GuiGameList.h"
|
||||
#include "GuiImage.h"
|
||||
#include "ImageComponent.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <sstream>
|
||||
#include "../Renderer.h"
|
||||
#include "../Log.h"
|
||||
|
||||
unsigned int GuiTheme::getColor(std::string name)
|
||||
unsigned int ThemeComponent::getColor(std::string name)
|
||||
{
|
||||
return mColorMap[name];
|
||||
}
|
||||
|
||||
bool GuiTheme::getBool(std::string name)
|
||||
bool ThemeComponent::getBool(std::string name)
|
||||
{
|
||||
return mBoolMap[name];
|
||||
}
|
||||
|
||||
float GuiTheme::getFloat(std::string name)
|
||||
float ThemeComponent::getFloat(std::string name)
|
||||
{
|
||||
return mFloatMap[name];
|
||||
}
|
||||
|
||||
std::shared_ptr<Sound> & GuiTheme::getSound(std::string name)
|
||||
std::shared_ptr<Sound> & ThemeComponent::getSound(std::string name)
|
||||
{
|
||||
return mSoundMap[name];
|
||||
}
|
||||
|
||||
std::string GuiTheme::getString(std::string name)
|
||||
std::string ThemeComponent::getString(std::string name)
|
||||
{
|
||||
return mStringMap[name];
|
||||
}
|
||||
|
||||
GuiBoxData GuiTheme::getBoxData() { return mBoxData; }
|
||||
GuiBoxData ThemeComponent::getBoxData() { return mBoxData; }
|
||||
|
||||
Font* GuiTheme::getListFont()
|
||||
Font* ThemeComponent::getListFont()
|
||||
{
|
||||
if(mListFont == NULL)
|
||||
return Renderer::getDefaultFont(Renderer::MEDIUM);
|
||||
|
@ -43,7 +43,7 @@ Font* GuiTheme::getListFont()
|
|||
return mListFont;
|
||||
}
|
||||
|
||||
Font* GuiTheme::getDescriptionFont()
|
||||
Font* ThemeComponent::getDescriptionFont()
|
||||
{
|
||||
if(mDescFont == NULL)
|
||||
return Renderer::getDefaultFont(Renderer::SMALL);
|
||||
|
@ -51,7 +51,7 @@ Font* GuiTheme::getDescriptionFont()
|
|||
return mDescFont;
|
||||
}
|
||||
|
||||
Font* GuiTheme::getFastSelectFont()
|
||||
Font* ThemeComponent::getFastSelectFont()
|
||||
{
|
||||
if(mFastSelectFont == NULL)
|
||||
return Renderer::getDefaultFont(Renderer::LARGE);
|
||||
|
@ -59,7 +59,7 @@ Font* GuiTheme::getFastSelectFont()
|
|||
return mFastSelectFont;
|
||||
}
|
||||
|
||||
GuiTheme::GuiTheme(Window* window, bool detailed, std::string path) : Gui(window)
|
||||
ThemeComponent::ThemeComponent(Window* window, bool detailed, std::string path) : GuiComponent(window)
|
||||
{
|
||||
mDetailed = detailed;
|
||||
|
||||
|
@ -84,12 +84,12 @@ GuiTheme::GuiTheme(Window* window, bool detailed, std::string path) : Gui(window
|
|||
readXML(path);
|
||||
}
|
||||
|
||||
GuiTheme::~GuiTheme()
|
||||
ThemeComponent::~ThemeComponent()
|
||||
{
|
||||
deleteComponents();
|
||||
}
|
||||
|
||||
void GuiTheme::setDefaults()
|
||||
void ThemeComponent::setDefaults()
|
||||
{
|
||||
mColorMap["primary"] = 0x0000FFFF;
|
||||
mColorMap["secondary"] = 0x00FF00FF;
|
||||
|
@ -144,14 +144,14 @@ void GuiTheme::setDefaults()
|
|||
}
|
||||
}
|
||||
|
||||
void GuiTheme::deleteComponents()
|
||||
void ThemeComponent::deleteComponents()
|
||||
{
|
||||
for(unsigned int i = 0; i < mComponentVector.size(); i++)
|
||||
for(unsigned int i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
delete mComponentVector.at(i);
|
||||
delete getChild(i);
|
||||
}
|
||||
|
||||
mComponentVector.clear();
|
||||
clearChildren();
|
||||
|
||||
//deletes fonts if any were created
|
||||
setDefaults();
|
||||
|
@ -159,7 +159,7 @@ void GuiTheme::deleteComponents()
|
|||
|
||||
|
||||
|
||||
void GuiTheme::readXML(std::string path)
|
||||
void ThemeComponent::readXML(std::string path)
|
||||
{
|
||||
if(mPath == path)
|
||||
return;
|
||||
|
@ -264,11 +264,11 @@ void GuiTheme::readXML(std::string path)
|
|||
}
|
||||
|
||||
//recursively creates components
|
||||
void GuiTheme::createComponentChildren(pugi::xml_node node, Gui* parent)
|
||||
void ThemeComponent::createComponentChildren(pugi::xml_node node, GuiComponent* parent)
|
||||
{
|
||||
for(pugi::xml_node data = node.child("component"); data; data = data.next_sibling("component"))
|
||||
{
|
||||
Gui* nextComp = createElement(data, parent);
|
||||
GuiComponent* nextComp = createElement(data, parent);
|
||||
|
||||
if(nextComp)
|
||||
createComponentChildren(data, nextComp);
|
||||
|
@ -276,7 +276,7 @@ void GuiTheme::createComponentChildren(pugi::xml_node node, Gui* parent)
|
|||
}
|
||||
|
||||
//takes an XML element definition and creates an object from it
|
||||
Gui* GuiTheme::createElement(pugi::xml_node data, Gui* parent)
|
||||
GuiComponent* ThemeComponent::createElement(pugi::xml_node data, GuiComponent* parent)
|
||||
{
|
||||
std::string type = data.child("type").text().get();
|
||||
|
||||
|
@ -315,12 +315,12 @@ Gui* GuiTheme::createElement(pugi::xml_node data, Gui* parent)
|
|||
float ox = strToFloat(originX);
|
||||
float oy = strToFloat(originY);
|
||||
|
||||
GuiImage* comp = new GuiImage(mWindow, x, y, "", w, h, true);
|
||||
ImageComponent* comp = new ImageComponent(mWindow, x, y, "", w, h, true);
|
||||
comp->setOrigin(ox, oy);
|
||||
comp->setTiling(tiled);
|
||||
comp->setImage(path);
|
||||
|
||||
mComponentVector.push_back(comp);
|
||||
addChild(comp);
|
||||
return comp;
|
||||
}
|
||||
|
||||
|
@ -330,8 +330,11 @@ Gui* GuiTheme::createElement(pugi::xml_node data, Gui* parent)
|
|||
}
|
||||
|
||||
//expands a file path (./ becomes the directory of this theme file, ~/ becomes $HOME/)
|
||||
std::string GuiTheme::expandPath(std::string path)
|
||||
std::string ThemeComponent::expandPath(std::string path)
|
||||
{
|
||||
if(path.empty())
|
||||
return "";
|
||||
|
||||
if(path[0] == '~')
|
||||
path = getHomePath() + path.substr(1, path.length() - 1);
|
||||
else if(path[0] == '.')
|
||||
|
@ -341,7 +344,7 @@ std::string GuiTheme::expandPath(std::string path)
|
|||
}
|
||||
|
||||
//takes a string containing a mathematical expression (possibly including variables) and resolves it to a float value
|
||||
float GuiTheme::resolveExp(std::string str, float defaultVal)
|
||||
float ThemeComponent::resolveExp(std::string str, float defaultVal)
|
||||
{
|
||||
if(str.empty())
|
||||
return defaultVal;
|
||||
|
@ -357,7 +360,7 @@ float GuiTheme::resolveExp(std::string str, float defaultVal)
|
|||
}
|
||||
|
||||
//takes a string of hex and resolves it to an integer
|
||||
unsigned int GuiTheme::resolveColor(std::string str, unsigned int defaultColor)
|
||||
unsigned int ThemeComponent::resolveColor(std::string str, unsigned int defaultColor)
|
||||
{
|
||||
if(str.empty())
|
||||
return defaultColor;
|
||||
|
@ -381,7 +384,7 @@ unsigned int GuiTheme::resolveColor(std::string str, unsigned int defaultColor)
|
|||
}
|
||||
|
||||
//splits a string in two at the first instance of the delimiter
|
||||
void GuiTheme::splitString(std::string str, char delim, std::string* before, std::string* after)
|
||||
void ThemeComponent::splitString(std::string str, char delim, std::string* before, std::string* after)
|
||||
{
|
||||
if(str.empty())
|
||||
return;
|
||||
|
@ -397,7 +400,7 @@ void GuiTheme::splitString(std::string str, char delim, std::string* before, std
|
|||
}
|
||||
|
||||
//converts a string to a float
|
||||
float GuiTheme::strToFloat(std::string str, float defaultVal)
|
||||
float ThemeComponent::strToFloat(std::string str, float defaultVal)
|
||||
{
|
||||
if(str.empty())
|
||||
return defaultVal;
|
||||
|
@ -409,7 +412,7 @@ float GuiTheme::strToFloat(std::string str, float defaultVal)
|
|||
return ret;
|
||||
}
|
||||
|
||||
Font* GuiTheme::resolveFont(pugi::xml_node node, std::string defaultPath, unsigned int defaultSize)
|
||||
Font* ThemeComponent::resolveFont(pugi::xml_node node, std::string defaultPath, unsigned int defaultSize)
|
||||
{
|
||||
if(!node)
|
||||
return NULL;
|
||||
|
@ -430,34 +433,21 @@ Font* GuiTheme::resolveFont(pugi::xml_node node, std::string defaultPath, unsign
|
|||
return new Font(path, size);
|
||||
}
|
||||
|
||||
void GuiTheme::render()
|
||||
void ThemeComponent::init()
|
||||
{
|
||||
for(unsigned int i = 0; i < mComponentVector.size(); i++)
|
||||
{
|
||||
mComponentVector.at(i)->render();
|
||||
}
|
||||
}
|
||||
|
||||
void GuiTheme::init()
|
||||
{
|
||||
for(unsigned int i = 0; i < mComponentVector.size(); i++)
|
||||
{
|
||||
mComponentVector.at(i)->init();
|
||||
}
|
||||
|
||||
//fonts are special
|
||||
if(mListFont) mListFont->init();
|
||||
if(mDescFont) mDescFont->init();
|
||||
if(mFastSelectFont) mFastSelectFont->init();
|
||||
|
||||
GuiComponent::init();
|
||||
}
|
||||
|
||||
void GuiTheme::deinit()
|
||||
void ThemeComponent::deinit()
|
||||
{
|
||||
for(unsigned int i = 0; i < mComponentVector.size(); i++)
|
||||
{
|
||||
mComponentVector.at(i)->deinit();
|
||||
}
|
||||
GuiComponent::deinit();
|
||||
|
||||
//fonts are special
|
||||
if(mListFont) mListFont->deinit();
|
||||
if(mDescFont) mDescFont->deinit();
|
||||
if(mFastSelectFont) mFastSelectFont->deinit();
|
|
@ -1,27 +1,25 @@
|
|||
#ifndef _GUITHEME_H_
|
||||
#define _GUITHEME_H_
|
||||
#ifndef _THEMECOMPONENT_H_
|
||||
#define _THEMECOMPONENT_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "../Gui.h"
|
||||
#include "../GuiComponent.h"
|
||||
#include "../pugiXML/pugixml.hpp"
|
||||
#include "GuiBox.h"
|
||||
#include "../AudioManager.h"
|
||||
#include "../Font.h"
|
||||
|
||||
//This class loads an XML-defined list of Guis.
|
||||
class GuiTheme : public Gui
|
||||
//This class loads an XML-defined list of GuiComponents.
|
||||
class ThemeComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
GuiTheme(Window* window, bool detailed, std::string path = "");
|
||||
~GuiTheme();
|
||||
ThemeComponent(Window* window, bool detailed, std::string path = "");
|
||||
virtual ~ThemeComponent();
|
||||
|
||||
void readXML(std::string path);
|
||||
|
||||
GuiBoxData getBoxData();
|
||||
|
||||
void render();
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
|
||||
|
@ -34,11 +32,12 @@ public:
|
|||
Font* getListFont();
|
||||
Font* getDescriptionFont();
|
||||
Font* getFastSelectFont();
|
||||
|
||||
private:
|
||||
void setDefaults();
|
||||
void deleteComponents();
|
||||
void createComponentChildren(pugi::xml_node node, Gui* parent);
|
||||
Gui* createElement(pugi::xml_node data, Gui* parent);
|
||||
void createComponentChildren(pugi::xml_node node, GuiComponent* parent);
|
||||
GuiComponent* createElement(pugi::xml_node data, GuiComponent* parent);
|
||||
|
||||
//utility functions
|
||||
std::string expandPath(std::string path);
|
||||
|
@ -48,7 +47,6 @@ private:
|
|||
float strToFloat(std::string str, float defaultVal = 0.0f);
|
||||
Font* resolveFont(pugi::xml_node node, std::string defaultPath, unsigned int defaultSize);
|
||||
|
||||
std::vector<Gui*> mComponentVector;
|
||||
std::string mPath;
|
||||
bool mDetailed;
|
||||
|
||||
|
@ -59,6 +57,7 @@ private:
|
|||
std::map<std::string, std::string> mStringMap;
|
||||
|
||||
GuiBoxData mBoxData;
|
||||
|
||||
Font* mListFont;
|
||||
Font* mDescFont;
|
||||
Font* mFastSelectFont;
|
37
src/main.cpp
37
src/main.cpp
|
@ -1,4 +1,5 @@
|
|||
//EmulationStation, a graphical front-end for ROM browsing. Created by Alec "Aloshi" Lofquist.
|
||||
//http://www.aloshi.com
|
||||
|
||||
#include <SDL.h>
|
||||
#include <iostream>
|
||||
|
@ -12,6 +13,8 @@
|
|||
#include "platform.h"
|
||||
#include "Log.h"
|
||||
#include "Window.h"
|
||||
#include "EmulationStation.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#ifdef _RPI_
|
||||
#include <bcm_host.h>
|
||||
|
@ -19,15 +22,6 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
//these can be set by command-line arguments
|
||||
bool PARSEGAMELISTONLY = false;
|
||||
bool IGNOREGAMELIST = false;
|
||||
bool DRAWFRAMERATE = false;
|
||||
bool DONTSHOWEXIT = false;
|
||||
bool DEBUG = false;
|
||||
bool WINDOWED = false;
|
||||
unsigned int DIMTIME = 30*1000;
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
|
@ -48,27 +42,27 @@ int main(int argc, char* argv[])
|
|||
i++; //skip the argument value
|
||||
}else if(strcmp(argv[i], "--gamelist-only") == 0)
|
||||
{
|
||||
PARSEGAMELISTONLY = true;
|
||||
Settings::getInstance()->setBool("PARSEGAMELISTONLY", true);
|
||||
}else if(strcmp(argv[i], "--ignore-gamelist") == 0)
|
||||
{
|
||||
IGNOREGAMELIST = true;
|
||||
Settings::getInstance()->setBool("IGNOREGAMELIST", true);
|
||||
}else if(strcmp(argv[i], "--draw-framerate") == 0)
|
||||
{
|
||||
DRAWFRAMERATE = true;
|
||||
Settings::getInstance()->setBool("DRAWFRAMERATE", true);
|
||||
}else if(strcmp(argv[i], "--no-exit") == 0)
|
||||
{
|
||||
DONTSHOWEXIT = true;
|
||||
Settings::getInstance()->setBool("DONTSHOWEXIT", true);
|
||||
}else if(strcmp(argv[i], "--debug") == 0)
|
||||
{
|
||||
DEBUG = true;
|
||||
Settings::getInstance()->setBool("DEBUG", true);
|
||||
Log::setReportingLevel(LogDebug);
|
||||
}else if(strcmp(argv[i], "--dimtime") == 0)
|
||||
{
|
||||
DIMTIME = atoi(argv[i + 1]) * 1000;
|
||||
Settings::getInstance()->setInt("DIMTIME", atoi(argv[i + 1]) * 1000);
|
||||
i++; //skip the argument value
|
||||
}else if(strcmp(argv[i], "--windowed") == 0)
|
||||
{
|
||||
WINDOWED = true;
|
||||
Settings::getInstance()->setBool("WINDOWED", true);
|
||||
}else if(strcmp(argv[i], "--help") == 0)
|
||||
{
|
||||
std::cout << "EmulationStation, a graphical front-end for ROM browsing.\n";
|
||||
|
@ -82,7 +76,7 @@ int main(int argc, char* argv[])
|
|||
std::cout << "--debug even more logging\n";
|
||||
std::cout << "--dimtime [seconds] time to wait before dimming the screen (default 30, use 0 for never)\n";
|
||||
|
||||
#ifdef _DESKTOP_
|
||||
#ifdef USE_OPENGL_DESKTOP
|
||||
std::cout << "--windowed not fullscreen\n";
|
||||
#endif
|
||||
|
||||
|
@ -110,6 +104,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
//start the logger
|
||||
Log::open();
|
||||
LOG(LogInfo) << "EmulationStation - " << PROGRAM_VERSION_STRING;
|
||||
|
||||
//the renderer also takes care of setting up SDL for input and sound
|
||||
bool renderInit = Renderer::init(width, height);
|
||||
|
@ -195,9 +190,10 @@ int main(int argc, char* argv[])
|
|||
lastTime = curTime;
|
||||
|
||||
window.update(deltaTime);
|
||||
Renderer::swapBuffers(); //swap here so we can read the last screen state during updates (see ImageComponent::copyScreen())
|
||||
window.render();
|
||||
|
||||
if(DRAWFRAMERATE)
|
||||
if(Settings::getInstance()->getBool("DRAWFRAMERATE"))
|
||||
{
|
||||
static int timeElapsed = 0;
|
||||
static int nrOfFrames = 0;
|
||||
|
@ -221,14 +217,15 @@ int main(int argc, char* argv[])
|
|||
//sleeping entails setting a flag to start skipping frames
|
||||
//and initially drawing a black semi-transparent rect to dim the screen
|
||||
timeSinceLastEvent += deltaTime;
|
||||
if(timeSinceLastEvent >= DIMTIME && DIMTIME != 0)
|
||||
if(timeSinceLastEvent >= (unsigned int)Settings::getInstance()->getInt("DIMTIME") && Settings::getInstance()->getInt("DIMTIME") != 0)
|
||||
{
|
||||
sleeping = true;
|
||||
timeSinceLastEvent = 0;
|
||||
Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0x000000A0);
|
||||
Renderer::swapBuffers();
|
||||
}
|
||||
|
||||
Renderer::swapBuffers();
|
||||
|
||||
Log::flush();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@ std::string getHomePath()
|
|||
if (envDir != nullptr && envPath != nullptr) {
|
||||
homePath = envDir;
|
||||
homePath += envPath;
|
||||
|
||||
for(unsigned int i = 0; i < homePath.length(); i++)
|
||||
if(homePath[i] == '\\')
|
||||
homePath[i] = '/';
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
|
Loading…
Reference in a new issue