Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Bim Overbohm 2013-06-24 11:57:19 +02:00
commit e809414558
65 changed files with 2542 additions and 1426 deletions

13
.gitignore vendored
View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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
============

View file

@ -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;
}

View file

@ -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

View file

@ -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]))
{

View file

@ -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()

View file

@ -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++)
{

View file

@ -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; }

View file

@ -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
View 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
View 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

View file

@ -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();

View file

@ -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];

View file

@ -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);

View file

@ -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

View file

@ -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
View 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
View 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

View file

@ -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
View 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

View file

@ -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";

View file

@ -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

View file

@ -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, "/");

View 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);
}
}

View file

@ -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

View 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;
}

View 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);

View file

@ -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);
}
}

View file

@ -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()

View file

@ -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

View file

@ -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()

View file

@ -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();

View file

@ -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)

View file

@ -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;

View file

@ -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);
}

View file

@ -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

View file

@ -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())

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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()
}

View file

@ -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);

View 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();
}

View 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

View file

@ -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();
}

View file

@ -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;
};

View 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;
}

View 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;
};

View 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;
}

View 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;
};

View 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);
}

View 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

View 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

View file

@ -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();

View file

@ -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;

View file

@ -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();
}

View file

@ -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