mirror of
https://github.com/Maschell/GX2_GUI_Template.git
synced 2024-11-25 01:16:54 +01:00
First commit, have fun!
This commit is contained in:
parent
fe63745a14
commit
2bf59b2557
2
.gitignore
vendored
2
.gitignore
vendored
@ -45,3 +45,5 @@ $RECYCLE.BIN/
|
|||||||
Network Trash Folder
|
Network Trash Folder
|
||||||
Temporary Items
|
Temporary Items
|
||||||
.apdisk
|
.apdisk
|
||||||
|
|
||||||
|
/build
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "src/dynamic_libs"]
|
||||||
|
path = src/dynamic_libs
|
||||||
|
url = https://github.com/Maschell/dynamic_libs
|
281
GX2_template.cbp
Normal file
281
GX2_template.cbp
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||||
|
<CodeBlocks_project_file>
|
||||||
|
<FileVersion major="1" minor="6" />
|
||||||
|
<Project>
|
||||||
|
<Option title="GX2_template" />
|
||||||
|
<Option makefile_is_custom="1" />
|
||||||
|
<Option pch_mode="2" />
|
||||||
|
<Option compiler="ppc-gcc" />
|
||||||
|
<Build>
|
||||||
|
<Target title="build">
|
||||||
|
<Option output="bin/Release/GX2_template" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option object_output="obj/Release/" />
|
||||||
|
<Option type="1" />
|
||||||
|
<Option compiler="ppc-gcc" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-O2" />
|
||||||
|
</Compiler>
|
||||||
|
<MakeCommands>
|
||||||
|
<Build command="$make -f $makefile $target -j8" />
|
||||||
|
<CompileFile command="$make -f $makefile $file" />
|
||||||
|
<Clean command="make clean" />
|
||||||
|
<DistClean command="$make -f $makefile distclean$target" />
|
||||||
|
<AskRebuildNeeded command="$make -q -f $makefile $target" />
|
||||||
|
<SilentBuild command="$make -f $makefile $target -j8 > $(CMD_NULL)" />
|
||||||
|
</MakeCommands>
|
||||||
|
</Target>
|
||||||
|
</Build>
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-Wall" />
|
||||||
|
</Compiler>
|
||||||
|
<Unit filename="build/Application.d" />
|
||||||
|
<Unit filename="build/AsyncDeleter.d" />
|
||||||
|
<Unit filename="build/BufferCircle.d" />
|
||||||
|
<Unit filename="build/CFile.d" />
|
||||||
|
<Unit filename="build/CVideo.d" />
|
||||||
|
<Unit filename="build/ColorShader.d" />
|
||||||
|
<Unit filename="build/DirList.d" />
|
||||||
|
<Unit filename="build/FXAAShader.d" />
|
||||||
|
<Unit filename="build/FreeTypeGX.d" />
|
||||||
|
<Unit filename="build/GameBgImage.d" />
|
||||||
|
<Unit filename="build/GameIcon.d" />
|
||||||
|
<Unit filename="build/GridBackground.d" />
|
||||||
|
<Unit filename="build/GuiButton.d" />
|
||||||
|
<Unit filename="build/GuiCheckBox.d" />
|
||||||
|
<Unit filename="build/GuiDragListener.d" />
|
||||||
|
<Unit filename="build/GuiElement.d" />
|
||||||
|
<Unit filename="build/GuiFrame.d" />
|
||||||
|
<Unit filename="build/GuiImage.d" />
|
||||||
|
<Unit filename="build/GuiImageAsync.d" />
|
||||||
|
<Unit filename="build/GuiImageData.d" />
|
||||||
|
<Unit filename="build/GuiParticleImage.d" />
|
||||||
|
<Unit filename="build/GuiSelectBox.d" />
|
||||||
|
<Unit filename="build/GuiSound.d" />
|
||||||
|
<Unit filename="build/GuiSwitch.d" />
|
||||||
|
<Unit filename="build/GuiText.d" />
|
||||||
|
<Unit filename="build/GuiToggle.d" />
|
||||||
|
<Unit filename="build/GuiTrigger.d" />
|
||||||
|
<Unit filename="build/MainWindow.d" />
|
||||||
|
<Unit filename="build/MainWindowTV.d" />
|
||||||
|
<Unit filename="build/Mp3Decoder.d" />
|
||||||
|
<Unit filename="build/OggDecoder.d" />
|
||||||
|
<Unit filename="build/Resources.d" />
|
||||||
|
<Unit filename="build/Scrollbar.d" />
|
||||||
|
<Unit filename="build/Shader3D.d" />
|
||||||
|
<Unit filename="build/ShaderFractalColor.d" />
|
||||||
|
<Unit filename="build/SoundDecoder.d" />
|
||||||
|
<Unit filename="build/SoundHandler.d" />
|
||||||
|
<Unit filename="build/StringTools.d" />
|
||||||
|
<Unit filename="build/Texture2DShader.d" />
|
||||||
|
<Unit filename="build/WavDecoder.d" />
|
||||||
|
<Unit filename="build/acp_functions.d" />
|
||||||
|
<Unit filename="build/aoc_functions.d" />
|
||||||
|
<Unit filename="build/ax_functions.d" />
|
||||||
|
<Unit filename="build/curl_functions.d" />
|
||||||
|
<Unit filename="build/entry.d" />
|
||||||
|
<Unit filename="build/exception_handler.d" />
|
||||||
|
<Unit filename="build/fs_functions.d" />
|
||||||
|
<Unit filename="build/fs_utils.d" />
|
||||||
|
<Unit filename="build/gx2_functions.d" />
|
||||||
|
<Unit filename="build/logger.d" />
|
||||||
|
<Unit filename="build/main.d" />
|
||||||
|
<Unit filename="build/memory.d" />
|
||||||
|
<Unit filename="build/os_functions.d" />
|
||||||
|
<Unit filename="build/padscore_functions.d" />
|
||||||
|
<Unit filename="build/sd_fat_devoptab.d" />
|
||||||
|
<Unit filename="build/socket_functions.d" />
|
||||||
|
<Unit filename="build/sys_functions.d" />
|
||||||
|
<Unit filename="build/syshid_functions.d" />
|
||||||
|
<Unit filename="build/vpad_functions.d" />
|
||||||
|
<Unit filename="src/Application.cpp" />
|
||||||
|
<Unit filename="src/Application.h" />
|
||||||
|
<Unit filename="src/common/common.h" />
|
||||||
|
<Unit filename="src/common/os_defs.h" />
|
||||||
|
<Unit filename="src/common/types.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/acp_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/dynamic_libs/acp_functions.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/aoc_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/dynamic_libs/aoc_functions.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/ax_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/dynamic_libs/ax_functions.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/curl_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/dynamic_libs/curl_functions.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/fs_defs.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/fs_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/dynamic_libs/fs_functions.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/gx2_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/dynamic_libs/gx2_functions.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/gx2_types.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/os_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/dynamic_libs/os_functions.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/os_types.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/padscore_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/dynamic_libs/padscore_functions.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/socket_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/dynamic_libs/socket_functions.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/sys_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/dynamic_libs/sys_functions.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/syshid_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/dynamic_libs/syshid_functions.h" />
|
||||||
|
<Unit filename="src/dynamic_libs/vpad_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/dynamic_libs/vpad_functions.h" />
|
||||||
|
<Unit filename="src/entry.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/fs/CFile.cpp" />
|
||||||
|
<Unit filename="src/fs/CFile.hpp" />
|
||||||
|
<Unit filename="src/fs/DirList.cpp" />
|
||||||
|
<Unit filename="src/fs/DirList.h" />
|
||||||
|
<Unit filename="src/fs/fs_utils.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/fs/fs_utils.h" />
|
||||||
|
<Unit filename="src/fs/sd_fat_devoptab.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/fs/sd_fat_devoptab.h" />
|
||||||
|
<Unit filename="src/gui/FreeTypeGX.cpp" />
|
||||||
|
<Unit filename="src/gui/FreeTypeGX.h" />
|
||||||
|
<Unit filename="src/gui/GameBgImage.cpp" />
|
||||||
|
<Unit filename="src/gui/GameBgImage.h" />
|
||||||
|
<Unit filename="src/gui/GameIcon.cpp" />
|
||||||
|
<Unit filename="src/gui/GameIcon.h" />
|
||||||
|
<Unit filename="src/gui/GameIconModel.h" />
|
||||||
|
<Unit filename="src/gui/GridBackground.cpp" />
|
||||||
|
<Unit filename="src/gui/GridBackground.h" />
|
||||||
|
<Unit filename="src/gui/Gui.h" />
|
||||||
|
<Unit filename="src/gui/GuiButton.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiButton.h" />
|
||||||
|
<Unit filename="src/gui/GuiCheckBox.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiCheckBox.h" />
|
||||||
|
<Unit filename="src/gui/GuiController.h" />
|
||||||
|
<Unit filename="src/gui/GuiDragListener.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiDragListener.h" />
|
||||||
|
<Unit filename="src/gui/GuiElement.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiElement.h" />
|
||||||
|
<Unit filename="src/gui/GuiFrame.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiFrame.h" />
|
||||||
|
<Unit filename="src/gui/GuiImage.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiImage.h" />
|
||||||
|
<Unit filename="src/gui/GuiImageAsync.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiImageAsync.h" />
|
||||||
|
<Unit filename="src/gui/GuiImageData.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiImageData.h" />
|
||||||
|
<Unit filename="src/gui/GuiMainWindowScreen.h" />
|
||||||
|
<Unit filename="src/gui/GuiParticleImage.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiParticleImage.h" />
|
||||||
|
<Unit filename="src/gui/GuiSelectBox.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiSelectBox.h" />
|
||||||
|
<Unit filename="src/gui/GuiSound.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiSound.h" />
|
||||||
|
<Unit filename="src/gui/GuiSwitch.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiSwitch.h" />
|
||||||
|
<Unit filename="src/gui/GuiText.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiText.h" />
|
||||||
|
<Unit filename="src/gui/GuiToggle.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiToggle.h" />
|
||||||
|
<Unit filename="src/gui/GuiTrigger.cpp" />
|
||||||
|
<Unit filename="src/gui/GuiTrigger.h" />
|
||||||
|
<Unit filename="src/gui/Scrollbar.cpp" />
|
||||||
|
<Unit filename="src/gui/Scrollbar.h" />
|
||||||
|
<Unit filename="src/gui/VPadController.h" />
|
||||||
|
<Unit filename="src/gui/WPadController.h" />
|
||||||
|
<Unit filename="src/gui/sigslot.h" />
|
||||||
|
<Unit filename="src/kernel/kernel_functions.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/kernel/kernel_functions.h" />
|
||||||
|
<Unit filename="src/kernel/kernel_hooks.S" />
|
||||||
|
<Unit filename="src/kernel/syscalls.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/kernel/syscalls.h" />
|
||||||
|
<Unit filename="src/kernel/syscalls_asm.S" />
|
||||||
|
<Unit filename="src/main.cpp" />
|
||||||
|
<Unit filename="src/main.h" />
|
||||||
|
<Unit filename="src/menu/MainWindow.cpp" />
|
||||||
|
<Unit filename="src/menu/MainWindow.h" />
|
||||||
|
<Unit filename="src/menu/MainWindowTV.cpp" />
|
||||||
|
<Unit filename="src/menu/MainWindowTV.h" />
|
||||||
|
<Unit filename="src/resources/Resources.cpp" />
|
||||||
|
<Unit filename="src/resources/Resources.h" />
|
||||||
|
<Unit filename="src/resources/filelist.h" />
|
||||||
|
<Unit filename="src/sounds/BufferCircle.cpp" />
|
||||||
|
<Unit filename="src/sounds/BufferCircle.hpp" />
|
||||||
|
<Unit filename="src/sounds/Mp3Decoder.cpp" />
|
||||||
|
<Unit filename="src/sounds/Mp3Decoder.hpp" />
|
||||||
|
<Unit filename="src/sounds/OggDecoder.cpp" />
|
||||||
|
<Unit filename="src/sounds/OggDecoder.hpp" />
|
||||||
|
<Unit filename="src/sounds/SoundDecoder.cpp" />
|
||||||
|
<Unit filename="src/sounds/SoundDecoder.hpp" />
|
||||||
|
<Unit filename="src/sounds/SoundHandler.cpp" />
|
||||||
|
<Unit filename="src/sounds/SoundHandler.hpp" />
|
||||||
|
<Unit filename="src/sounds/Voice.h" />
|
||||||
|
<Unit filename="src/sounds/WavDecoder.cpp" />
|
||||||
|
<Unit filename="src/sounds/WavDecoder.hpp" />
|
||||||
|
<Unit filename="src/system/AsyncDeleter.cpp" />
|
||||||
|
<Unit filename="src/system/AsyncDeleter.h" />
|
||||||
|
<Unit filename="src/system/CMutex.h" />
|
||||||
|
<Unit filename="src/system/CThread.h" />
|
||||||
|
<Unit filename="src/system/exception_handler.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/system/exception_handler.h" />
|
||||||
|
<Unit filename="src/system/memory.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/system/memory.h" />
|
||||||
|
<Unit filename="src/utils/StringTools.cpp" />
|
||||||
|
<Unit filename="src/utils/StringTools.h" />
|
||||||
|
<Unit filename="src/utils/logger.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/utils/logger.h" />
|
||||||
|
<Unit filename="src/utils/utils.h" />
|
||||||
|
<Unit filename="src/video/CVideo.cpp" />
|
||||||
|
<Unit filename="src/video/CVideo.h" />
|
||||||
|
<Unit filename="src/video/shaders/ColorShader.cpp" />
|
||||||
|
<Unit filename="src/video/shaders/ColorShader.h" />
|
||||||
|
<Unit filename="src/video/shaders/FXAAShader.cpp" />
|
||||||
|
<Unit filename="src/video/shaders/FXAAShader.h" />
|
||||||
|
<Unit filename="src/video/shaders/FetchShader.h" />
|
||||||
|
<Unit filename="src/video/shaders/PixelShader.h" />
|
||||||
|
<Unit filename="src/video/shaders/Shader.h" />
|
||||||
|
<Unit filename="src/video/shaders/Shader3D.cpp" />
|
||||||
|
<Unit filename="src/video/shaders/Shader3D.h" />
|
||||||
|
<Unit filename="src/video/shaders/ShaderFractalColor.cpp" />
|
||||||
|
<Unit filename="src/video/shaders/ShaderFractalColor.h" />
|
||||||
|
<Unit filename="src/video/shaders/Texture2DShader.cpp" />
|
||||||
|
<Unit filename="src/video/shaders/Texture2DShader.h" />
|
||||||
|
<Unit filename="src/video/shaders/VertexShader.h" />
|
||||||
|
<Extensions>
|
||||||
|
<code_completion />
|
||||||
|
<envvars />
|
||||||
|
<debugger />
|
||||||
|
</Extensions>
|
||||||
|
</Project>
|
||||||
|
</CodeBlocks_project_file>
|
674
LICENSE
Normal file
674
LICENSE
Normal file
@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
{one line to give the program's name and a brief idea of what it does.}
|
||||||
|
Copyright (C) {year} {name of author}
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
{project} Copyright (C) {year} {fullname}
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
227
Makefile
Normal file
227
Makefile
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# Clear the implicit built in rules
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
.SUFFIXES:
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(DEVKITPPC)),)
|
||||||
|
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
|
||||||
|
endif
|
||||||
|
ifeq ($(strip $(DEVKITPRO)),)
|
||||||
|
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPRO")
|
||||||
|
endif
|
||||||
|
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
|
||||||
|
export LIBOGC_INC := $(DEVKITPRO)/libogc/include
|
||||||
|
export LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii
|
||||||
|
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
|
||||||
|
|
||||||
|
PREFIX := powerpc-eabi-
|
||||||
|
|
||||||
|
export AS := $(PREFIX)as
|
||||||
|
export CC := $(PREFIX)gcc
|
||||||
|
export CXX := $(PREFIX)g++
|
||||||
|
export AR := $(PREFIX)ar
|
||||||
|
export OBJCOPY := $(PREFIX)objcopy
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# TARGET is the name of the output
|
||||||
|
# BUILD is the directory where object files & intermediate files will be placed
|
||||||
|
# SOURCES is a list of directories containing source code
|
||||||
|
# INCLUDES is a list of directories containing extra header files
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
TARGET := gx2_template
|
||||||
|
BUILD := build
|
||||||
|
BUILD_DBG := $(TARGET)_dbg
|
||||||
|
SOURCES := src \
|
||||||
|
src/common \
|
||||||
|
src/dynamic_libs \
|
||||||
|
src/fs \
|
||||||
|
src/game \
|
||||||
|
src/gui \
|
||||||
|
src/menu \
|
||||||
|
src/resources \
|
||||||
|
src/sounds \
|
||||||
|
src/system \
|
||||||
|
src/utils \
|
||||||
|
src/video \
|
||||||
|
src/video/shaders
|
||||||
|
DATA := data \
|
||||||
|
data/images \
|
||||||
|
data/fonts \
|
||||||
|
data/sounds
|
||||||
|
|
||||||
|
INCLUDES := src
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# options for code generation
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \
|
||||||
|
-O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
|
||||||
|
CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \
|
||||||
|
-O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
|
||||||
|
ASFLAGS := -mregnames
|
||||||
|
LDFLAGS := -nostartfiles -Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r,-wrap,valloc,-wrap,_valloc_r,-wrap,_pvalloc_r,--gc-sections
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
Q := @
|
||||||
|
MAKEFLAGS += --no-print-directory
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# any extra libraries we wish to link with the project
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBS := -lgcc -lgd -lpng -ljpeg -lz -lfreetype -lmad -lvorbisidec
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
# include and lib
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBDIRS := $(CURDIR) \
|
||||||
|
$(DEVKITPPC)/lib \
|
||||||
|
$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# no real need to edit anything past this point unless you need to add additional
|
||||||
|
# rules for different file extensions
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export PROJECTDIR := $(CURDIR)
|
||||||
|
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
|
||||||
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||||
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# automatically build a list of object files for our project
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
FILELIST := $(shell bash ./filelist.sh)
|
||||||
|
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||||
|
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||||
|
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||||
|
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
|
||||||
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||||
|
TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf)))
|
||||||
|
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# use CXX for linking C++ projects, CC for standard C
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(CPPFILES)),)
|
||||||
|
export LD := $(CC)
|
||||||
|
else
|
||||||
|
export LD := $(CXX)
|
||||||
|
endif
|
||||||
|
|
||||||
|
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
|
||||||
|
$(sFILES:.s=.o) $(SFILES:.S=.o) \
|
||||||
|
$(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES))
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# build a list of include paths
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||||
|
-I$(CURDIR)/$(BUILD) -I$(LIBOGC_INC) \
|
||||||
|
-I$(PORTLIBS)/include -I$(PORTLIBS)/include/freetype2
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# build a list of library paths
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
|
||||||
|
-L$(LIBOGC_LIB) -L$(PORTLIBS)/lib
|
||||||
|
|
||||||
|
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||||
|
.PHONY: $(BUILD) clean install
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(BUILD):
|
||||||
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
clean:
|
||||||
|
@echo clean ...
|
||||||
|
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
else
|
||||||
|
|
||||||
|
DEPENDS := $(OFILES:.o=.d)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# main targets
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(OUTPUT).elf: $(OFILES)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# This rule links in binary data with the .jpg extension
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.elf: link.ld $(OFILES)
|
||||||
|
@echo "linking ... $(TARGET).elf"
|
||||||
|
$(Q)$(LD) -n -T $^ $(LDFLAGS) -o ../$(BUILD_DBG).elf $(LIBPATHS) $(LIBS)
|
||||||
|
$(Q)$(OBJCOPY) -S -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@
|
||||||
|
|
||||||
|
../data/loader.bin:
|
||||||
|
$(MAKE) -C ../loader clean
|
||||||
|
$(MAKE) -C ../loader
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.a:
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
@echo $(notdir $@)
|
||||||
|
@rm -f $@
|
||||||
|
@$(AR) -rc $@ $^
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.o: %.cpp
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.o: %.c
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.o: %.S
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.png.o : %.png
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.jpg.o : %.jpg
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.ttf.o : %.ttf
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.bin.o : %.bin
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.wav.o : %.wav
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.mp3.o : %.mp3
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.ogg.o : %.ogg
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||||
|
|
||||||
|
-include $(DEPENDS)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
endif
|
||||||
|
#---------------------------------------------------------------------------------
|
13
README.md
Normal file
13
README.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#GX2_GUI_Template#
|
||||||
|
This a (hopefully clean) template for GX2 (gui) project. [...]
|
||||||
|
|
||||||
|
#Usage#
|
||||||
|
This example with render a white screen and return to the Homewbrew Launcher by pressing the Home button.<br />
|
||||||
|
At menu/MainWindowTV.cpp the magic of drawing the white screen is happening.
|
||||||
|
|
||||||
|
#Building#
|
||||||
|
In order to build this application, you need the custom liboGC and portlibs modified/created by dimok. You can find them on the loadiine_gx2 repo (https://github.com/dimok789/loadiine_gx2/releases/tag/v0.2). Simply put the files in your devkit folder and run the Makefile.
|
||||||
|
|
||||||
|
#Credits#
|
||||||
|
A big thanks goes out to <b>dimok</b> for creating the HBL, the dynamic libs and every stuff he made. The "environment" of this app is copied from HBL. In fact is just a cropped version of the HBL with a few extra GUI Element. So big shoutouts to dimok!
|
||||||
|
|
BIN
data/fonts/font.ttf
Normal file
BIN
data/fonts/font.ttf
Normal file
Binary file not shown.
BIN
data/sounds/bgMusic.ogg
Normal file
BIN
data/sounds/bgMusic.ogg
Normal file
Binary file not shown.
BIN
data/sounds/button_click.mp3
Normal file
BIN
data/sounds/button_click.mp3
Normal file
Binary file not shown.
83
filelist.sh
Normal file
83
filelist.sh
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
#
|
||||||
|
# Automatic resource file list generation
|
||||||
|
# Created by Dimok
|
||||||
|
|
||||||
|
outFile="./src/resources/filelist.h"
|
||||||
|
count_old=$(cat $outFile 2>/dev/null | tr -d '\n\n' | sed 's/[^0-9]*\([0-9]*\).*/\1/')
|
||||||
|
|
||||||
|
count=0
|
||||||
|
if [[ $OSTYPE == darwin* ]];
|
||||||
|
then
|
||||||
|
|
||||||
|
for i in $(gfind ./data/images/ ./data/sounds/ ./data/fonts/ -maxdepth 1 -type f \( ! -printf "%f\n" \) | sort -f)
|
||||||
|
do
|
||||||
|
files[count]=$i
|
||||||
|
count=$((count+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
for i in $(find ./data/images/ ./data/sounds/ ./data/fonts/ -maxdepth 1 -type f \( ! -printf "%f\n" \) | sort -f)
|
||||||
|
do
|
||||||
|
files[count]=$i
|
||||||
|
count=$((count+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$count_old" != "$count" ] || [ ! -f $outFile ]
|
||||||
|
then
|
||||||
|
|
||||||
|
echo "Generating filelist.h for $count files." >&2
|
||||||
|
cat <<EOF > $outFile
|
||||||
|
/****************************************************************************
|
||||||
|
* Loadiine resource files.
|
||||||
|
* This file is generated automatically.
|
||||||
|
* Includes $count files.
|
||||||
|
*
|
||||||
|
* NOTE:
|
||||||
|
* Any manual modification of this file will be overwriten by the generation.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef _FILELIST_H_
|
||||||
|
#define _FILELIST_H_
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
|
|
||||||
|
typedef struct _RecourceFile
|
||||||
|
{
|
||||||
|
const char *filename;
|
||||||
|
const u8 *DefaultFile;
|
||||||
|
const u32 &DefaultFileSize;
|
||||||
|
u8 *CustomFile;
|
||||||
|
u32 CustomFileSize;
|
||||||
|
} RecourceFile;
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
for i in ${files[@]}
|
||||||
|
do
|
||||||
|
filename=${i%.*}
|
||||||
|
extension=${i##*.}
|
||||||
|
echo 'extern const u8 '$filename'_'$extension'[];' >> $outFile
|
||||||
|
echo 'extern const u32 '$filename'_'$extension'_size;' >> $outFile
|
||||||
|
echo '' >> $outFile
|
||||||
|
done
|
||||||
|
|
||||||
|
echo 'static RecourceFile RecourceList[] =' >> $outFile
|
||||||
|
echo '{' >> $outFile
|
||||||
|
|
||||||
|
for i in ${files[@]}
|
||||||
|
do
|
||||||
|
filename=${i%.*}
|
||||||
|
extension=${i##*.}
|
||||||
|
echo -e '\t{"'$i'", '$filename'_'$extension', '$filename'_'$extension'_size, NULL, 0},' >> $outFile
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e '\t{NULL, NULL, 0, NULL, 0}' >> $outFile
|
||||||
|
echo '};' >> $outFile
|
||||||
|
|
||||||
|
echo '' >> $outFile
|
||||||
|
echo '#endif' >> $outFile
|
||||||
|
|
||||||
|
fi
|
BIN
gx2_template.elf
Normal file
BIN
gx2_template.elf
Normal file
Binary file not shown.
BIN
gx2_template_dbg.elf
Normal file
BIN
gx2_template_dbg.elf
Normal file
Binary file not shown.
198
src/Application.cpp
Normal file
198
src/Application.cpp
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "Application.h"
|
||||||
|
#include "common/common.h"
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
#include "gui/FreeTypeGX.h"
|
||||||
|
#include "gui/VPadController.h"
|
||||||
|
#include "gui/WPadController.h"
|
||||||
|
#include "resources/Resources.h"
|
||||||
|
#include "sounds/SoundHandler.hpp"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
|
Application *Application::applicationInstance = NULL;
|
||||||
|
bool Application::exitApplication = false;
|
||||||
|
|
||||||
|
Application::Application()
|
||||||
|
: CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 0, 0x20000)
|
||||||
|
, bgMusic(NULL)
|
||||||
|
, video(NULL)
|
||||||
|
, mainWindow(NULL)
|
||||||
|
, exitCode(EXIT_RELAUNCH_ON_LOAD)
|
||||||
|
{
|
||||||
|
controller[0] = new VPadController(GuiTrigger::CHANNEL_1);
|
||||||
|
controller[1] = new WPadController(GuiTrigger::CHANNEL_2);
|
||||||
|
controller[2] = new WPadController(GuiTrigger::CHANNEL_3);
|
||||||
|
controller[3] = new WPadController(GuiTrigger::CHANNEL_4);
|
||||||
|
controller[4] = new WPadController(GuiTrigger::CHANNEL_5);
|
||||||
|
|
||||||
|
//! create bgMusic
|
||||||
|
/*
|
||||||
|
bgMusic = new GuiSound(Resources::GetFile("bgMusic.ogg"), Resources::GetFileSize("bgMusic.ogg"));
|
||||||
|
bgMusic->SetLoop(true);
|
||||||
|
bgMusic->Play();
|
||||||
|
bgMusic->SetVolume(50);*/
|
||||||
|
|
||||||
|
exitApplication = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Application::~Application(){
|
||||||
|
log_printf("Destroy music\n");
|
||||||
|
|
||||||
|
delete bgMusic;
|
||||||
|
|
||||||
|
log_printf("Destroy controller\n");
|
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++)
|
||||||
|
delete controller[i];
|
||||||
|
|
||||||
|
log_printf("Destroy async deleter\n");
|
||||||
|
AsyncDeleter::triggerDeleteProcess();
|
||||||
|
AsyncDeleter::destroyInstance();
|
||||||
|
|
||||||
|
log_printf("Clear resources\n");
|
||||||
|
Resources::Clear();
|
||||||
|
|
||||||
|
log_printf("Stop sound handler\n");
|
||||||
|
SoundHandler::DestroyInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Application::exec(){
|
||||||
|
//! start main GX2 thread
|
||||||
|
resumeThread();
|
||||||
|
//! now wait for thread to finish
|
||||||
|
shutdownThread();
|
||||||
|
|
||||||
|
return exitCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::fadeOut(){
|
||||||
|
GuiImage fadeOut(video->getTvWidth(), video->getTvHeight(), (GX2Color){ 0, 0, 0, 255 });
|
||||||
|
|
||||||
|
for(int i = 0; i < 255; i += 10)
|
||||||
|
{
|
||||||
|
if(i > 255)
|
||||||
|
i = 255;
|
||||||
|
|
||||||
|
fadeOut.setAlpha(i / 255.0f);
|
||||||
|
|
||||||
|
//! start rendering DRC
|
||||||
|
video->prepareDrcRendering();
|
||||||
|
mainWindow->drawDrc(video);
|
||||||
|
|
||||||
|
GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_ALWAYS);
|
||||||
|
fadeOut.draw(video);
|
||||||
|
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL);
|
||||||
|
|
||||||
|
video->drcDrawDone();
|
||||||
|
|
||||||
|
//! start rendering TV
|
||||||
|
video->prepareTvRendering();
|
||||||
|
|
||||||
|
mainWindow->drawTv(video);
|
||||||
|
|
||||||
|
GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_ALWAYS);
|
||||||
|
fadeOut.draw(video);
|
||||||
|
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL);
|
||||||
|
|
||||||
|
video->tvDrawDone();
|
||||||
|
|
||||||
|
//! as last point update the effects as it can drop elements
|
||||||
|
mainWindow->updateEffects();
|
||||||
|
|
||||||
|
video->waitForVSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! one last cleared black screen
|
||||||
|
video->prepareDrcRendering();
|
||||||
|
video->drcDrawDone();
|
||||||
|
video->prepareTvRendering();
|
||||||
|
video->tvDrawDone();
|
||||||
|
video->waitForVSync();
|
||||||
|
video->tvEnable(false);
|
||||||
|
video->drcEnable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::executeThread(void){
|
||||||
|
log_printf("Initialize video\n");
|
||||||
|
video = new CVideo(GX2_TV_SCAN_MODE_720P, GX2_DRC_SINGLE);
|
||||||
|
|
||||||
|
log_printf("Video size %i x %i\n", video->getTvWidth(), video->getTvHeight());
|
||||||
|
|
||||||
|
//! setup default Font
|
||||||
|
log_printf("Initialize main font system\n");
|
||||||
|
FreeTypeGX *fontSystem = new FreeTypeGX(Resources::GetFile("font.ttf"), Resources::GetFileSize("font.ttf"), true);
|
||||||
|
GuiText::setPresetFont(fontSystem);
|
||||||
|
|
||||||
|
log_printf("Initialize main window\n");
|
||||||
|
|
||||||
|
mainWindow = new MainWindow(video->getTvWidth(), video->getTvHeight());
|
||||||
|
|
||||||
|
log_printf("Entering main loop\n");
|
||||||
|
|
||||||
|
//! main GX2 loop (60 Hz cycle with max priority on core 1)
|
||||||
|
while(!exitApplication)
|
||||||
|
{
|
||||||
|
//! Read out inputs
|
||||||
|
for(int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
if(controller[i]->update(video->getTvWidth(), video->getTvHeight()) == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(controller[i]->data.buttons_d & VPAD_BUTTON_HOME){
|
||||||
|
exitApplication = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! update controller states
|
||||||
|
mainWindow->update(controller[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
mainWindow->process();
|
||||||
|
|
||||||
|
//! start rendering DRC
|
||||||
|
video->prepareDrcRendering();
|
||||||
|
mainWindow->drawDrc(video);
|
||||||
|
video->drcDrawDone();
|
||||||
|
|
||||||
|
//! start rendering TV
|
||||||
|
video->prepareTvRendering();
|
||||||
|
mainWindow->drawTv(video);
|
||||||
|
video->tvDrawDone();
|
||||||
|
|
||||||
|
//! enable screen after first frame render
|
||||||
|
if(video->getFrameCount() == 0) {
|
||||||
|
video->tvEnable(true);
|
||||||
|
video->drcEnable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! as last point update the effects as it can drop elements
|
||||||
|
mainWindow->updateEffects();
|
||||||
|
|
||||||
|
video->waitForVSync();
|
||||||
|
|
||||||
|
//! transfer elements to real delete list here after all processes are finished
|
||||||
|
//! the elements are transfered to another list to delete the elements in a separate thread
|
||||||
|
//! and avoid blocking the GUI thread
|
||||||
|
AsyncDeleter::triggerDeleteProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
fadeOut();
|
||||||
|
|
||||||
|
delete mainWindow;
|
||||||
|
delete fontSystem;
|
||||||
|
delete video;
|
||||||
|
}
|
73
src/Application.h
Normal file
73
src/Application.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef _APPLICATION_H
|
||||||
|
#define _APPLICATION_H
|
||||||
|
|
||||||
|
#include "menu/MainWindow.h"
|
||||||
|
#include "video/CVideo.h"
|
||||||
|
#include "system/CThread.h"
|
||||||
|
|
||||||
|
class Application : public CThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Application * instance() {
|
||||||
|
if(!applicationInstance)
|
||||||
|
applicationInstance = new Application();
|
||||||
|
return applicationInstance;
|
||||||
|
}
|
||||||
|
static void destroyInstance() {
|
||||||
|
if(applicationInstance) {
|
||||||
|
delete applicationInstance;
|
||||||
|
applicationInstance = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CVideo *getVideo(void) const {
|
||||||
|
return video;
|
||||||
|
}
|
||||||
|
MainWindow *getMainWindow(void) const {
|
||||||
|
return mainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiSound *getBgMusic(void) const {
|
||||||
|
return bgMusic;
|
||||||
|
}
|
||||||
|
|
||||||
|
int exec(void);
|
||||||
|
void fadeOut(void);
|
||||||
|
|
||||||
|
void quit(int code) {
|
||||||
|
exitCode = code;
|
||||||
|
exitApplication = true;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Application();
|
||||||
|
virtual ~Application();
|
||||||
|
|
||||||
|
static Application *applicationInstance;
|
||||||
|
static bool exitApplication;
|
||||||
|
|
||||||
|
void executeThread(void);
|
||||||
|
|
||||||
|
GuiSound *bgMusic;
|
||||||
|
CVideo *video;
|
||||||
|
MainWindow *mainWindow;
|
||||||
|
GuiController *controller[5];
|
||||||
|
int exitCode;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_APPLICATION_H
|
59
src/common/common.h
Normal file
59
src/common/common.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#ifndef COMMON_H
|
||||||
|
#define COMMON_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "os_defs.h"
|
||||||
|
|
||||||
|
#define CAFE_OS_SD_PATH "/vol/external01"
|
||||||
|
#define SD_PATH "sd:"
|
||||||
|
#define WIIU_PATH "/wiiu"
|
||||||
|
|
||||||
|
/* Macros for libs */
|
||||||
|
#define LIB_CORE_INIT 0
|
||||||
|
#define LIB_NSYSNET 1
|
||||||
|
#define LIB_GX2 2
|
||||||
|
#define LIB_AOC 3
|
||||||
|
#define LIB_AX 4
|
||||||
|
#define LIB_FS 5
|
||||||
|
#define LIB_OS 6
|
||||||
|
#define LIB_PADSCORE 7
|
||||||
|
#define LIB_SOCKET 8
|
||||||
|
#define LIB_SYS 9
|
||||||
|
#define LIB_VPAD 10
|
||||||
|
#define LIB_NN_ACP 11
|
||||||
|
#define LIB_SYSHID 12
|
||||||
|
#define LIB_VPADBASE 13
|
||||||
|
|
||||||
|
// functions types
|
||||||
|
#define STATIC_FUNCTION 0
|
||||||
|
#define DYNAMIC_FUNCTION 1
|
||||||
|
|
||||||
|
// none dynamic libs
|
||||||
|
#define LIB_LOADER 0x1001
|
||||||
|
|
||||||
|
#ifndef MEM_BASE
|
||||||
|
#define MEM_BASE (0x00800000)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ELF_DATA_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x00))
|
||||||
|
#define ELF_DATA_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x04))
|
||||||
|
#define MAIN_ENTRY_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x00))
|
||||||
|
#define OS_FIRMWARE (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x04))
|
||||||
|
|
||||||
|
#define OS_SPECIFICS ((OsSpecifics*)(MEM_BASE + 0x1500))
|
||||||
|
|
||||||
|
#ifndef EXIT_SUCCESS
|
||||||
|
#define EXIT_SUCCESS 0
|
||||||
|
#endif
|
||||||
|
#define EXIT_HBL_EXIT 0xFFFFFFFE
|
||||||
|
#define EXIT_RELAUNCH_ON_LOAD 0xFFFFFFFD
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* COMMON_H */
|
||||||
|
|
25
src/common/os_defs.h
Normal file
25
src/common/os_defs.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __OS_DEFS_H_
|
||||||
|
#define __OS_DEFS_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct _OsSpecifics
|
||||||
|
{
|
||||||
|
unsigned int addr_OSDynLoad_Acquire;
|
||||||
|
unsigned int addr_OSDynLoad_FindExport;
|
||||||
|
unsigned int addr_OSTitle_main_entry;
|
||||||
|
|
||||||
|
unsigned int addr_KernSyscallTbl1;
|
||||||
|
unsigned int addr_KernSyscallTbl2;
|
||||||
|
unsigned int addr_KernSyscallTbl3;
|
||||||
|
unsigned int addr_KernSyscallTbl4;
|
||||||
|
unsigned int addr_KernSyscallTbl5;
|
||||||
|
} OsSpecifics;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __OS_DEFS_H_
|
7
src/common/types.h
Normal file
7
src/common/types.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef TYPES_H
|
||||||
|
#define TYPES_H
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
|
|
||||||
|
#endif /* TYPES_H */
|
||||||
|
|
1
src/dynamic_libs
Submodule
1
src/dynamic_libs
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit befce1016a6ca1ea5be68b038b396170aa618cad
|
14
src/entry.c
Normal file
14
src/entry.c
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
#include "dynamic_libs/sys_functions.h"
|
||||||
|
#include "common/common.h"
|
||||||
|
#include "utils/utils.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
int __entry_menu(int argc, char **argv)
|
||||||
|
{
|
||||||
|
//! *******************************************************************
|
||||||
|
//! * Jump to our application *
|
||||||
|
//! *******************************************************************
|
||||||
|
return Menu_Main();
|
||||||
|
}
|
198
src/fs/CFile.cpp
Normal file
198
src/fs/CFile.cpp
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "CFile.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
CFile::CFile()
|
||||||
|
{
|
||||||
|
iFd = -1;
|
||||||
|
mem_file = NULL;
|
||||||
|
filesize = 0;
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFile::CFile(const std::string & filepath, eOpenTypes mode)
|
||||||
|
{
|
||||||
|
iFd = -1;
|
||||||
|
this->open(filepath, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFile::CFile(const u8 * mem, int size)
|
||||||
|
{
|
||||||
|
iFd = -1;
|
||||||
|
this->open(mem, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFile::~CFile()
|
||||||
|
{
|
||||||
|
this->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CFile::open(const std::string & filepath, eOpenTypes mode)
|
||||||
|
{
|
||||||
|
this->close();
|
||||||
|
|
||||||
|
s32 openMode = 0;
|
||||||
|
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case ReadOnly:
|
||||||
|
openMode = O_RDONLY;
|
||||||
|
break;
|
||||||
|
case WriteOnly:
|
||||||
|
openMode = O_WRONLY;
|
||||||
|
break;
|
||||||
|
case ReadWrite:
|
||||||
|
openMode = O_RDWR;
|
||||||
|
break;
|
||||||
|
case Append:
|
||||||
|
openMode = O_APPEND | O_WRONLY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Using fopen works only on the first launch as expected
|
||||||
|
//! on the second launch it causes issues because we don't overwrite
|
||||||
|
//! the .data sections which is needed for a normal application to re-init
|
||||||
|
//! this will be added with launching as RPX
|
||||||
|
iFd = ::open(filepath.c_str(), openMode);
|
||||||
|
if(iFd < 0)
|
||||||
|
return iFd;
|
||||||
|
|
||||||
|
|
||||||
|
filesize = ::lseek(iFd, 0, SEEK_END);
|
||||||
|
::lseek(iFd, 0, SEEK_SET);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CFile::open(const u8 * mem, int size)
|
||||||
|
{
|
||||||
|
this->close();
|
||||||
|
|
||||||
|
mem_file = mem;
|
||||||
|
filesize = size;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFile::close()
|
||||||
|
{
|
||||||
|
if(iFd >= 0)
|
||||||
|
::close(iFd);
|
||||||
|
|
||||||
|
iFd = -1;
|
||||||
|
mem_file = NULL;
|
||||||
|
filesize = 0;
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CFile::read(u8 * ptr, size_t size)
|
||||||
|
{
|
||||||
|
if(iFd >= 0)
|
||||||
|
{
|
||||||
|
int ret = ::read(iFd, ptr,size);
|
||||||
|
if(ret > 0)
|
||||||
|
pos += ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int readsize = size;
|
||||||
|
|
||||||
|
if(readsize > (s64) (filesize-pos))
|
||||||
|
readsize = filesize-pos;
|
||||||
|
|
||||||
|
if(readsize <= 0)
|
||||||
|
return readsize;
|
||||||
|
|
||||||
|
if(mem_file != NULL)
|
||||||
|
{
|
||||||
|
memcpy(ptr, mem_file+pos, readsize);
|
||||||
|
pos += readsize;
|
||||||
|
return readsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CFile::write(const u8 * ptr, size_t size)
|
||||||
|
{
|
||||||
|
if(iFd >= 0)
|
||||||
|
{
|
||||||
|
size_t done = 0;
|
||||||
|
while(done < size)
|
||||||
|
{
|
||||||
|
int ret = ::write(iFd, ptr, size - done);
|
||||||
|
if(ret <= 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ptr += ret;
|
||||||
|
done += ret;
|
||||||
|
pos += ret;
|
||||||
|
}
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CFile::seek(long int offset, int origin)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
s64 newPos = pos;
|
||||||
|
|
||||||
|
if(origin == SEEK_SET)
|
||||||
|
{
|
||||||
|
newPos = offset;
|
||||||
|
}
|
||||||
|
else if(origin == SEEK_CUR)
|
||||||
|
{
|
||||||
|
newPos += offset;
|
||||||
|
}
|
||||||
|
else if(origin == SEEK_END)
|
||||||
|
{
|
||||||
|
newPos = filesize+offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newPos < 0)
|
||||||
|
{
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pos = newPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iFd >= 0)
|
||||||
|
ret = ::lseek(iFd, pos, SEEK_SET);
|
||||||
|
|
||||||
|
if(mem_file != NULL)
|
||||||
|
{
|
||||||
|
if(pos > filesize)
|
||||||
|
{
|
||||||
|
pos = filesize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CFile::fwrite(const char *format, ...)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
char * tmp = NULL;
|
||||||
|
|
||||||
|
va_list va;
|
||||||
|
va_start(va, format);
|
||||||
|
if((vasprintf(&tmp, format, va) >= 0) && tmp)
|
||||||
|
{
|
||||||
|
result = this->write((u8 *)tmp, strlen(tmp));
|
||||||
|
}
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
if(tmp)
|
||||||
|
free(tmp);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
57
src/fs/CFile.hpp
Normal file
57
src/fs/CFile.hpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#ifndef CFILE_HPP_
|
||||||
|
#define CFILE_HPP_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <gctypes.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
class CFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum eOpenTypes
|
||||||
|
{
|
||||||
|
ReadOnly,
|
||||||
|
WriteOnly,
|
||||||
|
ReadWrite,
|
||||||
|
Append
|
||||||
|
};
|
||||||
|
|
||||||
|
CFile();
|
||||||
|
CFile(const std::string & filepath, eOpenTypes mode);
|
||||||
|
CFile(const u8 * memory, int memsize);
|
||||||
|
virtual ~CFile();
|
||||||
|
|
||||||
|
int open(const std::string & filepath, eOpenTypes mode);
|
||||||
|
int open(const u8 * memory, int memsize);
|
||||||
|
|
||||||
|
bool isOpen() const {
|
||||||
|
if(iFd >= 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(mem_file)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close();
|
||||||
|
|
||||||
|
int read(u8 * ptr, size_t size);
|
||||||
|
int write(const u8 * ptr, size_t size);
|
||||||
|
int fwrite(const char *format, ...);
|
||||||
|
int seek(long int offset, int origin);
|
||||||
|
u64 tell() { return pos; };
|
||||||
|
u64 size() { return filesize; };
|
||||||
|
void rewind() { this->seek(0, SEEK_SET); };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int iFd;
|
||||||
|
const u8 * mem_file;
|
||||||
|
u64 filesize;
|
||||||
|
u64 pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
223
src/fs/DirList.cpp
Normal file
223
src/fs/DirList.cpp
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2010
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* DirList Class
|
||||||
|
* for WiiXplorer 2010
|
||||||
|
***************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/dirent.h>
|
||||||
|
|
||||||
|
#include "DirList.h"
|
||||||
|
#include "utils/StringTools.h"
|
||||||
|
|
||||||
|
DirList::DirList()
|
||||||
|
{
|
||||||
|
Flags = 0;
|
||||||
|
Filter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DirList::DirList(const std::string & path, const char *filter, u32 flags)
|
||||||
|
{
|
||||||
|
this->LoadPath(path, filter, flags);
|
||||||
|
this->SortList();
|
||||||
|
}
|
||||||
|
|
||||||
|
DirList::~DirList()
|
||||||
|
{
|
||||||
|
ClearList();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DirList::LoadPath(const std::string & folder, const char *filter, u32 flags)
|
||||||
|
{
|
||||||
|
if(folder.empty()) return false;
|
||||||
|
|
||||||
|
Flags = flags;
|
||||||
|
Filter = filter;
|
||||||
|
|
||||||
|
std::string folderpath(folder);
|
||||||
|
u32 length = folderpath.size();
|
||||||
|
|
||||||
|
//! clear path of double slashes
|
||||||
|
RemoveDoubleSlashs(folderpath);
|
||||||
|
|
||||||
|
//! remove last slash if exists
|
||||||
|
if(length > 0 && folderpath[length-1] == '/')
|
||||||
|
folderpath.erase(length-1);
|
||||||
|
|
||||||
|
return InternalLoadPath(folderpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DirList::InternalLoadPath(std::string &folderpath)
|
||||||
|
{
|
||||||
|
if(folderpath.size() < 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
struct dirent *dirent = NULL;
|
||||||
|
DIR *dir = NULL;
|
||||||
|
|
||||||
|
dir = opendir(folderpath.c_str());
|
||||||
|
if (dir == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while ((dirent = readdir(dir)) != 0)
|
||||||
|
{
|
||||||
|
bool isDir = dirent->d_type & DT_DIR;
|
||||||
|
const char *filename = dirent->d_name;
|
||||||
|
|
||||||
|
if(isDir)
|
||||||
|
{
|
||||||
|
if(strcmp(filename,".") == 0 || strcmp(filename,"..") == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(Flags & CheckSubfolders)
|
||||||
|
{
|
||||||
|
int length = folderpath.size();
|
||||||
|
if(length > 2 && folderpath[length-1] != '/')
|
||||||
|
folderpath += '/';
|
||||||
|
folderpath += filename;
|
||||||
|
InternalLoadPath(folderpath);
|
||||||
|
folderpath.erase(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(Flags & Dirs))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if(!(Flags & Files))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Filter)
|
||||||
|
{
|
||||||
|
char * fileext = strrchr(filename, '.');
|
||||||
|
if(!fileext)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(strtokcmp(fileext, Filter, ",") == 0)
|
||||||
|
AddEntrie(folderpath, filename, isDir);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddEntrie(folderpath, filename, isDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirList::AddEntrie(const std::string &filepath, const char * filename, bool isDir)
|
||||||
|
{
|
||||||
|
if(!filename)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int pos = FileInfo.size();
|
||||||
|
|
||||||
|
FileInfo.resize(pos+1);
|
||||||
|
|
||||||
|
FileInfo[pos].FilePath = (char *) malloc(filepath.size()+strlen(filename)+2);
|
||||||
|
if(!FileInfo[pos].FilePath)
|
||||||
|
{
|
||||||
|
FileInfo.resize(pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(FileInfo[pos].FilePath, "%s/%s", filepath.c_str(), filename);
|
||||||
|
FileInfo[pos].isDir = isDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirList::ClearList()
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < FileInfo.size(); ++i)
|
||||||
|
{
|
||||||
|
if(FileInfo[i].FilePath)
|
||||||
|
free(FileInfo[i].FilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileInfo.clear();
|
||||||
|
std::vector<DirEntry>().swap(FileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * DirList::GetFilename(int ind) const
|
||||||
|
{
|
||||||
|
if (!valid(ind))
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return FullpathToFilename(FileInfo[ind].FilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SortCallback(const DirEntry & f1, const DirEntry & f2)
|
||||||
|
{
|
||||||
|
if(f1.isDir && !(f2.isDir)) return true;
|
||||||
|
if(!(f1.isDir) && f2.isDir) return false;
|
||||||
|
|
||||||
|
if(f1.FilePath && !f2.FilePath) return true;
|
||||||
|
if(!f1.FilePath) return false;
|
||||||
|
|
||||||
|
if(strcasecmp(f1.FilePath, f2.FilePath) > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirList::SortList()
|
||||||
|
{
|
||||||
|
if(FileInfo.size() > 1)
|
||||||
|
std::sort(FileInfo.begin(), FileInfo.end(), SortCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirList::SortList(bool (*SortFunc)(const DirEntry &a, const DirEntry &b))
|
||||||
|
{
|
||||||
|
if(FileInfo.size() > 1)
|
||||||
|
std::sort(FileInfo.begin(), FileInfo.end(), SortFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 DirList::GetFilesize(int index) const
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
const char *path = GetFilepath(index);
|
||||||
|
|
||||||
|
if(!path || stat(path, &st) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return st.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DirList::GetFileIndex(const char *filename) const
|
||||||
|
{
|
||||||
|
if(!filename)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < FileInfo.size(); ++i)
|
||||||
|
{
|
||||||
|
if (strcasecmp(GetFilename(i), filename) == 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
95
src/fs/DirList.h
Normal file
95
src/fs/DirList.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2010
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* DirList Class
|
||||||
|
* for WiiXplorer 2010
|
||||||
|
***************************************************************************/
|
||||||
|
#ifndef ___DIRLIST_H_
|
||||||
|
#define ___DIRLIST_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <gctypes.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char * FilePath;
|
||||||
|
bool isDir;
|
||||||
|
} DirEntry;
|
||||||
|
|
||||||
|
class DirList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
DirList(void);
|
||||||
|
//!\param path Path from where to load the filelist of all files
|
||||||
|
//!\param filter A fileext that needs to be filtered
|
||||||
|
//!\param flags search/filter flags from the enum
|
||||||
|
DirList(const std::string & path, const char *filter = NULL, u32 flags = Files | Dirs);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~DirList();
|
||||||
|
//! Load all the files from a directory
|
||||||
|
bool LoadPath(const std::string & path, const char *filter = NULL, u32 flags = Files | Dirs);
|
||||||
|
//! Get a filename of the list
|
||||||
|
//!\param list index
|
||||||
|
const char * GetFilename(int index) const;
|
||||||
|
//! Get the a filepath of the list
|
||||||
|
//!\param list index
|
||||||
|
const char *GetFilepath(int index) const { if (!valid(index)) return ""; else return FileInfo[index].FilePath; }
|
||||||
|
//! Get the a filesize of the list
|
||||||
|
//!\param list index
|
||||||
|
u64 GetFilesize(int index) const;
|
||||||
|
//! Is index a dir or a file
|
||||||
|
//!\param list index
|
||||||
|
bool IsDir(int index) const { if(!valid(index)) return false; return FileInfo[index].isDir; };
|
||||||
|
//! Get the filecount of the whole list
|
||||||
|
int GetFilecount() const { return FileInfo.size(); };
|
||||||
|
//! Sort list by filepath
|
||||||
|
void SortList();
|
||||||
|
//! Custom sort command for custom sort functions definitions
|
||||||
|
void SortList(bool (*SortFunc)(const DirEntry &a, const DirEntry &b));
|
||||||
|
//! Get the index of the specified filename
|
||||||
|
int GetFileIndex(const char *filename) const;
|
||||||
|
//! Enum for search/filter flags
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Files = 0x01,
|
||||||
|
Dirs = 0x02,
|
||||||
|
CheckSubfolders = 0x08,
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
// Internal parser
|
||||||
|
bool InternalLoadPath(std::string &path);
|
||||||
|
//!Add a list entrie
|
||||||
|
void AddEntrie(const std::string &filepath, const char * filename, bool isDir);
|
||||||
|
//! Clear the list
|
||||||
|
void ClearList();
|
||||||
|
//! Check if valid pos is requested
|
||||||
|
inline bool valid(u32 pos) const { return (pos < FileInfo.size()); };
|
||||||
|
|
||||||
|
u32 Flags;
|
||||||
|
const char *Filter;
|
||||||
|
std::vector<DirEntry> FileInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
181
src/fs/fs_utils.c
Normal file
181
src/fs/fs_utils.c
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "dynamic_libs/fs_defs.h"
|
||||||
|
#include "dynamic_libs/fs_functions.h"
|
||||||
|
|
||||||
|
int MountFS(void *pClient, void *pCmd, char **mount_path)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
void *mountSrc = malloc(FS_MOUNT_SOURCE_SIZE);
|
||||||
|
if(!mountSrc)
|
||||||
|
return -3;
|
||||||
|
|
||||||
|
char* mountPath = (char*) malloc(FS_MAX_MOUNTPATH_SIZE);
|
||||||
|
if(!mountPath) {
|
||||||
|
free(mountSrc);
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(mountSrc, 0, FS_MOUNT_SOURCE_SIZE);
|
||||||
|
memset(mountPath, 0, FS_MAX_MOUNTPATH_SIZE);
|
||||||
|
|
||||||
|
// Mount sdcard
|
||||||
|
if (FSGetMountSource(pClient, pCmd, FS_SOURCETYPE_EXTERNAL, mountSrc, -1) == 0)
|
||||||
|
{
|
||||||
|
result = FSMount(pClient, pCmd, mountSrc, mountPath, FS_MAX_MOUNTPATH_SIZE, -1);
|
||||||
|
if((result == 0) && mount_path) {
|
||||||
|
*mount_path = (char*)malloc(strlen(mountPath) + 1);
|
||||||
|
if(*mount_path)
|
||||||
|
strcpy(*mount_path, mountPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(mountPath);
|
||||||
|
free(mountSrc);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UmountFS(void *pClient, void *pCmd, const char *mountPath)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
result = FSUnmount(pClient, pCmd, mountPath, -1);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size)
|
||||||
|
{
|
||||||
|
//! always initialze input
|
||||||
|
*inbuffer = NULL;
|
||||||
|
if(size)
|
||||||
|
*size = 0;
|
||||||
|
|
||||||
|
int iFd = open(filepath, O_RDONLY);
|
||||||
|
if (iFd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
u32 filesize = lseek(iFd, 0, SEEK_END);
|
||||||
|
lseek(iFd, 0, SEEK_SET);
|
||||||
|
|
||||||
|
u8 *buffer = (u8 *) malloc(filesize);
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
close(iFd);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 blocksize = 0x4000;
|
||||||
|
u32 done = 0;
|
||||||
|
int readBytes = 0;
|
||||||
|
|
||||||
|
while(done < filesize)
|
||||||
|
{
|
||||||
|
if(done + blocksize > filesize) {
|
||||||
|
blocksize = filesize - done;
|
||||||
|
}
|
||||||
|
readBytes = read(iFd, buffer + done, blocksize);
|
||||||
|
if(readBytes <= 0)
|
||||||
|
break;
|
||||||
|
done += readBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(iFd);
|
||||||
|
|
||||||
|
if (done != filesize)
|
||||||
|
{
|
||||||
|
free(buffer);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
*inbuffer = buffer;
|
||||||
|
|
||||||
|
//! sign is optional input
|
||||||
|
if(size)
|
||||||
|
*size = filesize;
|
||||||
|
|
||||||
|
return filesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CheckFile(const char * filepath)
|
||||||
|
{
|
||||||
|
if(!filepath)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
struct stat filestat;
|
||||||
|
|
||||||
|
char dirnoslash[strlen(filepath)+2];
|
||||||
|
snprintf(dirnoslash, sizeof(dirnoslash), "%s", filepath);
|
||||||
|
|
||||||
|
while(dirnoslash[strlen(dirnoslash)-1] == '/')
|
||||||
|
dirnoslash[strlen(dirnoslash)-1] = '\0';
|
||||||
|
|
||||||
|
char * notRoot = strrchr(dirnoslash, '/');
|
||||||
|
if(!notRoot)
|
||||||
|
{
|
||||||
|
strcat(dirnoslash, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat(dirnoslash, &filestat) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CreateSubfolder(const char * fullpath)
|
||||||
|
{
|
||||||
|
if(!fullpath)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
char dirnoslash[strlen(fullpath)+1];
|
||||||
|
strcpy(dirnoslash, fullpath);
|
||||||
|
|
||||||
|
int pos = strlen(dirnoslash)-1;
|
||||||
|
while(dirnoslash[pos] == '/')
|
||||||
|
{
|
||||||
|
dirnoslash[pos] = '\0';
|
||||||
|
pos--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(CheckFile(dirnoslash))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char parentpath[strlen(dirnoslash)+2];
|
||||||
|
strcpy(parentpath, dirnoslash);
|
||||||
|
char * ptr = strrchr(parentpath, '/');
|
||||||
|
|
||||||
|
if(!ptr)
|
||||||
|
{
|
||||||
|
//!Device root directory (must be with '/')
|
||||||
|
strcat(parentpath, "/");
|
||||||
|
struct stat filestat;
|
||||||
|
if (stat(parentpath, &filestat) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr++;
|
||||||
|
ptr[0] = '\0';
|
||||||
|
|
||||||
|
result = CreateSubfolder(parentpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (mkdir(dirnoslash, 0777) == -1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
23
src/fs/fs_utils.h
Normal file
23
src/fs/fs_utils.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef __FS_UTILS_H_
|
||||||
|
#define __FS_UTILS_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
|
|
||||||
|
int MountFS(void *pClient, void *pCmd, char **mount_path);
|
||||||
|
int UmountFS(void *pClient, void *pCmd, const char *mountPath);
|
||||||
|
|
||||||
|
int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size);
|
||||||
|
|
||||||
|
//! todo: C++ class
|
||||||
|
int CreateSubfolder(const char * fullpath);
|
||||||
|
int CheckFile(const char * filepath);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __FS_UTILS_H_
|
1019
src/fs/sd_fat_devoptab.c
Normal file
1019
src/fs/sd_fat_devoptab.c
Normal file
File diff suppressed because it is too large
Load Diff
38
src/fs/sd_fat_devoptab.h
Normal file
38
src/fs/sd_fat_devoptab.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2015
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
***************************************************************************/
|
||||||
|
#ifndef __SD_FAT_DEVOPTAB_H_
|
||||||
|
#define __SD_FAT_DEVOPTAB_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int mount_sd_fat(const char *path);
|
||||||
|
int unmount_sd_fat(const char *path);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __SD_FAT_DEVOPTAB_H_
|
608
src/gui/FreeTypeGX.cpp
Normal file
608
src/gui/FreeTypeGX.cpp
Normal file
@ -0,0 +1,608 @@
|
|||||||
|
/*
|
||||||
|
* FreeTypeGX is a wrapper class for libFreeType which renders a compiled
|
||||||
|
* FreeType parsable font into a GX texture for Wii homebrew development.
|
||||||
|
* Copyright (C) 2008 Armin Tamzarian
|
||||||
|
* Modified by Dimok, 2015 for WiiU GX2
|
||||||
|
*
|
||||||
|
* This file is part of FreeTypeGX.
|
||||||
|
*
|
||||||
|
* FreeTypeGX is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FreeTypeGX is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with FreeTypeGX. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FreeTypeGX.h"
|
||||||
|
#include "video/CVideo.h"
|
||||||
|
#include "video/shaders/Texture2DShader.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#define ALIGN4(x) (((x) + 3) & ~3)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor for the FreeTypeGX class for WiiXplorer.
|
||||||
|
*/
|
||||||
|
FreeTypeGX::FreeTypeGX(const uint8_t* fontBuffer, FT_Long bufferSize, bool lastFace)
|
||||||
|
{
|
||||||
|
int faceIndex = 0;
|
||||||
|
ftPointSize = 0;
|
||||||
|
GX2InitSampler(&ftSampler, GX2_TEX_CLAMP_CLAMP_BORDER, GX2_TEX_XY_FILTER_BILINEAR);
|
||||||
|
|
||||||
|
FT_Init_FreeType(&ftLibrary);
|
||||||
|
if(lastFace)
|
||||||
|
{
|
||||||
|
FT_New_Memory_Face(ftLibrary, (FT_Byte *)fontBuffer, bufferSize, -1, &ftFace);
|
||||||
|
faceIndex = ftFace->num_faces - 1; // Use the last face
|
||||||
|
FT_Done_Face(ftFace);
|
||||||
|
ftFace = NULL;
|
||||||
|
}
|
||||||
|
FT_New_Memory_Face(ftLibrary, (FT_Byte *) fontBuffer, bufferSize, faceIndex, &ftFace);
|
||||||
|
|
||||||
|
ftKerningEnabled = FT_HAS_KERNING(ftFace);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default destructor for the FreeTypeGX class.
|
||||||
|
*/
|
||||||
|
FreeTypeGX::~FreeTypeGX()
|
||||||
|
{
|
||||||
|
unloadFont();
|
||||||
|
FT_Done_Face(ftFace);
|
||||||
|
FT_Done_FreeType(ftLibrary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a short char string to a wide char string.
|
||||||
|
*
|
||||||
|
* This routine converts a supplied short character string into a wide character string.
|
||||||
|
* Note that it is the user's responsibility to clear the returned buffer once it is no longer needed.
|
||||||
|
*
|
||||||
|
* @param strChar Character string to be converted.
|
||||||
|
* @return Wide character representation of supplied character string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
wchar_t* FreeTypeGX::charToWideChar(const char* strChar)
|
||||||
|
{
|
||||||
|
if (!strChar) return NULL;
|
||||||
|
|
||||||
|
wchar_t *strWChar = new (std::nothrow) wchar_t[strlen(strChar) + 1];
|
||||||
|
if (!strWChar) return NULL;
|
||||||
|
|
||||||
|
int bt = mbstowcs(strWChar, strChar, strlen(strChar));
|
||||||
|
if (bt > 0)
|
||||||
|
{
|
||||||
|
strWChar[bt] = 0;
|
||||||
|
return strWChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t *tempDest = strWChar;
|
||||||
|
while ((*tempDest++ = *strChar++))
|
||||||
|
;
|
||||||
|
|
||||||
|
return strWChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *FreeTypeGX::wideCharToUTF8(const wchar_t* strChar)
|
||||||
|
{
|
||||||
|
if(!strChar) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t len = 0;
|
||||||
|
wchar_t wc;
|
||||||
|
|
||||||
|
for (size_t i = 0; strChar[i]; ++i)
|
||||||
|
{
|
||||||
|
wc = strChar[i];
|
||||||
|
if (wc < 0x80)
|
||||||
|
++len;
|
||||||
|
else if (wc < 0x800)
|
||||||
|
len += 2;
|
||||||
|
else if (wc < 0x10000)
|
||||||
|
len += 3;
|
||||||
|
else
|
||||||
|
len += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *pOut = new (std::nothrow) char[len];
|
||||||
|
if(!pOut)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; strChar[i]; ++i)
|
||||||
|
{
|
||||||
|
wc = strChar[i];
|
||||||
|
if (wc < 0x80)
|
||||||
|
pOut[n++] = (char)wc;
|
||||||
|
else if (wc < 0x800)
|
||||||
|
{
|
||||||
|
pOut[n++] = (char)((wc >> 6) | 0xC0);
|
||||||
|
pOut[n++] = (char)((wc & 0x3F) | 0x80);
|
||||||
|
}
|
||||||
|
else if (wc < 0x10000)
|
||||||
|
{
|
||||||
|
pOut[n++] = (char)((wc >> 12) | 0xE0);
|
||||||
|
pOut[n++] = (char)(((wc >> 6) & 0x3F) | 0x80);
|
||||||
|
pOut[n++] = (char)((wc & 0x3F) | 0x80);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pOut[n++] = (char)(((wc >> 18) & 0x07) | 0xF0);
|
||||||
|
pOut[n++] = (char)(((wc >> 12) & 0x3F) | 0x80);
|
||||||
|
pOut[n++] = (char)(((wc >> 6) & 0x3F) | 0x80);
|
||||||
|
pOut[n++] = (char)((wc & 0x3F) | 0x80);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all loaded font glyph data.
|
||||||
|
*
|
||||||
|
* This routine clears all members of the font map structure and frees all allocated memory back to the system.
|
||||||
|
*/
|
||||||
|
void FreeTypeGX::unloadFont()
|
||||||
|
{
|
||||||
|
map<int16_t, ftGX2Data >::iterator itr;
|
||||||
|
map<wchar_t, ftgxCharData>::iterator itr2;
|
||||||
|
|
||||||
|
for (itr = fontData.begin(); itr != fontData.end(); itr++)
|
||||||
|
{
|
||||||
|
for (itr2 = itr->second.ftgxCharMap.begin(); itr2 != itr->second.ftgxCharMap.end(); itr2++)
|
||||||
|
{
|
||||||
|
if(itr2->second.texture)
|
||||||
|
{
|
||||||
|
if(itr2->second.texture->surface.image_data)
|
||||||
|
free(itr2->second.texture->surface.image_data);
|
||||||
|
|
||||||
|
delete itr2->second.texture;
|
||||||
|
itr2->second.texture = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fontData.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caches the given font glyph in the instance font texture buffer.
|
||||||
|
*
|
||||||
|
* This routine renders and stores the requested glyph's bitmap and relevant information into its own quickly addressible
|
||||||
|
* structure within an instance-specific map.
|
||||||
|
*
|
||||||
|
* @param charCode The requested glyph's character code.
|
||||||
|
* @return A pointer to the allocated font structure.
|
||||||
|
*/
|
||||||
|
ftgxCharData * FreeTypeGX::cacheGlyphData(wchar_t charCode, int16_t pixelSize)
|
||||||
|
{
|
||||||
|
map<int16_t, ftGX2Data>::iterator itr = fontData.find(pixelSize);
|
||||||
|
if (itr != fontData.end())
|
||||||
|
{
|
||||||
|
map<wchar_t, ftgxCharData>::iterator itr2 = itr->second.ftgxCharMap.find(charCode);
|
||||||
|
if (itr2 != itr->second.ftgxCharMap.end())
|
||||||
|
{
|
||||||
|
return &itr2->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//!Cache ascender and decender as well
|
||||||
|
ftGX2Data *ftData = &fontData[pixelSize];
|
||||||
|
|
||||||
|
FT_UInt gIndex;
|
||||||
|
uint16_t textureWidth = 0, textureHeight = 0;
|
||||||
|
if (ftPointSize != pixelSize)
|
||||||
|
{
|
||||||
|
ftPointSize = pixelSize;
|
||||||
|
FT_Set_Pixel_Sizes(ftFace, 0, ftPointSize);
|
||||||
|
ftData->ftgxAlign.ascender = (int16_t) ftFace->size->metrics.ascender >> 6;
|
||||||
|
ftData->ftgxAlign.descender = (int16_t) ftFace->size->metrics.descender >> 6;
|
||||||
|
ftData->ftgxAlign.max = 0;
|
||||||
|
ftData->ftgxAlign.min = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gIndex = FT_Get_Char_Index(ftFace, (FT_ULong) charCode);
|
||||||
|
if (gIndex != 0 && FT_Load_Glyph(ftFace, gIndex, FT_LOAD_DEFAULT | FT_LOAD_RENDER) == 0)
|
||||||
|
{
|
||||||
|
if (ftFace->glyph->format == FT_GLYPH_FORMAT_BITMAP)
|
||||||
|
{
|
||||||
|
FT_Bitmap *glyphBitmap = &ftFace->glyph->bitmap;
|
||||||
|
|
||||||
|
textureWidth = ALIGN4(glyphBitmap->width);
|
||||||
|
textureHeight = ALIGN4(glyphBitmap->rows);
|
||||||
|
if(textureWidth == 0)
|
||||||
|
textureWidth = 4;
|
||||||
|
if(textureHeight == 0)
|
||||||
|
textureHeight = 4;
|
||||||
|
|
||||||
|
ftgxCharData *charData = &ftData->ftgxCharMap[charCode];
|
||||||
|
charData->renderOffsetX = (int16_t) ftFace->glyph->bitmap_left;
|
||||||
|
charData->glyphAdvanceX = (uint16_t) (ftFace->glyph->advance.x >> 6);
|
||||||
|
charData->glyphAdvanceY = (uint16_t) (ftFace->glyph->advance.y >> 6);
|
||||||
|
charData->glyphIndex = (uint32_t) gIndex;
|
||||||
|
charData->renderOffsetY = (int16_t) ftFace->glyph->bitmap_top;
|
||||||
|
charData->renderOffsetMax = (int16_t) ftFace->glyph->bitmap_top;
|
||||||
|
charData->renderOffsetMin = (int16_t) glyphBitmap->rows - ftFace->glyph->bitmap_top;
|
||||||
|
|
||||||
|
//! Initialize texture
|
||||||
|
charData->texture = new GX2Texture;
|
||||||
|
GX2InitTexture(charData->texture, textureWidth, textureHeight, 1, 0, GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM, GX2_SURFACE_DIM_2D, GX2_TILE_MODE_LINEAR_ALIGNED);
|
||||||
|
|
||||||
|
loadGlyphData(glyphBitmap, charData);
|
||||||
|
|
||||||
|
return charData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locates each character in this wrapper's configured font face and proccess them.
|
||||||
|
*
|
||||||
|
* This routine locates each character in the configured font face and renders the glyph's bitmap.
|
||||||
|
* Each bitmap and relevant information is loaded into its own quickly addressible structure within an instance-specific map.
|
||||||
|
*/
|
||||||
|
uint16_t FreeTypeGX::cacheGlyphDataComplete(int16_t pixelSize)
|
||||||
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
FT_UInt gIndex;
|
||||||
|
|
||||||
|
FT_ULong charCode = FT_Get_First_Char(ftFace, &gIndex);
|
||||||
|
while (gIndex != 0)
|
||||||
|
{
|
||||||
|
if (cacheGlyphData(charCode, pixelSize) != NULL) ++i;
|
||||||
|
charCode = FT_Get_Next_Char(ftFace, charCode, &gIndex);
|
||||||
|
}
|
||||||
|
return (uint16_t) (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the rendered bitmap into the relevant structure's data buffer.
|
||||||
|
*
|
||||||
|
* This routine does a simple byte-wise copy of the glyph's rendered 8-bit grayscale bitmap into the structure's buffer.
|
||||||
|
* Each byte is converted from the bitmap's intensity value into the a uint32_t RGBA value.
|
||||||
|
*
|
||||||
|
* @param bmp A pointer to the most recently rendered glyph's bitmap.
|
||||||
|
* @param charData A pointer to an allocated ftgxCharData structure whose data represent that of the last rendered glyph.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData)
|
||||||
|
{
|
||||||
|
charData->texture->surface.image_data = (uint8_t *) memalign(charData->texture->surface.align, charData->texture->surface.image_size);
|
||||||
|
if(!charData->texture->surface.image_data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memset(charData->texture->surface.image_data, 0x00, charData->texture->surface.image_size);
|
||||||
|
|
||||||
|
uint8_t *src = (uint8_t *)bmp->buffer;
|
||||||
|
uint16_t *dst = (uint16_t *)charData->texture->surface.image_data;
|
||||||
|
int32_t x, y;
|
||||||
|
|
||||||
|
for(y = 0; y < bmp->rows; y++)
|
||||||
|
{
|
||||||
|
for(x = 0; x < bmp->width; x++)
|
||||||
|
{
|
||||||
|
uint8_t intensity = src[y * bmp->width + x] >> 3;
|
||||||
|
dst[y * charData->texture->surface.pitch + x] = intensity ? ((intensity << 11) | (intensity << 6) | (intensity << 1) | 1) : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_TEXTURE, charData->texture->surface.image_data, charData->texture->surface.image_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the x offset of the rendered string.
|
||||||
|
*
|
||||||
|
* This routine calculates the x offset of the rendered string based off of a supplied positional format parameter.
|
||||||
|
*
|
||||||
|
* @param width Current pixel width of the string.
|
||||||
|
* @param format Positional format of the string.
|
||||||
|
*/
|
||||||
|
int16_t FreeTypeGX::getStyleOffsetWidth(uint16_t width, uint16_t format)
|
||||||
|
{
|
||||||
|
if (format & FTGX_JUSTIFY_LEFT)
|
||||||
|
return 0;
|
||||||
|
else if (format & FTGX_JUSTIFY_CENTER)
|
||||||
|
return -(width >> 1);
|
||||||
|
else if (format & FTGX_JUSTIFY_RIGHT) return -width;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the y offset of the rendered string.
|
||||||
|
*
|
||||||
|
* This routine calculates the y offset of the rendered string based off of a supplied positional format parameter.
|
||||||
|
*
|
||||||
|
* @param offset Current pixel offset data of the string.
|
||||||
|
* @param format Positional format of the string.
|
||||||
|
*/
|
||||||
|
int16_t FreeTypeGX::getStyleOffsetHeight(int16_t format, uint16_t pixelSize)
|
||||||
|
{
|
||||||
|
std::map<int16_t, ftGX2Data>::iterator itr = fontData.find(pixelSize);
|
||||||
|
if (itr == fontData.end()) return 0;
|
||||||
|
|
||||||
|
switch (format & FTGX_ALIGN_MASK)
|
||||||
|
{
|
||||||
|
case FTGX_ALIGN_TOP:
|
||||||
|
return itr->second.ftgxAlign.descender;
|
||||||
|
|
||||||
|
case FTGX_ALIGN_MIDDLE:
|
||||||
|
default:
|
||||||
|
return (itr->second.ftgxAlign.ascender + itr->second.ftgxAlign.descender + 1) >> 1;
|
||||||
|
|
||||||
|
case FTGX_ALIGN_BOTTOM:
|
||||||
|
return itr->second.ftgxAlign.ascender;
|
||||||
|
|
||||||
|
case FTGX_ALIGN_BASELINE:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case FTGX_ALIGN_GLYPH_TOP:
|
||||||
|
return itr->second.ftgxAlign.max;
|
||||||
|
|
||||||
|
case FTGX_ALIGN_GLYPH_MIDDLE:
|
||||||
|
return (itr->second.ftgxAlign.max + itr->second.ftgxAlign.min + 1) >> 1;
|
||||||
|
|
||||||
|
case FTGX_ALIGN_GLYPH_BOTTOM:
|
||||||
|
return itr->second.ftgxAlign.min;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the supplied text string and prints the results at the specified coordinates.
|
||||||
|
*
|
||||||
|
* This routine processes each character of the supplied text string, loads the relevant preprocessed bitmap buffer,
|
||||||
|
* a texture from said buffer, and loads the resultant texture into the EFB.
|
||||||
|
*
|
||||||
|
* @param x Screen X coordinate at which to output the text.
|
||||||
|
* @param y Screen Y coordinate at which to output the text. Note that this value corresponds to the text string origin and not the top or bottom of the glyphs.
|
||||||
|
* @param text NULL terminated string to output.
|
||||||
|
* @param color Optional color to apply to the text characters. If not specified default value is ftgxWhite: (GXColor){0xff, 0xff, 0xff, 0xff}
|
||||||
|
* @param textStyle Flags which specify any styling which should be applied to the rendered string.
|
||||||
|
* @return The number of characters printed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint16_t FreeTypeGX::drawText(CVideo *video, int16_t x, int16_t y, int16_t z, const wchar_t *text, int16_t pixelSize, const glm::vec4 & color, uint16_t textStyle, uint16_t textWidth, const float &textBlur, const float & colorBlurIntensity, const glm::vec4 & blurColor, const float & internalRenderingScale)
|
||||||
|
{
|
||||||
|
if (!text)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint16_t fullTextWidth = (textWidth > 0) ? textWidth : getWidth(text, pixelSize);
|
||||||
|
uint16_t x_pos = x, printed = 0;
|
||||||
|
uint16_t x_offset = 0, y_offset = 0;
|
||||||
|
FT_Vector pairDelta;
|
||||||
|
|
||||||
|
if (textStyle & FTGX_JUSTIFY_MASK)
|
||||||
|
{
|
||||||
|
x_offset = getStyleOffsetWidth(fullTextWidth, textStyle);
|
||||||
|
}
|
||||||
|
if (textStyle & FTGX_ALIGN_MASK)
|
||||||
|
{
|
||||||
|
y_offset = getStyleOffsetHeight(textStyle, pixelSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (text[i])
|
||||||
|
{
|
||||||
|
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
|
||||||
|
|
||||||
|
if (glyphData != NULL)
|
||||||
|
{
|
||||||
|
if (ftKerningEnabled && i > 0)
|
||||||
|
{
|
||||||
|
FT_Get_Kerning(ftFace, fontData[pixelSize].ftgxCharMap[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
|
||||||
|
x_pos += (pairDelta.x >> 6);
|
||||||
|
|
||||||
|
}
|
||||||
|
copyTextureToFramebuffer(video, glyphData->texture,x_pos + glyphData->renderOffsetX + x_offset, y + glyphData->renderOffsetY - y_offset, z, color, textBlur, colorBlurIntensity, blurColor,internalRenderingScale);
|
||||||
|
|
||||||
|
x_pos += glyphData->glyphAdvanceX;
|
||||||
|
++printed;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return printed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the supplied string and return the width of the string in pixels.
|
||||||
|
*
|
||||||
|
* This routine processes each character of the supplied text string and calculates the width of the entire string.
|
||||||
|
* Note that if precaching of the entire font set is not enabled any uncached glyph will be cached after the call to this function.
|
||||||
|
*
|
||||||
|
* @param text NULL terminated string to calculate.
|
||||||
|
* @return The width of the text string in pixels.
|
||||||
|
*/
|
||||||
|
uint16_t FreeTypeGX::getWidth(const wchar_t *text, int16_t pixelSize)
|
||||||
|
{
|
||||||
|
if (!text) return 0;
|
||||||
|
|
||||||
|
uint16_t strWidth = 0;
|
||||||
|
FT_Vector pairDelta;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (text[i])
|
||||||
|
{
|
||||||
|
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
|
||||||
|
|
||||||
|
if (glyphData != NULL)
|
||||||
|
{
|
||||||
|
if (ftKerningEnabled && (i > 0))
|
||||||
|
{
|
||||||
|
FT_Get_Kerning(ftFace, fontData[pixelSize].ftgxCharMap[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
|
||||||
|
strWidth += pairDelta.x >> 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
strWidth += glyphData->glyphAdvanceX;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return strWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Single char width
|
||||||
|
*/
|
||||||
|
uint16_t FreeTypeGX::getCharWidth(const wchar_t wChar, int16_t pixelSize, const wchar_t prevChar)
|
||||||
|
{
|
||||||
|
uint16_t strWidth = 0;
|
||||||
|
ftgxCharData * glyphData = cacheGlyphData(wChar, pixelSize);
|
||||||
|
|
||||||
|
if (glyphData != NULL)
|
||||||
|
{
|
||||||
|
if (ftKerningEnabled && prevChar != 0x0000)
|
||||||
|
{
|
||||||
|
FT_Vector pairDelta;
|
||||||
|
FT_Get_Kerning(ftFace, fontData[pixelSize].ftgxCharMap[prevChar].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
|
||||||
|
strWidth += pairDelta.x >> 6;
|
||||||
|
}
|
||||||
|
strWidth += glyphData->glyphAdvanceX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the supplied string and return the height of the string in pixels.
|
||||||
|
*
|
||||||
|
* This routine processes each character of the supplied text string and calculates the height of the entire string.
|
||||||
|
* Note that if precaching of the entire font set is not enabled any uncached glyph will be cached after the call to this function.
|
||||||
|
*
|
||||||
|
* @param text NULL terminated string to calculate.
|
||||||
|
* @return The height of the text string in pixels.
|
||||||
|
*/
|
||||||
|
uint16_t FreeTypeGX::getHeight(const wchar_t *text, int16_t pixelSize)
|
||||||
|
{
|
||||||
|
getOffset(text, pixelSize);
|
||||||
|
return fontData[pixelSize].ftgxAlign.max - fontData[pixelSize].ftgxAlign.min;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the maximum offset above and minimum offset below the font origin line.
|
||||||
|
*
|
||||||
|
* This function calculates the maximum pixel height above the font origin line and the minimum
|
||||||
|
* pixel height below the font origin line and returns the values in an addressible structure.
|
||||||
|
*
|
||||||
|
* @param text NULL terminated string to calculate.
|
||||||
|
* @param offset returns the max and min values above and below the font origin line
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void FreeTypeGX::getOffset(const wchar_t *text, int16_t pixelSize, uint16_t widthLimit)
|
||||||
|
{
|
||||||
|
if (fontData.find(pixelSize) != fontData.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int16_t strMax = 0, strMin = 9999;
|
||||||
|
uint16_t currWidth = 0;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (text[i])
|
||||||
|
{
|
||||||
|
if (widthLimit > 0 && currWidth >= widthLimit) break;
|
||||||
|
|
||||||
|
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
|
||||||
|
|
||||||
|
if (glyphData != NULL)
|
||||||
|
{
|
||||||
|
strMax = glyphData->renderOffsetMax > strMax ? glyphData->renderOffsetMax : strMax;
|
||||||
|
strMin = glyphData->renderOffsetMin < strMin ? glyphData->renderOffsetMin : strMin;
|
||||||
|
currWidth += glyphData->glyphAdvanceX;
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftPointSize != pixelSize)
|
||||||
|
{
|
||||||
|
ftPointSize = pixelSize;
|
||||||
|
FT_Set_Pixel_Sizes(ftFace, 0, ftPointSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
fontData[pixelSize].ftgxAlign.ascender = ftFace->size->metrics.ascender >> 6;
|
||||||
|
fontData[pixelSize].ftgxAlign.descender = ftFace->size->metrics.descender >> 6;
|
||||||
|
fontData[pixelSize].ftgxAlign.max = strMax;
|
||||||
|
fontData[pixelSize].ftgxAlign.min = strMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the supplied texture quad to the EFB.
|
||||||
|
*
|
||||||
|
* This routine uses the in-built GX quad builder functions to define the texture bounds and location on the EFB target.
|
||||||
|
*
|
||||||
|
* @param texObj A pointer to the glyph's initialized texture object.
|
||||||
|
* @param texWidth The pixel width of the texture object.
|
||||||
|
* @param texHeight The pixel height of the texture object.
|
||||||
|
* @param screenX The screen X coordinate at which to output the rendered texture.
|
||||||
|
* @param screenY The screen Y coordinate at which to output the rendered texture.
|
||||||
|
* @param color Color to apply to the texture.
|
||||||
|
*/
|
||||||
|
void FreeTypeGX::copyTextureToFramebuffer(CVideo *pVideo, GX2Texture *texture, int16_t x, int16_t y, int16_t z, const glm::vec4 & color, const float & defaultBlur, const float & blurIntensity, const glm::vec4 & blurColor, const float & internalRenderingScale)
|
||||||
|
{
|
||||||
|
static const f32 imageAngle = 0.0f;
|
||||||
|
static const f32 blurScale = (2.0f/ (internalRenderingScale));
|
||||||
|
|
||||||
|
f32 offsetLeft = blurScale * ((f32)x + 0.5f * (f32)texture->surface.width) * (f32)pVideo->getWidthScaleFactor();
|
||||||
|
f32 offsetTop = blurScale * ((f32)y - 0.5f * (f32)texture->surface.height) * (f32)pVideo->getHeightScaleFactor();
|
||||||
|
|
||||||
|
f32 widthScale = blurScale * (f32)texture->surface.width * pVideo->getWidthScaleFactor();
|
||||||
|
f32 heightScale = blurScale * (f32)texture->surface.height * pVideo->getHeightScaleFactor();
|
||||||
|
|
||||||
|
glm::vec3 positionOffsets( offsetLeft, offsetTop, (f32)z );
|
||||||
|
|
||||||
|
//! blur doubles due to blur we have to scale the texture
|
||||||
|
glm::vec3 scaleFactor( widthScale, heightScale, 1.0f );
|
||||||
|
|
||||||
|
glm::vec3 blurDirection;
|
||||||
|
blurDirection[2] = 1.0f;
|
||||||
|
|
||||||
|
Texture2DShader::instance()->setShaders();
|
||||||
|
Texture2DShader::instance()->setAttributeBuffer();
|
||||||
|
Texture2DShader::instance()->setAngle(imageAngle);
|
||||||
|
Texture2DShader::instance()->setOffset(positionOffsets);
|
||||||
|
Texture2DShader::instance()->setScale(scaleFactor);
|
||||||
|
Texture2DShader::instance()->setTextureAndSampler(texture, &ftSampler);
|
||||||
|
|
||||||
|
if(blurIntensity > 0.0f)
|
||||||
|
{
|
||||||
|
//! glow blur color
|
||||||
|
Texture2DShader::instance()->setColorIntensity(blurColor);
|
||||||
|
|
||||||
|
//! glow blur horizontal
|
||||||
|
blurDirection[0] = blurIntensity;
|
||||||
|
blurDirection[1] = 0.0f;
|
||||||
|
Texture2DShader::instance()->setBlurring(blurDirection);
|
||||||
|
Texture2DShader::instance()->draw();
|
||||||
|
|
||||||
|
//! glow blur vertical
|
||||||
|
blurDirection[0] = 0.0f;
|
||||||
|
blurDirection[1] = blurIntensity;
|
||||||
|
Texture2DShader::instance()->setBlurring(blurDirection);
|
||||||
|
Texture2DShader::instance()->draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! set text color
|
||||||
|
Texture2DShader::instance()->setColorIntensity(color);
|
||||||
|
|
||||||
|
//! blur horizontal
|
||||||
|
blurDirection[0] = defaultBlur;
|
||||||
|
blurDirection[1] = 0.0f;
|
||||||
|
Texture2DShader::instance()->setBlurring(blurDirection);
|
||||||
|
Texture2DShader::instance()->draw();
|
||||||
|
|
||||||
|
//! blur vertical
|
||||||
|
blurDirection[0] = 0.0f;
|
||||||
|
blurDirection[1] = defaultBlur;
|
||||||
|
Texture2DShader::instance()->setBlurring(blurDirection);
|
||||||
|
Texture2DShader::instance()->draw();
|
||||||
|
}
|
155
src/gui/FreeTypeGX.h
Normal file
155
src/gui/FreeTypeGX.h
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* FreeTypeGX is a wrapper class for libFreeType which renders a compiled
|
||||||
|
* FreeType parsable font into a GX texture for Wii homebrew development.
|
||||||
|
* Copyright (C) 2008 Armin Tamzarian
|
||||||
|
* Modified by Dimok, 2015 for WiiU GX2
|
||||||
|
*
|
||||||
|
* This file is part of FreeTypeGX.
|
||||||
|
*
|
||||||
|
* FreeTypeGX is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FreeTypeGX is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with FreeTypeGX. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREETYPEGX_H_
|
||||||
|
#define FREETYPEGX_H_
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
|
#include <string>
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_BITMAP_H
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
#include "dynamic_libs/gx2_functions.h"
|
||||||
|
|
||||||
|
/*! \struct ftgxCharData_
|
||||||
|
*
|
||||||
|
* Font face character glyph relevant data structure.
|
||||||
|
*/
|
||||||
|
typedef struct ftgxCharData_
|
||||||
|
{
|
||||||
|
int16_t renderOffsetX; /**< Texture X axis bearing offset. */
|
||||||
|
uint16_t glyphAdvanceX; /**< Character glyph X coordinate advance in pixels. */
|
||||||
|
uint16_t glyphAdvanceY; /**< Character glyph Y coordinate advance in pixels. */
|
||||||
|
uint32_t glyphIndex; /**< Charachter glyph index in the font face. */
|
||||||
|
|
||||||
|
int16_t renderOffsetY; /**< Texture Y axis bearing offset. */
|
||||||
|
int16_t renderOffsetMax; /**< Texture Y axis bearing maximum value. */
|
||||||
|
int16_t renderOffsetMin; /**< Texture Y axis bearing minimum value. */
|
||||||
|
|
||||||
|
GX2Texture * texture;
|
||||||
|
} ftgxCharData;
|
||||||
|
|
||||||
|
/*! \struct ftgxDataOffset_
|
||||||
|
*
|
||||||
|
* Offset structure which hold both a maximum and minimum value.
|
||||||
|
*/
|
||||||
|
typedef struct ftgxDataOffset_
|
||||||
|
{
|
||||||
|
int16_t ascender; /**< Maximum data offset. */
|
||||||
|
int16_t descender; /**< Minimum data offset. */
|
||||||
|
int16_t max; /**< Maximum data offset. */
|
||||||
|
int16_t min; /**< Minimum data offset. */
|
||||||
|
} ftgxDataOffset;
|
||||||
|
|
||||||
|
typedef struct ftgxCharData_ ftgxCharData;
|
||||||
|
typedef struct ftgxDataOffset_ ftgxDataOffset;
|
||||||
|
#define _TEXT(t) L ## t /**< Unicode helper macro. */
|
||||||
|
|
||||||
|
#define FTGX_NULL 0x0000
|
||||||
|
#define FTGX_JUSTIFY_LEFT 0x0001
|
||||||
|
#define FTGX_JUSTIFY_CENTER 0x0002
|
||||||
|
#define FTGX_JUSTIFY_RIGHT 0x0004
|
||||||
|
#define FTGX_JUSTIFY_MASK 0x000f
|
||||||
|
|
||||||
|
#define FTGX_ALIGN_TOP 0x0010
|
||||||
|
#define FTGX_ALIGN_MIDDLE 0x0020
|
||||||
|
#define FTGX_ALIGN_BOTTOM 0x0040
|
||||||
|
#define FTGX_ALIGN_BASELINE 0x0080
|
||||||
|
#define FTGX_ALIGN_GLYPH_TOP 0x0100
|
||||||
|
#define FTGX_ALIGN_GLYPH_MIDDLE 0x0200
|
||||||
|
#define FTGX_ALIGN_GLYPH_BOTTOM 0x0400
|
||||||
|
#define FTGX_ALIGN_MASK 0x0ff0
|
||||||
|
|
||||||
|
#define FTGX_STYLE_UNDERLINE 0x1000
|
||||||
|
#define FTGX_STYLE_STRIKE 0x2000
|
||||||
|
#define FTGX_STYLE_MASK 0xf000
|
||||||
|
|
||||||
|
/**< Constant color value used only to sanitize Doxygen documentation. */
|
||||||
|
static const GX2ColorF32 ftgxWhite = (GX2ColorF32){ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
|
|
||||||
|
|
||||||
|
//! forward declaration
|
||||||
|
class CVideo;
|
||||||
|
|
||||||
|
/*! \class FreeTypeGX
|
||||||
|
* \brief Wrapper class for the libFreeType library with GX rendering.
|
||||||
|
* \author Armin Tamzarian
|
||||||
|
* \version 0.2.4
|
||||||
|
*
|
||||||
|
* FreeTypeGX acts as a wrapper class for the libFreeType library. It supports precaching of transformed glyph data into
|
||||||
|
* a specified texture format. Rendering of the data to the EFB is accomplished through the application of high performance
|
||||||
|
* GX texture functions resulting in high throughput of string rendering.
|
||||||
|
*/
|
||||||
|
class FreeTypeGX
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
FT_Library ftLibrary; /**< FreeType FT_Library instance. */
|
||||||
|
FT_Face ftFace; /**< FreeType reusable FT_Face typographic object. */
|
||||||
|
int16_t ftPointSize; /**< Current set size of the rendered font. */
|
||||||
|
bool ftKerningEnabled; /**< Flag indicating the availability of font kerning data. */
|
||||||
|
uint8_t vertexIndex; /**< Vertex format descriptor index. */
|
||||||
|
GX2Sampler ftSampler;
|
||||||
|
|
||||||
|
typedef struct _ftGX2Data
|
||||||
|
{
|
||||||
|
ftgxDataOffset ftgxAlign;
|
||||||
|
std::map<wchar_t, ftgxCharData> ftgxCharMap;
|
||||||
|
} ftGX2Data;
|
||||||
|
|
||||||
|
std::map<int16_t, ftGX2Data> fontData; /**< Map which holds the glyph data structures for the corresponding characters in one size. */
|
||||||
|
|
||||||
|
int16_t getStyleOffsetWidth(uint16_t width, uint16_t format);
|
||||||
|
int16_t getStyleOffsetHeight(int16_t format, uint16_t pixelSize);
|
||||||
|
|
||||||
|
void unloadFont();
|
||||||
|
ftgxCharData *cacheGlyphData(wchar_t charCode, int16_t pixelSize);
|
||||||
|
uint16_t cacheGlyphDataComplete(int16_t pixelSize);
|
||||||
|
void loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData);
|
||||||
|
|
||||||
|
void copyTextureToFramebuffer(CVideo * pVideo, GX2Texture *tex, int16_t screenX, int16_t screenY, int16_t screenZ, const glm::vec4 & color, const float &textBlur, const float &colorBlurIntensity, const glm::vec4 & blurColor, const float & internalRenderingScale);
|
||||||
|
|
||||||
|
public:
|
||||||
|
FreeTypeGX(const uint8_t* fontBuffer, FT_Long bufferSize, bool lastFace = false);
|
||||||
|
~FreeTypeGX();
|
||||||
|
|
||||||
|
uint16_t drawText(CVideo * pVideo, int16_t x, int16_t y, int16_t z, const wchar_t *text, int16_t pixelSize, const glm::vec4 & color,
|
||||||
|
uint16_t textStyling, uint16_t textWidth, const float &textBlur, const float &colorBlurIntensity, const glm::vec4 & blurColor, const float & internalRenderingScale);
|
||||||
|
|
||||||
|
uint16_t getWidth(const wchar_t *text, int16_t pixelSize);
|
||||||
|
uint16_t getCharWidth(const wchar_t wChar, int16_t pixelSize, const wchar_t prevChar = 0x0000);
|
||||||
|
uint16_t getHeight(const wchar_t *text, int16_t pixelSize);
|
||||||
|
void getOffset(const wchar_t *text, int16_t pixelSize, uint16_t widthLimit = 0);
|
||||||
|
|
||||||
|
static wchar_t* charToWideChar(const char* p);
|
||||||
|
static char* wideCharToUTF8(const wchar_t* strChar);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FREETYPEGX_H_ */
|
42
src/gui/GameBgImage.cpp
Normal file
42
src/gui/GameBgImage.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include "GameBgImage.h"
|
||||||
|
#include "video/CVideo.h"
|
||||||
|
#include "video/shaders/Shader3D.h"
|
||||||
|
|
||||||
|
GameBgImage::GameBgImage(const std::string & filename, GuiImageData *preloadImage)
|
||||||
|
: GuiImageAsync(filename, preloadImage)
|
||||||
|
{
|
||||||
|
identity = glm::mat4(1.0f);
|
||||||
|
alphaFadeOut = glm::vec4(1.0f, 0.075f, 5.305f, 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
GameBgImage::~GameBgImage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameBgImage::draw(CVideo *pVideo)
|
||||||
|
{
|
||||||
|
if(!getImageData() || !getImageData()->getTexture())
|
||||||
|
return;
|
||||||
|
|
||||||
|
//! first setup 2D GUI positions
|
||||||
|
f32 currPosX = getCenterX();
|
||||||
|
f32 currPosY = getCenterY();
|
||||||
|
f32 currPosZ = getDepth();
|
||||||
|
f32 currScaleX = getScaleX() * (f32)getWidth() * pVideo->getWidthScaleFactor();
|
||||||
|
f32 currScaleY = getScaleY() * (f32)getHeight() * pVideo->getHeightScaleFactor();
|
||||||
|
f32 currScaleZ = getScaleZ() * (f32)getWidth() * pVideo->getDepthScaleFactor();
|
||||||
|
|
||||||
|
glm::mat4 m_modelView = glm::translate(identity, glm::vec3(currPosX,currPosY, currPosZ));
|
||||||
|
m_modelView = glm::scale(m_modelView, glm::vec3(currScaleX, currScaleY, currScaleZ));
|
||||||
|
|
||||||
|
Shader3D::instance()->setShaders();
|
||||||
|
Shader3D::instance()->setProjectionMtx(identity);
|
||||||
|
Shader3D::instance()->setViewMtx(identity);
|
||||||
|
Shader3D::instance()->setModelViewMtx(m_modelView);
|
||||||
|
Shader3D::instance()->setTextureAndSampler(getImageData()->getTexture(), getImageData()->getSampler());
|
||||||
|
Shader3D::instance()->setAlphaFadeOut(alphaFadeOut);
|
||||||
|
Shader3D::instance()->setDistanceFadeOut(0.0f);
|
||||||
|
Shader3D::instance()->setColorIntensity(glm::vec4(1.0f, 1.0f, 1.0f, getAlpha()));
|
||||||
|
Shader3D::instance()->setAttributeBuffer();
|
||||||
|
Shader3D::instance()->draw();
|
||||||
|
}
|
23
src/gui/GameBgImage.h
Normal file
23
src/gui/GameBgImage.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef _GAME_BG_IMAGE_H_
|
||||||
|
#define _GAME_BG_IMAGE_H_
|
||||||
|
|
||||||
|
#include "GuiImageAsync.h"
|
||||||
|
#include "video/shaders/Shader3D.h"
|
||||||
|
|
||||||
|
class GameBgImage : public GuiImageAsync
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GameBgImage(const std::string & filename, GuiImageData *preloadImage);
|
||||||
|
virtual ~GameBgImage();
|
||||||
|
|
||||||
|
void setAlphaFadeOut(const glm::vec4 & a) {
|
||||||
|
alphaFadeOut = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(CVideo *pVideo);
|
||||||
|
private:
|
||||||
|
glm::mat4 identity;
|
||||||
|
glm::vec4 alphaFadeOut;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _GAME_BG_IMAGE_H_
|
321
src/gui/GameIcon.cpp
Normal file
321
src/gui/GameIcon.cpp
Normal file
@ -0,0 +1,321 @@
|
|||||||
|
#include "GameIcon.h"
|
||||||
|
#include "GameIconModel.h"
|
||||||
|
#include "Application.h"
|
||||||
|
#include "video/CVideo.h"
|
||||||
|
#include "video/shaders/Shader3D.h"
|
||||||
|
#include "video/shaders/ShaderFractalColor.h"
|
||||||
|
|
||||||
|
static const f32 cfIconMirrorScale = 1.15f;
|
||||||
|
static const f32 cfIconMirrorAlpha = 0.45f;
|
||||||
|
|
||||||
|
GameIcon::GameIcon(const std::string & filename, GuiImageData *preloadImage)
|
||||||
|
: GuiImageAsync(filename, preloadImage)
|
||||||
|
{
|
||||||
|
bSelected = false;
|
||||||
|
bRenderStroke = true;
|
||||||
|
bRenderReflection = false;
|
||||||
|
bIconLast = false;
|
||||||
|
strokeFractalEnable = 1;
|
||||||
|
strokeBlurBorder = 0.0f;
|
||||||
|
distanceFadeout = 0.0f;
|
||||||
|
rotationX = 0.0f;
|
||||||
|
reflectionAlpha = 0.4f;
|
||||||
|
strokeWidth = 2.35f;
|
||||||
|
colorIntensity = glm::vec4(1.0f);
|
||||||
|
colorIntensityMirror = colorIntensity;
|
||||||
|
alphaFadeOutNorm = glm::vec4(0.0f);
|
||||||
|
alphaFadeOutRefl = glm::vec4(-1.0f, 0.0f, 0.9f, 1.0f);
|
||||||
|
selectionBlurOuterColorIntensity = glm::vec4(0.09411764f * 1.15f, 0.56862745f * 1.15f, 0.96862745098f * 1.15f, 1.0f);
|
||||||
|
selectionBlurOuterSize = 1.65f;
|
||||||
|
selectionBlurOuterBorderSize = 0.5f;
|
||||||
|
selectionBlurInnerColorIntensity = glm::vec4(0.46666667f, 0.90588235f, 1.0f, 1.0f);
|
||||||
|
selectionBlurInnerSize = 1.45f;
|
||||||
|
selectionBlurInnerBorderSize = 0.95f;
|
||||||
|
|
||||||
|
vtxCount = sizeof(cfGameIconPosVtxs) / (Shader3D::cuVertexAttrSize);
|
||||||
|
|
||||||
|
//! texture and vertex coordinates
|
||||||
|
posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, sizeof(cfGameIconPosVtxs));
|
||||||
|
texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, sizeof(cfGameIconTexCoords));
|
||||||
|
|
||||||
|
if(posVtxs)
|
||||||
|
{
|
||||||
|
memcpy((f32*)posVtxs, cfGameIconPosVtxs, sizeof(cfGameIconPosVtxs));
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, (f32*)posVtxs, sizeof(cfGameIconPosVtxs));
|
||||||
|
}
|
||||||
|
if(texCoords)
|
||||||
|
{
|
||||||
|
memcpy((f32*)texCoords, cfGameIconTexCoords, sizeof(cfGameIconTexCoords));
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, (f32*)texCoords, sizeof(cfGameIconTexCoords));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! create vertexes for the mirror frame
|
||||||
|
texCoordsMirror = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, sizeof(cfGameIconTexCoords));
|
||||||
|
|
||||||
|
if(texCoordsMirror)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < vtxCount; i++)
|
||||||
|
{
|
||||||
|
texCoordsMirror[i*2 + 0] = texCoords[i*2 + 0] * cfIconMirrorScale - ((cfIconMirrorScale - 1.0f) - (cfIconMirrorScale - 1.0f) * 0.5f);
|
||||||
|
texCoordsMirror[i*2 + 1] = texCoords[i*2 + 1] * cfIconMirrorScale - ((cfIconMirrorScale - 1.0f) - (cfIconMirrorScale - 1.0f) * 0.5f);
|
||||||
|
}
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, texCoordsMirror, sizeof(cfGameIconTexCoords));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! setup stroke of the icon
|
||||||
|
strokePosVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, sizeof(cfGameIconStrokeVtxs));
|
||||||
|
if(strokePosVtxs)
|
||||||
|
{
|
||||||
|
memcpy(strokePosVtxs, cfGameIconStrokeVtxs, sizeof(cfGameIconStrokeVtxs));
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, strokePosVtxs, sizeof(cfGameIconStrokeVtxs));
|
||||||
|
}
|
||||||
|
strokeTexCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, cuGameIconStrokeVtxCount * Shader::cuTexCoordAttrSize);
|
||||||
|
if(strokeTexCoords)
|
||||||
|
{
|
||||||
|
for(size_t i = 0, n = 0; i < cuGameIconStrokeVtxCount; n += 2, i += 3)
|
||||||
|
{
|
||||||
|
strokeTexCoords[n] = (1.0f + strokePosVtxs[i]) * 0.5f;
|
||||||
|
strokeTexCoords[n+1] = 1.0f - (1.0f + strokePosVtxs[i+1]) * 0.5f;
|
||||||
|
}
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, strokeTexCoords, cuGameIconStrokeVtxCount * Shader::cuTexCoordAttrSize);
|
||||||
|
}
|
||||||
|
strokeColorVtxs = (u8*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, cuGameIconStrokeVtxCount * Shader::cuColorAttrSize);
|
||||||
|
if(strokeColorVtxs)
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < (cuGameIconStrokeVtxCount * Shader::cuColorAttrSize); i++)
|
||||||
|
strokeColorVtxs[i] = 0xff;
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, strokeColorVtxs, cuGameIconStrokeVtxCount * Shader::cuColorAttrSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GameIcon::~GameIcon()
|
||||||
|
{
|
||||||
|
//! remove image so it can not be drawn anymore from this point on
|
||||||
|
imageData = NULL;
|
||||||
|
|
||||||
|
//! main image vertexes
|
||||||
|
if(posVtxs)
|
||||||
|
{
|
||||||
|
free((void*)posVtxs);
|
||||||
|
posVtxs = NULL;
|
||||||
|
}
|
||||||
|
if(texCoords)
|
||||||
|
{
|
||||||
|
free((void*)texCoords);
|
||||||
|
texCoords = NULL;
|
||||||
|
}
|
||||||
|
//! mirror image vertexes
|
||||||
|
if(texCoordsMirror)
|
||||||
|
{
|
||||||
|
free(texCoordsMirror);
|
||||||
|
texCoordsMirror = NULL;
|
||||||
|
}
|
||||||
|
//! stroke image vertexes
|
||||||
|
if(strokePosVtxs)
|
||||||
|
{
|
||||||
|
free(strokePosVtxs);
|
||||||
|
strokePosVtxs = NULL;
|
||||||
|
}
|
||||||
|
if(strokeTexCoords)
|
||||||
|
{
|
||||||
|
free(strokeTexCoords);
|
||||||
|
strokeTexCoords = NULL;
|
||||||
|
}
|
||||||
|
if(strokeColorVtxs)
|
||||||
|
{
|
||||||
|
free(strokeColorVtxs);
|
||||||
|
strokeColorVtxs = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GameIcon::checkRayIntersection(const glm::vec3 & rayOrigin, const glm::vec3 & rayDirFrac)
|
||||||
|
{
|
||||||
|
//! since we always face the camera we can just check the AABB intersection
|
||||||
|
//! otherwise an OOB intersection would be required
|
||||||
|
|
||||||
|
f32 currPosX = getCenterX() * Application::instance()->getVideo()->getWidthScaleFactor() * 2.0f;
|
||||||
|
f32 currPosY = getCenterY() * Application::instance()->getVideo()->getHeightScaleFactor() * 2.0f;
|
||||||
|
f32 currPosZ = getDepth() * Application::instance()->getVideo()->getDepthScaleFactor() * 2.0f;
|
||||||
|
f32 currScaleX = getScaleX() * (f32)getWidth() * Application::instance()->getVideo()->getWidthScaleFactor();
|
||||||
|
f32 currScaleY = getScaleY() * (f32)getHeight() * Application::instance()->getVideo()->getHeightScaleFactor();
|
||||||
|
f32 currScaleZ = getScaleZ() * (f32)getWidth() * Application::instance()->getVideo()->getDepthScaleFactor();
|
||||||
|
//! lb is the corner of AABB with minimal coordinates - left bottom, rt is maximal corner
|
||||||
|
glm::vec3 lb(currPosX - currScaleX, currPosY - currScaleY, currPosZ - currScaleZ);
|
||||||
|
glm::vec3 rt(currPosX + currScaleX, currPosY + currScaleY, currPosZ + currScaleZ);
|
||||||
|
|
||||||
|
float t1 = (lb.x - rayOrigin.x) * rayDirFrac.x;
|
||||||
|
float t2 = (rt.x - rayOrigin.x) * rayDirFrac.x;
|
||||||
|
float t3 = (lb.y - rayOrigin.y) * rayDirFrac.y;
|
||||||
|
float t4 = (rt.y - rayOrigin.y) * rayDirFrac.y;
|
||||||
|
float t5 = (lb.z - rayOrigin.z) * rayDirFrac.z;
|
||||||
|
float t6 = (rt.z - rayOrigin.z) * rayDirFrac.z;
|
||||||
|
|
||||||
|
float tmin = std::max(std::max(std::min(t1, t2), std::min(t3, t4)), std::min(t5, t6));
|
||||||
|
float tmax = std::min(std::min(std::max(t1, t2), std::max(t3, t4)), std::max(t5, t6));
|
||||||
|
|
||||||
|
//! if tmax < 0, ray (line) is intersecting AABB, but whole AABB is behing us
|
||||||
|
if (tmax < 0)
|
||||||
|
{
|
||||||
|
//t = tmax;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! if tmin > tmax, ray doesn't intersect AABB
|
||||||
|
if (tmin > tmax)
|
||||||
|
{
|
||||||
|
//t = tmax;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//t = tmin;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameIcon::draw(CVideo *pVideo, const glm::mat4 & projectionMtx, const glm::mat4 & viewMtx, const glm::mat4 & modelView)
|
||||||
|
{
|
||||||
|
//! first setup 2D GUI positions
|
||||||
|
f32 currPosX = getCenterX() * pVideo->getWidthScaleFactor() * 2.0f;
|
||||||
|
f32 currPosY = getCenterY() * pVideo->getHeightScaleFactor() * 2.0f;
|
||||||
|
f32 currPosZ = getDepth() * pVideo->getDepthScaleFactor() * 2.0f;
|
||||||
|
f32 currScaleX = getScaleX() * (f32)getWidth() * pVideo->getWidthScaleFactor();
|
||||||
|
f32 currScaleY = getScaleY() * (f32)getHeight() * pVideo->getHeightScaleFactor();
|
||||||
|
f32 currScaleZ = getScaleZ() * (f32)getWidth() * pVideo->getDepthScaleFactor();
|
||||||
|
f32 strokeScaleX = pVideo->getWidthScaleFactor() * strokeWidth * 0.25f + cfIconMirrorScale;
|
||||||
|
f32 strokeScaleY = pVideo->getHeightScaleFactor() * strokeWidth * 0.25f + cfIconMirrorScale;
|
||||||
|
|
||||||
|
for(int iDraw = 0; iDraw < 2; iDraw++)
|
||||||
|
{
|
||||||
|
glm::vec4 * alphaFadeOut;
|
||||||
|
glm::mat4 m_iconView;
|
||||||
|
glm::mat4 m_mirrorView;
|
||||||
|
glm::mat4 m_strokeView;
|
||||||
|
|
||||||
|
if(iDraw == RENDER_REFLECTION)
|
||||||
|
{
|
||||||
|
//! Reflection render
|
||||||
|
if(!bRenderReflection)
|
||||||
|
continue;
|
||||||
|
m_iconView = glm::translate(modelView, glm::vec3(currPosX, -currScaleY * 2.0f - currPosY, currPosZ + cosf(DegToRad(rotationX)) * currScaleZ * 2.0f));
|
||||||
|
m_iconView = glm::rotate(m_iconView, DegToRad(rotationX), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
|
m_iconView = glm::scale(m_iconView, glm::vec3(currScaleX, -currScaleY, currScaleZ));
|
||||||
|
|
||||||
|
colorIntensity[3] = reflectionAlpha * getAlpha();
|
||||||
|
selectionBlurOuterColorIntensity[3] = colorIntensity[3] * 0.7f;
|
||||||
|
selectionBlurInnerColorIntensity[3] = colorIntensity[3] * 0.7f;
|
||||||
|
alphaFadeOut = &alphaFadeOutRefl;
|
||||||
|
|
||||||
|
GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_ENABLE, GX2_DISABLE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//! Normal render
|
||||||
|
m_iconView = glm::translate(modelView, glm::vec3(currPosX,currPosY, currPosZ));
|
||||||
|
m_iconView = glm::rotate(m_iconView, DegToRad(rotationX), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
|
m_iconView = glm::scale(m_iconView, glm::vec3(currScaleX, currScaleY, currScaleZ));
|
||||||
|
|
||||||
|
colorIntensity[3] = getAlpha();
|
||||||
|
selectionBlurOuterColorIntensity[3] = colorIntensity[3];
|
||||||
|
selectionBlurInnerColorIntensity[3] = colorIntensity[3];
|
||||||
|
alphaFadeOut = &alphaFadeOutNorm;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_mirrorView = glm::scale(m_iconView, glm::vec3(cfIconMirrorScale, cfIconMirrorScale, cfIconMirrorScale));
|
||||||
|
|
||||||
|
colorIntensityMirror[3] = cfIconMirrorAlpha * colorIntensity[3];
|
||||||
|
|
||||||
|
if(!bIconLast)
|
||||||
|
{
|
||||||
|
Shader3D::instance()->setShaders();
|
||||||
|
Shader3D::instance()->setProjectionMtx(projectionMtx);
|
||||||
|
Shader3D::instance()->setViewMtx(viewMtx);
|
||||||
|
Shader3D::instance()->setTextureAndSampler(imageData->getTexture(), imageData->getSampler());
|
||||||
|
Shader3D::instance()->setAlphaFadeOut(*alphaFadeOut);
|
||||||
|
Shader3D::instance()->setDistanceFadeOut(distanceFadeout);
|
||||||
|
|
||||||
|
//! render the real symbol
|
||||||
|
Shader3D::instance()->setModelViewMtx(m_iconView);
|
||||||
|
Shader3D::instance()->setColorIntensity(colorIntensity);
|
||||||
|
Shader3D::instance()->setAttributeBuffer(vtxCount, posVtxs, texCoords);
|
||||||
|
Shader3D::instance()->draw(GX2_PRIMITIVE_QUADS, vtxCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bSelected)
|
||||||
|
{
|
||||||
|
strokeFractalEnable = 0;
|
||||||
|
|
||||||
|
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_DISABLE, GX2_COMPARE_LEQUAL);
|
||||||
|
m_strokeView = glm::scale(m_iconView, glm::vec3(selectionBlurOuterSize, selectionBlurOuterSize, 0.0f));
|
||||||
|
ShaderFractalColor::instance()->setShaders();
|
||||||
|
ShaderFractalColor::instance()->setProjectionMtx(projectionMtx);
|
||||||
|
ShaderFractalColor::instance()->setViewMtx(viewMtx);
|
||||||
|
ShaderFractalColor::instance()->setModelViewMtx(m_strokeView);
|
||||||
|
ShaderFractalColor::instance()->setFractalColor(strokeFractalEnable);
|
||||||
|
ShaderFractalColor::instance()->setBlurBorder(selectionBlurOuterBorderSize);
|
||||||
|
ShaderFractalColor::instance()->setColorIntensity(selectionBlurOuterColorIntensity);
|
||||||
|
ShaderFractalColor::instance()->setAlphaFadeOut(*alphaFadeOut);
|
||||||
|
ShaderFractalColor::instance()->setAttributeBuffer();
|
||||||
|
ShaderFractalColor::instance()->draw();
|
||||||
|
|
||||||
|
m_strokeView = glm::scale(m_iconView, glm::vec3(selectionBlurInnerSize, selectionBlurInnerSize, 0.0f));
|
||||||
|
ShaderFractalColor::instance()->setBlurBorder(selectionBlurInnerBorderSize);
|
||||||
|
ShaderFractalColor::instance()->setColorIntensity(selectionBlurInnerColorIntensity);
|
||||||
|
ShaderFractalColor::instance()->draw();
|
||||||
|
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iDraw == RENDER_NORMAL && bRenderStroke)
|
||||||
|
{
|
||||||
|
strokeFractalEnable = 1;
|
||||||
|
//! now render the icon stroke
|
||||||
|
//! make the stroke a little bigger than the mirror, just by the line width on each side
|
||||||
|
m_strokeView = glm::scale(m_iconView, glm::vec3(strokeScaleX, strokeScaleY, cfIconMirrorScale));
|
||||||
|
|
||||||
|
ShaderFractalColor::instance()->setShaders();
|
||||||
|
ShaderFractalColor::instance()->setLineWidth(strokeWidth);
|
||||||
|
ShaderFractalColor::instance()->setProjectionMtx(projectionMtx);
|
||||||
|
ShaderFractalColor::instance()->setViewMtx(viewMtx);
|
||||||
|
ShaderFractalColor::instance()->setModelViewMtx(m_strokeView);
|
||||||
|
ShaderFractalColor::instance()->setFractalColor(strokeFractalEnable);
|
||||||
|
ShaderFractalColor::instance()->setBlurBorder(strokeBlurBorder);
|
||||||
|
ShaderFractalColor::instance()->setColorIntensity(colorIntensity);
|
||||||
|
ShaderFractalColor::instance()->setAlphaFadeOut(*alphaFadeOut);
|
||||||
|
ShaderFractalColor::instance()->setAttributeBuffer(cuGameIconStrokeVtxCount, strokePosVtxs, strokeTexCoords, strokeColorVtxs);
|
||||||
|
ShaderFractalColor::instance()->draw(GX2_PRIMITIVE_LINE_STRIP, cuGameIconStrokeVtxCount);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//! render the background mirror frame
|
||||||
|
Shader3D::instance()->setShaders();
|
||||||
|
Shader3D::instance()->setProjectionMtx(projectionMtx);
|
||||||
|
Shader3D::instance()->setViewMtx(viewMtx);
|
||||||
|
Shader3D::instance()->setTextureAndSampler(imageData->getTexture(), imageData->getSampler());
|
||||||
|
Shader3D::instance()->setAlphaFadeOut(*alphaFadeOut);
|
||||||
|
Shader3D::instance()->setDistanceFadeOut(distanceFadeout);
|
||||||
|
Shader3D::instance()->setModelViewMtx(m_mirrorView);
|
||||||
|
Shader3D::instance()->setColorIntensity(colorIntensityMirror);
|
||||||
|
Shader3D::instance()->setAttributeBuffer(vtxCount, posVtxs, texCoordsMirror);
|
||||||
|
Shader3D::instance()->draw(GX2_PRIMITIVE_QUADS, vtxCount);
|
||||||
|
|
||||||
|
if(bIconLast)
|
||||||
|
{
|
||||||
|
Shader3D::instance()->setShaders();
|
||||||
|
Shader3D::instance()->setProjectionMtx(projectionMtx);
|
||||||
|
Shader3D::instance()->setViewMtx(viewMtx);
|
||||||
|
Shader3D::instance()->setTextureAndSampler(imageData->getTexture(), imageData->getSampler());
|
||||||
|
Shader3D::instance()->setAlphaFadeOut(*alphaFadeOut);
|
||||||
|
Shader3D::instance()->setDistanceFadeOut(distanceFadeout);
|
||||||
|
|
||||||
|
//! render the real symbol
|
||||||
|
Shader3D::instance()->setModelViewMtx(m_iconView);
|
||||||
|
Shader3D::instance()->setColorIntensity(colorIntensity);
|
||||||
|
Shader3D::instance()->setAttributeBuffer(vtxCount, posVtxs, texCoords);
|
||||||
|
Shader3D::instance()->draw(GX2_PRIMITIVE_QUADS, vtxCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! return back normal culling
|
||||||
|
if(iDraw == RENDER_REFLECTION)
|
||||||
|
{
|
||||||
|
GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_DISABLE, GX2_ENABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
src/gui/GameIcon.h
Normal file
85
src/gui/GameIcon.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#ifndef _GAME_ICON_H_
|
||||||
|
#define _GAME_ICON_H_
|
||||||
|
|
||||||
|
#include "GuiImageAsync.h"
|
||||||
|
#include "video/shaders/Shader3D.h"
|
||||||
|
|
||||||
|
class GameIcon : public GuiImageAsync
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GameIcon(const std::string & filename, GuiImageData *preloadImage);
|
||||||
|
virtual ~GameIcon();
|
||||||
|
|
||||||
|
void setRotationX(f32 r) {
|
||||||
|
rotationX = r;
|
||||||
|
}
|
||||||
|
void setColorIntensity(const glm::vec4 & color) {
|
||||||
|
colorIntensity = color;
|
||||||
|
colorIntensityMirror = colorIntensity;
|
||||||
|
selectionBlurOuterColorIntensity = color * glm::vec4(0.09411764f * 1.15f, 0.56862745f * 1.15f, 0.96862745098f * 1.15f, 1.0f);
|
||||||
|
selectionBlurInnerColorIntensity = color * glm::vec4(0.46666667f, 0.90588235f, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
const glm::vec4 & getColorIntensity() const {
|
||||||
|
return colorIntensity;
|
||||||
|
}
|
||||||
|
void setAlphaFadeOutNorm(const glm::vec4 & a) {
|
||||||
|
alphaFadeOutNorm = a;
|
||||||
|
}
|
||||||
|
void setAlphaFadeOutRefl(const glm::vec4 & a) {
|
||||||
|
alphaFadeOutRefl = a;
|
||||||
|
}
|
||||||
|
void setRenderReflection(bool enable) {
|
||||||
|
bRenderReflection = enable;
|
||||||
|
}
|
||||||
|
void setSelected(bool enable) {
|
||||||
|
bSelected = enable;
|
||||||
|
}
|
||||||
|
void setStrokeRender(bool enable) {
|
||||||
|
bRenderStroke = enable;
|
||||||
|
}
|
||||||
|
void setRenderIconLast(bool enable) {
|
||||||
|
bIconLast = enable;
|
||||||
|
}
|
||||||
|
void draw(CVideo *pVideo) {
|
||||||
|
static const glm::mat4 identity(1.0f);
|
||||||
|
draw(pVideo, identity, identity, identity);
|
||||||
|
}
|
||||||
|
void draw(CVideo *pVideo, const glm::mat4 & projection, const glm::mat4 & view, const glm::mat4 & modelView);
|
||||||
|
|
||||||
|
bool checkRayIntersection(const glm::vec3 & rayOrigin, const glm::vec3 & rayDirFrac);
|
||||||
|
private:
|
||||||
|
enum eRenderState
|
||||||
|
{
|
||||||
|
RENDER_REFLECTION,
|
||||||
|
RENDER_NORMAL
|
||||||
|
};
|
||||||
|
|
||||||
|
bool bSelected;
|
||||||
|
bool bRenderStroke;
|
||||||
|
bool bRenderReflection;
|
||||||
|
bool bIconLast;
|
||||||
|
glm::vec4 colorIntensity;
|
||||||
|
glm::vec4 colorIntensityMirror;
|
||||||
|
glm::vec4 alphaFadeOutNorm;
|
||||||
|
glm::vec4 alphaFadeOutRefl;
|
||||||
|
|
||||||
|
f32 reflectionAlpha;
|
||||||
|
f32 strokeWidth;
|
||||||
|
f32 rotationX;
|
||||||
|
f32 rgbReduction;
|
||||||
|
f32 distanceFadeout;
|
||||||
|
f32 *texCoordsMirror;
|
||||||
|
f32 *strokePosVtxs;
|
||||||
|
f32 *strokeTexCoords;
|
||||||
|
u8 *strokeColorVtxs;
|
||||||
|
int strokeFractalEnable;
|
||||||
|
f32 strokeBlurBorder;
|
||||||
|
glm::vec4 selectionBlurOuterColorIntensity;
|
||||||
|
f32 selectionBlurOuterSize;
|
||||||
|
f32 selectionBlurOuterBorderSize;
|
||||||
|
glm::vec4 selectionBlurInnerColorIntensity;
|
||||||
|
f32 selectionBlurInnerSize;
|
||||||
|
f32 selectionBlurInnerBorderSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _GAME_ICON_H_
|
760
src/gui/GameIconModel.h
Normal file
760
src/gui/GameIconModel.h
Normal file
@ -0,0 +1,760 @@
|
|||||||
|
#ifndef ICON_MODEL_H_
|
||||||
|
#define ICON_MODEL_H_
|
||||||
|
|
||||||
|
static const float cfGameIconPosVtxs[] = {
|
||||||
|
-0.844501f,-0.861263f,0.050154f,-0.802664f,-0.8797f,0.054004f,-0.809968f,-0.828995f,0.061777f,-0.864233f,-0.822169f,0.054004f,
|
||||||
|
-0.802664f,-0.8797f,0.054004f,-0.726455f,-0.89991f,0.058224f,-0.730326f,-0.842312f,0.067487f,-0.809968f,-0.828995f,0.061777f,
|
||||||
|
-0.809968f,-0.828995f,0.061777f,-0.730326f,-0.842312f,0.067487f,-0.738488f,-0.760488f,0.074426f,-0.824221f,-0.752861f,0.067487f,
|
||||||
|
-0.864233f,-0.822169f,0.054004f,-0.809968f,-0.828995f,0.061777f,-0.824221f,-0.752861f,0.067487f,-0.885862f,-0.749245f,0.058224f,
|
||||||
|
-0.726455f,-0.89991f,0.058224f,-0.612405f,-0.916988f,0.061789f,-0.614352f,-0.854962f,0.071886f,-0.730326f,-0.842312f,0.067487f,
|
||||||
|
-0.612405f,-0.916988f,0.061789f,-0.392243f,-0.928623f,0.064218f,-0.39312f,-0.8642f,0.074693f,-0.614352f,-0.854962f,0.071886f,
|
||||||
|
-0.614352f,-0.854962f,0.071886f,-0.39312f,-0.8642f,0.074693f,-0.395094f,-0.775509f,0.082561f,-0.618732f,-0.768902f,0.079479f,
|
||||||
|
-0.730326f,-0.842312f,0.067487f,-0.614352f,-0.854962f,0.071886f,-0.618732f,-0.768902f,0.079479f,-0.738488f,-0.760488f,0.074426f,
|
||||||
|
-0.738488f,-0.760488f,0.074426f,-0.618732f,-0.768902f,0.079479f,-0.624085f,-0.648442f,0.084918f,-0.747494f,-0.64344f,0.079479f,
|
||||||
|
-0.618732f,-0.768902f,0.079479f,-0.395094f,-0.775509f,0.082561f,-0.397505f,-0.652534f,0.088189f,-0.624085f,-0.648442f,0.084918f,
|
||||||
|
-0.624085f,-0.648442f,0.084918f,-0.397505f,-0.652534f,0.088189f,-0.399478f,-0.422739f,0.09157f,-0.628465f,-0.420911f,0.088189f,
|
||||||
|
-0.747494f,-0.64344f,0.079479f,-0.624085f,-0.648442f,0.084918f,-0.628465f,-0.420911f,0.088189f,-0.754564f,-0.418675f,0.082561f,
|
||||||
|
-0.885862f,-0.749245f,0.058224f,-0.824221f,-0.752861f,0.067487f,-0.837759f,-0.639347f,0.071886f,-0.90414f,-0.637528f,0.061789f,
|
||||||
|
-0.824221f,-0.752861f,0.067487f,-0.738488f,-0.760488f,0.074426f,-0.747494f,-0.64344f,0.079479f,-0.837759f,-0.639347f,0.071886f,
|
||||||
|
-0.837759f,-0.639347f,0.071886f,-0.747494f,-0.64344f,0.079479f,-0.754564f,-0.418675f,0.082561f,-0.847646f,-0.416846f,0.074693f,
|
||||||
|
-0.90414f,-0.637528f,0.061789f,-0.837759f,-0.639347f,0.071886f,-0.847646f,-0.416846f,0.074693f,-0.916591f,-0.416033f,0.064218f,
|
||||||
|
-0.399478f,-0.422739f,0.09157f,-0.397505f,-0.652534f,0.088189f,0.002274f,-0.653898f,0.089279f,0.002265f,-0.423349f,0.092698f,
|
||||||
|
-0.397505f,-0.652534f,0.088189f,-0.395094f,-0.775509f,0.082561f,0.002284f,-0.777711f,0.083588f,0.002274f,-0.653898f,0.089279f,
|
||||||
|
0.002274f,-0.653898f,0.089279f,0.002284f,-0.777711f,0.083588f,0.399509f,-0.775509f,0.082561f,0.401892f,-0.652534f,0.088189f,
|
||||||
|
0.002265f,-0.423349f,0.092698f,0.002274f,-0.653898f,0.089279f,0.401892f,-0.652534f,0.088189f,0.403842f,-0.422739f,0.09157f,
|
||||||
|
-0.395094f,-0.775509f,0.082561f,-0.39312f,-0.8642f,0.074693f,0.002293f,-0.867279f,0.075629f,0.002284f,-0.777711f,0.083588f,
|
||||||
|
-0.39312f,-0.8642f,0.074693f,-0.392243f,-0.928623f,0.064218f,0.002297f,-0.932501f,0.065028f,0.002293f,-0.867279f,0.075629f,
|
||||||
|
0.002293f,-0.867279f,0.075629f,0.002297f,-0.932501f,0.065028f,0.396693f,-0.928623f,0.064218f,0.397559f,-0.8642f,0.074693f,
|
||||||
|
0.002284f,-0.777711f,0.083588f,0.002293f,-0.867279f,0.075629f,0.397559f,-0.8642f,0.074693f,0.399509f,-0.775509f,0.082561f,
|
||||||
|
-0.399478f,-0.422739f,0.09157f,0.002265f,-0.423349f,0.092698f,0.002263f,-0.013572f,0.093837f,-0.400136f,-0.013589f,0.092698f,
|
||||||
|
0.002265f,-0.423349f,0.092698f,0.403842f,-0.422739f,0.09157f,0.404492f,-0.013589f,0.092698f,0.002263f,-0.013572f,0.093837f,
|
||||||
|
0.002263f,-0.013572f,0.093837f,0.404492f,-0.013589f,0.092698f,0.403842f,0.396564f,0.09157f,0.002265f,0.397221f,0.092698f,
|
||||||
|
-0.400136f,-0.013589f,0.092698f,0.002263f,-0.013572f,0.093837f,0.002265f,0.397221f,0.092698f,-0.399478f,0.396564f,0.09157f,
|
||||||
|
-0.754564f,0.392188f,0.082561f,-0.847646f,0.390218f,0.074693f,-0.850941f,-0.013754f,0.075629f,-0.756921f,-0.013703f,0.083588f,
|
||||||
|
-0.847646f,0.390218f,0.074693f,-0.916591f,0.389343f,0.064218f,-0.920742f,-0.013776f,0.065028f,-0.850941f,-0.013754f,0.075629f,
|
||||||
|
-0.850941f,-0.013754f,0.075629f,-0.920742f,-0.013776f,0.065028f,-0.916591f,-0.416033f,0.064218f,-0.847646f,-0.416846f,0.074693f,
|
||||||
|
-0.756921f,-0.013703f,0.083588f,-0.850941f,-0.013754f,0.075629f,-0.847646f,-0.416846f,0.074693f,-0.754564f,-0.418675f,0.082561f,
|
||||||
|
-0.754564f,0.392188f,0.082561f,-0.756921f,-0.013703f,0.083588f,-0.629925f,-0.01364f,0.089279f,-0.628465f,0.394595f,0.088189f,
|
||||||
|
-0.756921f,-0.013703f,0.083588f,-0.754564f,-0.418675f,0.082561f,-0.628465f,-0.420911f,0.088189f,-0.629925f,-0.01364f,0.089279f,
|
||||||
|
-0.629925f,-0.01364f,0.089279f,-0.628465f,-0.420911f,0.088189f,-0.399478f,-0.422739f,0.09157f,-0.400136f,-0.013589f,0.092698f,
|
||||||
|
-0.628465f,0.394595f,0.088189f,-0.629925f,-0.01364f,0.089279f,-0.400136f,-0.013589f,0.092698f,-0.399478f,0.396564f,0.09157f,
|
||||||
|
-0.844501f,0.846382f,0.050154f,-0.802664f,0.865969f,0.054004f,-0.814648f,0.914535f,0.037876f,-0.871108f,0.872793f,0.036675f,
|
||||||
|
-0.802664f,0.865969f,0.054004f,-0.726455f,0.887439f,0.058224f,-0.733131f,0.94538f,0.040237f,-0.814648f,0.914535f,0.037876f,
|
||||||
|
-0.814648f,0.914535f,0.037876f,-0.733131f,0.94538f,0.040237f,-0.74278f,0.982563f,0.019733f,-0.830745f,0.945555f,0.018815f,
|
||||||
|
-0.871108f,0.872793f,0.036675f,-0.814648f,0.914535f,0.037876f,-0.830745f,0.945555f,0.018815f,-0.894756f,0.896267f,0.018385f,
|
||||||
|
-0.726455f,0.887439f,0.058224f,-0.612405f,0.905582f,0.061789f,-0.615909f,0.968735f,0.042517f,-0.733131f,0.94538f,0.040237f,
|
||||||
|
-0.612405f,0.905582f,0.061789f,-0.392243f,0.917941f,0.064218f,-0.393822f,0.983443f,0.044197f,-0.615909f,0.968735f,0.042517f,
|
||||||
|
-0.615909f,0.968735f,0.042517f,-0.393822f,0.983443f,0.044197f,-0.396235f,1.025424f,0.021594f,-0.621266f,1.009264f,0.020771f,
|
||||||
|
-0.733131f,0.94538f,0.040237f,-0.615909f,0.968735f,0.042517f,-0.621266f,1.009264f,0.020771f,-0.74278f,0.982563f,0.019733f,
|
||||||
|
-0.621266f,1.009264f,0.020771f,-0.396235f,1.025424f,0.021594f,-0.398382f,1.047552f,0.0f,-0.626031f,1.030658f,0.0f,
|
||||||
|
-0.74278f,0.982563f,0.019733f,-0.621266f,1.009264f,0.020771f,-0.626031f,1.030658f,0.0f,-0.750636f,1.002556f,0.0f,
|
||||||
|
-0.830745f,0.945555f,0.018815f,-0.74278f,0.982563f,0.019733f,-0.750636f,1.002556f,0.0f,-0.842153f,0.963302f,0.0f,
|
||||||
|
-0.894756f,0.896267f,0.018385f,-0.830745f,0.945555f,0.018815f,-0.842153f,0.963302f,0.0f,-0.909674f,0.911075f,0.0f,
|
||||||
|
-0.398382f,1.047552f,0.0f,-0.396235f,1.025424f,0.021594f,0.002279f,1.030811f,0.021869f,0.00227f,1.053183f,0.0f,
|
||||||
|
0.002279f,1.030811f,0.021869f,-0.396235f,1.025424f,0.021594f,-0.393822f,0.983443f,0.044197f,0.00229f,0.988345f,0.044757f,
|
||||||
|
0.400637f,1.025424f,0.021594f,0.002279f,1.030811f,0.021869f,0.00229f,0.988345f,0.044757f,0.398253f,0.983443f,0.044197f,
|
||||||
|
0.00227f,1.053183f,0.0f,0.002279f,1.030811f,0.021869f,0.400637f,1.025424f,0.021594f,0.402758f,1.047552f,0.0f,
|
||||||
|
-0.393822f,0.983443f,0.044197f,-0.392243f,0.917941f,0.064218f,0.002297f,0.922061f,0.065028f,0.00229f,0.988345f,0.044757f,
|
||||||
|
0.00229f,0.988345f,0.044757f,0.002297f,0.922061f,0.065028f,0.396693f,0.917941f,0.064218f,0.398253f,0.983443f,0.044197f,
|
||||||
|
0.396693f,-0.928623f,0.064218f,0.002297f,-0.932501f,0.065028f,0.00229f,-0.994896f,0.044757f,0.398253f,-0.990281f,0.044197f,
|
||||||
|
0.002297f,-0.932501f,0.065028f,-0.392243f,-0.928623f,0.064218f,-0.393822f,-0.990281f,0.044197f,0.00229f,-0.994896f,0.044757f,
|
||||||
|
0.00229f,-0.994896f,0.044757f,-0.393822f,-0.990281f,0.044197f,-0.396235f,-1.0298f,0.021594f,0.002279f,-1.034871f,0.021869f,
|
||||||
|
0.398253f,-0.990281f,0.044197f,0.00229f,-0.994896f,0.044757f,0.002279f,-1.034871f,0.021869f,0.400637f,-1.0298f,0.021594f,
|
||||||
|
-0.396235f,-1.0298f,0.021594f,-0.398382f,-1.050629f,0.0f,0.00227f,-1.05593f,0.0f,0.002279f,-1.034871f,0.021869f,
|
||||||
|
0.002279f,-1.034871f,0.021869f,0.00227f,-1.05593f,0.0f,0.402758f,-1.050629f,0.0f,0.400637f,-1.0298f,0.021594f,
|
||||||
|
-0.909674f,-0.922159f,0.0f,-0.842153f,-0.971323f,0.0f,-0.830745f,-0.954616f,0.018815f,-0.894756f,-0.90822f,0.018385f,
|
||||||
|
-0.842153f,-0.971323f,0.0f,-0.750636f,-1.008273f,0.0f,-0.74278f,-0.989453f,0.019733f,-0.830745f,-0.954616f,0.018815f,
|
||||||
|
-0.830745f,-0.954616f,0.018815f,-0.74278f,-0.989453f,0.019733f,-0.733131f,-0.954452f,0.040237f,-0.814648f,-0.925416f,0.037876f,
|
||||||
|
-0.894756f,-0.90822f,0.018385f,-0.830745f,-0.954616f,0.018815f,-0.814648f,-0.925416f,0.037876f,-0.871108f,-0.886124f,0.036675f,
|
||||||
|
-0.750636f,-1.008273f,0.0f,-0.626031f,-1.034726f,0.0f,-0.621266f,-1.014588f,0.020771f,-0.74278f,-0.989453f,0.019733f,
|
||||||
|
-0.626031f,-1.034726f,0.0f,-0.398382f,-1.050629f,0.0f,-0.396235f,-1.0298f,0.021594f,-0.621266f,-1.014588f,0.020771f,
|
||||||
|
-0.621266f,-1.014588f,0.020771f,-0.396235f,-1.0298f,0.021594f,-0.393822f,-0.990281f,0.044197f,-0.615909f,-0.976437f,0.042517f,
|
||||||
|
-0.74278f,-0.989453f,0.019733f,-0.621266f,-1.014588f,0.020771f,-0.615909f,-0.976437f,0.042517f,-0.733131f,-0.954452f,0.040237f,
|
||||||
|
-0.615909f,-0.976437f,0.042517f,-0.393822f,-0.990281f,0.044197f,-0.392243f,-0.928623f,0.064218f,-0.612405f,-0.916988f,0.061789f,
|
||||||
|
-0.733131f,-0.954452f,0.040237f,-0.615909f,-0.976437f,0.042517f,-0.612405f,-0.916988f,0.061789f,-0.726455f,-0.89991f,0.058224f,
|
||||||
|
-0.814648f,-0.925416f,0.037876f,-0.733131f,-0.954452f,0.040237f,-0.726455f,-0.89991f,0.058224f,-0.802664f,-0.8797f,0.054004f,
|
||||||
|
-0.871108f,-0.886124f,0.036675f,-0.814648f,-0.925416f,0.037876f,-0.802664f,-0.8797f,0.054004f,-0.844501f,-0.861263f,0.050154f,
|
||||||
|
0.846982f,-0.861263f,0.050154f,0.87333f,-0.886124f,0.036675f,0.914973f,-0.833367f,0.037876f,0.866523f,-0.822169f,0.054004f,
|
||||||
|
0.914973f,-0.833367f,0.037876f,0.87333f,-0.886124f,0.036675f,0.896749f,-0.90822f,0.018385f,0.94592f,-0.848408f,0.018815f,
|
||||||
|
0.945745f,-0.755482f,0.040237f,0.914973f,-0.833367f,0.037876f,0.94592f,-0.848408f,0.018815f,0.982841f,-0.764498f,0.019733f,
|
||||||
|
0.866523f,-0.822169f,0.054004f,0.914973f,-0.833367f,0.037876f,0.945745f,-0.755482f,0.040237f,0.887941f,-0.749245f,0.058224f,
|
||||||
|
0.896749f,-0.90822f,0.018385f,0.911522f,-0.922159f,0.0f,0.963626f,-0.859068f,0.0f,0.94592f,-0.848408f,0.018815f,
|
||||||
|
0.94592f,-0.848408f,0.018815f,0.963626f,-0.859068f,0.0f,1.002787f,-0.771839f,0.0f,0.982841f,-0.764498f,0.019733f,
|
||||||
|
0.945745f,-0.755482f,0.040237f,0.982841f,-0.764498f,0.019733f,1.009478f,-0.645808f,0.020771f,0.969045f,-0.640802f,0.042517f,
|
||||||
|
0.982841f,-0.764498f,0.019733f,1.002787f,-0.771839f,0.0f,1.030822f,-0.650261f,0.0f,1.009478f,-0.645808f,0.020771f,
|
||||||
|
1.009478f,-0.645808f,0.020771f,1.030822f,-0.650261f,0.0f,1.047675f,-0.421723f,0.0f,1.025601f,-0.419734f,0.021594f,
|
||||||
|
1.009478f,-0.645808f,0.020771f,1.025601f,-0.419734f,0.021594f,0.983719f,-0.417497f,0.044197f,0.969045f,-0.640802f,0.042517f,
|
||||||
|
0.887941f,-0.749245f,0.058224f,0.945745f,-0.755482f,0.040237f,0.969045f,-0.640802f,0.042517f,0.906041f,-0.637528f,0.061789f,
|
||||||
|
0.906041f,-0.637528f,0.061789f,0.969045f,-0.640802f,0.042517f,0.983719f,-0.417497f,0.044197f,0.918372f,-0.416033f,0.064218f,
|
||||||
|
0.918372f,-0.416033f,0.064218f,0.983719f,-0.417497f,0.044197f,0.98861f,-0.013736f,0.044757f,0.922482f,-0.013776f,0.065028f,
|
||||||
|
0.98861f,-0.013736f,0.044757f,0.983719f,-0.417497f,0.044197f,1.025601f,-0.419734f,0.021594f,1.030975f,-0.013673f,0.021869f,
|
||||||
|
0.983719f,0.390919f,0.044197f,0.98861f,-0.013736f,0.044757f,1.030975f,-0.013673f,0.021869f,1.025601f,0.393327f,0.021594f,
|
||||||
|
0.922482f,-0.013776f,0.065028f,0.98861f,-0.013736f,0.044757f,0.983719f,0.390919f,0.044197f,0.918372f,0.389343f,0.064218f,
|
||||||
|
1.025601f,-0.419734f,0.021594f,1.047675f,-0.421723f,0.0f,1.053293f,-0.013618f,0.0f,1.030975f,-0.013673f,0.021869f,
|
||||||
|
1.030975f,-0.013673f,0.021869f,1.053293f,-0.013618f,0.0f,1.047675f,0.39547f,0.0f,1.025601f,0.393327f,0.021594f,
|
||||||
|
-0.909674f,-0.922159f,0.0f,-0.894756f,-0.90822f,0.018385f,-0.944409f,-0.848408f,0.018815f,-0.962289f,-0.859068f,0.0f,
|
||||||
|
-0.944409f,-0.848408f,0.018815f,-0.894756f,-0.90822f,0.018385f,-0.871108f,-0.886124f,0.036675f,-0.913159f,-0.833367f,0.037876f,
|
||||||
|
-0.981692f,-0.764498f,0.019733f,-0.944409f,-0.848408f,0.018815f,-0.913159f,-0.833367f,0.037876f,-0.944233f,-0.755482f,0.040237f,
|
||||||
|
-0.962289f,-0.859068f,0.0f,-0.944409f,-0.848408f,0.018815f,-0.981692f,-0.764498f,0.019733f,-1.001834f,-0.771839f,0.0f,
|
||||||
|
-0.871108f,-0.886124f,0.036675f,-0.844501f,-0.861263f,0.050154f,-0.864233f,-0.822169f,0.054004f,-0.913159f,-0.833367f,0.037876f,
|
||||||
|
-0.913159f,-0.833367f,0.037876f,-0.864233f,-0.822169f,0.054004f,-0.885862f,-0.749245f,0.058224f,-0.944233f,-0.755482f,0.040237f,
|
||||||
|
-0.981692f,-0.764498f,0.019733f,-0.944233f,-0.755482f,0.040237f,-0.967761f,-0.640802f,0.042517f,-1.008591f,-0.645808f,0.020771f,
|
||||||
|
-0.944233f,-0.755482f,0.040237f,-0.885862f,-0.749245f,0.058224f,-0.90414f,-0.637528f,0.061789f,-0.967761f,-0.640802f,0.042517f,
|
||||||
|
-0.967761f,-0.640802f,0.042517f,-0.90414f,-0.637528f,0.061789f,-0.916591f,-0.416033f,0.064218f,-0.982578f,-0.417497f,0.044197f,
|
||||||
|
-0.967761f,-0.640802f,0.042517f,-0.982578f,-0.417497f,0.044197f,-1.024871f,-0.419734f,0.021594f,-1.008591f,-0.645808f,0.020771f,
|
||||||
|
-1.001834f,-0.771839f,0.0f,-0.981692f,-0.764498f,0.019733f,-1.008591f,-0.645808f,0.020771f,-1.030143f,-0.650261f,0.0f,
|
||||||
|
-1.030143f,-0.650261f,0.0f,-1.008591f,-0.645808f,0.020771f,-1.024871f,-0.419734f,0.021594f,-1.047163f,-0.421723f,0.0f,
|
||||||
|
-1.047163f,0.39547f,0.0f,-1.052836f,-0.013618f,0.0f,-1.030298f,-0.013673f,0.021869f,-1.024871f,0.393327f,0.021594f,
|
||||||
|
-1.052836f,-0.013618f,0.0f,-1.047163f,-0.421723f,0.0f,-1.024871f,-0.419734f,0.021594f,-1.030298f,-0.013673f,0.021869f,
|
||||||
|
-1.030298f,-0.013673f,0.021869f,-1.024871f,-0.419734f,0.021594f,-0.982578f,-0.417497f,0.044197f,-0.987517f,-0.013736f,0.044757f,
|
||||||
|
-1.024871f,0.393327f,0.021594f,-1.030298f,-0.013673f,0.021869f,-0.987517f,-0.013736f,0.044757f,-0.982578f,0.390919f,0.044197f,
|
||||||
|
-0.982578f,-0.417497f,0.044197f,-0.916591f,-0.416033f,0.064218f,-0.920742f,-0.013776f,0.065028f,-0.987517f,-0.013736f,0.044757f,
|
||||||
|
-0.987517f,-0.013736f,0.044757f,-0.920742f,-0.013776f,0.065028f,-0.916591f,0.389343f,0.064218f,-0.982578f,0.390919f,0.044197f,
|
||||||
|
0.396693f,0.917941f,0.064218f,0.616423f,0.905582f,0.061789f,0.619893f,0.968735f,0.042517f,0.398253f,0.983443f,0.044197f,
|
||||||
|
0.616423f,0.905582f,0.061789f,0.729904f,0.887439f,0.058224f,0.736514f,0.94538f,0.040237f,0.619893f,0.968735f,0.042517f,
|
||||||
|
0.619893f,0.968735f,0.042517f,0.736514f,0.94538f,0.040237f,0.746069f,0.982563f,0.019733f,0.625198f,1.009264f,0.020771f,
|
||||||
|
0.400637f,1.025424f,0.021594f,0.398253f,0.983443f,0.044197f,0.619893f,0.968735f,0.042517f,0.625198f,1.009264f,0.020771f,
|
||||||
|
0.729904f,0.887439f,0.058224f,0.805551f,0.865969f,0.054004f,0.817418f,0.914535f,0.037876f,0.736514f,0.94538f,0.040237f,
|
||||||
|
0.805551f,0.865969f,0.054004f,0.846982f,0.846382f,0.050154f,0.87333f,0.872793f,0.036675f,0.817418f,0.914535f,0.037876f,
|
||||||
|
0.817418f,0.914535f,0.037876f,0.87333f,0.872793f,0.036675f,0.896749f,0.896267f,0.018385f,0.833359f,0.945555f,0.018815f,
|
||||||
|
0.736514f,0.94538f,0.040237f,0.817418f,0.914535f,0.037876f,0.833359f,0.945555f,0.018815f,0.746069f,0.982563f,0.019733f,
|
||||||
|
0.833359f,0.945555f,0.018815f,0.896749f,0.896267f,0.018385f,0.911522f,0.911075f,0.0f,0.844656f,0.963302f,0.0f,
|
||||||
|
0.746069f,0.982563f,0.019733f,0.833359f,0.945555f,0.018815f,0.844656f,0.963302f,0.0f,0.753849f,1.002556f,0.0f,
|
||||||
|
0.625198f,1.009264f,0.020771f,0.746069f,0.982563f,0.019733f,0.753849f,1.002556f,0.0f,0.629917f,1.030658f,0.0f,
|
||||||
|
0.400637f,1.025424f,0.021594f,0.625198f,1.009264f,0.020771f,0.629917f,1.030658f,0.0f,0.402758f,1.047552f,0.0f,
|
||||||
|
0.396693f,-0.928623f,0.064218f,0.398253f,-0.990281f,0.044197f,0.619893f,-0.976437f,0.042517f,0.616423f,-0.916988f,0.061789f,
|
||||||
|
0.619893f,-0.976437f,0.042517f,0.398253f,-0.990281f,0.044197f,0.400637f,-1.0298f,0.021594f,0.625198f,-1.014588f,0.020771f,
|
||||||
|
0.736514f,-0.954452f,0.040237f,0.619893f,-0.976437f,0.042517f,0.625198f,-1.014588f,0.020771f,0.746069f,-0.989453f,0.019733f,
|
||||||
|
0.616423f,-0.916988f,0.061789f,0.619893f,-0.976437f,0.042517f,0.736514f,-0.954452f,0.040237f,0.729904f,-0.89991f,0.058224f,
|
||||||
|
0.400637f,-1.0298f,0.021594f,0.402758f,-1.050629f,0.0f,0.629917f,-1.034726f,0.0f,0.625198f,-1.014588f,0.020771f,
|
||||||
|
0.625198f,-1.014588f,0.020771f,0.629917f,-1.034726f,0.0f,0.753849f,-1.008273f,0.0f,0.746069f,-0.989453f,0.019733f,
|
||||||
|
0.736514f,-0.954452f,0.040237f,0.746069f,-0.989453f,0.019733f,0.833359f,-0.954616f,0.018815f,0.817418f,-0.925416f,0.037876f,
|
||||||
|
0.746069f,-0.989453f,0.019733f,0.753849f,-1.008273f,0.0f,0.844656f,-0.971323f,0.0f,0.833359f,-0.954616f,0.018815f,
|
||||||
|
0.833359f,-0.954616f,0.018815f,0.844656f,-0.971323f,0.0f,0.911522f,-0.922159f,0.0f,0.896749f,-0.90822f,0.018385f,
|
||||||
|
0.833359f,-0.954616f,0.018815f,0.896749f,-0.90822f,0.018385f,0.87333f,-0.886124f,0.036675f,0.817418f,-0.925416f,0.037876f,
|
||||||
|
0.729904f,-0.89991f,0.058224f,0.736514f,-0.954452f,0.040237f,0.817418f,-0.925416f,0.037876f,0.805551f,-0.8797f,0.054004f,
|
||||||
|
0.805551f,-0.8797f,0.054004f,0.817418f,-0.925416f,0.037876f,0.87333f,-0.886124f,0.036675f,0.846982f,-0.861263f,0.050154f,
|
||||||
|
0.403842f,-0.422739f,0.09157f,0.401892f,-0.652534f,0.088189f,0.62799f,-0.648441f,0.084918f,0.632327f,-0.420911f,0.088189f,
|
||||||
|
0.401892f,-0.652534f,0.088189f,0.399509f,-0.775509f,0.082561f,0.622688f,-0.768902f,0.079479f,0.62799f,-0.648441f,0.084918f,
|
||||||
|
0.62799f,-0.648441f,0.084918f,0.622688f,-0.768902f,0.079479f,0.741819f,-0.760488f,0.074426f,0.750737f,-0.64344f,0.079479f,
|
||||||
|
0.632327f,-0.420911f,0.088189f,0.62799f,-0.648441f,0.084918f,0.750737f,-0.64344f,0.079479f,0.757739f,-0.418675f,0.082561f,
|
||||||
|
0.399509f,-0.775509f,0.082561f,0.397559f,-0.8642f,0.074693f,0.618351f,-0.854962f,0.071886f,0.622688f,-0.768902f,0.079479f,
|
||||||
|
0.397559f,-0.8642f,0.074693f,0.396693f,-0.928623f,0.064218f,0.616423f,-0.916988f,0.061789f,0.618351f,-0.854962f,0.071886f,
|
||||||
|
0.618351f,-0.854962f,0.071886f,0.616423f,-0.916988f,0.061789f,0.729904f,-0.89991f,0.058224f,0.733736f,-0.842312f,0.067487f,
|
||||||
|
0.622688f,-0.768902f,0.079479f,0.618351f,-0.854962f,0.071886f,0.733736f,-0.842312f,0.067487f,0.741819f,-0.760488f,0.074426f,
|
||||||
|
0.741819f,-0.760488f,0.074426f,0.733736f,-0.842312f,0.067487f,0.812784f,-0.828995f,0.061777f,0.826898f,-0.752861f,0.067487f,
|
||||||
|
0.733736f,-0.842312f,0.067487f,0.729904f,-0.89991f,0.058224f,0.805551f,-0.8797f,0.054004f,0.812784f,-0.828995f,0.061777f,
|
||||||
|
0.812784f,-0.828995f,0.061777f,0.805551f,-0.8797f,0.054004f,0.846982f,-0.861263f,0.050154f,0.866523f,-0.822169f,0.054004f,
|
||||||
|
0.826898f,-0.752861f,0.067487f,0.812784f,-0.828995f,0.061777f,0.866523f,-0.822169f,0.054004f,0.887941f,-0.749245f,0.058224f,
|
||||||
|
0.757739f,-0.418675f,0.082561f,0.750737f,-0.64344f,0.079479f,0.840305f,-0.639347f,0.071886f,0.850096f,-0.416846f,0.074693f,
|
||||||
|
0.750737f,-0.64344f,0.079479f,0.741819f,-0.760488f,0.074426f,0.826898f,-0.752861f,0.067487f,0.840305f,-0.639347f,0.071886f,
|
||||||
|
0.840305f,-0.639347f,0.071886f,0.826898f,-0.752861f,0.067487f,0.887941f,-0.749245f,0.058224f,0.906041f,-0.637528f,0.061789f,
|
||||||
|
0.850096f,-0.416846f,0.074693f,0.840305f,-0.639347f,0.071886f,0.906041f,-0.637528f,0.061789f,0.918372f,-0.416033f,0.064218f,
|
||||||
|
0.403842f,0.396564f,0.09157f,0.404492f,-0.013589f,0.092698f,0.633773f,-0.01364f,0.08928f,0.632327f,0.394595f,0.088189f,
|
||||||
|
0.404492f,-0.013589f,0.092698f,0.403842f,-0.422739f,0.09157f,0.632327f,-0.420911f,0.088189f,0.633773f,-0.01364f,0.08928f,
|
||||||
|
0.633773f,-0.01364f,0.08928f,0.632327f,-0.420911f,0.088189f,0.757739f,-0.418675f,0.082561f,0.760073f,-0.013703f,0.083588f,
|
||||||
|
0.632327f,0.394595f,0.088189f,0.633773f,-0.01364f,0.08928f,0.760073f,-0.013703f,0.083588f,0.757739f,0.392188f,0.082561f,
|
||||||
|
0.757739f,-0.418675f,0.082561f,0.850096f,-0.416846f,0.074693f,0.853359f,-0.013754f,0.075629f,0.760073f,-0.013703f,0.083588f,
|
||||||
|
0.850096f,-0.416846f,0.074693f,0.918372f,-0.416033f,0.064218f,0.922482f,-0.013776f,0.065028f,0.853359f,-0.013754f,0.075629f,
|
||||||
|
0.853359f,-0.013754f,0.075629f,0.922482f,-0.013776f,0.065028f,0.918372f,0.389343f,0.064218f,0.850096f,0.390218f,0.074693f,
|
||||||
|
0.760073f,-0.013703f,0.083588f,0.853359f,-0.013754f,0.075629f,0.850096f,0.390218f,0.074693f,0.757739f,0.392188f,0.082561f,
|
||||||
|
-1.047163f,0.39547f,0.0f,-1.024871f,0.393327f,0.021594f,-1.008591f,0.622221f,0.020771f,-1.030143f,0.626951f,0.0f,
|
||||||
|
-1.008591f,0.622221f,0.020771f,-1.024871f,0.393327f,0.021594f,-0.982578f,0.390919f,0.044197f,-0.967761f,0.616903f,0.042517f,
|
||||||
|
-0.981692f,0.744767f,0.019733f,-1.008591f,0.622221f,0.020771f,-0.967761f,0.616903f,0.042517f,-0.944233f,0.735189f,0.040237f,
|
||||||
|
-1.030143f,0.626951f,0.0f,-1.008591f,0.622221f,0.020771f,-0.981692f,0.744767f,0.019733f,-1.001834f,0.752565f,0.0f,
|
||||||
|
-0.982578f,0.390919f,0.044197f,-0.916591f,0.389343f,0.064218f,-0.90414f,0.613425f,0.061789f,-0.967761f,0.616903f,0.042517f,
|
||||||
|
-0.967761f,0.616903f,0.042517f,-0.90414f,0.613425f,0.061789f,-0.885862f,0.728563f,0.058224f,-0.944233f,0.735189f,0.040237f,
|
||||||
|
-0.981692f,0.744767f,0.019733f,-0.944233f,0.735189f,0.040237f,-0.913159f,0.816749f,0.037876f,-0.944409f,0.832727f,0.018815f,
|
||||||
|
-0.944233f,0.735189f,0.040237f,-0.885862f,0.728563f,0.058224f,-0.864233f,0.804853f,0.054004f,-0.913159f,0.816749f,0.037876f,
|
||||||
|
-0.913159f,0.816749f,0.037876f,-0.864233f,0.804853f,0.054004f,-0.844501f,0.846382f,0.050154f,-0.871108f,0.872793f,0.036675f,
|
||||||
|
-0.913159f,0.816749f,0.037876f,-0.871108f,0.872793f,0.036675f,-0.894756f,0.896267f,0.018385f,-0.944409f,0.832727f,0.018815f,
|
||||||
|
-1.001834f,0.752565f,0.0f,-0.981692f,0.744767f,0.019733f,-0.944409f,0.832727f,0.018815f,-0.962289f,0.844051f,0.0f,
|
||||||
|
-0.962289f,0.844051f,0.0f,-0.944409f,0.832727f,0.018815f,-0.894756f,0.896267f,0.018385f,-0.909674f,0.911075f,0.0f,
|
||||||
|
0.918372f,0.389343f,0.064218f,0.983719f,0.390919f,0.044197f,0.969045f,0.616903f,0.042517f,0.906041f,0.613425f,0.061789f,
|
||||||
|
0.969045f,0.616903f,0.042517f,0.983719f,0.390919f,0.044197f,1.025601f,0.393327f,0.021594f,1.009478f,0.622221f,0.020771f,
|
||||||
|
0.945745f,0.735189f,0.040237f,0.969045f,0.616903f,0.042517f,1.009478f,0.622221f,0.020771f,0.982841f,0.744767f,0.019733f,
|
||||||
|
0.906041f,0.613425f,0.061789f,0.969045f,0.616903f,0.042517f,0.945745f,0.735189f,0.040237f,0.887941f,0.728563f,0.058224f,
|
||||||
|
1.025601f,0.393327f,0.021594f,1.047675f,0.39547f,0.0f,1.030822f,0.626951f,0.0f,1.009478f,0.622221f,0.020771f,
|
||||||
|
1.009478f,0.622221f,0.020771f,1.030822f,0.626951f,0.0f,1.002787f,0.752565f,0.0f,0.982841f,0.744767f,0.019733f,
|
||||||
|
0.945745f,0.735189f,0.040237f,0.982841f,0.744767f,0.019733f,0.94592f,0.832727f,0.018815f,0.914973f,0.816749f,0.037876f,
|
||||||
|
0.982841f,0.744767f,0.019733f,1.002787f,0.752565f,0.0f,0.963626f,0.844051f,0.0f,0.94592f,0.832727f,0.018815f,
|
||||||
|
0.94592f,0.832727f,0.018815f,0.963626f,0.844051f,0.0f,0.911522f,0.911075f,0.0f,0.896749f,0.896267f,0.018385f,
|
||||||
|
0.94592f,0.832727f,0.018815f,0.896749f,0.896267f,0.018385f,0.87333f,0.872793f,0.036675f,0.914973f,0.816749f,0.037876f,
|
||||||
|
0.887941f,0.728563f,0.058224f,0.945745f,0.735189f,0.040237f,0.914973f,0.816749f,0.037876f,0.866523f,0.804853f,0.054004f,
|
||||||
|
0.866523f,0.804853f,0.054004f,0.914973f,0.816749f,0.037876f,0.87333f,0.872793f,0.036675f,0.846982f,0.846382f,0.050154f,
|
||||||
|
0.396693f,0.917941f,0.064218f,0.397559f,0.849503f,0.074693f,0.618351f,0.83969f,0.071886f,0.616423f,0.905582f,0.061789f,
|
||||||
|
0.397559f,0.849503f,0.074693f,0.399509f,0.756465f,0.082561f,0.622688f,0.749446f,0.079479f,0.618351f,0.83969f,0.071886f,
|
||||||
|
0.618351f,0.83969f,0.071886f,0.622688f,0.749446f,0.079479f,0.741819f,0.740507f,0.074426f,0.733736f,0.826251f,0.067487f,
|
||||||
|
0.616423f,0.905582f,0.061789f,0.618351f,0.83969f,0.071886f,0.733736f,0.826251f,0.067487f,0.729904f,0.887439f,0.058224f,
|
||||||
|
0.399509f,0.756465f,0.082561f,0.401892f,0.629367f,0.088189f,0.62799f,0.625019f,0.084918f,0.622688f,0.749446f,0.079479f,
|
||||||
|
0.401892f,0.629367f,0.088189f,0.403842f,0.396564f,0.09157f,0.632327f,0.394595f,0.088189f,0.62799f,0.625019f,0.084918f,
|
||||||
|
0.62799f,0.625019f,0.084918f,0.632327f,0.394595f,0.088189f,0.757739f,0.392188f,0.082561f,0.750737f,0.619705f,0.079479f,
|
||||||
|
0.622688f,0.749446f,0.079479f,0.62799f,0.625019f,0.084918f,0.750737f,0.619705f,0.079479f,0.741819f,0.740507f,0.074426f,
|
||||||
|
0.741819f,0.740507f,0.074426f,0.750737f,0.619705f,0.079479f,0.840305f,0.615357f,0.071886f,0.826898f,0.732405f,0.067487f,
|
||||||
|
0.750737f,0.619705f,0.079479f,0.757739f,0.392188f,0.082561f,0.850096f,0.390218f,0.074693f,0.840305f,0.615357f,0.071886f,
|
||||||
|
0.840305f,0.615357f,0.071886f,0.850096f,0.390218f,0.074693f,0.918372f,0.389343f,0.064218f,0.906041f,0.613425f,0.061789f,
|
||||||
|
0.826898f,0.732405f,0.067487f,0.840305f,0.615357f,0.071886f,0.906041f,0.613425f,0.061789f,0.887941f,0.728563f,0.058224f,
|
||||||
|
0.729904f,0.887439f,0.058224f,0.733736f,0.826251f,0.067487f,0.812784f,0.812104f,0.061777f,0.805551f,0.865969f,0.054004f,
|
||||||
|
0.733736f,0.826251f,0.067487f,0.741819f,0.740507f,0.074426f,0.826898f,0.732405f,0.067487f,0.812784f,0.812104f,0.061777f,
|
||||||
|
0.812784f,0.812104f,0.061777f,0.826898f,0.732405f,0.067487f,0.887941f,0.728563f,0.058224f,0.866523f,0.804853f,0.054004f,
|
||||||
|
0.805551f,0.865969f,0.054004f,0.812784f,0.812104f,0.061777f,0.866523f,0.804853f,0.054004f,0.846982f,0.846382f,0.050154f,
|
||||||
|
0.399509f,0.756465f,0.082561f,0.397559f,0.849503f,0.074693f,0.002293f,0.852774f,0.075629f,0.002284f,0.758804f,0.083588f,
|
||||||
|
0.397559f,0.849503f,0.074693f,0.396693f,0.917941f,0.064218f,0.002297f,0.922061f,0.065028f,0.002293f,0.852774f,0.075629f,
|
||||||
|
0.002293f,0.852774f,0.075629f,0.002297f,0.922061f,0.065028f,-0.392243f,0.917941f,0.064218f,-0.39312f,0.849503f,0.074693f,
|
||||||
|
0.002284f,0.758804f,0.083588f,0.002293f,0.852774f,0.075629f,-0.39312f,0.849503f,0.074693f,-0.395094f,0.756465f,0.082561f,
|
||||||
|
0.399509f,0.756465f,0.082561f,0.002284f,0.758804f,0.083588f,0.002274f,0.630816f,0.089279f,0.401892f,0.629367f,0.088189f,
|
||||||
|
0.002284f,0.758804f,0.083588f,-0.395094f,0.756465f,0.082561f,-0.397505f,0.629367f,0.088189f,0.002274f,0.630816f,0.089279f,
|
||||||
|
0.002274f,0.630816f,0.089279f,-0.397505f,0.629367f,0.088189f,-0.399478f,0.396564f,0.09157f,0.002265f,0.397221f,0.092698f,
|
||||||
|
0.401892f,0.629367f,0.088189f,0.002274f,0.630816f,0.089279f,0.002265f,0.397221f,0.092698f,0.403842f,0.396564f,0.09157f,
|
||||||
|
-0.916591f,0.389343f,0.064218f,-0.847646f,0.390218f,0.074693f,-0.837759f,0.615357f,0.071886f,-0.90414f,0.613425f,0.061789f,
|
||||||
|
-0.847646f,0.390218f,0.074693f,-0.754564f,0.392188f,0.082561f,-0.747494f,0.619705f,0.079479f,-0.837759f,0.615357f,0.071886f,
|
||||||
|
-0.837759f,0.615357f,0.071886f,-0.747494f,0.619705f,0.079479f,-0.738488f,0.740507f,0.074426f,-0.824221f,0.732405f,0.067487f,
|
||||||
|
-0.90414f,0.613425f,0.061789f,-0.837759f,0.615357f,0.071886f,-0.824221f,0.732405f,0.067487f,-0.885862f,0.728563f,0.058224f,
|
||||||
|
-0.754564f,0.392188f,0.082561f,-0.628465f,0.394595f,0.088189f,-0.624085f,0.625019f,0.084918f,-0.747494f,0.619705f,0.079479f,
|
||||||
|
-0.628465f,0.394595f,0.088189f,-0.399478f,0.396564f,0.09157f,-0.397505f,0.629367f,0.088189f,-0.624085f,0.625019f,0.084918f,
|
||||||
|
-0.624085f,0.625019f,0.084918f,-0.397505f,0.629367f,0.088189f,-0.395094f,0.756465f,0.082561f,-0.618732f,0.749446f,0.079479f,
|
||||||
|
-0.747494f,0.619705f,0.079479f,-0.624085f,0.625019f,0.084918f,-0.618732f,0.749446f,0.079479f,-0.738488f,0.740507f,0.074426f,
|
||||||
|
-0.738488f,0.740507f,0.074426f,-0.618732f,0.749446f,0.079479f,-0.614352f,0.83969f,0.071886f,-0.730326f,0.826251f,0.067487f,
|
||||||
|
-0.618732f,0.749446f,0.079479f,-0.395094f,0.756465f,0.082561f,-0.39312f,0.849503f,0.074693f,-0.614352f,0.83969f,0.071886f,
|
||||||
|
-0.614352f,0.83969f,0.071886f,-0.39312f,0.849503f,0.074693f,-0.392243f,0.917941f,0.064218f,-0.612405f,0.905582f,0.061789f,
|
||||||
|
-0.730326f,0.826251f,0.067487f,-0.614352f,0.83969f,0.071886f,-0.612405f,0.905582f,0.061789f,-0.726455f,0.887439f,0.058224f,
|
||||||
|
-0.885862f,0.728563f,0.058224f,-0.824221f,0.732405f,0.067487f,-0.809968f,0.812104f,0.061777f,-0.864233f,0.804853f,0.054004f,
|
||||||
|
-0.824221f,0.732405f,0.067487f,-0.738488f,0.740507f,0.074426f,-0.730326f,0.826251f,0.067487f,-0.809968f,0.812104f,0.061777f,
|
||||||
|
-0.809968f,0.812104f,0.061777f,-0.730326f,0.826251f,0.067487f,-0.726455f,0.887439f,0.058224f,-0.802664f,0.865969f,0.054004f,
|
||||||
|
-0.864233f,0.804853f,0.054004f,-0.809968f,0.812104f,0.061777f,-0.802664f,0.865969f,0.054004f,-0.844501f,0.846382f,0.050154f,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const float cfGameIconTexCoords[] = {
|
||||||
|
0.098918f,0.907702f,0.118783f,0.916444f,0.115314f,0.892403f,0.089549f,0.889167f,
|
||||||
|
0.118783f,0.916444f,0.154967f,0.926026f,0.153129f,0.898717f,0.115314f,0.892403f,
|
||||||
|
0.115314f,0.892403f,0.153129f,0.898717f,0.149254f,0.859921f,0.108547f,0.856305f,
|
||||||
|
0.089549f,0.889167f,0.115314f,0.892403f,0.108547f,0.856305f,0.07928f,0.854591f,
|
||||||
|
0.154967f,0.926026f,0.209119f,0.934124f,0.208194f,0.904715f,0.153129f,0.898717f,
|
||||||
|
0.209119f,0.934124f,0.313652f,0.93964f,0.313236f,0.909095f,0.208194f,0.904715f,
|
||||||
|
0.208194f,0.904715f,0.313236f,0.909095f,0.312299f,0.867044f,0.206115f,0.863911f,
|
||||||
|
0.153129f,0.898717f,0.208194f,0.904715f,0.206115f,0.863911f,0.149254f,0.859921f,
|
||||||
|
0.149254f,0.859921f,0.206115f,0.863911f,0.203573f,0.806797f,0.144978f,0.804425f,
|
||||||
|
0.206115f,0.863911f,0.312299f,0.867044f,0.311154f,0.808737f,0.203573f,0.806797f,
|
||||||
|
0.203573f,0.806797f,0.311154f,0.808737f,0.310217f,0.699784f,0.201493f,0.698917f,
|
||||||
|
0.144978f,0.804425f,0.203573f,0.806797f,0.201493f,0.698917f,0.141621f,0.697857f,
|
||||||
|
0.07928f,0.854591f,0.108547f,0.856305f,0.102119f,0.802484f,0.070602f,0.801622f,
|
||||||
|
0.108547f,0.856305f,0.149254f,0.859921f,0.144978f,0.804425f,0.102119f,0.802484f,
|
||||||
|
0.102119f,0.802484f,0.144978f,0.804425f,0.141621f,0.697857f,0.097425f,0.69699f,
|
||||||
|
0.070602f,0.801622f,0.102119f,0.802484f,0.097425f,0.69699f,0.064689f,0.696604f,
|
||||||
|
0.310217f,0.699784f,0.311154f,0.808737f,0.500971f,0.809384f,0.500967f,0.700073f,
|
||||||
|
0.311154f,0.808737f,0.312299f,0.867044f,0.500976f,0.868088f,0.500971f,0.809384f,
|
||||||
|
0.500971f,0.809384f,0.500976f,0.868088f,0.68958f,0.867044f,0.690711f,0.808737f,
|
||||||
|
0.500967f,0.700073f,0.500971f,0.809384f,0.690711f,0.808737f,0.691637f,0.699784f,
|
||||||
|
0.312299f,0.867044f,0.313236f,0.909095f,0.50098f,0.910555f,0.500976f,0.868088f,
|
||||||
|
0.313236f,0.909095f,0.313652f,0.93964f,0.500982f,0.941479f,0.50098f,0.910555f,
|
||||||
|
0.50098f,0.910555f,0.500982f,0.941479f,0.688243f,0.93964f,0.688654f,0.909095f,
|
||||||
|
0.500976f,0.868088f,0.50098f,0.910555f,0.688654f,0.909095f,0.68958f,0.867044f,
|
||||||
|
0.310217f,0.699784f,0.500967f,0.700073f,0.500965f,0.505784f,0.309905f,0.505792f,
|
||||||
|
0.500967f,0.700073f,0.691637f,0.699784f,0.691946f,0.505792f,0.500965f,0.505784f,
|
||||||
|
0.500965f,0.505784f,0.691946f,0.505792f,0.691637f,0.311325f,0.500967f,0.311013f,
|
||||||
|
0.309905f,0.505792f,0.500965f,0.505784f,0.500967f,0.311013f,0.310217f,0.311325f,
|
||||||
|
0.141621f,0.3134f,0.097425f,0.314333f,0.09586f,0.50587f,0.140502f,0.505846f,
|
||||||
|
0.097425f,0.314333f,0.064689f,0.314748f,0.062719f,0.505881f,0.09586f,0.50587f,
|
||||||
|
0.09586f,0.50587f,0.062719f,0.505881f,0.064689f,0.696604f,0.097425f,0.69699f,
|
||||||
|
0.140502f,0.505846f,0.09586f,0.50587f,0.097425f,0.69699f,0.141621f,0.697857f,
|
||||||
|
0.141621f,0.3134f,0.140502f,0.505846f,0.2008f,0.505816f,0.201493f,0.312259f,
|
||||||
|
0.140502f,0.505846f,0.141621f,0.697857f,0.201493f,0.698917f,0.2008f,0.505816f,
|
||||||
|
0.2008f,0.505816f,0.201493f,0.698917f,0.310217f,0.699784f,0.309905f,0.505792f,
|
||||||
|
0.201493f,0.312259f,0.2008f,0.505816f,0.309905f,0.505792f,0.310217f,0.311325f,
|
||||||
|
0.098918f,0.098051f,0.118783f,0.088764f,0.115314f,0.070013f,0.089549f,0.088764f,
|
||||||
|
0.118783f,0.088764f,0.154967f,0.078585f,0.153129f,0.056238f,0.115314f,0.070013f,
|
||||||
|
0.115314f,0.070013f,0.153129f,0.056238f,0.14647f,0.030613f,0.104205f,0.048635f,
|
||||||
|
0.089549f,0.088764f,0.115314f,0.070013f,0.104205f,0.048635f,0.073229f,0.072587f,
|
||||||
|
0.154967f,0.078585f,0.209119f,0.069983f,0.208194f,0.045626f,0.153129f,0.056238f,
|
||||||
|
0.209119f,0.069983f,0.313652f,0.064123f,0.313236f,0.038853f,0.208194f,0.045626f,
|
||||||
|
0.208194f,0.045626f,0.313236f,0.038853f,0.31157f,0.009921f,0.204497f,0.017695f,
|
||||||
|
0.153129f,0.056238f,0.208194f,0.045626f,0.204497f,0.017695f,0.14647f,0.030613f,
|
||||||
|
0.204497f,0.017695f,0.31157f,0.009921f,0.269666f,0.0f,0.202648f,0.01068f,
|
||||||
|
0.14647f,0.030613f,0.204497f,0.017695f,0.202648f,0.01068f,0.135631f,0.02136f,
|
||||||
|
0.104205f,0.048635f,0.14647f,0.030613f,0.135631f,0.02136f,0.100033f,0.042615f,
|
||||||
|
0.073229f,0.072587f,0.104205f,0.048635f,0.100033f,0.042615f,0.064435f,0.06387f,
|
||||||
|
0.269666f,0.0f,0.31157f,0.009921f,0.500973f,0.007329f,0.500969f,0.0f,
|
||||||
|
0.500973f,0.007329f,0.31157f,0.009921f,0.313236f,0.038853f,0.50098f,0.036595f,
|
||||||
|
0.6903f,0.009921f,0.500973f,0.007329f,0.50098f,0.036595f,0.688654f,0.038853f,
|
||||||
|
0.500969f,0.0f,0.500973f,0.007329f,0.6903f,0.009921f,0.732272f,0.0f,
|
||||||
|
0.313236f,0.038853f,0.313652f,0.064123f,0.500982f,0.062169f,0.50098f,0.036595f,
|
||||||
|
0.50098f,0.036595f,0.500982f,0.062169f,0.688243f,0.064123f,0.688654f,0.038853f,
|
||||||
|
0.688243f,0.93964f,0.500982f,0.941479f,0.50098f,0.965553f,0.688654f,0.963427f,
|
||||||
|
0.500982f,0.941479f,0.313652f,0.93964f,0.313236f,0.963427f,0.50098f,0.965553f,
|
||||||
|
0.50098f,0.965553f,0.313236f,0.963427f,0.31157f,0.990661f,0.500973f,0.993101f,
|
||||||
|
0.688654f,0.963427f,0.50098f,0.965553f,0.500973f,0.993101f,0.6903f,0.990661f,
|
||||||
|
0.31157f,0.990661f,0.269666f,1.0f,0.500969f,1.0f,0.500973f,0.993101f,
|
||||||
|
0.500973f,0.993101f,0.500969f,1.0f,0.732272f,1.0f,0.6903f,0.990661f,
|
||||||
|
0.064435f,0.939877f,0.100033f,0.959885f,0.104205f,0.954218f,0.073229f,0.931672f,
|
||||||
|
0.100033f,0.959885f,0.135631f,0.979893f,0.14647f,0.971183f,0.104205f,0.954218f,
|
||||||
|
0.104205f,0.954218f,0.14647f,0.971183f,0.153129f,0.947062f,0.115314f,0.934095f,
|
||||||
|
0.073229f,0.931672f,0.104205f,0.954218f,0.115314f,0.934095f,0.089549f,0.916444f,
|
||||||
|
0.135631f,0.979893f,0.202648f,0.989946f,0.204497f,0.983343f,0.14647f,0.971183f,
|
||||||
|
0.202648f,0.989946f,0.269666f,1.0f,0.31157f,0.990661f,0.204497f,0.983343f,
|
||||||
|
0.204497f,0.983343f,0.31157f,0.990661f,0.313236f,0.963427f,0.208194f,0.957052f,
|
||||||
|
0.14647f,0.971183f,0.204497f,0.983343f,0.208194f,0.957052f,0.153129f,0.947062f,
|
||||||
|
0.208194f,0.957052f,0.313236f,0.963427f,0.313652f,0.93964f,0.209119f,0.934124f,
|
||||||
|
0.153129f,0.947062f,0.208194f,0.957052f,0.209119f,0.934124f,0.154967f,0.926026f,
|
||||||
|
0.115314f,0.934095f,0.153129f,0.947062f,0.154967f,0.926026f,0.118783f,0.916444f,
|
||||||
|
0.089549f,0.916444f,0.115314f,0.934095f,0.118783f,0.916444f,0.098918f,0.907702f,
|
||||||
|
0.902043f,0.907702f,0.91132f,0.916444f,0.930054f,0.892403f,0.91132f,0.889167f,
|
||||||
|
0.930054f,0.892403f,0.91132f,0.916444f,0.927482f,0.931672f,0.951411f,0.902768f,
|
||||||
|
0.943816f,0.856305f,0.930054f,0.892403f,0.951411f,0.902768f,0.969416f,0.862518f,
|
||||||
|
0.91132f,0.889167f,0.930054f,0.892403f,0.943816f,0.856305f,0.92149f,0.854591f,
|
||||||
|
0.927482f,0.931672f,0.93619f,0.939877f,0.957425f,0.906662f,0.951411f,0.902768f,
|
||||||
|
0.951411f,0.902768f,0.957425f,0.906662f,0.97866f,0.873446f,0.969416f,0.862518f,
|
||||||
|
0.943816f,0.856305f,0.969416f,0.862518f,0.982322f,0.805934f,0.954418f,0.802484f,
|
||||||
|
0.969416f,0.862518f,0.97866f,0.873446f,0.98933f,0.807659f,0.982322f,0.805934f,
|
||||||
|
0.982322f,0.805934f,0.98933f,0.807659f,1.0f,0.741872f,0.990089f,0.698531f,
|
||||||
|
0.982322f,0.805934f,0.990089f,0.698531f,0.961185f,0.69699f,0.954418f,0.802484f,
|
||||||
|
0.92149f,0.854591f,0.943816f,0.856305f,0.954418f,0.802484f,0.930084f,0.801622f,
|
||||||
|
0.930084f,0.801622f,0.954418f,0.802484f,0.961185f,0.69699f,0.935938f,0.696604f,
|
||||||
|
0.935938f,0.696604f,0.961185f,0.69699f,0.96344f,0.50587f,0.93789f,0.505881f,
|
||||||
|
0.96344f,0.50587f,0.961185f,0.69699f,0.990089f,0.698531f,0.992677f,0.505827f,
|
||||||
|
0.961185f,0.314333f,0.96344f,0.50587f,0.992677f,0.505827f,0.990089f,0.312674f,
|
||||||
|
0.93789f,0.505881f,0.96344f,0.50587f,0.961185f,0.314333f,0.935938f,0.314748f,
|
||||||
|
0.990089f,0.698531f,1.0f,0.741872f,1.0f,0.505805f,0.992677f,0.505827f,
|
||||||
|
0.992677f,0.505827f,1.0f,0.505805f,1.0f,0.269739f,0.990089f,0.312674f,
|
||||||
|
0.064435f,0.939877f,0.073229f,0.931672f,0.049066f,0.902768f,0.042992f,0.906662f,
|
||||||
|
0.049066f,0.902768f,0.073229f,0.931672f,0.089549f,0.916444f,0.070633f,0.892403f,
|
||||||
|
0.030884f,0.862518f,0.049066f,0.902768f,0.070633f,0.892403f,0.056735f,0.856305f,
|
||||||
|
0.042992f,0.906662f,0.049066f,0.902768f,0.030884f,0.862518f,0.021549f,0.873446f,
|
||||||
|
0.089549f,0.916444f,0.098918f,0.907702f,0.089549f,0.889167f,0.070633f,0.892403f,
|
||||||
|
0.070633f,0.892403f,0.089549f,0.889167f,0.07928f,0.854591f,0.056735f,0.856305f,
|
||||||
|
0.030884f,0.862518f,0.056735f,0.856305f,0.046029f,0.802484f,0.017852f,0.805934f,
|
||||||
|
0.056735f,0.856305f,0.07928f,0.854591f,0.070602f,0.801622f,0.046029f,0.802484f,
|
||||||
|
0.046029f,0.802484f,0.070602f,0.801622f,0.064689f,0.696604f,0.039196f,0.69699f,
|
||||||
|
0.046029f,0.802484f,0.039196f,0.69699f,0.010008f,0.698531f,0.017852f,0.805934f,
|
||||||
|
0.021549f,0.873446f,0.030884f,0.862518f,0.017852f,0.805934f,0.010774f,0.807659f,
|
||||||
|
0.010774f,0.807659f,0.017852f,0.805934f,0.010008f,0.698531f,0.0f,0.741872f,
|
||||||
|
0.0f,0.269739f,0.0f,0.505805f,0.007394f,0.505827f,0.010008f,0.312673f,
|
||||||
|
0.0f,0.505805f,0.0f,0.741872f,0.010008f,0.698531f,0.007394f,0.505827f,
|
||||||
|
0.007394f,0.505827f,0.010008f,0.698531f,0.039196f,0.69699f,0.036918f,0.50587f,
|
||||||
|
0.010008f,0.312673f,0.007394f,0.505827f,0.036918f,0.50587f,0.039196f,0.314333f,
|
||||||
|
0.039196f,0.69699f,0.064689f,0.696604f,0.062719f,0.505881f,0.036918f,0.50587f,
|
||||||
|
0.036918f,0.50587f,0.062719f,0.505881f,0.064689f,0.314748f,0.039196f,0.314333f,
|
||||||
|
0.688243f,0.064123f,0.792572f,0.069983f,0.793487f,0.045626f,0.688654f,0.038853f,
|
||||||
|
0.792572f,0.069983f,0.846453f,0.078585f,0.848273f,0.056238f,0.793487f,0.045626f,
|
||||||
|
0.793487f,0.045626f,0.848273f,0.056238f,0.854867f,0.030613f,0.797148f,0.017695f,
|
||||||
|
0.6903f,0.009921f,0.688654f,0.038853f,0.793487f,0.045626f,0.797148f,0.017695f,
|
||||||
|
0.846453f,0.078585f,0.882371f,0.088764f,0.885805f,0.070013f,0.848273f,0.056238f,
|
||||||
|
0.882371f,0.088764f,0.902043f,0.098051f,0.91132f,0.088764f,0.885805f,0.070013f,
|
||||||
|
0.885805f,0.070013f,0.91132f,0.088764f,0.927482f,0.072587f,0.896806f,0.048635f,
|
||||||
|
0.848273f,0.056238f,0.885805f,0.070013f,0.896806f,0.048635f,0.854867f,0.030613f,
|
||||||
|
0.896806f,0.048635f,0.927482f,0.072587f,0.93619f,0.06387f,0.900938f,0.042615f,
|
||||||
|
0.854867f,0.030613f,0.896806f,0.048635f,0.900938f,0.042615f,0.865686f,0.02136f,
|
||||||
|
0.797148f,0.017695f,0.854867f,0.030613f,0.865686f,0.02136f,0.798979f,0.01068f,
|
||||||
|
0.6903f,0.009921f,0.797148f,0.017695f,0.798979f,0.01068f,0.732272f,0.0f,
|
||||||
|
0.688243f,0.93964f,0.688654f,0.963427f,0.793487f,0.957052f,0.792572f,0.934124f,
|
||||||
|
0.793487f,0.957052f,0.688654f,0.963427f,0.6903f,0.990661f,0.797148f,0.983343f,
|
||||||
|
0.848273f,0.947062f,0.793487f,0.957052f,0.797148f,0.983343f,0.854867f,0.971183f,
|
||||||
|
0.792572f,0.934124f,0.793487f,0.957052f,0.848273f,0.947062f,0.846453f,0.926026f,
|
||||||
|
0.6903f,0.990661f,0.732272f,1.0f,0.798979f,0.989946f,0.797148f,0.983343f,
|
||||||
|
0.797148f,0.983343f,0.798979f,0.989946f,0.865686f,0.979893f,0.854867f,0.971183f,
|
||||||
|
0.848273f,0.947062f,0.854867f,0.971183f,0.896806f,0.954218f,0.885805f,0.934095f,
|
||||||
|
0.854867f,0.971183f,0.865686f,0.979893f,0.900938f,0.959885f,0.896806f,0.954218f,
|
||||||
|
0.896806f,0.954218f,0.900938f,0.959885f,0.93619f,0.939877f,0.927482f,0.931672f,
|
||||||
|
0.896806f,0.954218f,0.927482f,0.931672f,0.91132f,0.916444f,0.885805f,0.934095f,
|
||||||
|
0.846453f,0.926026f,0.848273f,0.947062f,0.885805f,0.934095f,0.882371f,0.916444f,
|
||||||
|
0.882371f,0.916444f,0.885805f,0.934095f,0.91132f,0.916444f,0.902043f,0.907702f,
|
||||||
|
0.691637f,0.699784f,0.690711f,0.808737f,0.798063f,0.806796f,0.800123f,0.698917f,
|
||||||
|
0.690711f,0.808737f,0.68958f,0.867044f,0.795546f,0.863911f,0.798063f,0.806796f,
|
||||||
|
0.798063f,0.806796f,0.795546f,0.863911f,0.85211f,0.859921f,0.856345f,0.804425f,
|
||||||
|
0.800123f,0.698917f,0.798063f,0.806796f,0.856345f,0.804425f,0.859669f,0.697857f,
|
||||||
|
0.68958f,0.867044f,0.688654f,0.909095f,0.793487f,0.904715f,0.795546f,0.863911f,
|
||||||
|
0.688654f,0.909095f,0.688243f,0.93964f,0.792572f,0.934124f,0.793487f,0.904715f,
|
||||||
|
0.793487f,0.904715f,0.792572f,0.934124f,0.846453f,0.926026f,0.848273f,0.898717f,
|
||||||
|
0.795546f,0.863911f,0.793487f,0.904715f,0.848273f,0.898717f,0.85211f,0.859921f,
|
||||||
|
0.85211f,0.859921f,0.848273f,0.898717f,0.885805f,0.892403f,0.892507f,0.856305f,
|
||||||
|
0.848273f,0.898717f,0.846453f,0.926026f,0.882371f,0.916444f,0.885805f,0.892403f,
|
||||||
|
0.885805f,0.892403f,0.882371f,0.916444f,0.902043f,0.907702f,0.91132f,0.889167f,
|
||||||
|
0.892507f,0.856305f,0.885805f,0.892403f,0.91132f,0.889167f,0.92149f,0.854591f,
|
||||||
|
0.859669f,0.697857f,0.856345f,0.804425f,0.898872f,0.802484f,0.903521f,0.69699f,
|
||||||
|
0.856345f,0.804425f,0.85211f,0.859921f,0.892507f,0.856305f,0.898872f,0.802484f,
|
||||||
|
0.898872f,0.802484f,0.892507f,0.856305f,0.92149f,0.854591f,0.930084f,0.801622f,
|
||||||
|
0.903521f,0.69699f,0.898872f,0.802484f,0.930084f,0.801622f,0.935938f,0.696604f,
|
||||||
|
0.691637f,0.311325f,0.691946f,0.505792f,0.800809f,0.505816f,0.800123f,0.312259f,
|
||||||
|
0.691946f,0.505792f,0.691637f,0.699784f,0.800123f,0.698917f,0.800809f,0.505816f,
|
||||||
|
0.800809f,0.505816f,0.800123f,0.698917f,0.859669f,0.697857f,0.860777f,0.505846f,
|
||||||
|
0.800123f,0.312259f,0.800809f,0.505816f,0.860777f,0.505846f,0.859669f,0.3134f,
|
||||||
|
0.859669f,0.697857f,0.903521f,0.69699f,0.90507f,0.50587f,0.860777f,0.505846f,
|
||||||
|
0.903521f,0.69699f,0.935938f,0.696604f,0.93789f,0.505881f,0.90507f,0.50587f,
|
||||||
|
0.90507f,0.50587f,0.93789f,0.505881f,0.935938f,0.314748f,0.903521f,0.314333f,
|
||||||
|
0.860777f,0.505846f,0.90507f,0.50587f,0.903521f,0.314333f,0.859669f,0.3134f,
|
||||||
|
0.0f,0.269739f,0.010008f,0.312673f,0.017852f,0.203923f,0.010774f,0.202091f,
|
||||||
|
0.017852f,0.203923f,0.010008f,0.312673f,0.039196f,0.314333f,0.046029f,0.207588f,
|
||||||
|
0.030884f,0.14549f,0.017852f,0.203923f,0.046029f,0.207588f,0.056735f,0.152091f,
|
||||||
|
0.010774f,0.202091f,0.017852f,0.203923f,0.030884f,0.14549f,0.021549f,0.134442f,
|
||||||
|
0.039196f,0.314333f,0.064689f,0.314748f,0.070602f,0.208504f,0.046029f,0.207588f,
|
||||||
|
0.046029f,0.207588f,0.070602f,0.208504f,0.07928f,0.153913f,0.056735f,0.152091f,
|
||||||
|
0.030884f,0.14549f,0.056735f,0.152091f,0.070632f,0.114303f,0.049066f,0.103292f,
|
||||||
|
0.056735f,0.152091f,0.07928f,0.153913f,0.089549f,0.117742f,0.070632f,0.114303f,
|
||||||
|
0.070632f,0.114303f,0.089549f,0.117742f,0.098918f,0.098051f,0.089549f,0.088764f,
|
||||||
|
0.070632f,0.114303f,0.089549f,0.088764f,0.073229f,0.072587f,0.049066f,0.103292f,
|
||||||
|
0.021549f,0.134442f,0.030884f,0.14549f,0.049066f,0.103292f,0.042992f,0.099156f,
|
||||||
|
0.042992f,0.099156f,0.049066f,0.103292f,0.073229f,0.072587f,0.064435f,0.06387f,
|
||||||
|
0.935938f,0.314748f,0.961185f,0.314333f,0.954418f,0.207588f,0.930084f,0.208504f,
|
||||||
|
0.954418f,0.207588f,0.961185f,0.314333f,0.990089f,0.312674f,0.982322f,0.203923f,
|
||||||
|
0.943816f,0.152092f,0.954418f,0.207588f,0.982322f,0.203923f,0.969416f,0.145491f,
|
||||||
|
0.930084f,0.208504f,0.954418f,0.207588f,0.943816f,0.152092f,0.92149f,0.153913f,
|
||||||
|
0.990089f,0.312674f,1.0f,0.269739f,0.98933f,0.202091f,0.982322f,0.203923f,
|
||||||
|
0.982322f,0.203923f,0.98933f,0.202091f,0.97866f,0.134442f,0.969416f,0.145491f,
|
||||||
|
0.943816f,0.152092f,0.969416f,0.145491f,0.951411f,0.103292f,0.930054f,0.114304f,
|
||||||
|
0.969416f,0.145491f,0.97866f,0.134442f,0.957425f,0.099156f,0.951411f,0.103292f,
|
||||||
|
0.951411f,0.103292f,0.957425f,0.099156f,0.93619f,0.06387f,0.927482f,0.072587f,
|
||||||
|
0.951411f,0.103292f,0.927482f,0.072587f,0.91132f,0.088764f,0.930054f,0.114304f,
|
||||||
|
0.92149f,0.153913f,0.943816f,0.152092f,0.930054f,0.114304f,0.91132f,0.117742f,
|
||||||
|
0.91132f,0.117742f,0.930054f,0.114304f,0.91132f,0.088764f,0.902043f,0.098051f,
|
||||||
|
0.688243f,0.064123f,0.688654f,0.096571f,0.793487f,0.101224f,0.792572f,0.069983f,
|
||||||
|
0.688654f,0.096571f,0.68958f,0.140684f,0.795546f,0.144012f,0.793487f,0.101224f,
|
||||||
|
0.793487f,0.101224f,0.795546f,0.144012f,0.85211f,0.14825f,0.848273f,0.107596f,
|
||||||
|
0.792572f,0.069983f,0.793487f,0.101224f,0.848273f,0.107596f,0.846453f,0.078585f,
|
||||||
|
0.68958f,0.140684f,0.690711f,0.200945f,0.798063f,0.203007f,0.795546f,0.144012f,
|
||||||
|
0.690711f,0.200945f,0.691637f,0.311325f,0.800123f,0.312259f,0.798063f,0.203007f,
|
||||||
|
0.798063f,0.203007f,0.800123f,0.312259f,0.859669f,0.3134f,0.856345f,0.205526f,
|
||||||
|
0.795546f,0.144012f,0.798063f,0.203007f,0.856345f,0.205526f,0.85211f,0.14825f,
|
||||||
|
0.85211f,0.14825f,0.856345f,0.205526f,0.898872f,0.207588f,0.892507f,0.152092f,
|
||||||
|
0.856345f,0.205526f,0.859669f,0.3134f,0.903521f,0.314333f,0.898872f,0.207588f,
|
||||||
|
0.898872f,0.207588f,0.903521f,0.314333f,0.935938f,0.314748f,0.930084f,0.208504f,
|
||||||
|
0.892507f,0.152092f,0.898872f,0.207588f,0.930084f,0.208504f,0.92149f,0.153913f,
|
||||||
|
0.846453f,0.078585f,0.848273f,0.107596f,0.885805f,0.114304f,0.882371f,0.088764f,
|
||||||
|
0.848273f,0.107596f,0.85211f,0.14825f,0.892507f,0.152092f,0.885805f,0.114304f,
|
||||||
|
0.885805f,0.114304f,0.892507f,0.152092f,0.92149f,0.153913f,0.91132f,0.117742f,
|
||||||
|
0.882371f,0.088764f,0.885805f,0.114304f,0.91132f,0.117742f,0.902043f,0.098051f,
|
||||||
|
0.68958f,0.140684f,0.688654f,0.096571f,0.50098f,0.095021f,0.500976f,0.139575f,
|
||||||
|
0.688654f,0.096571f,0.688243f,0.064123f,0.500982f,0.062169f,0.50098f,0.095021f,
|
||||||
|
0.50098f,0.095021f,0.500982f,0.062169f,0.313652f,0.064123f,0.313236f,0.096571f,
|
||||||
|
0.500976f,0.139575f,0.50098f,0.095021f,0.313236f,0.096571f,0.312299f,0.140684f,
|
||||||
|
0.68958f,0.140684f,0.500976f,0.139575f,0.500971f,0.200258f,0.690711f,0.200945f,
|
||||||
|
0.500976f,0.139575f,0.312299f,0.140684f,0.311154f,0.200945f,0.500971f,0.200258f,
|
||||||
|
0.500971f,0.200258f,0.311154f,0.200945f,0.310217f,0.311325f,0.500967f,0.311013f,
|
||||||
|
0.690711f,0.200945f,0.500971f,0.200258f,0.500967f,0.311013f,0.691637f,0.311325f,
|
||||||
|
0.064689f,0.314748f,0.097425f,0.314333f,0.102119f,0.207588f,0.070602f,0.208504f,
|
||||||
|
0.097425f,0.314333f,0.141621f,0.3134f,0.144978f,0.205526f,0.102119f,0.207588f,
|
||||||
|
0.102119f,0.207588f,0.144978f,0.205526f,0.149254f,0.14825f,0.108547f,0.152092f,
|
||||||
|
0.070602f,0.208504f,0.102119f,0.207588f,0.108547f,0.152092f,0.07928f,0.153913f,
|
||||||
|
0.141621f,0.3134f,0.201493f,0.312259f,0.203573f,0.203007f,0.144978f,0.205526f,
|
||||||
|
0.201493f,0.312259f,0.310217f,0.311325f,0.311154f,0.200945f,0.203573f,0.203007f,
|
||||||
|
0.203573f,0.203007f,0.311154f,0.200945f,0.312299f,0.140684f,0.206115f,0.144012f,
|
||||||
|
0.144978f,0.205526f,0.203573f,0.203007f,0.206115f,0.144012f,0.149254f,0.14825f,
|
||||||
|
0.149254f,0.14825f,0.206115f,0.144012f,0.208194f,0.101224f,0.153129f,0.107596f,
|
||||||
|
0.206115f,0.144012f,0.312299f,0.140684f,0.313236f,0.096571f,0.208194f,0.101224f,
|
||||||
|
0.208194f,0.101224f,0.313236f,0.096571f,0.313652f,0.064123f,0.209119f,0.069983f,
|
||||||
|
0.153129f,0.107596f,0.208194f,0.101224f,0.209119f,0.069983f,0.154967f,0.078585f,
|
||||||
|
0.07928f,0.153913f,0.108547f,0.152092f,0.115314f,0.114304f,0.089549f,0.117742f,
|
||||||
|
0.108547f,0.152092f,0.149254f,0.14825f,0.153129f,0.107596f,0.115314f,0.114304f,
|
||||||
|
0.115314f,0.114304f,0.153129f,0.107596f,0.154967f,0.078585f,0.118783f,0.088764f,
|
||||||
|
0.089549f,0.117742f,0.115314f,0.114304f,0.118783f,0.088764f,0.098918f,0.098051f,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const float cfGameIconNormals[] = {
|
||||||
|
-0.210457f,-0.226211f,0.951071f,-0.137777f,-0.231234f,0.963093f,-0.113627f,-0.120055f,0.986243f,-0.216181f,-0.146015f,0.965373f,
|
||||||
|
-0.137777f,-0.231234f,0.963093f,-0.083714f,-0.234126f,0.968595f,-0.06603f,-0.119508f,0.990635f,-0.113627f,-0.120055f,0.986243f,
|
||||||
|
-0.113627f,-0.120055f,0.986243f,-0.06603f,-0.119508f,0.990635f,-0.062379f,-0.064577f,0.995961f,-0.113032f,-0.068284f,0.991242f,
|
||||||
|
-0.216181f,-0.146015f,0.965373f,-0.113627f,-0.120055f,0.986243f,-0.113032f,-0.068284f,0.991242f,-0.219508f,-0.086774f,0.971744f,
|
||||||
|
-0.083714f,-0.234126f,0.968595f,-0.036722f,-0.235389f,0.971207f,-0.028482f,-0.119193f,0.992463f,-0.06603f,-0.119508f,0.990635f,
|
||||||
|
-0.036722f,-0.235389f,0.971207f,-0.010823f,-0.235649f,0.971778f,-0.008321f,-0.119124f,0.992845f,-0.028482f,-0.119193f,0.992463f,
|
||||||
|
-0.028482f,-0.119193f,0.992463f,-0.008321f,-0.119124f,0.992845f,-0.007465f,-0.063717f,0.99794f,-0.026099f,-0.06375f,0.997625f,
|
||||||
|
-0.06603f,-0.119508f,0.990635f,-0.028482f,-0.119193f,0.992463f,-0.026099f,-0.06375f,0.997625f,-0.062379f,-0.064577f,0.995961f,
|
||||||
|
-0.062379f,-0.064577f,0.995961f,-0.026099f,-0.06375f,0.997625f,-0.025391f,-0.025563f,0.999351f,-0.061589f,-0.026301f,0.997755f,
|
||||||
|
-0.026099f,-0.06375f,0.997625f,-0.007465f,-0.063717f,0.99794f,-0.007172f,-0.02556f,0.999648f,-0.025391f,-0.025563f,0.999351f,
|
||||||
|
-0.025391f,-0.025563f,0.999351f,-0.007172f,-0.02556f,0.999648f,-0.007161f,-0.00707f,0.999949f,-0.025395f,-0.007088f,0.999652f,
|
||||||
|
-0.061589f,-0.026301f,0.997755f,-0.025391f,-0.025563f,0.999351f,-0.025395f,-0.007088f,0.999652f,-0.061548f,-0.00739f,0.998077f,
|
||||||
|
-0.219508f,-0.086774f,0.971744f,-0.113032f,-0.068284f,0.991242f,-0.112752f,-0.028685f,0.993209f,-0.22077f,-0.037047f,0.974622f,
|
||||||
|
-0.113032f,-0.068284f,0.991242f,-0.062379f,-0.064577f,0.995961f,-0.061589f,-0.026301f,0.997755f,-0.112752f,-0.028685f,0.993209f,
|
||||||
|
-0.112752f,-0.028685f,0.993209f,-0.061589f,-0.026301f,0.997755f,-0.061548f,-0.00739f,0.998077f,-0.112673f,-0.008234f,0.993598f,
|
||||||
|
-0.22077f,-0.037047f,0.974622f,-0.112752f,-0.028685f,0.993209f,-0.112673f,-0.008234f,0.993598f,-0.221f,-0.010721f,0.975215f,
|
||||||
|
-0.007161f,-0.00707f,0.999949f,-0.007172f,-0.02556f,0.999648f,0.0f,-0.025624f,0.999672f,0.0f,-0.007089f,0.999975f,
|
||||||
|
-0.007172f,-0.02556f,0.999648f,-0.007465f,-0.063717f,0.99794f,0.0f,-0.06378f,0.997964f,0.0f,-0.025624f,0.999672f,
|
||||||
|
0.0f,-0.025624f,0.999672f,0.0f,-0.06378f,0.997964f,0.007472f,-0.063716f,0.99794f,0.007179f,-0.025559f,0.999648f,
|
||||||
|
0.0f,-0.007089f,0.999975f,0.0f,-0.025624f,0.999672f,0.007179f,-0.025559f,0.999648f,0.007169f,-0.00707f,0.999949f,
|
||||||
|
-0.007465f,-0.063717f,0.99794f,-0.008321f,-0.119124f,0.992845f,0.0f,-0.119133f,0.992878f,0.0f,-0.06378f,0.997964f,
|
||||||
|
-0.008321f,-0.119124f,0.992845f,-0.010823f,-0.235649f,0.971778f,0.0f,-0.235564f,0.971859f,0.0f,-0.119133f,0.992878f,
|
||||||
|
0.0f,-0.119133f,0.992878f,0.0f,-0.235564f,0.971859f,0.010835f,-0.23565f,0.971778f,0.008329f,-0.119124f,0.992845f,
|
||||||
|
0.0f,-0.06378f,0.997964f,0.0f,-0.119133f,0.992878f,0.008329f,-0.119124f,0.992845f,0.007472f,-0.063716f,0.99794f,
|
||||||
|
-0.007161f,-0.00707f,0.999949f,0.0f,-0.007089f,0.999975f,0.0f,0.0f,1.0f,-0.007181f,0.0f,0.999974f,
|
||||||
|
0.0f,-0.007089f,0.999975f,0.007169f,-0.00707f,0.999949f,0.007189f,0.0f,0.999974f,0.0f,0.0f,1.0f,
|
||||||
|
0.0f,0.0f,1.0f,0.007189f,0.0f,0.999974f,0.00717f,0.007027f,0.99995f,0.0f,0.007045f,0.999975f,
|
||||||
|
-0.007181f,0.0f,0.999974f,0.0f,0.0f,1.0f,0.0f,0.007045f,0.999975f,-0.007163f,0.007027f,0.99995f,
|
||||||
|
-0.061553f,0.007347f,0.998077f,-0.112675f,0.008187f,0.993598f,-0.112665f,0.0f,0.993633f,-0.061598f,0.0f,0.998101f,
|
||||||
|
-0.112675f,0.008187f,0.993598f,-0.220997f,0.010655f,0.975216f,-0.220914f,-1.0E-6f,0.975293f,-0.112665f,0.0f,0.993633f,
|
||||||
|
-0.112665f,0.0f,0.993633f,-0.220914f,-1.0E-6f,0.975293f,-0.221f,-0.010721f,0.975215f,-0.112673f,-0.008234f,0.993598f,
|
||||||
|
-0.061598f,0.0f,0.998101f,-0.112665f,0.0f,0.993633f,-0.112673f,-0.008234f,0.993598f,-0.061548f,-0.00739f,0.998077f,
|
||||||
|
-0.061553f,0.007347f,0.998077f,-0.061598f,0.0f,0.998101f,-0.025456f,0.0f,0.999676f,-0.025398f,0.007046f,0.999653f,
|
||||||
|
-0.061598f,0.0f,0.998101f,-0.061548f,-0.00739f,0.998077f,-0.025395f,-0.007088f,0.999652f,-0.025456f,0.0f,0.999676f,
|
||||||
|
-0.025456f,0.0f,0.999676f,-0.025395f,-0.007088f,0.999652f,-0.007161f,-0.00707f,0.999949f,-0.007181f,0.0f,0.999974f,
|
||||||
|
-0.025398f,0.007046f,0.999653f,-0.025456f,0.0f,0.999676f,-0.007181f,0.0f,0.999974f,-0.007163f,0.007027f,0.99995f,
|
||||||
|
-0.211482f,0.213152f,0.953856f,-0.138447f,0.218126f,0.966051f,-0.198978f,0.347214f,0.916433f,-0.296456f,0.298724f,0.907126f,
|
||||||
|
-0.138447f,0.218126f,0.966051f,-0.084089f,0.221062f,0.971628f,-0.117212f,0.361162f,0.925107f,-0.198978f,0.347214f,0.916433f,
|
||||||
|
-0.198978f,0.347214f,0.916433f,-0.117212f,0.361162f,0.925107f,-0.168084f,0.541107f,0.823985f,-0.282777f,0.494303f,0.822011f,
|
||||||
|
-0.296456f,0.298724f,0.907126f,-0.198978f,0.347214f,0.916433f,-0.282777f,0.494303f,0.822011f,-0.402197f,0.405178f,0.821017f,
|
||||||
|
-0.084089f,0.221062f,0.971628f,-0.036885f,0.222305f,0.974279f,-0.050723f,0.367918f,0.928474f,-0.117212f,0.361162f,0.925107f,
|
||||||
|
-0.036885f,0.222305f,0.974279f,-0.010867f,0.22256f,0.974858f,-0.014805f,0.369601f,0.929073f,-0.050723f,0.367918f,0.928474f,
|
||||||
|
-0.050723f,0.367918f,0.928474f,-0.014805f,0.369601f,0.929073f,-0.020782f,0.568602f,0.822351f,-0.072149f,0.563165f,0.823189f,
|
||||||
|
-0.117212f,0.361162f,0.925107f,-0.050723f,0.367918f,0.928474f,-0.072149f,0.563165f,0.823189f,-0.168084f,0.541107f,0.823985f,
|
||||||
|
-0.072149f,0.563165f,0.823189f,-0.020782f,0.568602f,0.822351f,-0.025372f,0.696348f,0.717256f,-0.088478f,0.684053f,0.724047f,
|
||||||
|
-0.168084f,0.541107f,0.823985f,-0.072149f,0.563165f,0.823189f,-0.088478f,0.684053f,0.724047f,-0.20294f,0.64707f,0.734926f,
|
||||||
|
-0.282777f,0.494303f,0.822011f,-0.168084f,0.541107f,0.823985f,-0.20294f,0.64707f,0.734926f,-0.333245f,0.577074f,0.745609f,
|
||||||
|
-0.402197f,0.405178f,0.821017f,-0.282777f,0.494303f,0.822011f,-0.333245f,0.577074f,0.745609f,-0.466013f,0.469045f,0.75022f,
|
||||||
|
-0.025372f,0.696348f,0.717256f,-0.020782f,0.568602f,0.822351f,0.0f,0.568694f,0.822549f,-2.0E-6f,0.698486f,0.715623f,
|
||||||
|
0.0f,0.568694f,0.822549f,-0.020782f,0.568602f,0.822351f,-0.014805f,0.369601f,0.929073f,0.0f,0.369504f,0.929229f,
|
||||||
|
0.020804f,0.568602f,0.82235f,0.0f,0.568694f,0.822549f,0.0f,0.369504f,0.929229f,0.01482f,0.369601f,0.929072f,
|
||||||
|
-2.0E-6f,0.698486f,0.715623f,0.0f,0.568694f,0.822549f,0.020804f,0.568602f,0.82235f,0.025388f,0.696365f,0.717239f,
|
||||||
|
-0.014805f,0.369601f,0.929073f,-0.010867f,0.22256f,0.974858f,0.0f,0.222477f,0.974938f,0.0f,0.369504f,0.929229f,
|
||||||
|
0.0f,0.369504f,0.929229f,0.0f,0.222477f,0.974938f,0.010878f,0.222561f,0.974858f,0.01482f,0.369601f,0.929072f,
|
||||||
|
0.010835f,-0.23565f,0.971778f,0.0f,-0.235564f,0.971859f,0.0f,-0.389089f,0.9212f,0.014687f,-0.38921f,0.921032f,
|
||||||
|
0.0f,-0.235564f,0.971859f,-0.010823f,-0.235649f,0.971778f,-0.014671f,-0.38921f,0.921032f,0.0f,-0.389089f,0.9212f,
|
||||||
|
0.0f,-0.389089f,0.9212f,-0.014671f,-0.38921f,0.921032f,-0.020367f,-0.591835f,0.805802f,0.0f,-0.591896f,0.806014f,
|
||||||
|
0.014687f,-0.38921f,0.921032f,0.0f,-0.389089f,0.9212f,0.0f,-0.591896f,0.806014f,0.020387f,-0.591837f,0.8058f,
|
||||||
|
-0.020367f,-0.591835f,0.805802f,-0.024675f,-0.717705f,0.69591f,-2.0E-6f,-0.719788f,0.694194f,0.0f,-0.591896f,0.806014f,
|
||||||
|
0.0f,-0.591896f,0.806014f,-2.0E-6f,-0.719788f,0.694194f,0.02469f,-0.717725f,0.695889f,0.020387f,-0.591837f,0.8058f,
|
||||||
|
-0.46128f,-0.48965f,0.739908f,-0.32814f,-0.599132f,0.730319f,-0.27855f,-0.517113f,0.809323f,-0.397988f,-0.425903f,0.812534f,
|
||||||
|
-0.32814f,-0.599132f,0.730319f,-0.198659f,-0.669215f,0.716021f,-0.165045f,-0.564346f,0.808872f,-0.27855f,-0.517113f,0.809323f,
|
||||||
|
-0.27855f,-0.517113f,0.809323f,-0.165045f,-0.564346f,0.808872f,-0.116165f,-0.380579f,0.917423f,-0.197289f,-0.366449f,0.909281f,
|
||||||
|
-0.397988f,-0.425903f,0.812534f,-0.27855f,-0.517113f,0.809323f,-0.197289f,-0.366449f,0.909281f,-0.294472f,-0.315809f,0.901971f,
|
||||||
|
-0.198659f,-0.669215f,0.716021f,-0.086339f,-0.705672f,0.703258f,-0.070739f,-0.586438f,0.806899f,-0.165045f,-0.564346f,0.808872f,
|
||||||
|
-0.086339f,-0.705672f,0.703258f,-0.024675f,-0.717705f,0.69591f,-0.020367f,-0.591835f,0.805802f,-0.070739f,-0.586438f,0.806899f,
|
||||||
|
-0.070739f,-0.586438f,0.806899f,-0.020367f,-0.591835f,0.805802f,-0.014671f,-0.38921f,0.921032f,-0.050259f,-0.387507f,0.920496f,
|
||||||
|
-0.165045f,-0.564346f,0.808872f,-0.070739f,-0.586438f,0.806899f,-0.050259f,-0.387507f,0.920496f,-0.116165f,-0.380579f,0.917423f,
|
||||||
|
-0.050259f,-0.387507f,0.920496f,-0.014671f,-0.38921f,0.921032f,-0.010823f,-0.235649f,0.971778f,-0.036722f,-0.235389f,0.971207f,
|
||||||
|
-0.116165f,-0.380579f,0.917423f,-0.050259f,-0.387507f,0.920496f,-0.036722f,-0.235389f,0.971207f,-0.083714f,-0.234126f,0.968595f,
|
||||||
|
-0.197289f,-0.366449f,0.909281f,-0.116165f,-0.380579f,0.917423f,-0.083714f,-0.234126f,0.968595f,-0.137777f,-0.231234f,0.963093f,
|
||||||
|
-0.294472f,-0.315809f,0.901971f,-0.197289f,-0.366449f,0.909281f,-0.137777f,-0.231234f,0.963093f,-0.210457f,-0.226211f,0.951071f,
|
||||||
|
0.212501f,-0.226048f,0.950655f,0.297154f,-0.315494f,0.901201f,0.347306f,-0.209845f,0.913971f,0.218237f,-0.145906f,0.964927f,
|
||||||
|
0.347306f,-0.209845f,0.913971f,0.297154f,-0.315494f,0.901201f,0.401261f,-0.425239f,0.811271f,0.493682f,-0.297695f,0.817102f,
|
||||||
|
0.362206f,-0.121013f,0.924209f,0.347306f,-0.209845f,0.913971f,0.493682f,-0.297695f,0.817102f,0.542487f,-0.173678f,0.821915f,
|
||||||
|
0.218237f,-0.145906f,0.964927f,0.347306f,-0.209845f,0.913971f,0.362206f,-0.121013f,0.924209f,0.221558f,-0.086713f,0.971284f,
|
||||||
|
0.401261f,-0.425239f,0.811271f,0.464547f,-0.488911f,0.738351f,0.57643f,-0.348399f,0.739153f,0.493682f,-0.297695f,0.817102f,
|
||||||
|
0.493682f,-0.297695f,0.817102f,0.57643f,-0.348399f,0.739153f,0.648687f,-0.208869f,0.731832f,0.542487f,-0.173678f,0.821915f,
|
||||||
|
0.362206f,-0.121013f,0.924209f,0.542487f,-0.173678f,0.821915f,0.564441f,-0.072486f,0.822285f,0.368823f,-0.050932f,0.928103f,
|
||||||
|
0.542487f,-0.173678f,0.821915f,0.648687f,-0.208869f,0.731832f,0.685633f,-0.08861f,0.722534f,0.564441f,-0.072486f,0.822285f,
|
||||||
|
0.564441f,-0.072486f,0.822285f,0.685633f,-0.08861f,0.722534f,0.697362f,-0.024953f,0.716285f,0.569527f,-0.020487f,0.821717f,
|
||||||
|
0.564441f,-0.072486f,0.822285f,0.569527f,-0.020487f,0.821717f,0.370348f,-0.014597f,0.928778f,0.368823f,-0.050932f,0.928103f,
|
||||||
|
0.221558f,-0.086713f,0.971284f,0.362206f,-0.121013f,0.924209f,0.368823f,-0.050932f,0.928103f,0.222823f,-0.037022f,0.974156f,
|
||||||
|
0.222823f,-0.037022f,0.974156f,0.368823f,-0.050932f,0.928103f,0.370348f,-0.014597f,0.928778f,0.223053f,-0.010715f,0.974747f,
|
||||||
|
0.223053f,-0.010715f,0.974747f,0.370348f,-0.014597f,0.928778f,0.37024f,-1.0E-6f,0.928936f,0.222967f,-1.0E-6f,0.974826f,
|
||||||
|
0.37024f,-1.0E-6f,0.928936f,0.370348f,-0.014597f,0.928778f,0.569527f,-0.020487f,0.821717f,0.569586f,-1.0E-6f,0.821932f,
|
||||||
|
0.37035f,0.014508f,0.928779f,0.37024f,-1.0E-6f,0.928936f,0.569586f,-1.0E-6f,0.821932f,0.569522f,0.020364f,0.821724f,
|
||||||
|
0.222967f,-1.0E-6f,0.974826f,0.37024f,-1.0E-6f,0.928936f,0.37035f,0.014508f,0.928779f,0.223051f,0.010649f,0.974749f,
|
||||||
|
0.569527f,-0.020487f,0.821717f,0.697362f,-0.024953f,0.716285f,0.699353f,1.1E-5f,0.714776f,0.569586f,-1.0E-6f,0.821932f,
|
||||||
|
0.569586f,-1.0E-6f,0.821932f,0.699353f,1.1E-5f,0.714776f,0.697248f,0.024864f,0.716398f,0.569522f,0.020364f,0.821724f,
|
||||||
|
-0.46128f,-0.48965f,0.739908f,-0.397988f,-0.425903f,0.812534f,-0.490028f,-0.298377f,0.819051f,-0.572885f,-0.349196f,0.741529f,
|
||||||
|
-0.490028f,-0.298377f,0.819051f,-0.397988f,-0.425903f,0.812534f,-0.294472f,-0.315809f,0.901971f,-0.344264f,-0.210118f,0.915059f,
|
||||||
|
-0.538747f,-0.174169f,0.824268f,-0.490028f,-0.298377f,0.819051f,-0.344264f,-0.210118f,0.915059f,-0.359131f,-0.12118f,0.925386f,
|
||||||
|
-0.572885f,-0.349196f,0.741529f,-0.490028f,-0.298377f,0.819051f,-0.538747f,-0.174169f,0.824268f,-0.645088f,-0.209547f,0.734814f,
|
||||||
|
-0.294472f,-0.315809f,0.901971f,-0.210457f,-0.226211f,0.951071f,-0.216181f,-0.146015f,0.965373f,-0.344264f,-0.210118f,0.915059f,
|
||||||
|
-0.344264f,-0.210118f,0.915059f,-0.216181f,-0.146015f,0.965373f,-0.219508f,-0.086774f,0.971744f,-0.359131f,-0.12118f,0.925386f,
|
||||||
|
-0.538747f,-0.174169f,0.824268f,-0.359131f,-0.12118f,0.925386f,-0.365721f,-0.051004f,0.929326f,-0.560687f,-0.072708f,0.82483f,
|
||||||
|
-0.359131f,-0.12118f,0.925386f,-0.219508f,-0.086774f,0.971744f,-0.22077f,-0.037047f,0.974622f,-0.365721f,-0.051004f,0.929326f,
|
||||||
|
-0.365721f,-0.051004f,0.929326f,-0.22077f,-0.037047f,0.974622f,-0.221f,-0.010721f,0.975215f,-0.367244f,-0.014617f,0.93001f,
|
||||||
|
-0.365721f,-0.051004f,0.929326f,-0.367244f,-0.014617f,0.93001f,-0.565774f,-0.020551f,0.824304f,-0.560687f,-0.072708f,0.82483f,
|
||||||
|
-0.645088f,-0.209547f,0.734814f,-0.538747f,-0.174169f,0.824268f,-0.560687f,-0.072708f,0.82483f,-0.682094f,-0.088945f,0.725836f,
|
||||||
|
-0.682094f,-0.088945f,0.725836f,-0.560687f,-0.072708f,0.82483f,-0.565774f,-0.020551f,0.824304f,-0.69385f,-0.025062f,0.719683f,
|
||||||
|
-0.693736f,0.024972f,0.719796f,-0.695847f,1.1E-5f,0.71819f,-0.565837f,-1.0E-6f,0.824517f,-0.565768f,0.020427f,0.824311f,
|
||||||
|
-0.695847f,1.1E-5f,0.71819f,-0.69385f,-0.025062f,0.719683f,-0.565774f,-0.020551f,0.824304f,-0.565837f,-1.0E-6f,0.824517f,
|
||||||
|
-0.565837f,-1.0E-6f,0.824517f,-0.565774f,-0.020551f,0.824304f,-0.367244f,-0.014617f,0.93001f,-0.36714f,-1.0E-6f,0.930166f,
|
||||||
|
-0.565768f,0.020427f,0.824311f,-0.565837f,-1.0E-6f,0.824517f,-0.36714f,-1.0E-6f,0.930166f,-0.367245f,0.014528f,0.930011f,
|
||||||
|
-0.367244f,-0.014617f,0.93001f,-0.221f,-0.010721f,0.975215f,-0.220914f,-1.0E-6f,0.975293f,-0.36714f,-1.0E-6f,0.930166f,
|
||||||
|
-0.36714f,-1.0E-6f,0.930166f,-0.220914f,-1.0E-6f,0.975293f,-0.220997f,0.010655f,0.975216f,-0.367245f,0.014528f,0.930011f,
|
||||||
|
0.010878f,0.222561f,0.974858f,0.037001f,0.222307f,0.974274f,0.050884f,0.367932f,0.92846f,0.01482f,0.369601f,0.929072f,
|
||||||
|
0.037001f,0.222307f,0.974274f,0.084603f,0.221056f,0.971585f,0.117939f,0.361173f,0.92501f,0.050884f,0.367932f,0.92846f,
|
||||||
|
0.050884f,0.367932f,0.92846f,0.117939f,0.361173f,0.92501f,0.169134f,0.541105f,0.823771f,0.072381f,0.563194f,0.823149f,
|
||||||
|
0.020804f,0.568602f,0.82235f,0.01482f,0.369601f,0.929072f,0.050884f,0.367932f,0.92846f,0.072381f,0.563194f,0.823149f,
|
||||||
|
0.084603f,0.221056f,0.971585f,0.139597f,0.218066f,0.965898f,0.200629f,0.347092f,0.91612f,0.117939f,0.361173f,0.92501f,
|
||||||
|
0.139597f,0.218066f,0.965898f,0.213531f,0.212993f,0.953435f,0.299149f,0.298419f,0.906342f,0.200629f,0.347092f,0.91612f,
|
||||||
|
0.200629f,0.347092f,0.91612f,0.299149f,0.298419f,0.906342f,0.405489f,0.404531f,0.819716f,0.285031f,0.494036f,0.821393f,
|
||||||
|
0.117939f,0.361173f,0.92501f,0.200629f,0.347092f,0.91612f,0.285031f,0.494036f,0.821393f,0.169134f,0.541105f,0.823771f,
|
||||||
|
0.285031f,0.494036f,0.821393f,0.405489f,0.404531f,0.819716f,0.4693f,0.468325f,0.748619f,0.335556f,0.576804f,0.744781f,
|
||||||
|
0.169134f,0.541105f,0.823771f,0.285031f,0.494036f,0.821393f,0.335556f,0.576804f,0.744781f,0.204073f,0.64709f,0.734595f,
|
||||||
|
0.072381f,0.563194f,0.823149f,0.169134f,0.541105f,0.823771f,0.204073f,0.64709f,0.734595f,0.088715f,0.684119f,0.723955f,
|
||||||
|
0.020804f,0.568602f,0.82235f,0.072381f,0.563194f,0.823149f,0.088715f,0.684119f,0.723955f,0.025388f,0.696365f,0.717239f,
|
||||||
|
0.010835f,-0.23565f,0.971778f,0.014687f,-0.38921f,0.921032f,0.050418f,-0.38752f,0.920482f,0.036837f,-0.235391f,0.971203f,
|
||||||
|
0.050418f,-0.38752f,0.920482f,0.014687f,-0.38921f,0.921032f,0.020387f,-0.591837f,0.8058f,0.070967f,-0.586467f,0.806858f,
|
||||||
|
0.116885f,-0.380591f,0.917327f,0.050418f,-0.38752f,0.920482f,0.070967f,-0.586467f,0.806858f,0.166076f,-0.564345f,0.808662f,
|
||||||
|
0.036837f,-0.235391f,0.971203f,0.050418f,-0.38752f,0.920482f,0.116885f,-0.380591f,0.917327f,0.084225f,-0.234121f,0.968552f,
|
||||||
|
0.020387f,-0.591837f,0.8058f,0.02469f,-0.717725f,0.695889f,0.086571f,-0.705739f,0.703163f,0.070967f,-0.586467f,0.806858f,
|
||||||
|
0.070967f,-0.586467f,0.806858f,0.086571f,-0.705739f,0.703163f,0.199773f,-0.669232f,0.715695f,0.166076f,-0.564345f,0.808662f,
|
||||||
|
0.116885f,-0.380591f,0.917327f,0.166076f,-0.564345f,0.808662f,0.280776f,-0.516844f,0.808725f,0.198928f,-0.366325f,0.908974f,
|
||||||
|
0.166076f,-0.564345f,0.808662f,0.199773f,-0.669232f,0.715695f,0.33043f,-0.598851f,0.729516f,0.280776f,-0.516844f,0.808725f,
|
||||||
|
0.280776f,-0.516844f,0.808725f,0.33043f,-0.598851f,0.729516f,0.464547f,-0.488911f,0.738351f,0.401261f,-0.425239f,0.811271f,
|
||||||
|
0.280776f,-0.516844f,0.808725f,0.401261f,-0.425239f,0.811271f,0.297154f,-0.315494f,0.901201f,0.198928f,-0.366325f,0.908974f,
|
||||||
|
0.084225f,-0.234121f,0.968552f,0.116885f,-0.380591f,0.917327f,0.198928f,-0.366325f,0.908974f,0.138923f,-0.231173f,0.962943f,
|
||||||
|
0.138923f,-0.231173f,0.962943f,0.198928f,-0.366325f,0.908974f,0.297154f,-0.315494f,0.901201f,0.212501f,-0.226048f,0.950655f,
|
||||||
|
0.007169f,-0.00707f,0.999949f,0.007179f,-0.025559f,0.999648f,0.025473f,-0.02556f,0.999349f,0.025479f,-0.007087f,0.99965f,
|
||||||
|
0.007179f,-0.025559f,0.999648f,0.007472f,-0.063716f,0.99794f,0.02618f,-0.063744f,0.997623f,0.025473f,-0.02556f,0.999349f,
|
||||||
|
0.025473f,-0.02556f,0.999349f,0.02618f,-0.063744f,0.997623f,0.062764f,-0.064559f,0.995938f,0.061979f,-0.026292f,0.997731f,
|
||||||
|
0.025479f,-0.007087f,0.99965f,0.025473f,-0.02556f,0.999349f,0.061979f,-0.026292f,0.997731f,0.061944f,-0.007387f,0.998052f,
|
||||||
|
0.007472f,-0.063716f,0.99794f,0.008329f,-0.119124f,0.992845f,0.028568f,-0.119188f,0.992461f,0.02618f,-0.063744f,0.997623f,
|
||||||
|
0.008329f,-0.119124f,0.992845f,0.010835f,-0.23565f,0.971778f,0.036837f,-0.235391f,0.971203f,0.028568f,-0.119188f,0.992461f,
|
||||||
|
0.028568f,-0.119188f,0.992461f,0.036837f,-0.235391f,0.971203f,0.084225f,-0.234121f,0.968552f,0.066426f,-0.119489f,0.990611f,
|
||||||
|
0.02618f,-0.063744f,0.997623f,0.028568f,-0.119188f,0.992461f,0.066426f,-0.119489f,0.990611f,0.062764f,-0.064559f,0.995938f,
|
||||||
|
0.062764f,-0.064559f,0.995938f,0.066426f,-0.119489f,0.990611f,0.114563f,-0.120018f,0.98614f,0.113981f,-0.068259f,0.991135f,
|
||||||
|
0.066426f,-0.119489f,0.990611f,0.084225f,-0.234121f,0.968552f,0.138923f,-0.231173f,0.962943f,0.114563f,-0.120018f,0.98614f,
|
||||||
|
0.114563f,-0.120018f,0.98614f,0.138923f,-0.231173f,0.962943f,0.212501f,-0.226048f,0.950655f,0.218237f,-0.145906f,0.964927f,
|
||||||
|
0.113981f,-0.068259f,0.991135f,0.114563f,-0.120018f,0.98614f,0.218237f,-0.145906f,0.964927f,0.221558f,-0.086713f,0.971284f,
|
||||||
|
0.061944f,-0.007387f,0.998052f,0.061979f,-0.026292f,0.997731f,0.113708f,-0.028673f,0.9931f,0.113635f,-0.008231f,0.993489f,
|
||||||
|
0.061979f,-0.026292f,0.997731f,0.062764f,-0.064559f,0.995938f,0.113981f,-0.068259f,0.991135f,0.113708f,-0.028673f,0.9931f,
|
||||||
|
0.113708f,-0.028673f,0.9931f,0.113981f,-0.068259f,0.991135f,0.221558f,-0.086713f,0.971284f,0.222823f,-0.037022f,0.974156f,
|
||||||
|
0.113635f,-0.008231f,0.993489f,0.113708f,-0.028673f,0.9931f,0.222823f,-0.037022f,0.974156f,0.223053f,-0.010715f,0.974747f,
|
||||||
|
0.00717f,0.007027f,0.99995f,0.007189f,0.0f,0.999974f,0.025542f,0.0f,0.999674f,0.025482f,0.007044f,0.999651f,
|
||||||
|
0.007189f,0.0f,0.999974f,0.007169f,-0.00707f,0.999949f,0.025479f,-0.007087f,0.99965f,0.025542f,0.0f,0.999674f,
|
||||||
|
0.025542f,0.0f,0.999674f,0.025479f,-0.007087f,0.99965f,0.061944f,-0.007387f,0.998052f,0.061996f,0.0f,0.998076f,
|
||||||
|
0.025482f,0.007044f,0.999651f,0.025542f,0.0f,0.999674f,0.061996f,0.0f,0.998076f,0.061948f,0.007344f,0.998052f,
|
||||||
|
0.061944f,-0.007387f,0.998052f,0.113635f,-0.008231f,0.993489f,0.11363f,0.0f,0.993523f,0.061996f,0.0f,0.998076f,
|
||||||
|
0.113635f,-0.008231f,0.993489f,0.223053f,-0.010715f,0.974747f,0.222967f,-1.0E-6f,0.974826f,0.11363f,0.0f,0.993523f,
|
||||||
|
0.11363f,0.0f,0.993523f,0.222967f,-1.0E-6f,0.974826f,0.223051f,0.010649f,0.974749f,0.113637f,0.008184f,0.993489f,
|
||||||
|
0.061996f,0.0f,0.998076f,0.11363f,0.0f,0.993523f,0.113637f,0.008184f,0.993489f,0.061948f,0.007344f,0.998052f,
|
||||||
|
-0.693736f,0.024972f,0.719796f,-0.565768f,0.020427f,0.824311f,-0.560511f,0.071322f,0.82507f,-0.681667f,0.087549f,0.726406f,
|
||||||
|
-0.560511f,0.071322f,0.82507f,-0.565768f,0.020427f,0.824311f,-0.367245f,0.014528f,0.930011f,-0.365644f,0.050051f,0.929408f,
|
||||||
|
-0.53875f,0.167715f,0.825603f,-0.560511f,0.071322f,0.82507f,-0.365644f,0.050051f,0.929408f,-0.359059f,0.116722f,0.925987f,
|
||||||
|
-0.681667f,0.087549f,0.726406f,-0.560511f,0.071322f,0.82507f,-0.53875f,0.167715f,0.825603f,-0.644943f,0.202621f,0.736881f,
|
||||||
|
-0.367245f,0.014528f,0.930011f,-0.220997f,0.010655f,0.975216f,-0.220758f,0.036362f,0.974651f,-0.365644f,0.050051f,0.929408f,
|
||||||
|
-0.365644f,0.050051f,0.929408f,-0.220758f,0.036362f,0.974651f,-0.219543f,0.083629f,0.972012f,-0.359059f,0.116722f,0.925987f,
|
||||||
|
-0.53875f,0.167715f,0.825603f,-0.359059f,0.116722f,0.925987f,-0.34505f,0.199733f,0.917086f,-0.491757f,0.284219f,0.82304f,
|
||||||
|
-0.359059f,0.116722f,0.925987f,-0.219543f,0.083629f,0.972012f,-0.216564f,0.138788f,0.966353f,-0.34505f,0.199733f,0.917086f,
|
||||||
|
-0.34505f,0.199733f,0.917086f,-0.216564f,0.138788f,0.966353f,-0.211482f,0.213152f,0.953856f,-0.296456f,0.298724f,0.907126f,
|
||||||
|
-0.34505f,0.199733f,0.917086f,-0.296456f,0.298724f,0.907126f,-0.402197f,0.405178f,0.821017f,-0.491757f,0.284219f,0.82304f,
|
||||||
|
-0.644943f,0.202621f,0.736881f,-0.53875f,0.167715f,0.825603f,-0.491757f,0.284219f,0.82304f,-0.574618f,0.33479f,0.746813f,
|
||||||
|
-0.574618f,0.33479f,0.746813f,-0.491757f,0.284219f,0.82304f,-0.402197f,0.405178f,0.821017f,-0.466013f,0.469045f,0.75022f,
|
||||||
|
0.223051f,0.010649f,0.974749f,0.37035f,0.014508f,0.928779f,0.368745f,0.04998f,0.928186f,0.222811f,0.036337f,0.974184f,
|
||||||
|
0.368745f,0.04998f,0.928186f,0.37035f,0.014508f,0.928779f,0.569522f,0.020364f,0.821724f,0.564266f,0.071105f,0.822525f,
|
||||||
|
0.362133f,0.116561f,0.92481f,0.368745f,0.04998f,0.928186f,0.564266f,0.071105f,0.822525f,0.54249f,0.167243f,0.823246f,
|
||||||
|
0.222811f,0.036337f,0.974184f,0.368745f,0.04998f,0.928186f,0.362133f,0.116561f,0.92481f,0.221593f,0.083571f,0.971552f,
|
||||||
|
0.569522f,0.020364f,0.821724f,0.697248f,0.024864f,0.716398f,0.685209f,0.08722f,0.723105f,0.564266f,0.071105f,0.822525f,
|
||||||
|
0.564266f,0.071105f,0.822525f,0.685209f,0.08722f,0.723105f,0.648546f,0.20196f,0.733894f,0.54249f,0.167243f,0.823246f,
|
||||||
|
0.362133f,0.116561f,0.92481f,0.54249f,0.167243f,0.823246f,0.495412f,0.283564f,0.821071f,0.348093f,0.199473f,0.915992f,
|
||||||
|
0.54249f,0.167243f,0.823246f,0.648546f,0.20196f,0.733894f,0.578173f,0.334012f,0.744414f,0.495412f,0.283564f,0.821071f,
|
||||||
|
0.495412f,0.283564f,0.821071f,0.578173f,0.334012f,0.744414f,0.4693f,0.468325f,0.748619f,0.405489f,0.404531f,0.819716f,
|
||||||
|
0.495412f,0.283564f,0.821071f,0.405489f,0.404531f,0.819716f,0.299149f,0.298419f,0.906342f,0.348093f,0.199473f,0.915992f,
|
||||||
|
0.221593f,0.083571f,0.971552f,0.362133f,0.116561f,0.92481f,0.348093f,0.199473f,0.915992f,0.218621f,0.138683f,0.965905f,
|
||||||
|
0.218621f,0.138683f,0.965905f,0.348093f,0.199473f,0.915992f,0.299149f,0.298419f,0.906342f,0.213531f,0.212993f,0.953435f,
|
||||||
|
0.010878f,0.222561f,0.974858f,0.008351f,0.113056f,0.993554f,0.028645f,0.113157f,0.993164f,0.037001f,0.222307f,0.974274f,
|
||||||
|
0.008351f,0.113056f,0.993554f,0.007491f,0.061287f,0.998092f,0.026239f,0.061352f,0.997771f,0.028645f,0.113157f,0.993164f,
|
||||||
|
0.028645f,0.113157f,0.993164f,0.026239f,0.061352f,0.997771f,0.062873f,0.062197f,0.996082f,0.066588f,0.113508f,0.991303f,
|
||||||
|
0.037001f,0.222307f,0.974274f,0.028645f,0.113157f,0.993164f,0.066588f,0.113508f,0.991303f,0.084603f,0.221056f,0.971585f,
|
||||||
|
0.007491f,0.061287f,0.998092f,0.007187f,0.025058f,0.99966f,0.025494f,0.025072f,0.999361f,0.026239f,0.061352f,0.997771f,
|
||||||
|
0.007187f,0.025058f,0.99966f,0.00717f,0.007027f,0.99995f,0.025482f,0.007044f,0.999651f,0.025494f,0.025072f,0.999361f,
|
||||||
|
0.025494f,0.025072f,0.999361f,0.025482f,0.007044f,0.999651f,0.061948f,0.007344f,0.998052f,0.062015f,0.025807f,0.997742f,
|
||||||
|
0.026239f,0.061352f,0.997771f,0.025494f,0.025072f,0.999361f,0.062015f,0.025807f,0.997742f,0.062873f,0.062197f,0.996082f,
|
||||||
|
0.062873f,0.062197f,0.996082f,0.062015f,0.025807f,0.997742f,0.113738f,0.028159f,0.993112f,0.114097f,0.065833f,0.991286f,
|
||||||
|
0.062015f,0.025807f,0.997742f,0.061948f,0.007344f,0.998052f,0.113637f,0.008184f,0.993489f,0.113738f,0.028159f,0.993112f,
|
||||||
|
0.113738f,0.028159f,0.993112f,0.113637f,0.008184f,0.993489f,0.223051f,0.010649f,0.974749f,0.222811f,0.036337f,0.974184f,
|
||||||
|
0.114097f,0.065833f,0.991286f,0.113738f,0.028159f,0.993112f,0.222811f,0.036337f,0.974184f,0.221593f,0.083571f,0.971552f,
|
||||||
|
0.084603f,0.221056f,0.971585f,0.066588f,0.113508f,0.991303f,0.114794f,0.114134f,0.986811f,0.139597f,0.218066f,0.965898f,
|
||||||
|
0.066588f,0.113508f,0.991303f,0.062873f,0.062197f,0.996082f,0.114097f,0.065833f,0.991286f,0.114794f,0.114134f,0.986811f,
|
||||||
|
0.114794f,0.114134f,0.986811f,0.114097f,0.065833f,0.991286f,0.221593f,0.083571f,0.971552f,0.218621f,0.138683f,0.965905f,
|
||||||
|
0.139597f,0.218066f,0.965898f,0.114794f,0.114134f,0.986811f,0.218621f,0.138683f,0.965905f,0.213531f,0.212993f,0.953435f,
|
||||||
|
0.007491f,0.061287f,0.998092f,0.008351f,0.113056f,0.993554f,0.0f,0.113048f,0.99359f,0.0f,0.061335f,0.998117f,
|
||||||
|
0.008351f,0.113056f,0.993554f,0.010878f,0.222561f,0.974858f,0.0f,0.222477f,0.974938f,0.0f,0.113048f,0.99359f,
|
||||||
|
0.0f,0.113048f,0.99359f,0.0f,0.222477f,0.974938f,-0.010867f,0.22256f,0.974858f,-0.008343f,0.113057f,0.993554f,
|
||||||
|
0.0f,0.061335f,0.998117f,0.0f,0.113048f,0.99359f,-0.008343f,0.113057f,0.993554f,-0.007484f,0.061287f,0.998092f,
|
||||||
|
0.007491f,0.061287f,0.998092f,0.0f,0.061335f,0.998117f,0.0f,0.025116f,0.999685f,0.007187f,0.025058f,0.99966f,
|
||||||
|
0.0f,0.061335f,0.998117f,-0.007484f,0.061287f,0.998092f,-0.00718f,0.025059f,0.99966f,0.0f,0.025116f,0.999685f,
|
||||||
|
0.0f,0.025116f,0.999685f,-0.00718f,0.025059f,0.99966f,-0.007163f,0.007027f,0.99995f,0.0f,0.007045f,0.999975f,
|
||||||
|
0.007187f,0.025058f,0.99966f,0.0f,0.025116f,0.999685f,0.0f,0.007045f,0.999975f,0.00717f,0.007027f,0.99995f,
|
||||||
|
-0.220997f,0.010655f,0.975216f,-0.112675f,0.008187f,0.993598f,-0.112781f,0.02817f,0.993221f,-0.220758f,0.036362f,0.974651f,
|
||||||
|
-0.112675f,0.008187f,0.993598f,-0.061553f,0.007347f,0.998077f,-0.061625f,0.025816f,0.997765f,-0.112781f,0.02817f,0.993221f,
|
||||||
|
-0.112781f,0.02817f,0.993221f,-0.061625f,0.025816f,0.997765f,-0.062487f,0.062214f,0.996105f,-0.113147f,0.065858f,0.991393f,
|
||||||
|
-0.220758f,0.036362f,0.974651f,-0.112781f,0.02817f,0.993221f,-0.113147f,0.065858f,0.991393f,-0.219543f,0.083629f,0.972012f,
|
||||||
|
-0.061553f,0.007347f,0.998077f,-0.025398f,0.007046f,0.999653f,-0.025412f,0.025076f,0.999363f,-0.061625f,0.025816f,0.997765f,
|
||||||
|
-0.025398f,0.007046f,0.999653f,-0.007163f,0.007027f,0.99995f,-0.00718f,0.025059f,0.99966f,-0.025412f,0.025076f,0.999363f,
|
||||||
|
-0.025412f,0.025076f,0.999363f,-0.00718f,0.025059f,0.99966f,-0.007484f,0.061287f,0.998092f,-0.026157f,0.061358f,0.997773f,
|
||||||
|
-0.061625f,0.025816f,0.997765f,-0.025412f,0.025076f,0.999363f,-0.026157f,0.061358f,0.997773f,-0.062487f,0.062214f,0.996105f,
|
||||||
|
-0.062487f,0.062214f,0.996105f,-0.026157f,0.061358f,0.997773f,-0.028558f,0.113162f,0.993166f,-0.066192f,0.113526f,0.991328f,
|
||||||
|
-0.026157f,0.061358f,0.997773f,-0.007484f,0.061287f,0.998092f,-0.008343f,0.113057f,0.993554f,-0.028558f,0.113162f,0.993166f,
|
||||||
|
-0.028558f,0.113162f,0.993166f,-0.008343f,0.113057f,0.993554f,-0.010867f,0.22256f,0.974858f,-0.036885f,0.222305f,0.974279f,
|
||||||
|
-0.066192f,0.113526f,0.991328f,-0.028558f,0.113162f,0.993166f,-0.036885f,0.222305f,0.974279f,-0.084089f,0.221062f,0.971628f,
|
||||||
|
-0.219543f,0.083629f,0.972012f,-0.113147f,0.065858f,0.991393f,-0.113857f,0.11417f,0.986915f,-0.216564f,0.138788f,0.966353f,
|
||||||
|
-0.113147f,0.065858f,0.991393f,-0.062487f,0.062214f,0.996105f,-0.066192f,0.113526f,0.991328f,-0.113857f,0.11417f,0.986915f,
|
||||||
|
-0.113857f,0.11417f,0.986915f,-0.066192f,0.113526f,0.991328f,-0.084089f,0.221062f,0.971628f,-0.138447f,0.218126f,0.966051f,
|
||||||
|
-0.216564f,0.138788f,0.966353f,-0.113857f,0.11417f,0.986915f,-0.138447f,0.218126f,0.966051f,-0.211482f,0.213152f,0.953856f,
|
||||||
|
};
|
||||||
|
|
||||||
|
const float cfGameIconStrokeVtxs[] =
|
||||||
|
{
|
||||||
|
-0.376756459475,1.046143651009f,0.0f,
|
||||||
|
-0.512206375599f,1.039104461670f,0.0f,
|
||||||
|
-0.613150417805f,1.029256582260f,0.0f,
|
||||||
|
-0.688333272934f,1.016606807709f,0.0f,
|
||||||
|
-0.746499598026f,1.001162052155f,0.0f,
|
||||||
|
-0.796394228935f,0.982929229736,0.0f,
|
||||||
|
-0.839153468609,0.961680650711,0.0f,
|
||||||
|
-0.875913500786,0.93718868494,0.0f,
|
||||||
|
-0.907810747623,0.909225344658,0.0f,
|
||||||
|
-0.93598151207,0.877562940121,0.0f,
|
||||||
|
-0.960655272007,0.840993285179,0.0f,
|
||||||
|
-0.982061386108,0.79830801487,0.0f,
|
||||||
|
-1.00042927265,0.748299062252,0.0f,
|
||||||
|
-1.015988588333,0.689758002758,0.0f,
|
||||||
|
-1.028732180595,0.613717556,0.0f,
|
||||||
|
-1.038653135300,0.511210441589,0.0f,
|
||||||
|
-1.045744538307,0.373269081116,0.0f,
|
||||||
|
-1.049999356270,0.190926194191,0.0f,
|
||||||
|
-1.051417708397,-1.349482312799E-002,0.0f,
|
||||||
|
-1.049999356270,-0.217670500278,0.0f,
|
||||||
|
-1.04574441910,-0.399277359247,0.0f,
|
||||||
|
-1.038653135300,-0.535992026329,0.0f,
|
||||||
|
-1.028732180595,-0.636890649796,0.0f,
|
||||||
|
-1.015988588333,-0.711049556732,0.0f,
|
||||||
|
-1.00042927265,-0.767545044422,0.0f,
|
||||||
|
-0.982061386108,-0.815453350544,0.0f,
|
||||||
|
-0.960655212402,-0.856050789356,0.0f,
|
||||||
|
-0.93598151207,-0.890613555908,0.0f,
|
||||||
|
-0.907810747623,-0.920418143272,0.0f,
|
||||||
|
-0.875913500786,-0.946740865707,0.0f,
|
||||||
|
-0.839153468609,-0.969795942307,0.0f,
|
||||||
|
-0.796394228935,-0.989797830582,0.0f,
|
||||||
|
-0.746499598026,-1.006960868835,0.0f,
|
||||||
|
-0.688333272934,-1.021499633789,0.0f,
|
||||||
|
-0.613150477409,-1.033407211304,0.0f,
|
||||||
|
-0.512206375599,-1.042677521706,0.0f,
|
||||||
|
-0.376756429672,-1.049303770065,0.0f,
|
||||||
|
-0.19805586338,-1.053279519081,0.0f,
|
||||||
|
2.249561250210E-003,-1.054604768753,0.0f,
|
||||||
|
0.202514111996,-1.053279519081,0.0f,
|
||||||
|
0.381092041731,-1.049303770065,0.0f,
|
||||||
|
0.516337633133,-1.042677521706,0.0f,
|
||||||
|
0.617013633251,-1.033407211304,0.0f,
|
||||||
|
0.691882967949,-1.021499633789,0.0f,
|
||||||
|
0.749708354473,-1.006960868835,0.0f,
|
||||||
|
0.79925262928,-0.989797830582,0.0f,
|
||||||
|
0.841663658619,-0.969795942307,0.0f,
|
||||||
|
0.87808907032,-0.946740865707,0.0f,
|
||||||
|
0.909676492214,-0.920418143272,0.0f,
|
||||||
|
0.93757379055,-0.890613555908,0.0f,
|
||||||
|
0.962008118629,-0.856050789356,0.0f,
|
||||||
|
0.983206510544,-0.815453350544,0.0f,
|
||||||
|
1.001396179199,-0.767545044422,0.0f,
|
||||||
|
1.016804218292,-0.711049556732,0.0f,
|
||||||
|
1.029423952103,-0.636890649796,0.0f,
|
||||||
|
1.039248347282,-0.535992026329,0.0f,
|
||||||
|
1.046270728111,-0.399277359247,0.0f,
|
||||||
|
1.050484061241,-0.217670500278,0.0f,
|
||||||
|
1.051888465881,-1.349482685328E-002,0.0f,
|
||||||
|
1.050484061241,0.190926194191,0.0f,
|
||||||
|
1.046270728111,0.373269081116,0.0f,
|
||||||
|
1.039248347282,0.511210441589,0.0f,
|
||||||
|
1.029423952103,0.613717556,0.0f,
|
||||||
|
1.016804218292,0.689758002758,0.0f,
|
||||||
|
1.001396059990,0.748299002647,0.0f,
|
||||||
|
0.983206450939,0.79830801487,0.0f,
|
||||||
|
0.962008118629,0.840993225574,0.0f,
|
||||||
|
0.93757379055,0.877562940121,0.0f,
|
||||||
|
0.909676492214,0.909225344658,0.0f,
|
||||||
|
0.87808907032,0.93718868494,0.0f,
|
||||||
|
0.841663658619,0.961680650711,0.0f,
|
||||||
|
0.79925262928,0.982929229736,0.0f,
|
||||||
|
0.749708354473,1.001162052155,0.0f,
|
||||||
|
0.691882967949,1.016606807709,0.0f,
|
||||||
|
0.617013692856,1.029256582260,0.0f,
|
||||||
|
0.516337633133,1.039104580879,0.0f,
|
||||||
|
0.381092071533,1.046143770218,0.0f,
|
||||||
|
0.202514111996,1.050367355347,0.0f,
|
||||||
|
2.249561250210E-003,1.051775097847,0.0f,
|
||||||
|
-0.19805586338,1.050367236137,0.0f,
|
||||||
|
-0.376756459475,1.046143651009,0.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned int cuGameIconStrokeVtxCount = sizeof(cfGameIconStrokeVtxs) / (sizeof(float) * 3);
|
||||||
|
|
||||||
|
#endif
|
100
src/gui/GridBackground.cpp
Normal file
100
src/gui/GridBackground.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#include "GridBackground.h"
|
||||||
|
#include "video/CVideo.h"
|
||||||
|
#include "video/shaders/Shader3D.h"
|
||||||
|
|
||||||
|
static const float bgRepeat = 1000.0f;
|
||||||
|
static const float bgTexRotate = 39.0f;
|
||||||
|
|
||||||
|
GridBackground::GridBackground(GuiImageData *img)
|
||||||
|
: GuiImage(img)
|
||||||
|
{
|
||||||
|
colorIntensity = glm::vec4(1.0f, 1.0f, 1.0f, 0.9f);
|
||||||
|
alphaFadeOut = glm::vec4(0.0f);
|
||||||
|
distanceFadeOut = 0.15f;
|
||||||
|
|
||||||
|
vtxCount = 4;
|
||||||
|
|
||||||
|
//! texture and vertex coordinates
|
||||||
|
f32 *m_posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, vtxCount * Shader3D::cuVertexAttrSize);
|
||||||
|
f32 *m_texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, vtxCount * Shader3D::cuTexCoordAttrSize);
|
||||||
|
|
||||||
|
if(m_posVtxs)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
m_posVtxs[i++] = -1.0f; m_posVtxs[i++] = 0.0f; m_posVtxs[i++] = 1.0f;
|
||||||
|
m_posVtxs[i++] = 1.0f; m_posVtxs[i++] = 0.0f; m_posVtxs[i++] = 1.0f;
|
||||||
|
m_posVtxs[i++] = 1.0f; m_posVtxs[i++] = 0.0f; m_posVtxs[i++] = -1.0f;
|
||||||
|
m_posVtxs[i++] = -1.0f; m_posVtxs[i++] = 0.0f; m_posVtxs[i++] = -1.0f;
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, m_posVtxs, vtxCount * Shader3D::cuVertexAttrSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_texCoords)
|
||||||
|
{
|
||||||
|
glm::vec2 texCoordVec[4];
|
||||||
|
texCoordVec[0][0] = -0.5f * bgRepeat; texCoordVec[0][1] = 0.5f * bgRepeat;
|
||||||
|
texCoordVec[1][0] = 0.5f * bgRepeat; texCoordVec[1][1] = 0.5f * bgRepeat;
|
||||||
|
texCoordVec[2][0] = 0.5f * bgRepeat; texCoordVec[2][1] = -0.5f * bgRepeat;
|
||||||
|
texCoordVec[3][0] = -0.5f * bgRepeat; texCoordVec[3][1] = -0.5f * bgRepeat;
|
||||||
|
|
||||||
|
const float cosRot = cosf(DegToRad(bgTexRotate));
|
||||||
|
const float sinRot = sinf(DegToRad(bgTexRotate));
|
||||||
|
|
||||||
|
glm::mat2 texRotateMtx({
|
||||||
|
cosRot, -sinRot,
|
||||||
|
sinRot, cosRot
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
texCoordVec[i] = texRotateMtx * texCoordVec[i];
|
||||||
|
m_texCoords[i*2 + 0] = texCoordVec[i][0];
|
||||||
|
m_texCoords[i*2 + 1] = texCoordVec[i][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, m_texCoords, vtxCount * Shader3D::cuTexCoordAttrSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! assign to internal variables which are const but oh well
|
||||||
|
posVtxs = m_posVtxs;
|
||||||
|
texCoords = m_texCoords;
|
||||||
|
}
|
||||||
|
|
||||||
|
GridBackground::~GridBackground()
|
||||||
|
{
|
||||||
|
//! remove image so it can not be drawn anymore from this point on
|
||||||
|
imageData = NULL;
|
||||||
|
|
||||||
|
//! main image vertexes
|
||||||
|
if(posVtxs)
|
||||||
|
{
|
||||||
|
free((void*)posVtxs);
|
||||||
|
posVtxs = NULL;
|
||||||
|
}
|
||||||
|
if(texCoords)
|
||||||
|
{
|
||||||
|
free((void*)texCoords);
|
||||||
|
texCoords = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridBackground::draw(CVideo *pVideo, const glm::mat4 & modelView)
|
||||||
|
{
|
||||||
|
//! first setup 2D GUI positions
|
||||||
|
f32 currScaleX = bgRepeat * scaleX * (f32)getWidth() * pVideo->getWidthScaleFactor();
|
||||||
|
f32 currScaleY = 1.0f;
|
||||||
|
f32 currScaleZ = bgRepeat * scaleZ * (f32)getHeight() * pVideo->getDepthScaleFactor();
|
||||||
|
|
||||||
|
m_modelView = glm::scale(modelView, glm::vec3(currScaleX, currScaleY, currScaleZ));
|
||||||
|
|
||||||
|
colorIntensity[3] = getAlpha();
|
||||||
|
|
||||||
|
Shader3D::instance()->setShaders();
|
||||||
|
Shader3D::instance()->setTextureAndSampler(imageData->getTexture(), imageData->getSampler());
|
||||||
|
Shader3D::instance()->setProjectionMtx(pVideo->getProjectionMtx());
|
||||||
|
Shader3D::instance()->setViewMtx(pVideo->getViewMtx());
|
||||||
|
Shader3D::instance()->setModelViewMtx(m_modelView);
|
||||||
|
Shader3D::instance()->setDistanceFadeOut(distanceFadeOut);
|
||||||
|
Shader3D::instance()->setAlphaFadeOut(alphaFadeOut);
|
||||||
|
Shader3D::instance()->setColorIntensity(colorIntensity);
|
||||||
|
Shader3D::instance()->setAttributeBuffer(vtxCount, posVtxs, texCoords);
|
||||||
|
Shader3D::instance()->draw(GX2_PRIMITIVE_QUADS, vtxCount);
|
||||||
|
}
|
30
src/gui/GridBackground.h
Normal file
30
src/gui/GridBackground.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef _GRID_BACKGROUND_H_
|
||||||
|
#define _GRID_BACKGROUND_H_
|
||||||
|
|
||||||
|
#include "GuiImage.h"
|
||||||
|
#include "video/shaders/Shader.h"
|
||||||
|
|
||||||
|
class GridBackground : public GuiImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GridBackground(GuiImageData *imgData);
|
||||||
|
virtual ~GridBackground();
|
||||||
|
|
||||||
|
void setColorIntensity(const glm::vec4 & color) {
|
||||||
|
colorIntensity = color;
|
||||||
|
}
|
||||||
|
const glm::vec4 & getColorIntensity() const {
|
||||||
|
return colorIntensity;
|
||||||
|
}
|
||||||
|
void setDistanceFadeOut(const float & a) {
|
||||||
|
distanceFadeOut = a;
|
||||||
|
}
|
||||||
|
void draw(CVideo *pVideo, const glm::mat4 & modelView);
|
||||||
|
private:
|
||||||
|
glm::mat4 m_modelView;
|
||||||
|
glm::vec4 colorIntensity;
|
||||||
|
glm::vec4 alphaFadeOut;
|
||||||
|
float distanceFadeOut;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _GRID_BACKGROUND_H_
|
30
src/gui/Gui.h
Normal file
30
src/gui/Gui.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef __GUI_H
|
||||||
|
#define __GUI_H
|
||||||
|
|
||||||
|
#include "GuiElement.h"
|
||||||
|
#include "GuiImageData.h"
|
||||||
|
#include "GuiImage.h"
|
||||||
|
#include "GuiFrame.h"
|
||||||
|
#include "GuiController.h"
|
||||||
|
#include "GuiText.h"
|
||||||
|
#include "GuiSound.h"
|
||||||
|
#include "GuiButton.h"
|
||||||
|
#include "GuiTrigger.h"
|
||||||
|
|
||||||
|
#endif
|
301
src/gui/GuiButton.cpp
Normal file
301
src/gui/GuiButton.cpp
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "GuiButton.h"
|
||||||
|
#include "GuiTrigger.h"
|
||||||
|
#include "GuiController.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the GuiButton class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
GuiButton::GuiButton(f32 w, f32 h)
|
||||||
|
{
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
image = NULL;
|
||||||
|
imageOver = NULL;
|
||||||
|
imageHold = NULL;
|
||||||
|
imageClick = NULL;
|
||||||
|
icon = NULL;
|
||||||
|
iconOver = NULL;
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
label[i] = NULL;
|
||||||
|
labelOver[i] = NULL;
|
||||||
|
labelHold[i] = NULL;
|
||||||
|
labelClick[i] = NULL;
|
||||||
|
}
|
||||||
|
for(int i = 0; i < iMaxGuiTriggers; i++)
|
||||||
|
{
|
||||||
|
trigger[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
soundOver = NULL;
|
||||||
|
soundHold = NULL;
|
||||||
|
soundClick = NULL;
|
||||||
|
clickedTrigger = NULL;
|
||||||
|
heldTrigger = NULL;
|
||||||
|
selectable = true;
|
||||||
|
holdable = false;
|
||||||
|
clickable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor for the GuiButton class.
|
||||||
|
*/
|
||||||
|
GuiButton::~GuiButton()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiButton::setImage(GuiImage* img)
|
||||||
|
{
|
||||||
|
image = img;
|
||||||
|
if(img) img->setParent(this);
|
||||||
|
}
|
||||||
|
void GuiButton::setImageOver(GuiImage* img)
|
||||||
|
{
|
||||||
|
imageOver = img;
|
||||||
|
if(img) img->setParent(this);
|
||||||
|
}
|
||||||
|
void GuiButton::setImageHold(GuiImage* img)
|
||||||
|
{
|
||||||
|
imageHold = img;
|
||||||
|
if(img) img->setParent(this);
|
||||||
|
}
|
||||||
|
void GuiButton::setImageClick(GuiImage* img)
|
||||||
|
{
|
||||||
|
imageClick = img;
|
||||||
|
if(img) img->setParent(this);
|
||||||
|
}
|
||||||
|
void GuiButton::setIcon(GuiImage* img)
|
||||||
|
{
|
||||||
|
icon = img;
|
||||||
|
if(img) img->setParent(this);
|
||||||
|
}
|
||||||
|
void GuiButton::setIconOver(GuiImage* img)
|
||||||
|
{
|
||||||
|
iconOver = img;
|
||||||
|
if(img) img->setParent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiButton::setLabel(GuiText* txt, int n)
|
||||||
|
{
|
||||||
|
label[n] = txt;
|
||||||
|
if(txt) txt->setParent(this);
|
||||||
|
}
|
||||||
|
void GuiButton::setLabelOver(GuiText* txt, int n)
|
||||||
|
{
|
||||||
|
labelOver[n] = txt;
|
||||||
|
if(txt) txt->setParent(this);
|
||||||
|
}
|
||||||
|
void GuiButton::setLabelHold(GuiText* txt, int n)
|
||||||
|
{
|
||||||
|
labelHold[n] = txt;
|
||||||
|
if(txt) txt->setParent(this);
|
||||||
|
}
|
||||||
|
void GuiButton::setLabelClick(GuiText* txt, int n)
|
||||||
|
{
|
||||||
|
labelClick[n] = txt;
|
||||||
|
if(txt) txt->setParent(this);
|
||||||
|
}
|
||||||
|
void GuiButton::setSoundOver(GuiSound * snd)
|
||||||
|
{
|
||||||
|
soundOver = snd;
|
||||||
|
}
|
||||||
|
void GuiButton::setSoundHold(GuiSound * snd)
|
||||||
|
{
|
||||||
|
soundHold = snd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiButton::setSoundClick(GuiSound * snd)
|
||||||
|
{
|
||||||
|
soundClick = snd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiButton::setTrigger(GuiTrigger * t, int idx)
|
||||||
|
{
|
||||||
|
if(idx >= 0 && idx < iMaxGuiTriggers)
|
||||||
|
{
|
||||||
|
trigger[idx] = t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < iMaxGuiTriggers; i++)
|
||||||
|
{
|
||||||
|
if(!trigger[i])
|
||||||
|
{
|
||||||
|
trigger[i] = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiButton::resetState(void)
|
||||||
|
{
|
||||||
|
clickedTrigger = NULL;
|
||||||
|
heldTrigger = NULL;
|
||||||
|
GuiElement::resetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the button on screen
|
||||||
|
*/
|
||||||
|
void GuiButton::draw(CVideo *v)
|
||||||
|
{
|
||||||
|
if(!this->isVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// draw image
|
||||||
|
if((isDrawOverOnlyWhenSelected() && (isStateSet(STATE_SELECTED) && imageOver)) ||
|
||||||
|
(!isDrawOverOnlyWhenSelected() && (isStateSet(STATE_OVER | STATE_SELECTED | STATE_CLICKED | STATE_HELD) && imageOver)))
|
||||||
|
imageOver->draw(v);
|
||||||
|
else if(image)
|
||||||
|
image->draw(v);
|
||||||
|
|
||||||
|
if((isDrawOverOnlyWhenSelected() && (isStateSet(STATE_SELECTED) && iconOver)) ||
|
||||||
|
(!isDrawOverOnlyWhenSelected() && (isStateSet(STATE_OVER | STATE_SELECTED | STATE_CLICKED | STATE_HELD) && iconOver)))
|
||||||
|
iconOver->draw(v);
|
||||||
|
else if(icon)
|
||||||
|
icon->draw(v);
|
||||||
|
|
||||||
|
// draw text
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if(isStateSet(STATE_OVER | STATE_SELECTED | STATE_CLICKED | STATE_HELD) && labelOver[i])
|
||||||
|
labelOver[i]->draw(v);
|
||||||
|
else if(label[i])
|
||||||
|
label[i]->draw(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiButton::update(GuiController * c)
|
||||||
|
{
|
||||||
|
if(!c || isStateSet(STATE_DISABLED|STATE_HIDDEN|STATE_DISABLE_INPUT, c->chan))
|
||||||
|
return;
|
||||||
|
else if(parentElement && (parentElement->isStateSet(STATE_DISABLED|STATE_HIDDEN|STATE_DISABLE_INPUT, c->chan)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(selectable)
|
||||||
|
{
|
||||||
|
if(c->data.validPointer && this->isInside(c->data.x, c->data.y))
|
||||||
|
{
|
||||||
|
if(!isStateSet(STATE_OVER, c->chan))
|
||||||
|
{
|
||||||
|
setState(STATE_OVER, c->chan);
|
||||||
|
|
||||||
|
//if(this->isRumbleActive())
|
||||||
|
// this->rumble(t->chan);
|
||||||
|
|
||||||
|
if(soundOver)
|
||||||
|
soundOver->Play();
|
||||||
|
|
||||||
|
if(effectsOver && !effects)
|
||||||
|
{
|
||||||
|
// initiate effects
|
||||||
|
effects = effectsOver;
|
||||||
|
effectAmount = effectAmountOver;
|
||||||
|
effectTarget = effectTargetOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointedOn(this, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(isStateSet(STATE_OVER, c->chan))
|
||||||
|
{
|
||||||
|
this->clearState(STATE_OVER, c->chan);
|
||||||
|
pointedOff(this, c);
|
||||||
|
|
||||||
|
if(effectTarget == effectTargetOver && effectAmount == effectAmountOver)
|
||||||
|
{
|
||||||
|
// initiate effects (in reverse)
|
||||||
|
effects = effectsOver;
|
||||||
|
effectAmount = -effectAmountOver;
|
||||||
|
effectTarget = 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < iMaxGuiTriggers; i++)
|
||||||
|
{
|
||||||
|
if(!trigger[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// button triggers
|
||||||
|
if(clickable)
|
||||||
|
{
|
||||||
|
|
||||||
|
int isClicked = trigger[i]->clicked(c);
|
||||||
|
|
||||||
|
if( !clickedTrigger && (isClicked != GuiTrigger::CLICKED_NONE)
|
||||||
|
&& (trigger[i]->isClickEverywhere() || (isStateSet(STATE_SELECTED | STATE_OVER, c->chan) && trigger[i]->isSelectionClickEverywhere()) || this->isInside(c->data.x, c->data.y)))
|
||||||
|
{
|
||||||
|
if(soundClick)
|
||||||
|
soundClick->Play();
|
||||||
|
|
||||||
|
clickedTrigger = trigger[i];
|
||||||
|
|
||||||
|
if(!isStateSet(STATE_CLICKED, c->chan)){
|
||||||
|
if(isClicked == GuiTrigger::CLICKED_TOUCH){
|
||||||
|
setState(STATE_CLICKED_TOUCH, c->chan);
|
||||||
|
}else{
|
||||||
|
setState(STATE_CLICKED, c->chan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clicked(this, c, trigger[i]);
|
||||||
|
}
|
||||||
|
else if((isStateSet(STATE_CLICKED, c->chan) || isStateSet(STATE_CLICKED_TOUCH, c->chan)) && (clickedTrigger == trigger[i]) && !isStateSet(STATE_HELD, c->chan) && !trigger[i]->held(c) && ((isClicked == GuiTrigger::CLICKED_NONE) || trigger[i]->released(c)))
|
||||||
|
{
|
||||||
|
if((isStateSet(STATE_CLICKED_TOUCH, c->chan) && this->isInside(c->data.x, c->data.y)) || (isStateSet(STATE_CLICKED, c->chan))){
|
||||||
|
clickedTrigger = NULL;
|
||||||
|
clearState(STATE_CLICKED, c->chan);
|
||||||
|
released(this, c, trigger[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(holdable)
|
||||||
|
{
|
||||||
|
bool isHeld = trigger[i]->held(c);
|
||||||
|
|
||||||
|
if( (!heldTrigger || heldTrigger == trigger[i]) && isHeld
|
||||||
|
&& (trigger[i]->isHoldEverywhere() || (isStateSet(STATE_SELECTED | STATE_OVER, c->chan) && trigger[i]->isSelectionClickEverywhere()) || this->isInside(c->data.x, c->data.y)))
|
||||||
|
{
|
||||||
|
heldTrigger = trigger[i];
|
||||||
|
|
||||||
|
if(!isStateSet(STATE_HELD, c->chan))
|
||||||
|
setState(STATE_HELD, c->chan);
|
||||||
|
|
||||||
|
held(this, c, trigger[i]);
|
||||||
|
}
|
||||||
|
else if(isStateSet(STATE_HELD, c->chan) && (heldTrigger == trigger[i]) && (!isHeld || trigger[i]->released(c)))
|
||||||
|
{
|
||||||
|
//! click is removed at this point and converted to held
|
||||||
|
if(clickedTrigger == trigger[i])
|
||||||
|
{
|
||||||
|
clickedTrigger = NULL;
|
||||||
|
clearState(STATE_CLICKED, c->chan);
|
||||||
|
}
|
||||||
|
heldTrigger = NULL;
|
||||||
|
clearState(STATE_HELD, c->chan);
|
||||||
|
released(this, c, trigger[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
117
src/gui/GuiButton.h
Normal file
117
src/gui/GuiButton.h
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_BUTTON_H_
|
||||||
|
#define GUI_BUTTON_H_
|
||||||
|
|
||||||
|
#include "GuiElement.h"
|
||||||
|
#include "GuiText.h"
|
||||||
|
#include "GuiController.h"
|
||||||
|
#include "GuiImage.h"
|
||||||
|
#include "GuiSound.h"
|
||||||
|
#include "GuiTrigger.h"
|
||||||
|
|
||||||
|
//!Display, manage, and manipulate buttons in the GUI. Buttons can have images, icons, text, and sound set (all of which are optional)
|
||||||
|
class GuiButton : public GuiElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
//!\param w Width
|
||||||
|
//!\param h Height
|
||||||
|
GuiButton(f32 w, f32 h);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiButton();
|
||||||
|
//!Sets the button's image
|
||||||
|
//!\param i Pointer to GuiImage object
|
||||||
|
void setImage(GuiImage* i);
|
||||||
|
//!Sets the button's image on over
|
||||||
|
//!\param i Pointer to GuiImage object
|
||||||
|
void setImageOver(GuiImage* i);
|
||||||
|
|
||||||
|
void setIcon(GuiImage* i);
|
||||||
|
void setIconOver(GuiImage* i);
|
||||||
|
//!Sets the button's image on hold
|
||||||
|
//!\param i Pointer to GuiImage object
|
||||||
|
void setImageHold(GuiImage* i);
|
||||||
|
//!Sets the button's image on click
|
||||||
|
//!\param i Pointer to GuiImage object
|
||||||
|
void setImageClick(GuiImage* i);
|
||||||
|
//!Sets the button's label
|
||||||
|
//!\param t Pointer to GuiText object
|
||||||
|
//!\param n Index of label to set (optional, default is 0)
|
||||||
|
void setLabel(GuiText* t, int n = 0);
|
||||||
|
//!Sets the button's label on over (eg: different colored text)
|
||||||
|
//!\param t Pointer to GuiText object
|
||||||
|
//!\param n Index of label to set (optional, default is 0)
|
||||||
|
void setLabelOver(GuiText* t, int n = 0);
|
||||||
|
//!Sets the button's label on hold
|
||||||
|
//!\param t Pointer to GuiText object
|
||||||
|
//!\param n Index of label to set (optional, default is 0)
|
||||||
|
void setLabelHold(GuiText* t, int n = 0);
|
||||||
|
//!Sets the button's label on click
|
||||||
|
//!\param t Pointer to GuiText object
|
||||||
|
//!\param n Index of label to set (optional, default is 0)
|
||||||
|
void setLabelClick(GuiText* t, int n = 0);
|
||||||
|
//!Sets the sound to play on over
|
||||||
|
//!\param s Pointer to GuiSound object
|
||||||
|
void setSoundOver(GuiSound * s);
|
||||||
|
//!Sets the sound to play on hold
|
||||||
|
//!\param s Pointer to GuiSound object
|
||||||
|
void setSoundHold(GuiSound * s);
|
||||||
|
//!Sets the sound to play on click
|
||||||
|
//!\param s Pointer to GuiSound object
|
||||||
|
void setSoundClick(GuiSound * s);
|
||||||
|
//!Set a new GuiTrigger for the element
|
||||||
|
//!\param i Index of trigger array to set
|
||||||
|
//!\param t Pointer to GuiTrigger
|
||||||
|
void setTrigger(GuiTrigger * t, int idx = -1);
|
||||||
|
//!
|
||||||
|
void resetState(void);
|
||||||
|
//!Constantly called to draw the GuiButton
|
||||||
|
void draw(CVideo *video);
|
||||||
|
//!Constantly called to allow the GuiButton to respond to updated input data
|
||||||
|
//!\param t Pointer to a GuiTrigger, containing the current input data from PAD/WPAD
|
||||||
|
void update(GuiController * c);
|
||||||
|
|
||||||
|
sigslot::signal2<GuiButton *, const GuiController *> selected;
|
||||||
|
sigslot::signal2<GuiButton *, const GuiController *> deSelected;
|
||||||
|
sigslot::signal2<GuiButton *, const GuiController *> pointedOn;
|
||||||
|
sigslot::signal2<GuiButton *, const GuiController *> pointedOff;
|
||||||
|
sigslot::signal3<GuiButton *, const GuiController *, GuiTrigger *> clicked;
|
||||||
|
sigslot::signal3<GuiButton *, const GuiController *, GuiTrigger *> held;
|
||||||
|
sigslot::signal3<GuiButton *, const GuiController *, GuiTrigger *> released;
|
||||||
|
protected:
|
||||||
|
static const int iMaxGuiTriggers = 10;
|
||||||
|
|
||||||
|
GuiImage * image; //!< Button image (default)
|
||||||
|
GuiImage * imageOver; //!< Button image for STATE_SELECTED
|
||||||
|
GuiImage * imageHold; //!< Button image for STATE_HELD
|
||||||
|
GuiImage * imageClick; //!< Button image for STATE_CLICKED
|
||||||
|
GuiImage * icon;
|
||||||
|
GuiImage * iconOver;
|
||||||
|
GuiText * label[4]; //!< Label(s) to display (default)
|
||||||
|
GuiText * labelOver[4]; //!< Label(s) to display for STATE_SELECTED
|
||||||
|
GuiText * labelHold[4]; //!< Label(s) to display for STATE_HELD
|
||||||
|
GuiText * labelClick[4]; //!< Label(s) to display for STATE_CLICKED
|
||||||
|
GuiSound * soundOver; //!< Sound to play for STATE_SELECTED
|
||||||
|
GuiSound * soundHold; //!< Sound to play for STATE_HELD
|
||||||
|
GuiSound * soundClick; //!< Sound to play for STATE_CLICKED
|
||||||
|
GuiTrigger * trigger[iMaxGuiTriggers]; //!< GuiTriggers (input actions) that this element responds to
|
||||||
|
GuiTrigger * clickedTrigger;
|
||||||
|
GuiTrigger * heldTrigger;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
63
src/gui/GuiCheckBox.cpp
Normal file
63
src/gui/GuiCheckBox.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "GuiCheckBox.h"
|
||||||
|
#include "GuiImage.h"
|
||||||
|
#include "GuiImageData.h"
|
||||||
|
/**
|
||||||
|
* Constructor for the GuiCheckBox class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
GuiCheckBox::GuiCheckBox(bool checked)
|
||||||
|
: GuiToggle(checked,50,50)
|
||||||
|
,checkbox_imgdata(Resources::GetImageData("checkbox.png"))
|
||||||
|
,checkbox_img(checkbox_imgdata)
|
||||||
|
,checkbox_selected_imgdata(Resources::GetImageData("checkbox_selected.png"))
|
||||||
|
,checkbox_selected_img(checkbox_selected_imgdata)
|
||||||
|
,highlighted_imgdata(Resources::GetImageData("checkbox_highlighted.png"))
|
||||||
|
,highlighted_img(highlighted_imgdata)
|
||||||
|
{
|
||||||
|
checkbox_selected_img.setScale(height/checkbox_selected_img.getHeight());
|
||||||
|
checkbox_img.setScale(height/checkbox_img.getHeight());
|
||||||
|
highlighted_img.setScale(height/highlighted_img.getHeight());
|
||||||
|
|
||||||
|
setImage(&checkbox_img);
|
||||||
|
setIconOver(&highlighted_img);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor for the GuiButton class.
|
||||||
|
*/
|
||||||
|
GuiCheckBox::~GuiCheckBox()
|
||||||
|
{
|
||||||
|
Resources::RemoveImageData(checkbox_imgdata);
|
||||||
|
Resources::RemoveImageData(checkbox_selected_imgdata);
|
||||||
|
Resources::RemoveImageData(highlighted_imgdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GuiCheckBox::update(GuiController * c){
|
||||||
|
if(bChanged){
|
||||||
|
if(selected){
|
||||||
|
GuiButton::setImage(&checkbox_selected_img);
|
||||||
|
}else{
|
||||||
|
GuiButton::setImage(&checkbox_img);
|
||||||
|
}
|
||||||
|
bChanged = false;
|
||||||
|
}
|
||||||
|
GuiToggle::update(c);
|
||||||
|
}
|
||||||
|
|
47
src/gui/GuiCheckBox.h
Normal file
47
src/gui/GuiCheckBox.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_CHECKBOX_H_
|
||||||
|
#define GUI_CHECKBOX_H_
|
||||||
|
|
||||||
|
#include "GuiToggle.h"
|
||||||
|
#include "GuiImage.h"
|
||||||
|
#include "GuiImageData.h"
|
||||||
|
|
||||||
|
//!A simple CheckBox
|
||||||
|
class GuiCheckBox : public GuiToggle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
//!\param checked Checked
|
||||||
|
GuiCheckBox(bool checked);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiCheckBox();
|
||||||
|
protected:
|
||||||
|
|
||||||
|
GuiImageData * checkbox_imgdata;
|
||||||
|
GuiImage checkbox_img;
|
||||||
|
|
||||||
|
GuiImageData * checkbox_selected_imgdata;
|
||||||
|
GuiImage checkbox_selected_img;
|
||||||
|
|
||||||
|
GuiImageData * highlighted_imgdata;
|
||||||
|
GuiImage highlighted_img;
|
||||||
|
|
||||||
|
void update(GuiController * c);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
78
src/gui/GuiController.h
Normal file
78
src/gui/GuiController.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_CONTROLLER_H_
|
||||||
|
#define GUI_CONTROLLER_H_
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "GuiTrigger.h"
|
||||||
|
|
||||||
|
class GuiController
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
GuiController(int channel)
|
||||||
|
: chan(channel)
|
||||||
|
{
|
||||||
|
memset(&lastData, 0, sizeof(lastData));
|
||||||
|
memset(&data, 0, sizeof(data));
|
||||||
|
|
||||||
|
switch(chan)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case GuiTrigger::CHANNEL_1:
|
||||||
|
chanIdx = 0;
|
||||||
|
break;
|
||||||
|
case GuiTrigger::CHANNEL_2:
|
||||||
|
chanIdx = 1;
|
||||||
|
break;
|
||||||
|
case GuiTrigger::CHANNEL_3:
|
||||||
|
chanIdx = 2;
|
||||||
|
break;
|
||||||
|
case GuiTrigger::CHANNEL_4:
|
||||||
|
chanIdx = 3;
|
||||||
|
break;
|
||||||
|
case GuiTrigger::CHANNEL_5:
|
||||||
|
chanIdx = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiController() {}
|
||||||
|
|
||||||
|
virtual bool update(int width, int height) = 0;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int buttons_h;
|
||||||
|
unsigned int buttons_d;
|
||||||
|
unsigned int buttons_r;
|
||||||
|
bool validPointer;
|
||||||
|
bool touched;
|
||||||
|
float pointerAngle;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
} PadData;
|
||||||
|
|
||||||
|
int chan;
|
||||||
|
int chanIdx;
|
||||||
|
PadData data;
|
||||||
|
PadData lastData;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
82
src/gui/GuiDragListener.cpp
Normal file
82
src/gui/GuiDragListener.cpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016 Maschell
|
||||||
|
* based on GuiButton by dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "GuiDragListener.h"
|
||||||
|
#include "GuiController.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the GuiDragListener class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
GuiDragListener::GuiDragListener(f32 w,f32 h){
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
for(int i = 0; i < iMaxGuiTriggers; i++)
|
||||||
|
{
|
||||||
|
trigger[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor for the GuiDragListener class.
|
||||||
|
*/
|
||||||
|
GuiDragListener::~GuiDragListener(){
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiDragListener::setTrigger(GuiTrigger * t, int idx){
|
||||||
|
if(idx >= 0 && idx < iMaxGuiTriggers)
|
||||||
|
{
|
||||||
|
trigger[idx] = t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < iMaxGuiTriggers; i++)
|
||||||
|
{
|
||||||
|
if(!trigger[i])
|
||||||
|
{
|
||||||
|
trigger[i] = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiDragListener::update(GuiController * c){
|
||||||
|
if(!c || isStateSet(STATE_DISABLED|STATE_HIDDEN|STATE_DISABLE_INPUT, c->chan))
|
||||||
|
return;
|
||||||
|
else if(parentElement && (parentElement->isStateSet(STATE_DISABLED|STATE_HIDDEN|STATE_DISABLE_INPUT, c->chan)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(int i = 0; i < iMaxGuiTriggers; i++){
|
||||||
|
if(!trigger[i]){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isHeld = trigger[i]->held(c);
|
||||||
|
|
||||||
|
|
||||||
|
if(isHeld && this->isInside(c->data.x, c->data.y)){
|
||||||
|
int dx = c->data.x - c->lastData.x;
|
||||||
|
int dy = c->data.y - c->lastData.y;
|
||||||
|
|
||||||
|
if(dx == 0 && dy == 0) continue;
|
||||||
|
|
||||||
|
dragged(this, c, trigger[i],dx,dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
src/gui/GuiDragListener.h
Normal file
50
src/gui/GuiDragListener.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_DRAG_LISTENER_H_
|
||||||
|
#define GUI_DRAG_LISTENER_H_
|
||||||
|
|
||||||
|
#include "GuiElement.h"
|
||||||
|
#include "GuiController.h"
|
||||||
|
#include "GuiTrigger.h"
|
||||||
|
#include "GuiButton.h"
|
||||||
|
|
||||||
|
class GuiDragListener : public GuiElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
//!\param w Width
|
||||||
|
//!\param h Height
|
||||||
|
GuiDragListener(f32 w,f32 h);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiDragListener();
|
||||||
|
//!Set a new GuiTrigger for the element
|
||||||
|
//!\param i Index of trigger array to set
|
||||||
|
//!\param t Pointer to GuiTrigger
|
||||||
|
void setTrigger(GuiTrigger * t, int idx = -1);
|
||||||
|
|
||||||
|
//!Constantly called to allow the GuiDragListener to respond to updated input data
|
||||||
|
//!\param t Pointer to a GuiTrigger, containing the current input data from PAD/WPAD
|
||||||
|
void update(GuiController * c);
|
||||||
|
|
||||||
|
sigslot::signal5<GuiDragListener *, const GuiController *, GuiTrigger *,int,int> dragged;
|
||||||
|
protected:
|
||||||
|
static const int iMaxGuiTriggers = 10;
|
||||||
|
|
||||||
|
GuiTrigger * trigger[iMaxGuiTriggers]; //!< GuiTriggers (input actions) that this element responds to
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
343
src/gui/GuiElement.cpp
Normal file
343
src/gui/GuiElement.cpp
Normal file
@ -0,0 +1,343 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "GuiElement.h"
|
||||||
|
|
||||||
|
//! TODO remove this!
|
||||||
|
static int screenwidth = 1280;
|
||||||
|
static int screenheight = 720;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the Object class.
|
||||||
|
*/
|
||||||
|
GuiElement::GuiElement()
|
||||||
|
{
|
||||||
|
xoffset = 0.0f;
|
||||||
|
yoffset = 0.0f;
|
||||||
|
zoffset = 0.0f;
|
||||||
|
width = 0.0f;
|
||||||
|
height = 0.0f;
|
||||||
|
alpha = 1.0f;
|
||||||
|
scaleX = 1.0f;
|
||||||
|
scaleY = 1.0f;
|
||||||
|
scaleZ = 1.0f;
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
state[i] = STATE_DEFAULT;
|
||||||
|
stateChan = -1;
|
||||||
|
parentElement = NULL;
|
||||||
|
rumble = true;
|
||||||
|
selectable = false;
|
||||||
|
clickable = false;
|
||||||
|
holdable = false;
|
||||||
|
drawOverOnlyWhenSelected = false;
|
||||||
|
visible = true;
|
||||||
|
yoffsetDyn = 0;
|
||||||
|
xoffsetDyn = 0;
|
||||||
|
alphaDyn = -1;
|
||||||
|
scaleDyn = 1;
|
||||||
|
effects = EFFECT_NONE;
|
||||||
|
effectAmount = 0;
|
||||||
|
effectTarget = 0;
|
||||||
|
effectsOver = EFFECT_NONE;
|
||||||
|
effectAmountOver = 0;
|
||||||
|
effectTargetOver = 0;
|
||||||
|
angle = 0.0f;
|
||||||
|
|
||||||
|
// default alignment - align to top left
|
||||||
|
alignment = (ALIGN_CENTER | ALIGN_MIDDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the left position of the GuiElement.
|
||||||
|
* @see SetLeft()
|
||||||
|
* @return Left position in pixel.
|
||||||
|
*/
|
||||||
|
f32 GuiElement::getLeft()
|
||||||
|
{
|
||||||
|
f32 pWidth = 0;
|
||||||
|
f32 pLeft = 0;
|
||||||
|
f32 pScaleX = 1.0f;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
{
|
||||||
|
pWidth = parentElement->getWidth();
|
||||||
|
pLeft = parentElement->getLeft();
|
||||||
|
pScaleX = parentElement->getScaleX();
|
||||||
|
}
|
||||||
|
|
||||||
|
pLeft += xoffsetDyn;
|
||||||
|
|
||||||
|
f32 x = pLeft;
|
||||||
|
|
||||||
|
//! TODO: the conversion from int to float and back to int is bad for performance, change that
|
||||||
|
if(alignment & ALIGN_CENTER)
|
||||||
|
{
|
||||||
|
x = pLeft + pWidth * 0.5f * pScaleX - width * 0.5f * getScaleX();
|
||||||
|
}
|
||||||
|
else if(alignment & ALIGN_RIGHT)
|
||||||
|
{
|
||||||
|
x = pLeft + pWidth * pScaleX - width * getScaleX();
|
||||||
|
}
|
||||||
|
|
||||||
|
return x + xoffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the top position of the GuiElement.
|
||||||
|
* @see SetTop()
|
||||||
|
* @return Top position in pixel.
|
||||||
|
*/
|
||||||
|
f32 GuiElement::getTop()
|
||||||
|
{
|
||||||
|
f32 pHeight = 0;
|
||||||
|
f32 pTop = 0;
|
||||||
|
f32 pScaleY = 1.0f;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
{
|
||||||
|
pHeight = parentElement->getHeight();
|
||||||
|
pTop = parentElement->getTop();
|
||||||
|
pScaleY = parentElement->getScaleY();
|
||||||
|
}
|
||||||
|
|
||||||
|
pTop += yoffsetDyn;
|
||||||
|
|
||||||
|
f32 y = pTop;
|
||||||
|
|
||||||
|
//! TODO: the conversion from int to float and back to int is bad for performance, change that
|
||||||
|
if(alignment & ALIGN_MIDDLE)
|
||||||
|
{
|
||||||
|
y = pTop + pHeight * 0.5f * pScaleY - height * 0.5f * getScaleY();
|
||||||
|
}
|
||||||
|
else if(alignment & ALIGN_BOTTOM)
|
||||||
|
{
|
||||||
|
y = pTop + pHeight * pScaleY - height * getScaleY();
|
||||||
|
}
|
||||||
|
|
||||||
|
return y + yoffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiElement::setEffect(int eff, int amount, int target)
|
||||||
|
{
|
||||||
|
if(eff & EFFECT_SLIDE_IN)
|
||||||
|
{
|
||||||
|
// these calculations overcompensate a little
|
||||||
|
if(eff & EFFECT_SLIDE_TOP)
|
||||||
|
{
|
||||||
|
if(eff & EFFECT_SLIDE_FROM)
|
||||||
|
yoffsetDyn = (int) -getHeight()*scaleY;
|
||||||
|
else
|
||||||
|
yoffsetDyn = -screenheight;
|
||||||
|
}
|
||||||
|
else if(eff & EFFECT_SLIDE_LEFT)
|
||||||
|
{
|
||||||
|
if(eff & EFFECT_SLIDE_FROM)
|
||||||
|
xoffsetDyn = (int) -getWidth()*scaleX;
|
||||||
|
else
|
||||||
|
xoffsetDyn = -screenwidth;
|
||||||
|
}
|
||||||
|
else if(eff & EFFECT_SLIDE_BOTTOM)
|
||||||
|
{
|
||||||
|
if(eff & EFFECT_SLIDE_FROM)
|
||||||
|
yoffsetDyn = (int) getHeight()*scaleY;
|
||||||
|
else
|
||||||
|
yoffsetDyn = screenheight;
|
||||||
|
}
|
||||||
|
else if(eff & EFFECT_SLIDE_RIGHT)
|
||||||
|
{
|
||||||
|
if(eff & EFFECT_SLIDE_FROM)
|
||||||
|
xoffsetDyn = (int) getWidth()*scaleX;
|
||||||
|
else
|
||||||
|
xoffsetDyn = screenwidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((eff & EFFECT_FADE) && amount > 0)
|
||||||
|
{
|
||||||
|
alphaDyn = 0;
|
||||||
|
}
|
||||||
|
else if((eff & EFFECT_FADE) && amount < 0)
|
||||||
|
{
|
||||||
|
alphaDyn = alpha;
|
||||||
|
}
|
||||||
|
effects |= eff;
|
||||||
|
effectAmount = amount;
|
||||||
|
effectTarget = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
//!Sets an effect to be enabled on wiimote cursor over
|
||||||
|
//!\param e Effect to enable
|
||||||
|
//!\param a Amount of the effect (usage varies on effect)
|
||||||
|
//!\param t Target amount of the effect (usage varies on effect)
|
||||||
|
void GuiElement::setEffectOnOver(int e, int a, int t)
|
||||||
|
{
|
||||||
|
effectsOver |= e;
|
||||||
|
effectAmountOver = a;
|
||||||
|
effectTargetOver = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiElement::resetEffects()
|
||||||
|
{
|
||||||
|
yoffsetDyn = 0;
|
||||||
|
xoffsetDyn = 0;
|
||||||
|
alphaDyn = -1;
|
||||||
|
scaleDyn = 1;
|
||||||
|
effects = EFFECT_NONE;
|
||||||
|
effectAmount = 0;
|
||||||
|
effectTarget = 0;
|
||||||
|
effectsOver = EFFECT_NONE;
|
||||||
|
effectAmountOver = 0;
|
||||||
|
effectTargetOver = 0;
|
||||||
|
}
|
||||||
|
void GuiElement::updateEffects()
|
||||||
|
{
|
||||||
|
if(!this->isVisible() && parentElement)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(effects & (EFFECT_SLIDE_IN | EFFECT_SLIDE_OUT | EFFECT_SLIDE_FROM))
|
||||||
|
{
|
||||||
|
if(effects & EFFECT_SLIDE_IN)
|
||||||
|
{
|
||||||
|
if(effects & EFFECT_SLIDE_LEFT)
|
||||||
|
{
|
||||||
|
xoffsetDyn += effectAmount;
|
||||||
|
|
||||||
|
if(xoffsetDyn >= 0)
|
||||||
|
{
|
||||||
|
xoffsetDyn = 0;
|
||||||
|
effects = 0;
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(effects & EFFECT_SLIDE_RIGHT)
|
||||||
|
{
|
||||||
|
xoffsetDyn -= effectAmount;
|
||||||
|
|
||||||
|
if(xoffsetDyn <= 0)
|
||||||
|
{
|
||||||
|
xoffsetDyn = 0;
|
||||||
|
effects = 0;
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(effects & EFFECT_SLIDE_TOP)
|
||||||
|
{
|
||||||
|
yoffsetDyn += effectAmount;
|
||||||
|
|
||||||
|
if(yoffsetDyn >= 0)
|
||||||
|
{
|
||||||
|
yoffsetDyn = 0;
|
||||||
|
effects = 0;
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(effects & EFFECT_SLIDE_BOTTOM)
|
||||||
|
{
|
||||||
|
yoffsetDyn -= effectAmount;
|
||||||
|
|
||||||
|
if(yoffsetDyn <= 0)
|
||||||
|
{
|
||||||
|
yoffsetDyn = 0;
|
||||||
|
effects = 0;
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(effects & EFFECT_SLIDE_LEFT)
|
||||||
|
{
|
||||||
|
xoffsetDyn -= effectAmount;
|
||||||
|
|
||||||
|
if(xoffsetDyn <= -screenwidth) {
|
||||||
|
effects = 0; // shut off effect
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
else if((effects & EFFECT_SLIDE_FROM) && xoffsetDyn <= -getWidth()) {
|
||||||
|
effects = 0; // shut off effect
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(effects & EFFECT_SLIDE_RIGHT)
|
||||||
|
{
|
||||||
|
xoffsetDyn += effectAmount;
|
||||||
|
|
||||||
|
if(xoffsetDyn >= screenwidth) {
|
||||||
|
effects = 0; // shut off effect
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
else if((effects & EFFECT_SLIDE_FROM) && xoffsetDyn >= getWidth()*scaleX) {
|
||||||
|
effects = 0; // shut off effect
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(effects & EFFECT_SLIDE_TOP)
|
||||||
|
{
|
||||||
|
yoffsetDyn -= effectAmount;
|
||||||
|
|
||||||
|
if(yoffsetDyn <= -screenheight) {
|
||||||
|
effects = 0; // shut off effect
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
else if((effects & EFFECT_SLIDE_FROM) && yoffsetDyn <= -getHeight()) {
|
||||||
|
effects = 0; // shut off effect
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(effects & EFFECT_SLIDE_BOTTOM)
|
||||||
|
{
|
||||||
|
yoffsetDyn += effectAmount;
|
||||||
|
|
||||||
|
if(yoffsetDyn >= screenheight) {
|
||||||
|
effects = 0; // shut off effect
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
else if((effects & EFFECT_SLIDE_FROM) && yoffsetDyn >= getHeight()) {
|
||||||
|
effects = 0; // shut off effect
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(effects & EFFECT_FADE)
|
||||||
|
{
|
||||||
|
alphaDyn += effectAmount * (1.0f / 255.0f);
|
||||||
|
|
||||||
|
if(effectAmount < 0 && alphaDyn <= 0)
|
||||||
|
{
|
||||||
|
alphaDyn = 0;
|
||||||
|
effects = 0; // shut off effect
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
else if(effectAmount > 0 && alphaDyn >= alpha)
|
||||||
|
{
|
||||||
|
alphaDyn = alpha;
|
||||||
|
effects = 0; // shut off effect
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(effects & EFFECT_SCALE)
|
||||||
|
{
|
||||||
|
scaleDyn += effectAmount * 0.01f;
|
||||||
|
|
||||||
|
if((effectAmount < 0 && scaleDyn <= (effectTarget * 0.01f))
|
||||||
|
|| (effectAmount > 0 && scaleDyn >= (effectTarget * 0.01f)))
|
||||||
|
{
|
||||||
|
scaleDyn = effectTarget * 0.01f;
|
||||||
|
effects = 0; // shut off effect
|
||||||
|
effectFinished(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
529
src/gui/GuiElement.h
Normal file
529
src/gui/GuiElement.h
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_ELEMENT_H_
|
||||||
|
#define GUI_ELEMENT_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <gctypes.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "sigslot.h"
|
||||||
|
#include "glm/glm.hpp"
|
||||||
|
#include "glm/gtc/matrix_transform.hpp"
|
||||||
|
|
||||||
|
#include "dynamic_libs/gx2_types.h"
|
||||||
|
#include "resources/Resources.h"
|
||||||
|
#include "system/AsyncDeleter.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
EFFECT_NONE = 0x00,
|
||||||
|
EFFECT_SLIDE_TOP = 0x01,
|
||||||
|
EFFECT_SLIDE_BOTTOM = 0x02,
|
||||||
|
EFFECT_SLIDE_RIGHT = 0x04,
|
||||||
|
EFFECT_SLIDE_LEFT = 0x08,
|
||||||
|
EFFECT_SLIDE_IN = 0x10,
|
||||||
|
EFFECT_SLIDE_OUT = 0x20,
|
||||||
|
EFFECT_SLIDE_FROM = 0x40,
|
||||||
|
EFFECT_FADE = 0x80,
|
||||||
|
EFFECT_SCALE = 0x100,
|
||||||
|
EFFECT_COLOR_TRANSITION = 0x200
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ALIGN_LEFT = 0x01,
|
||||||
|
ALIGN_CENTER = 0x02,
|
||||||
|
ALIGN_RIGHT = 0x04,
|
||||||
|
ALIGN_TOP = 0x10,
|
||||||
|
ALIGN_MIDDLE = 0x20,
|
||||||
|
ALIGN_BOTTOM = 0x40,
|
||||||
|
ALIGN_TOP_LEFT = ALIGN_LEFT | ALIGN_TOP,
|
||||||
|
ALIGN_TOP_CENTER = ALIGN_CENTER | ALIGN_TOP,
|
||||||
|
ALIGN_TOP_RIGHT = ALIGN_RIGHT | ALIGN_TOP,
|
||||||
|
ALIGN_CENTERED = ALIGN_CENTER | ALIGN_MIDDLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
//!Forward declaration
|
||||||
|
class GuiController;
|
||||||
|
class CVideo;
|
||||||
|
|
||||||
|
//!Primary GUI class. Most other classes inherit from this class.
|
||||||
|
class GuiElement : public AsyncDeleter::Element
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
GuiElement();
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiElement() {}
|
||||||
|
//!Set the element's parent
|
||||||
|
//!\param e Pointer to parent element
|
||||||
|
virtual void setParent(GuiElement * e) { parentElement = e; }
|
||||||
|
//!Gets the element's parent
|
||||||
|
//!\return Pointer to parent element
|
||||||
|
virtual GuiElement * getParent() { return parentElement; }
|
||||||
|
//!Gets the current leftmost coordinate of the element
|
||||||
|
//!Considers horizontal alignment, x offset, width, and parent element's GetLeft() / GetWidth() values
|
||||||
|
//!\return left coordinate
|
||||||
|
virtual f32 getLeft();
|
||||||
|
//!Gets the current topmost coordinate of the element
|
||||||
|
//!Considers vertical alignment, y offset, height, and parent element's GetTop() / GetHeight() values
|
||||||
|
//!\return top coordinate
|
||||||
|
virtual f32 getTop();
|
||||||
|
//!Gets the current Z coordinate of the element
|
||||||
|
//!\return Z coordinate
|
||||||
|
virtual f32 getDepth()
|
||||||
|
{
|
||||||
|
f32 zParent = 0.0f;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
zParent = parentElement->getDepth();
|
||||||
|
|
||||||
|
return zParent+zoffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual f32 getCenterX(void)
|
||||||
|
{
|
||||||
|
f32 pCenterX = 0.0f;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
pCenterX = parentElement->getCenterX();
|
||||||
|
|
||||||
|
pCenterX += xoffset + xoffsetDyn;
|
||||||
|
|
||||||
|
if(alignment & ALIGN_LEFT)
|
||||||
|
{
|
||||||
|
f32 pWidth = 0.0f;
|
||||||
|
f32 pScale = 0.0f;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
{
|
||||||
|
pWidth = parentElement->getWidth();
|
||||||
|
pScale = parentElement->getScaleX();
|
||||||
|
}
|
||||||
|
|
||||||
|
pCenterX -= pWidth * 0.5f * pScale - width * 0.5f * getScaleX();
|
||||||
|
}
|
||||||
|
else if(alignment & ALIGN_RIGHT)
|
||||||
|
{
|
||||||
|
f32 pWidth = 0.0f;
|
||||||
|
f32 pScale = 0.0f;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
{
|
||||||
|
pWidth = parentElement->getWidth();
|
||||||
|
pScale = parentElement->getScaleX();
|
||||||
|
}
|
||||||
|
|
||||||
|
pCenterX += pWidth * 0.5f * pScale - width * 0.5f * getScaleX();
|
||||||
|
}
|
||||||
|
return pCenterX;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual f32 getCenterY(void)
|
||||||
|
{
|
||||||
|
f32 pCenterY = 0.0f;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
pCenterY = parentElement->getCenterY();
|
||||||
|
|
||||||
|
pCenterY += yoffset + yoffsetDyn;
|
||||||
|
|
||||||
|
if(alignment & ALIGN_TOP)
|
||||||
|
{
|
||||||
|
f32 pHeight = 0.0f;
|
||||||
|
f32 pScale = 0.0f;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
{
|
||||||
|
pHeight = parentElement->getHeight();
|
||||||
|
pScale = parentElement->getScaleY();
|
||||||
|
}
|
||||||
|
|
||||||
|
pCenterY += pHeight * 0.5f * pScale - height * 0.5f * getScaleY();
|
||||||
|
}
|
||||||
|
else if(alignment & ALIGN_BOTTOM)
|
||||||
|
{
|
||||||
|
f32 pHeight = 0.0f;
|
||||||
|
f32 pScale = 0.0f;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
{
|
||||||
|
pHeight = parentElement->getHeight();
|
||||||
|
pScale = parentElement->getScaleY();
|
||||||
|
}
|
||||||
|
|
||||||
|
pCenterY -= pHeight * 0.5f * pScale - height * 0.5f * getScaleY();
|
||||||
|
}
|
||||||
|
return pCenterY;
|
||||||
|
}
|
||||||
|
//!Gets elements xoffset
|
||||||
|
virtual f32 getOffsetX() { return xoffset; }
|
||||||
|
//!Gets elements yoffset
|
||||||
|
virtual f32 getOffsetY() { return yoffset; }
|
||||||
|
//!Gets the current width of the element. Does not currently consider the scale
|
||||||
|
//!\return width
|
||||||
|
virtual f32 getWidth() { return width; };
|
||||||
|
//!Gets the height of the element. Does not currently consider the scale
|
||||||
|
//!\return height
|
||||||
|
virtual f32 getHeight() { return height; }
|
||||||
|
//!Sets the size (width/height) of the element
|
||||||
|
//!\param w Width of element
|
||||||
|
//!\param h Height of element
|
||||||
|
virtual void setSize(f32 w, f32 h)
|
||||||
|
{
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
}
|
||||||
|
//!Sets the element's visibility
|
||||||
|
//!\param v Visibility (true = visible)
|
||||||
|
virtual void setVisible(bool v)
|
||||||
|
{
|
||||||
|
visible = v;
|
||||||
|
visibleChanged(this, v);
|
||||||
|
}
|
||||||
|
//!Checks whether or not the element is visible
|
||||||
|
//!\return true if visible, false otherwise
|
||||||
|
virtual bool isVisible() const { return !isStateSet(STATE_HIDDEN) && visible; };
|
||||||
|
//!Checks whether or not the element is selectable
|
||||||
|
//!\return true if selectable, false otherwise
|
||||||
|
virtual bool isSelectable()
|
||||||
|
{
|
||||||
|
return !isStateSet(STATE_DISABLED) && selectable;
|
||||||
|
}
|
||||||
|
virtual bool isDrawOverOnlyWhenSelected()
|
||||||
|
{
|
||||||
|
return drawOverOnlyWhenSelected;
|
||||||
|
}
|
||||||
|
virtual void setdrawOverOnlyWhenSelected(bool s) { drawOverOnlyWhenSelected = s; }
|
||||||
|
//!Checks whether or not the element is clickable
|
||||||
|
//!\return true if clickable, false otherwise
|
||||||
|
virtual bool isClickable()
|
||||||
|
{
|
||||||
|
return !isStateSet(STATE_DISABLED) && clickable;
|
||||||
|
}
|
||||||
|
//!Checks whether or not the element is holdable
|
||||||
|
//!\return true if holdable, false otherwise
|
||||||
|
virtual bool isHoldable() { return !isStateSet(STATE_DISABLED) && holdable; }
|
||||||
|
//!Sets whether or not the element is selectable
|
||||||
|
//!\param s Selectable
|
||||||
|
virtual void setSelectable(bool s) { selectable = s; }
|
||||||
|
//!Sets whether or not the element is clickable
|
||||||
|
//!\param c Clickable
|
||||||
|
virtual void setClickable(bool c) { clickable = c; }
|
||||||
|
//!Sets whether or not the element is holdable
|
||||||
|
//!\param c Holdable
|
||||||
|
virtual void setHoldable(bool d) { holdable = d; }
|
||||||
|
//!Sets the element's state
|
||||||
|
//!\param s State (STATE_DEFAULT, STATE_SELECTED, STATE_CLICKED, STATE_DISABLED)
|
||||||
|
//!\param c Controller channel (0-3, -1 = none)
|
||||||
|
virtual void setState(int s, int c = -1)
|
||||||
|
{
|
||||||
|
if(c >= 0 && c < 4)
|
||||||
|
{
|
||||||
|
state[c] |= s;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
state[i] |= s;
|
||||||
|
}
|
||||||
|
stateChan = c;
|
||||||
|
stateChanged(this, s, c);
|
||||||
|
}
|
||||||
|
virtual void clearState(int s, int c = -1)
|
||||||
|
{
|
||||||
|
if(c >= 0 && c < 4)
|
||||||
|
{
|
||||||
|
state[c] &= ~s;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
state[i] &= ~s;
|
||||||
|
}
|
||||||
|
stateChan = c;
|
||||||
|
stateChanged(this, s, c);
|
||||||
|
}
|
||||||
|
virtual bool isStateSet(int s, int c = -1) const
|
||||||
|
{
|
||||||
|
if(c >= 0 && c < 4)
|
||||||
|
{
|
||||||
|
return (state[c] & s) != 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
if((state[i] & s) != 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//!Gets the element's current state
|
||||||
|
//!\return state
|
||||||
|
virtual int getState(int c = 0) { return state[c]; };
|
||||||
|
//!Gets the controller channel that last changed the element's state
|
||||||
|
//!\return Channel number (0-3, -1 = no channel)
|
||||||
|
virtual int getStateChan() { return stateChan; };
|
||||||
|
//!Resets the element's state to STATE_DEFAULT
|
||||||
|
virtual void resetState()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
state[i] = STATE_DEFAULT;
|
||||||
|
stateChan = -1;
|
||||||
|
}
|
||||||
|
//!Sets the element's alpha value
|
||||||
|
//!\param a alpha value
|
||||||
|
virtual void setAlpha(f32 a) { alpha = a; }
|
||||||
|
//!Gets the element's alpha value
|
||||||
|
//!Considers alpha, alphaDyn, and the parent element's getAlpha() value
|
||||||
|
//!\return alpha
|
||||||
|
virtual f32 getAlpha()
|
||||||
|
{
|
||||||
|
f32 a;
|
||||||
|
|
||||||
|
if(alphaDyn >= 0)
|
||||||
|
a = alphaDyn;
|
||||||
|
else
|
||||||
|
a = alpha;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
a = (a * parentElement->getAlpha());
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
//!Sets the element's scale
|
||||||
|
//!\param s scale (1 is 100%)
|
||||||
|
virtual void setScale(float s)
|
||||||
|
{
|
||||||
|
scaleX = s;
|
||||||
|
scaleY = s;
|
||||||
|
scaleZ = s;
|
||||||
|
}
|
||||||
|
//!Sets the element's scale
|
||||||
|
//!\param s scale (1 is 100%)
|
||||||
|
virtual void setScaleX(float s) { scaleX = s; }
|
||||||
|
//!Sets the element's scale
|
||||||
|
//!\param s scale (1 is 100%)
|
||||||
|
virtual void setScaleY(float s) { scaleY = s; }
|
||||||
|
//!Sets the element's scale
|
||||||
|
//!\param s scale (1 is 100%)
|
||||||
|
virtual void setScaleZ(float s) { scaleZ = s; }
|
||||||
|
//!Gets the element's current scale
|
||||||
|
//!Considers scale, scaleDyn, and the parent element's getScale() value
|
||||||
|
virtual float getScale()
|
||||||
|
{
|
||||||
|
float s = 0.5f * (scaleX+scaleY) * scaleDyn;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
s *= parentElement->getScale();
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
//!Gets the element's current scale
|
||||||
|
//!Considers scale, scaleDyn, and the parent element's getScale() value
|
||||||
|
virtual float getScaleX()
|
||||||
|
{
|
||||||
|
float s = scaleX * scaleDyn;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
s *= parentElement->getScaleX();
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
//!Gets the element's current scale
|
||||||
|
//!Considers scale, scaleDyn, and the parent element's getScale() value
|
||||||
|
virtual float getScaleY()
|
||||||
|
{
|
||||||
|
float s = scaleY * scaleDyn;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
s *= parentElement->getScaleY();
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
//!Gets the element's current scale
|
||||||
|
//!Considers scale, scaleDyn, and the parent element's getScale() value
|
||||||
|
virtual float getScaleZ()
|
||||||
|
{
|
||||||
|
float s = scaleZ;
|
||||||
|
|
||||||
|
if(parentElement)
|
||||||
|
s *= parentElement->getScaleZ();
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
//!Checks whether rumble was requested by the element
|
||||||
|
//!\return true is rumble was requested, false otherwise
|
||||||
|
virtual bool isRumbleActive() { return rumble; }
|
||||||
|
//!Sets whether or not the element is requesting a rumble event
|
||||||
|
//!\param r true if requesting rumble, false if not
|
||||||
|
virtual void setRumble(bool r) { rumble = r; }
|
||||||
|
//!Set an effect for the element
|
||||||
|
//!\param e Effect to enable
|
||||||
|
//!\param a Amount of the effect (usage varies on effect)
|
||||||
|
//!\param t Target amount of the effect (usage varies on effect)
|
||||||
|
virtual void setEffect(int e, int a, int t=0);
|
||||||
|
//!Sets an effect to be enabled on wiimote cursor over
|
||||||
|
//!\param e Effect to enable
|
||||||
|
//!\param a Amount of the effect (usage varies on effect)
|
||||||
|
//!\param t Target amount of the effect (usage varies on effect)
|
||||||
|
virtual void setEffectOnOver(int e, int a, int t=0);
|
||||||
|
//!Shortcut to SetEffectOnOver(EFFECT_SCALE, 4, 110)
|
||||||
|
virtual void setEffectGrow() { setEffectOnOver(EFFECT_SCALE, 4, 110); }
|
||||||
|
//!Reset all applied effects
|
||||||
|
virtual void resetEffects();
|
||||||
|
//!Gets the current element effects
|
||||||
|
//!\return element effects
|
||||||
|
virtual int getEffect() const { return effects; }
|
||||||
|
//!\return true if element animation is on going
|
||||||
|
virtual bool isAnimated() const { return (parentElement != 0) && (getEffect() > 0); }
|
||||||
|
//!Checks whether the specified coordinates are within the element's boundaries
|
||||||
|
//!\param x X coordinate
|
||||||
|
//!\param y Y coordinate
|
||||||
|
//!\return true if contained within, false otherwise
|
||||||
|
virtual bool isInside(f32 x, f32 y)
|
||||||
|
{
|
||||||
|
return ( x > (this->getCenterX() - getScaleX() * getWidth() * 0.5f)
|
||||||
|
&& x < (this->getCenterX() + getScaleX() * getWidth() * 0.5f)
|
||||||
|
&& y > (this->getCenterY() - getScaleY() * getHeight() * 0.5f)
|
||||||
|
&& y < (this->getCenterY() + getScaleY() * getHeight() * 0.5f));
|
||||||
|
}
|
||||||
|
//!Sets the element's position
|
||||||
|
//!\param x X coordinate
|
||||||
|
//!\param y Y coordinate
|
||||||
|
virtual void setPosition(f32 x, f32 y)
|
||||||
|
{
|
||||||
|
xoffset = x;
|
||||||
|
yoffset = y;
|
||||||
|
}
|
||||||
|
//!Sets the element's position
|
||||||
|
//!\param x X coordinate
|
||||||
|
//!\param y Y coordinate
|
||||||
|
//!\param z Z coordinate
|
||||||
|
virtual void setPosition(f32 x, f32 y, f32 z)
|
||||||
|
{
|
||||||
|
xoffset = x;
|
||||||
|
yoffset = y;
|
||||||
|
zoffset = z;
|
||||||
|
}
|
||||||
|
//!Gets whether or not the element is in STATE_SELECTED
|
||||||
|
//!\return true if selected, false otherwise
|
||||||
|
virtual int getSelected() { return -1; }
|
||||||
|
//!Sets the element's alignment respective to its parent element
|
||||||
|
//!Bitwise ALIGN_LEFT | ALIGN_RIGHT | ALIGN_CENTRE, ALIGN_TOP, ALIGN_BOTTOM, ALIGN_MIDDLE)
|
||||||
|
//!\param align Alignment
|
||||||
|
virtual void setAlignment(int a) { alignment = a; }
|
||||||
|
//!Gets the element's alignment
|
||||||
|
virtual int getAlignment() const { return alignment; }
|
||||||
|
//!Angle of the object
|
||||||
|
virtual void setAngle(f32 a) { angle = a; }
|
||||||
|
//!Angle of the object
|
||||||
|
virtual f32 getAngle() const { f32 r_angle = angle; if(parentElement) r_angle += parentElement->getAngle(); return r_angle; }
|
||||||
|
//!Called constantly to allow the element to respond to the current input data
|
||||||
|
//!\param t Pointer to a GuiController, containing the current input data from PAD/WPAD/VPAD
|
||||||
|
virtual void update(GuiController * t) { }
|
||||||
|
//!Called constantly to redraw the element
|
||||||
|
virtual void draw(CVideo * v) { }
|
||||||
|
//!Called constantly to process stuff in the element
|
||||||
|
virtual void process() { }
|
||||||
|
|
||||||
|
//!Updates the element's effects (dynamic values)
|
||||||
|
//!Called by Draw(), used for animation purposes
|
||||||
|
virtual void updateEffects();
|
||||||
|
|
||||||
|
typedef struct _POINT {
|
||||||
|
s32 x;
|
||||||
|
s32 y;
|
||||||
|
} POINT;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
STATE_DEFAULT = 0,
|
||||||
|
STATE_SELECTED = 0x01,
|
||||||
|
STATE_CLICKED = 0x02,
|
||||||
|
STATE_HELD = 0x04,
|
||||||
|
STATE_OVER = 0x08,
|
||||||
|
STATE_HIDDEN = 0x10,
|
||||||
|
STATE_DISABLE_INPUT = 0x20,
|
||||||
|
STATE_CLICKED_TOUCH = 0x40,
|
||||||
|
STATE_DISABLED = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Switch pointer from control to screen position
|
||||||
|
POINT PtrToScreen(POINT p)
|
||||||
|
{
|
||||||
|
//! TODO for 3D
|
||||||
|
//POINT r = { p.x + getLeft(), p.y + getTop() };
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
//! Switch pointer screen to control position
|
||||||
|
POINT PtrToControl(POINT p)
|
||||||
|
{
|
||||||
|
//! TODO for 3D
|
||||||
|
//POINT r = { p.x - getLeft(), p.y - getTop() };
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
//! Signals
|
||||||
|
sigslot::signal2<GuiElement *, bool> visibleChanged;
|
||||||
|
sigslot::signal3<GuiElement *, int, int> stateChanged;
|
||||||
|
sigslot::signal1<GuiElement *> effectFinished;
|
||||||
|
protected:
|
||||||
|
bool rumble; //!< Wiimote rumble (on/off) - set to on when this element requests a rumble event
|
||||||
|
bool visible; //!< Visibility of the element. If false, Draw() is skipped
|
||||||
|
bool selectable; //!< Whether or not this element selectable (can change to SELECTED state)
|
||||||
|
bool clickable; //!< Whether or not this element is clickable (can change to CLICKED state)
|
||||||
|
bool holdable; //!< Whether or not this element is holdable (can change to HELD state)
|
||||||
|
bool drawOverOnlyWhenSelected; //!< Whether or not this element is holdable (can change to HELD state)
|
||||||
|
f32 width; //!< Element width
|
||||||
|
f32 height; //!< Element height
|
||||||
|
f32 xoffset; //!< Element X offset
|
||||||
|
f32 yoffset; //!< Element Y offset
|
||||||
|
f32 zoffset; //!< Element Z offset
|
||||||
|
f32 alpha; //!< Element alpha value (0-255)
|
||||||
|
f32 angle; //!< Angle of the object (0-360)
|
||||||
|
f32 scaleX; //!< Element scale (1 = 100%)
|
||||||
|
f32 scaleY; //!< Element scale (1 = 100%)
|
||||||
|
f32 scaleZ; //!< Element scale (1 = 100%)
|
||||||
|
int alignment; //!< Horizontal element alignment, respective to parent element
|
||||||
|
int state[4]; //!< Element state (DEFAULT, SELECTED, CLICKED, DISABLED)
|
||||||
|
int stateChan; //!< Which controller channel is responsible for the last change in state
|
||||||
|
GuiElement * parentElement; //!< Parent element
|
||||||
|
|
||||||
|
//! TODO: Move me to some Animator class
|
||||||
|
int xoffsetDyn; //!< Element X offset, dynamic (added to xoffset value for animation effects)
|
||||||
|
int yoffsetDyn; //!< Element Y offset, dynamic (added to yoffset value for animation effects)
|
||||||
|
f32 alphaDyn; //!< Element alpha, dynamic (multiplied by alpha value for blending/fading effects)
|
||||||
|
f32 scaleDyn; //!< Element scale, dynamic (multiplied by alpha value for blending/fading effects)
|
||||||
|
int effects; //!< Currently enabled effect(s). 0 when no effects are enabled
|
||||||
|
int effectAmount; //!< Effect amount. Used by different effects for different purposes
|
||||||
|
int effectTarget; //!< Effect target amount. Used by different effects for different purposes
|
||||||
|
int effectsOver; //!< Effects to enable when wiimote cursor is over this element. Copied to effects variable on over event
|
||||||
|
int effectAmountOver; //!< EffectAmount to set when wiimote cursor is over this element
|
||||||
|
int effectTargetOver; //!< EffectTarget to set when wiimote cursor is over this element
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
230
src/gui/GuiFrame.cpp
Normal file
230
src/gui/GuiFrame.cpp
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "GuiFrame.h"
|
||||||
|
|
||||||
|
GuiFrame::GuiFrame(GuiFrame *p)
|
||||||
|
{
|
||||||
|
parent = p;
|
||||||
|
width = 0;
|
||||||
|
height = 0;
|
||||||
|
dim = false;
|
||||||
|
|
||||||
|
if(parent)
|
||||||
|
parent->append(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiFrame::GuiFrame(f32 w, f32 h, GuiFrame *p)
|
||||||
|
{
|
||||||
|
parent = p;
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
dim = false;
|
||||||
|
|
||||||
|
if(parent)
|
||||||
|
parent->append(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiFrame::~GuiFrame()
|
||||||
|
{
|
||||||
|
closing(this);
|
||||||
|
|
||||||
|
if(parent)
|
||||||
|
parent->remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::append(GuiElement* e)
|
||||||
|
{
|
||||||
|
if (e == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
remove(e);
|
||||||
|
elements.push_back(e);
|
||||||
|
e->setParent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::insert(GuiElement* e, u32 index)
|
||||||
|
{
|
||||||
|
if (e == NULL || (index >= elements.size()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
remove(e);
|
||||||
|
elements.insert(elements.begin()+index, e);
|
||||||
|
e->setParent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::remove(GuiElement* e)
|
||||||
|
{
|
||||||
|
if (e == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < elements.size(); ++i)
|
||||||
|
{
|
||||||
|
if(e == elements[i])
|
||||||
|
{
|
||||||
|
elements.erase(elements.begin()+i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::removeAll()
|
||||||
|
{
|
||||||
|
elements.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::close()
|
||||||
|
{
|
||||||
|
//Application::instance()->pushForDelete(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::dimBackground(bool d)
|
||||||
|
{
|
||||||
|
dim = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiElement* GuiFrame::getGuiElementAt(u32 index) const
|
||||||
|
{
|
||||||
|
if (index >= elements.size())
|
||||||
|
return NULL;
|
||||||
|
return elements[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GuiFrame::getSize()
|
||||||
|
{
|
||||||
|
return elements.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::resetState()
|
||||||
|
{
|
||||||
|
GuiElement::resetState();
|
||||||
|
|
||||||
|
for (u32 i = 0; i < elements.size(); ++i)
|
||||||
|
{
|
||||||
|
elements[i]->resetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::setState(int s, int c)
|
||||||
|
{
|
||||||
|
GuiElement::setState(s, c);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < elements.size(); ++i)
|
||||||
|
{
|
||||||
|
elements[i]->setState(s, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::clearState(int s, int c)
|
||||||
|
{
|
||||||
|
GuiElement::clearState(s, c);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < elements.size(); ++i)
|
||||||
|
{
|
||||||
|
elements[i]->clearState(s, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::setVisible(bool v)
|
||||||
|
{
|
||||||
|
visible = v;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < elements.size(); ++i)
|
||||||
|
{
|
||||||
|
elements[i]->setVisible(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GuiFrame::getSelected()
|
||||||
|
{
|
||||||
|
// find selected element
|
||||||
|
int found = -1;
|
||||||
|
for (u32 i = 0; i < elements.size(); ++i)
|
||||||
|
{
|
||||||
|
if(elements[i]->isStateSet(STATE_SELECTED | STATE_OVER))
|
||||||
|
{
|
||||||
|
found = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::draw(CVideo * v)
|
||||||
|
{
|
||||||
|
if(!this->isVisible() && parentElement)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(parentElement && dim == true)
|
||||||
|
{
|
||||||
|
//GXColor dimColor = (GXColor){0, 0, 0, 0x70};
|
||||||
|
//Menu_DrawRectangle(0, 0, GetZPosition(), screenwidth,screenheight, &dimColor, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! render appended items next frame but allow stop of render if size is reached
|
||||||
|
u32 size = elements.size();
|
||||||
|
|
||||||
|
for (u32 i = 0; i < size && i < elements.size(); ++i)
|
||||||
|
{
|
||||||
|
elements[i]->draw(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::updateEffects()
|
||||||
|
{
|
||||||
|
if(!this->isVisible() && parentElement)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GuiElement::updateEffects();
|
||||||
|
|
||||||
|
//! render appended items next frame but allow stop of render if size is reached
|
||||||
|
u32 size = elements.size();
|
||||||
|
|
||||||
|
for (u32 i = 0; i < size && i < elements.size(); ++i)
|
||||||
|
{
|
||||||
|
elements[i]->updateEffects();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::process()
|
||||||
|
{
|
||||||
|
if(!this->isVisible() && parentElement)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GuiElement::process();
|
||||||
|
|
||||||
|
//! render appended items next frame but allow stop of render if size is reached
|
||||||
|
u32 size = elements.size();
|
||||||
|
|
||||||
|
for (u32 i = 0; i < size && i < elements.size(); ++i)
|
||||||
|
{
|
||||||
|
elements[i]->process();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiFrame::update(GuiController * c)
|
||||||
|
{
|
||||||
|
if(isStateSet(STATE_DISABLED) && parentElement)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//! update appended items next frame
|
||||||
|
u32 size = elements.size();
|
||||||
|
|
||||||
|
for (u32 i = 0; i < size && i < elements.size(); ++i)
|
||||||
|
{
|
||||||
|
elements[i]->update(c);
|
||||||
|
}
|
||||||
|
}
|
98
src/gui/GuiFrame.h
Normal file
98
src/gui/GuiFrame.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_FRAME_H_
|
||||||
|
#define GUI_FRAME_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "GuiElement.h"
|
||||||
|
#include "sigslot.h"
|
||||||
|
|
||||||
|
//!Allows GuiElements to be grouped together into a "window"
|
||||||
|
class GuiFrame : public GuiElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
GuiFrame(GuiFrame *parent = 0);
|
||||||
|
//!\overload
|
||||||
|
//!\param w Width of window
|
||||||
|
//!\param h Height of window
|
||||||
|
GuiFrame(f32 w, f32 h, GuiFrame *parent = 0);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiFrame();
|
||||||
|
//!Appends a GuiElement to the GuiFrame
|
||||||
|
//!\param e The GuiElement to append. If it is already in the GuiFrame, it is removed first
|
||||||
|
void append(GuiElement* e);
|
||||||
|
//!Inserts a GuiElement into the GuiFrame at the specified index
|
||||||
|
//!\param e The GuiElement to insert. If it is already in the GuiFrame, it is removed first
|
||||||
|
//!\param i Index in which to insert the element
|
||||||
|
void insert(GuiElement* e, u32 i);
|
||||||
|
//!Removes the specified GuiElement from the GuiFrame
|
||||||
|
//!\param e GuiElement to be removed
|
||||||
|
void remove(GuiElement* e);
|
||||||
|
//!Removes all GuiElements
|
||||||
|
void removeAll();
|
||||||
|
//!Bring element to front of the window
|
||||||
|
void bringToFront(GuiElement *e) { remove(e); append(e); }
|
||||||
|
//!Returns the GuiElement at the specified index
|
||||||
|
//!\param index The index of the element
|
||||||
|
//!\return A pointer to the element at the index, NULL on error (eg: out of bounds)
|
||||||
|
GuiElement* getGuiElementAt(u32 index) const;
|
||||||
|
//!Returns the size of the list of elements
|
||||||
|
//!\return The size of the current element list
|
||||||
|
u32 getSize();
|
||||||
|
//!Sets the visibility of the window
|
||||||
|
//!\param v visibility (true = visible)
|
||||||
|
void setVisible(bool v);
|
||||||
|
//!Resets the window's state to STATE_DEFAULT
|
||||||
|
void resetState();
|
||||||
|
//!Sets the window's state
|
||||||
|
//!\param s State
|
||||||
|
void setState(int s, int c = -1);
|
||||||
|
void clearState(int s, int c = -1);
|
||||||
|
//!Gets the index of the GuiElement inside the window that is currently selected
|
||||||
|
//!\return index of selected GuiElement
|
||||||
|
int getSelected();
|
||||||
|
//!Dim the Window's background
|
||||||
|
void dimBackground(bool d);
|
||||||
|
//!Draws all the elements in this GuiFrame
|
||||||
|
void draw(CVideo * v);
|
||||||
|
//!Updates the window and all elements contains within
|
||||||
|
//!Allows the GuiFrame and all elements to respond to the input data specified
|
||||||
|
//!\param t Pointer to a GuiTrigger, containing the current input data from PAD/WPAD
|
||||||
|
void update(GuiController * t);
|
||||||
|
//!virtual Close Window - this will put the object on the delete queue in MainWindow
|
||||||
|
virtual void close();
|
||||||
|
//!virtual show window function
|
||||||
|
virtual void show() {}
|
||||||
|
//!virtual hide window function
|
||||||
|
virtual void hide() {}
|
||||||
|
//!virtual enter main loop function (blocking)
|
||||||
|
virtual void exec() {}
|
||||||
|
//!virtual updateEffects which is called by the main loop
|
||||||
|
virtual void updateEffects();
|
||||||
|
//!virtual process which is called by the main loop
|
||||||
|
virtual void process();
|
||||||
|
//! Signals
|
||||||
|
//! On Closing
|
||||||
|
sigslot::signal1<GuiFrame *> closing;
|
||||||
|
protected:
|
||||||
|
bool dim; //! Enable/disable dim of a window only
|
||||||
|
GuiFrame *parent; //!< Parent Window
|
||||||
|
std::vector<GuiElement*> elements; //!< Contains all elements within the GuiFrame
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
289
src/gui/GuiImage.cpp
Normal file
289
src/gui/GuiImage.cpp
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "GuiImage.h"
|
||||||
|
#include "video/CVideo.h"
|
||||||
|
#include "video/shaders/Texture2DShader.h"
|
||||||
|
#include "video/shaders/ColorShader.h"
|
||||||
|
|
||||||
|
static const f32 fPiDiv180 = ((f32)M_PI / 180.0f);
|
||||||
|
|
||||||
|
GuiImage::GuiImage(GuiImageData * img)
|
||||||
|
{
|
||||||
|
if(img && img->getTexture())
|
||||||
|
{
|
||||||
|
width = img->getWidth();
|
||||||
|
height = img->getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
internalInit(width, height);
|
||||||
|
imageData = img;
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiImage::GuiImage(int w, int h, const GX2Color & c, int type)
|
||||||
|
{
|
||||||
|
internalInit(w, h);
|
||||||
|
imgType = type;
|
||||||
|
colorCount = ColorShader::cuColorVtxsSize / ColorShader::cuColorAttrSize;
|
||||||
|
|
||||||
|
colorVtxs = (u8 *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, colorCount * ColorShader::cuColorAttrSize);
|
||||||
|
if(colorVtxs)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < colorCount; i++)
|
||||||
|
setImageColor(c, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiImage::GuiImage(int w, int h, const GX2Color *c, u32 color_count, int type)
|
||||||
|
{
|
||||||
|
internalInit(w, h);
|
||||||
|
imgType = type;
|
||||||
|
colorCount = ColorShader::cuColorVtxsSize / ColorShader::cuColorAttrSize;
|
||||||
|
if(colorCount < color_count)
|
||||||
|
colorCount = color_count;
|
||||||
|
|
||||||
|
colorVtxs = (u8 *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, colorCount * ColorShader::cuColorAttrSize);
|
||||||
|
if(colorVtxs)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < colorCount; i++)
|
||||||
|
{
|
||||||
|
// take the last as reference if not enough colors defined
|
||||||
|
int idx = (i < color_count) ? i : (color_count - 1);
|
||||||
|
setImageColor(c[idx], i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor for the GuiImage class.
|
||||||
|
*/
|
||||||
|
GuiImage::~GuiImage()
|
||||||
|
{
|
||||||
|
if(colorVtxs) {
|
||||||
|
free(colorVtxs);
|
||||||
|
colorVtxs = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImage::internalInit(int w, int h)
|
||||||
|
{
|
||||||
|
imageData = NULL;
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
tileHorizontal = -1;
|
||||||
|
tileVertical = -1;
|
||||||
|
imgType = IMAGE_TEXTURE;
|
||||||
|
colorVtxsDirty = false;
|
||||||
|
colorVtxs = NULL;
|
||||||
|
colorCount = 0;
|
||||||
|
posVtxs = NULL;
|
||||||
|
texCoords = NULL;
|
||||||
|
vtxCount = 4;
|
||||||
|
primitive = GX2_PRIMITIVE_QUADS;
|
||||||
|
|
||||||
|
imageAngle = 0.0f;
|
||||||
|
blurDirection = glm::vec3(0.0f);
|
||||||
|
positionOffsets = glm::vec3(0.0f);
|
||||||
|
scaleFactor = glm::vec3(1.0f);
|
||||||
|
colorIntensity = glm::vec4(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImage::setImageData(GuiImageData * img)
|
||||||
|
{
|
||||||
|
imageData = img;
|
||||||
|
width = 0;
|
||||||
|
height = 0;
|
||||||
|
if(img && img->getTexture())
|
||||||
|
{
|
||||||
|
width = img->getWidth();
|
||||||
|
height = img->getHeight();
|
||||||
|
}
|
||||||
|
imgType = IMAGE_TEXTURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GX2Color GuiImage::getPixel(int x, int y)
|
||||||
|
{
|
||||||
|
if(!imageData || this->getWidth() <= 0 || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight())
|
||||||
|
return (GX2Color){0, 0, 0, 0};
|
||||||
|
|
||||||
|
u32 pitch = imageData->getTexture()->surface.pitch;
|
||||||
|
u32 *imagePtr = (u32*)imageData->getTexture()->surface.image_data;
|
||||||
|
|
||||||
|
u32 color_u32 = imagePtr[y * pitch + x];
|
||||||
|
GX2Color color;
|
||||||
|
color.r = (color_u32 >> 24) & 0xFF;
|
||||||
|
color.g = (color_u32 >> 16) & 0xFF;
|
||||||
|
color.b = (color_u32 >> 8) & 0xFF;
|
||||||
|
color.a = (color_u32 >> 0) & 0xFF;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImage::setPixel(int x, int y, const GX2Color & color)
|
||||||
|
{
|
||||||
|
if(!imageData || this->getWidth() <= 0 || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight())
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
u32 pitch = imageData->getTexture()->surface.pitch;
|
||||||
|
u32 *imagePtr = (u32*)imageData->getTexture()->surface.image_data;
|
||||||
|
imagePtr[y * pitch + x] = (color.r << 24) | (color.g << 16) | (color.b << 8) | (color.a << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImage::setImageColor(const GX2Color & c, int idx)
|
||||||
|
{
|
||||||
|
if(!colorVtxs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(idx >= 0 && idx < (int)colorCount)
|
||||||
|
{
|
||||||
|
colorVtxs[(idx << 2) + 0] = c.r;
|
||||||
|
colorVtxs[(idx << 2) + 1] = c.g;
|
||||||
|
colorVtxs[(idx << 2) + 2] = c.b;
|
||||||
|
colorVtxs[(idx << 2) + 3] = c.a;
|
||||||
|
colorVtxsDirty = true;
|
||||||
|
}
|
||||||
|
else if(colorVtxs)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < (ColorShader::cuColorVtxsSize / sizeof(u8)); i += 4)
|
||||||
|
{
|
||||||
|
colorVtxs[i + 0] = c.r;
|
||||||
|
colorVtxs[i + 1] = c.g;
|
||||||
|
colorVtxs[i + 2] = c.b;
|
||||||
|
colorVtxs[i + 3] = c.a;
|
||||||
|
}
|
||||||
|
colorVtxsDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImage::setSize(int w, int h)
|
||||||
|
{
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImage::setPrimitiveVertex(s32 prim, const f32 *posVtx, const f32 *texCoord, u32 vtxcount)
|
||||||
|
{
|
||||||
|
primitive = prim;
|
||||||
|
vtxCount = vtxcount;
|
||||||
|
posVtxs = posVtx;
|
||||||
|
texCoords = texCoord;
|
||||||
|
|
||||||
|
if(imgType == IMAGE_COLOR)
|
||||||
|
{
|
||||||
|
u8 * newColorVtxs = (u8 *) memalign(0x40, ColorShader::cuColorAttrSize * vtxCount);
|
||||||
|
|
||||||
|
for(u32 i = 0; i < vtxCount; i++)
|
||||||
|
{
|
||||||
|
int newColorIdx = (i << 2);
|
||||||
|
int colorIdx = (i < colorCount) ? (newColorIdx) : ((colorCount - 1) << 2);
|
||||||
|
|
||||||
|
newColorVtxs[newColorIdx + 0] = colorVtxs[colorIdx + 0];
|
||||||
|
newColorVtxs[newColorIdx + 1] = colorVtxs[colorIdx + 1];
|
||||||
|
newColorVtxs[newColorIdx + 2] = colorVtxs[colorIdx + 2];
|
||||||
|
newColorVtxs[newColorIdx + 3] = colorVtxs[colorIdx + 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
free(colorVtxs);
|
||||||
|
colorVtxs = newColorVtxs;
|
||||||
|
colorCount = vtxCount;
|
||||||
|
colorVtxsDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImage::draw(CVideo *pVideo)
|
||||||
|
{
|
||||||
|
if(!this->isVisible() || tileVertical == 0 || tileHorizontal == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
f32 currScaleX = getScaleX();
|
||||||
|
f32 currScaleY = getScaleY();
|
||||||
|
|
||||||
|
positionOffsets[0] = getCenterX() * pVideo->getWidthScaleFactor() * 2.0f;
|
||||||
|
positionOffsets[1] = getCenterY() * pVideo->getHeightScaleFactor() * 2.0f;
|
||||||
|
positionOffsets[2] = getDepth() * pVideo->getDepthScaleFactor() * 2.0f;
|
||||||
|
|
||||||
|
scaleFactor[0] = currScaleX * getWidth() * pVideo->getWidthScaleFactor();
|
||||||
|
scaleFactor[1] = currScaleY * getHeight() * pVideo->getHeightScaleFactor();
|
||||||
|
scaleFactor[2] = getScaleZ();
|
||||||
|
|
||||||
|
//! add other colors intensities parameters
|
||||||
|
colorIntensity[3] = getAlpha();
|
||||||
|
|
||||||
|
//! angle of the object
|
||||||
|
imageAngle = DegToRad(getAngle());
|
||||||
|
|
||||||
|
// if(image && tileHorizontal > 0 && tileVertical > 0)
|
||||||
|
// {
|
||||||
|
// for(int n=0; n<tileVertical; n++)
|
||||||
|
// for(int i=0; i<tileHorizontal; i++)
|
||||||
|
// {
|
||||||
|
// if(bUnCut)
|
||||||
|
// Menu_DrawImg(image, width, height, format, currLeft+width*i, currTop+width*n, currZ, imageangle, currScaleX, currScaleY, currAlpha);
|
||||||
|
// else
|
||||||
|
// Menu_DrawImgCut(image, width, height, format, currLeft+width*i, currTop+width*n, currZ, imageangle, currScaleX, currScaleY, currAlpha, cutBoundsRect.x1(), cutBoundsRect.x2(), cutBoundsRect.y1(), cutBoundsRect.y2());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else if(image && tileHorizontal > 0)
|
||||||
|
// {
|
||||||
|
// for(int i=0; i<tileHorizontal; i++)
|
||||||
|
// {
|
||||||
|
// int widthTile = (imageangle == 90 || imageangle == 270) ? height : width;
|
||||||
|
// if(bUnCut)
|
||||||
|
// Menu_DrawImg(image, width, height, format, currLeft+widthTile*i, currTop, currZ, imageangle, currScaleX, currScaleY, currAlpha);
|
||||||
|
// else
|
||||||
|
// Menu_DrawImgCut(image, width, height, format, currLeft+widthTile*i, currTop, currZ, imageangle, currScaleX, currScaleY, currAlpha, cutBoundsRect.x1(), cutBoundsRect.x2(), cutBoundsRect.y1(), cutBoundsRect.y2());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else if(image && tileVertical > 0)
|
||||||
|
// {
|
||||||
|
// for(int i=0; i<tileVertical; i++)
|
||||||
|
// {
|
||||||
|
// if(bUnCut)
|
||||||
|
// Menu_DrawImg(image, width, height, format, currLeft, currTop+height*i, currZ, imageangle, currScaleX, currScaleY, currAlpha);
|
||||||
|
// else
|
||||||
|
// Menu_DrawImgCut(image, width, height, format, currLeft, currTop+height*i, currZ, imageangle, currScaleX, currScaleY, currAlpha, cutBoundsRect.x1(), cutBoundsRect.x2(), cutBoundsRect.y1(), cutBoundsRect.y2());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
if(colorVtxsDirty && colorVtxs) {
|
||||||
|
//! flush color vertex only on main GX2 thread
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, colorVtxs, colorCount * ColorShader::cuColorAttrSize);
|
||||||
|
colorVtxsDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(imgType == IMAGE_COLOR && colorVtxs)
|
||||||
|
{
|
||||||
|
ColorShader::instance()->setShaders();
|
||||||
|
ColorShader::instance()->setAttributeBuffer(colorVtxs, posVtxs, vtxCount);
|
||||||
|
ColorShader::instance()->setAngle(imageAngle);
|
||||||
|
ColorShader::instance()->setOffset(positionOffsets);
|
||||||
|
ColorShader::instance()->setScale(scaleFactor);
|
||||||
|
ColorShader::instance()->setColorIntensity(colorIntensity);
|
||||||
|
ColorShader::instance()->draw(primitive, vtxCount);
|
||||||
|
}
|
||||||
|
else if(imageData)
|
||||||
|
{
|
||||||
|
Texture2DShader::instance()->setShaders();
|
||||||
|
Texture2DShader::instance()->setAttributeBuffer(texCoords, posVtxs, vtxCount);
|
||||||
|
Texture2DShader::instance()->setAngle(imageAngle);
|
||||||
|
Texture2DShader::instance()->setOffset(positionOffsets);
|
||||||
|
Texture2DShader::instance()->setScale(scaleFactor);
|
||||||
|
Texture2DShader::instance()->setColorIntensity(colorIntensity);
|
||||||
|
Texture2DShader::instance()->setBlurring(blurDirection);
|
||||||
|
Texture2DShader::instance()->setTextureAndSampler(imageData->getTexture(), imageData->getSampler());
|
||||||
|
Texture2DShader::instance()->draw(primitive, vtxCount);
|
||||||
|
}
|
||||||
|
}
|
110
src/gui/GuiImage.h
Normal file
110
src/gui/GuiImage.h
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_IMAGE_H_
|
||||||
|
#define GUI_IMAGE_H_
|
||||||
|
|
||||||
|
#include "video/shaders/Shader.h"
|
||||||
|
#include "GuiElement.h"
|
||||||
|
#include "GuiImageData.h"
|
||||||
|
|
||||||
|
//!Display, manage, and manipulate images in the GUI
|
||||||
|
class GuiImage : public GuiElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum ImageTypes
|
||||||
|
{
|
||||||
|
IMAGE_TEXTURE,
|
||||||
|
IMAGE_COLOR
|
||||||
|
};
|
||||||
|
|
||||||
|
//!\overload
|
||||||
|
//!\param img Pointer to GuiImageData element
|
||||||
|
GuiImage(GuiImageData * img);
|
||||||
|
//!\overload
|
||||||
|
//!Creates an image filled with the specified color
|
||||||
|
//!\param w Image width
|
||||||
|
//!\param h Image height
|
||||||
|
//!\param c Array with 4 x image color (BL, BR, TL, TR)
|
||||||
|
GuiImage(int w, int h, const GX2Color & c, int imgType = IMAGE_COLOR);
|
||||||
|
GuiImage(int w, int h, const GX2Color * c, u32 colorCount = 1, int imgType = IMAGE_COLOR);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiImage();
|
||||||
|
//!Sets the number of times to draw the image horizontally
|
||||||
|
//!\param t Number of times to draw the image
|
||||||
|
void setTileHorizontal(int t) { tileHorizontal = t; }
|
||||||
|
//!Sets the number of times to draw the image vertically
|
||||||
|
//!\param t Number of times to draw the image
|
||||||
|
void setTileVertical(int t) { tileVertical = t; }
|
||||||
|
//!Constantly called to draw the image
|
||||||
|
void draw(CVideo *pVideo);
|
||||||
|
//!Gets the image data
|
||||||
|
//!\return pointer to image data
|
||||||
|
GuiImageData * getImageData() const { return imageData; }
|
||||||
|
//!Sets up a new image using the GuiImageData object specified
|
||||||
|
//!\param img Pointer to GuiImageData object
|
||||||
|
void setImageData(GuiImageData * img);
|
||||||
|
//!Gets the pixel color at the specified coordinates of the image
|
||||||
|
//!\param x X coordinate
|
||||||
|
//!\param y Y coordinate
|
||||||
|
GX2Color getPixel(int x, int y);
|
||||||
|
//!Sets the pixel color at the specified coordinates of the image
|
||||||
|
//!\param x X coordinate
|
||||||
|
//!\param y Y coordinate
|
||||||
|
//!\param color Pixel color
|
||||||
|
void setPixel(int x, int y, const GX2Color & color);
|
||||||
|
//!Change ImageColor
|
||||||
|
void setImageColor(const GX2Color & c, int idx = -1);
|
||||||
|
//!Change ImageColor
|
||||||
|
void setSize(int w, int h);
|
||||||
|
|
||||||
|
void setPrimitiveVertex(s32 prim, const f32 *pos, const f32 *tex, u32 count);
|
||||||
|
|
||||||
|
void setBlurDirection(u8 dir, f32 value)
|
||||||
|
{
|
||||||
|
if(dir < 2) {
|
||||||
|
blurDirection[dir] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void setColorIntensity(const glm::vec4 & col)
|
||||||
|
{
|
||||||
|
colorIntensity = col;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
void internalInit(int w, int h);
|
||||||
|
|
||||||
|
int imgType; //!< Type of image data (IMAGE_TEXTURE, IMAGE_COLOR, IMAGE_DATA)
|
||||||
|
GuiImageData * imageData; //!< Poiner to image data. May be shared with GuiImageData data
|
||||||
|
int tileHorizontal; //!< Number of times to draw (tile) the image horizontally
|
||||||
|
int tileVertical; //!< Number of times to draw (tile) the image vertically
|
||||||
|
|
||||||
|
//! Internally used variables for rendering
|
||||||
|
u8 *colorVtxs;
|
||||||
|
u32 colorCount;
|
||||||
|
bool colorVtxsDirty;
|
||||||
|
glm::vec3 positionOffsets;
|
||||||
|
glm::vec3 scaleFactor;
|
||||||
|
glm::vec4 colorIntensity;
|
||||||
|
f32 imageAngle;
|
||||||
|
glm::vec3 blurDirection;
|
||||||
|
|
||||||
|
const f32 * posVtxs;
|
||||||
|
const f32 * texCoords;
|
||||||
|
u32 vtxCount;
|
||||||
|
s32 primitive;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
173
src/gui/GuiImageAsync.cpp
Normal file
173
src/gui/GuiImageAsync.cpp
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "GuiImageAsync.h"
|
||||||
|
#include "fs/fs_utils.h"
|
||||||
|
|
||||||
|
std::vector<GuiImageAsync *> GuiImageAsync::imageQueue;
|
||||||
|
CThread * GuiImageAsync::pThread = NULL;
|
||||||
|
CMutex * GuiImageAsync::pMutex = NULL;
|
||||||
|
u32 GuiImageAsync::threadRefCounter = 0;
|
||||||
|
bool GuiImageAsync::bExitRequested = false;
|
||||||
|
GuiImageAsync * GuiImageAsync::pInUse = NULL;
|
||||||
|
|
||||||
|
GuiImageAsync::GuiImageAsync(const u8 *imageBuffer, const u32 & imageBufferSize, GuiImageData * preloadImg)
|
||||||
|
: GuiImage(preloadImg)
|
||||||
|
, imgData(NULL)
|
||||||
|
, imgBuffer(imageBuffer)
|
||||||
|
, imgBufferSize(imageBufferSize)
|
||||||
|
{
|
||||||
|
threadInit();
|
||||||
|
threadAddImage(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiImageAsync::GuiImageAsync(const std::string & file, GuiImageData * preloadImg)
|
||||||
|
: GuiImage(preloadImg)
|
||||||
|
, imgData(NULL)
|
||||||
|
, filename(file)
|
||||||
|
, imgBuffer(NULL)
|
||||||
|
, imgBufferSize(0)
|
||||||
|
{
|
||||||
|
threadInit();
|
||||||
|
threadAddImage(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiImageAsync::~GuiImageAsync()
|
||||||
|
{
|
||||||
|
threadRemoveImage(this);
|
||||||
|
while(pInUse == this)
|
||||||
|
usleep(1000);
|
||||||
|
|
||||||
|
if (imgData)
|
||||||
|
delete imgData;
|
||||||
|
|
||||||
|
//threadExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImageAsync::threadAddImage(GuiImageAsync *Image)
|
||||||
|
{
|
||||||
|
pMutex->lock();
|
||||||
|
imageQueue.push_back(Image);
|
||||||
|
pMutex->unlock();
|
||||||
|
pThread->resumeThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImageAsync::threadRemoveImage(GuiImageAsync *image)
|
||||||
|
{
|
||||||
|
pMutex->lock();
|
||||||
|
for(u32 i = 0; i < imageQueue.size(); ++i)
|
||||||
|
{
|
||||||
|
if(imageQueue[i] == image)
|
||||||
|
{
|
||||||
|
imageQueue.erase(imageQueue.begin() + i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pMutex->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImageAsync::clearQueue()
|
||||||
|
{
|
||||||
|
pMutex->lock();
|
||||||
|
imageQueue.clear();
|
||||||
|
pMutex->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImageAsync::guiImageAsyncThread(CThread *thread, void *arg)
|
||||||
|
{
|
||||||
|
while(!bExitRequested)
|
||||||
|
{
|
||||||
|
if(imageQueue.empty() && !bExitRequested)
|
||||||
|
pThread->suspendThread();
|
||||||
|
|
||||||
|
if(!imageQueue.empty() && !bExitRequested)
|
||||||
|
{
|
||||||
|
pMutex->lock();
|
||||||
|
pInUse = imageQueue.front();
|
||||||
|
imageQueue.erase(imageQueue.begin());
|
||||||
|
pMutex->unlock();
|
||||||
|
|
||||||
|
if (!pInUse)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
if(pInUse->imgBuffer && pInUse->imgBufferSize)
|
||||||
|
{
|
||||||
|
pInUse->imgData = new GuiImageData(pInUse->imgBuffer, pInUse->imgBufferSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u8 *buffer = NULL;
|
||||||
|
u32 bufferSize = 0;
|
||||||
|
|
||||||
|
int iResult = LoadFileToMem(pInUse->filename.c_str(), &buffer, &bufferSize);
|
||||||
|
if(iResult > 0)
|
||||||
|
{
|
||||||
|
pInUse->imgData = new GuiImageData(buffer, bufferSize, GX2_TEX_CLAMP_MIRROR);
|
||||||
|
|
||||||
|
//! free original image buffer which is converted to texture now and not needed anymore
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pInUse->imgData)
|
||||||
|
{
|
||||||
|
if(pInUse->imgData->getTexture())
|
||||||
|
{
|
||||||
|
pInUse->width = pInUse->imgData->getWidth();
|
||||||
|
pInUse->height = pInUse->imgData->getHeight();
|
||||||
|
pInUse->imageData = pInUse->imgData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete pInUse->imgData;
|
||||||
|
pInUse->imgData = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pInUse->imageLoaded(pInUse);
|
||||||
|
pInUse = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImageAsync::threadInit()
|
||||||
|
{
|
||||||
|
if (pThread == NULL)
|
||||||
|
{
|
||||||
|
bExitRequested = false;
|
||||||
|
pMutex = new CMutex();
|
||||||
|
pThread = CThread::create(GuiImageAsync::guiImageAsyncThread, NULL, CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 10);
|
||||||
|
pThread->resumeThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
++threadRefCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImageAsync::threadExit()
|
||||||
|
{
|
||||||
|
if(threadRefCounter)
|
||||||
|
--threadRefCounter;
|
||||||
|
|
||||||
|
if(/*(threadRefCounter == 0) &&*/ (pThread != NULL))
|
||||||
|
{
|
||||||
|
bExitRequested = true;
|
||||||
|
delete pThread;
|
||||||
|
delete pMutex;
|
||||||
|
pThread = NULL;
|
||||||
|
pMutex = NULL;
|
||||||
|
}
|
||||||
|
}
|
62
src/gui/GuiImageAsync.h
Normal file
62
src/gui/GuiImageAsync.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef _GUIIMAGEASYNC_H_
|
||||||
|
#define _GUIIMAGEASYNC_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "GuiImage.h"
|
||||||
|
#include "system/CThread.h"
|
||||||
|
#include "system/CMutex.h"
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
|
||||||
|
class GuiImageAsync : public GuiImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GuiImageAsync(const u8 *imageBuffer, const u32 & imageBufferSize, GuiImageData * preloadImg);
|
||||||
|
GuiImageAsync(const std::string & filename, GuiImageData * preloadImg);
|
||||||
|
virtual ~GuiImageAsync();
|
||||||
|
|
||||||
|
static void clearQueue();
|
||||||
|
static void removeFromQueue(GuiImageAsync * image) {
|
||||||
|
threadRemoveImage(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! don't forget to LOCK GUI if using this asynchron call
|
||||||
|
sigslot::signal1<GuiImageAsync *> imageLoaded;
|
||||||
|
static void threadExit();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void threadInit();
|
||||||
|
|
||||||
|
GuiImageData *imgData;
|
||||||
|
std::string filename;
|
||||||
|
const u8 *imgBuffer;
|
||||||
|
const u32 imgBufferSize;
|
||||||
|
|
||||||
|
static void guiImageAsyncThread(CThread *thread, void *arg);
|
||||||
|
static void threadAddImage(GuiImageAsync* Image);
|
||||||
|
static void threadRemoveImage(GuiImageAsync* Image);
|
||||||
|
|
||||||
|
static std::vector<GuiImageAsync *> imageQueue;
|
||||||
|
static CThread *pThread;
|
||||||
|
static CMutex * pMutex;
|
||||||
|
static u32 threadRefCounter;
|
||||||
|
static GuiImageAsync * pInUse;
|
||||||
|
static bool bExitRequested;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*_GUIIMAGEASYNC_H_*/
|
207
src/gui/GuiImageData.cpp
Normal file
207
src/gui/GuiImageData.cpp
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "GuiImageData.h"
|
||||||
|
#include "system/memory.h"
|
||||||
|
/**
|
||||||
|
* Constructor for the GuiImageData class.
|
||||||
|
*/
|
||||||
|
GuiImageData::GuiImageData()
|
||||||
|
{
|
||||||
|
texture = NULL;
|
||||||
|
sampler = NULL;
|
||||||
|
memoryType = eMemTypeMEM2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the GuiImageData class.
|
||||||
|
*/
|
||||||
|
GuiImageData::GuiImageData(const u8 * img, int imgSize, int textureClamp, int textureFormat)
|
||||||
|
{
|
||||||
|
texture = NULL;
|
||||||
|
sampler = NULL;
|
||||||
|
loadImage(img, imgSize, textureClamp, textureFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor for the GuiImageData class.
|
||||||
|
*/
|
||||||
|
GuiImageData::~GuiImageData()
|
||||||
|
{
|
||||||
|
releaseData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImageData::releaseData(void)
|
||||||
|
{
|
||||||
|
if(texture) {
|
||||||
|
if(texture->surface.image_data)
|
||||||
|
{
|
||||||
|
switch(memoryType)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case eMemTypeMEM2:
|
||||||
|
free(texture->surface.image_data);
|
||||||
|
break;
|
||||||
|
case eMemTypeMEM1:
|
||||||
|
MEM1_free(texture->surface.image_data);
|
||||||
|
break;
|
||||||
|
case eMemTypeMEMBucket:
|
||||||
|
MEMBucket_free(texture->surface.image_data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete texture;
|
||||||
|
texture = NULL;
|
||||||
|
}
|
||||||
|
if(sampler) {
|
||||||
|
delete sampler;
|
||||||
|
sampler = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImageData::loadImage(const u8 *img, int imgSize, int textureClamp, int textureFormat)
|
||||||
|
{
|
||||||
|
if(!img || (imgSize < 8))
|
||||||
|
return;
|
||||||
|
|
||||||
|
releaseData();
|
||||||
|
gdImagePtr gdImg = 0;
|
||||||
|
|
||||||
|
if (img[0] == 0xFF && img[1] == 0xD8)
|
||||||
|
{
|
||||||
|
//! not needed for now therefore comment out to safe ELF size
|
||||||
|
//! if needed uncomment, adds 200 kb to the ELF size
|
||||||
|
// IMAGE_JPEG
|
||||||
|
gdImg = gdImageCreateFromJpegPtr(imgSize, (u8*) img);
|
||||||
|
}
|
||||||
|
else if (img[0] == 'B' && img[1] == 'M')
|
||||||
|
{
|
||||||
|
// IMAGE_BMP
|
||||||
|
gdImg = gdImageCreateFromBmpPtr(imgSize, (u8*) img);
|
||||||
|
}
|
||||||
|
else if (img[0] == 0x89 && img[1] == 'P' && img[2] == 'N' && img[3] == 'G')
|
||||||
|
{
|
||||||
|
// IMAGE_PNG
|
||||||
|
gdImg = gdImageCreateFromPngPtr(imgSize, (u8*) img);
|
||||||
|
}
|
||||||
|
//!This must be last since it can also intefere with outher formats
|
||||||
|
else if(img[0] == 0x00)
|
||||||
|
{
|
||||||
|
// Try loading TGA image
|
||||||
|
gdImg = gdImageCreateFromTgaPtr(imgSize, (u8*) img);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gdImg == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u32 width = (gdImageSX(gdImg));
|
||||||
|
u32 height = (gdImageSY(gdImg));
|
||||||
|
|
||||||
|
//! Initialize texture
|
||||||
|
texture = new GX2Texture;
|
||||||
|
GX2InitTexture(texture, width, height, 1, 0, textureFormat, GX2_SURFACE_DIM_2D, GX2_TILE_MODE_LINEAR_ALIGNED);
|
||||||
|
|
||||||
|
//! if this fails something went horribly wrong
|
||||||
|
if(texture->surface.image_size == 0) {
|
||||||
|
delete texture;
|
||||||
|
texture = NULL;
|
||||||
|
gdImageDestroy(gdImg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! allocate memory for the surface
|
||||||
|
memoryType = eMemTypeMEM2;
|
||||||
|
texture->surface.image_data = memalign(texture->surface.align, texture->surface.image_size);
|
||||||
|
//! try MEM1 on failure
|
||||||
|
if(!texture->surface.image_data) {
|
||||||
|
memoryType = eMemTypeMEM1;
|
||||||
|
texture->surface.image_data = MEM1_alloc(texture->surface.image_size, texture->surface.align);
|
||||||
|
}
|
||||||
|
//! try MEM bucket on failure
|
||||||
|
if(!texture->surface.image_data) {
|
||||||
|
memoryType = eMemTypeMEMBucket;
|
||||||
|
texture->surface.image_data = MEMBucket_alloc(texture->surface.image_size, texture->surface.align);
|
||||||
|
}
|
||||||
|
//! check if memory is available for image
|
||||||
|
if(!texture->surface.image_data) {
|
||||||
|
gdImageDestroy(gdImg);
|
||||||
|
delete texture;
|
||||||
|
texture = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//! set mip map data pointer
|
||||||
|
texture->surface.mip_data = NULL;
|
||||||
|
//! convert image to texture
|
||||||
|
switch(textureFormat)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM:
|
||||||
|
gdImageToUnormR8G8B8A8(gdImg, (u32*)texture->surface.image_data, texture->surface.width, texture->surface.height, texture->surface.pitch);
|
||||||
|
break;
|
||||||
|
case GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM:
|
||||||
|
gdImageToUnormR5G6B5(gdImg, (u16*)texture->surface.image_data, texture->surface.width, texture->surface.height, texture->surface.pitch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! free memory of image as its not needed anymore
|
||||||
|
gdImageDestroy(gdImg);
|
||||||
|
|
||||||
|
//! invalidate the memory
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_TEXTURE, texture->surface.image_data, texture->surface.image_size);
|
||||||
|
//! initialize the sampler
|
||||||
|
sampler = new GX2Sampler;
|
||||||
|
GX2InitSampler(sampler, textureClamp, GX2_TEX_XY_FILTER_BILINEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiImageData::gdImageToUnormR8G8B8A8(gdImagePtr gdImg, u32 *imgBuffer, u32 width, u32 height, u32 pitch)
|
||||||
|
{
|
||||||
|
for(u32 y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
|
for(u32 x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
u32 pixel = gdImageGetPixel(gdImg, x, y);
|
||||||
|
|
||||||
|
u8 a = 254 - 2*((u8)gdImageAlpha(gdImg, pixel));
|
||||||
|
if(a == 254) a++;
|
||||||
|
|
||||||
|
u8 r = gdImageRed(gdImg, pixel);
|
||||||
|
u8 g = gdImageGreen(gdImg, pixel);
|
||||||
|
u8 b = gdImageBlue(gdImg, pixel);
|
||||||
|
|
||||||
|
imgBuffer[y * pitch + x] = (r << 24) | (g << 16) | (b << 8) | (a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! TODO: figure out why this seems to not work correct yet
|
||||||
|
void GuiImageData::gdImageToUnormR5G6B5(gdImagePtr gdImg, u16 *imgBuffer, u32 width, u32 height, u32 pitch)
|
||||||
|
{
|
||||||
|
for(u32 y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
|
for(u32 x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
u32 pixel = gdImageGetPixel(gdImg, x, y);
|
||||||
|
|
||||||
|
u8 r = gdImageRed(gdImg, pixel);
|
||||||
|
u8 g = gdImageGreen(gdImg, pixel);
|
||||||
|
u8 b = gdImageBlue(gdImg, pixel);
|
||||||
|
|
||||||
|
imgBuffer[y * pitch + x] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
67
src/gui/GuiImageData.h
Normal file
67
src/gui/GuiImageData.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_IMAGEDATA_H_
|
||||||
|
#define GUI_IMAGEDATA_H_
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
|
#include <gd.h>
|
||||||
|
#include "dynamic_libs/gx2_functions.h"
|
||||||
|
#include "system/AsyncDeleter.h"
|
||||||
|
|
||||||
|
class GuiImageData : public AsyncDeleter::Element
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
GuiImageData();
|
||||||
|
//!\param img Image data
|
||||||
|
//!\param imgSize The image size
|
||||||
|
GuiImageData(const u8 * img, int imgSize, int textureClamp = GX2_TEX_CLAMP_CLAMP, int textureFormat = GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiImageData();
|
||||||
|
//!Load image from buffer
|
||||||
|
//!\param img Image data
|
||||||
|
//!\param imgSize The image size
|
||||||
|
void loadImage(const u8 * img, int imgSize, int textureClamp = GX2_TEX_CLAMP_CLAMP, int textureFormat = GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM);
|
||||||
|
//! getter functions
|
||||||
|
const GX2Texture * getTexture() const { return texture; };
|
||||||
|
const GX2Sampler * getSampler() const { return sampler; };
|
||||||
|
//!Gets the image width
|
||||||
|
//!\return image width
|
||||||
|
int getWidth() const { if(texture) return texture->surface.width; else return 0; };
|
||||||
|
//!Gets the image height
|
||||||
|
//!\return image height
|
||||||
|
int getHeight() const { if(texture) return texture->surface.height; else return 0; };
|
||||||
|
//! release memory of the image data
|
||||||
|
void releaseData(void);
|
||||||
|
private:
|
||||||
|
void gdImageToUnormR8G8B8A8(gdImagePtr gdImg, u32 *imgBuffer, u32 width, u32 height, u32 pitch);
|
||||||
|
void gdImageToUnormR5G6B5(gdImagePtr gdImg, u16 *imgBuffer, u32 width, u32 height, u32 pitch);
|
||||||
|
|
||||||
|
GX2Texture *texture;
|
||||||
|
GX2Sampler *sampler;
|
||||||
|
|
||||||
|
enum eMemoryTypes
|
||||||
|
{
|
||||||
|
eMemTypeMEM2,
|
||||||
|
eMemTypeMEM1,
|
||||||
|
eMemTypeMEMBucket
|
||||||
|
};
|
||||||
|
|
||||||
|
u8 memoryType;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
30
src/gui/GuiMainWindowScreen.h
Normal file
30
src/gui/GuiMainWindowScreen.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_MAIN_WINDOW_SCREEN_H_
|
||||||
|
#define GUI_MAIN_WINDOW_SCREEN_H_
|
||||||
|
|
||||||
|
#include "Gui.h"
|
||||||
|
#include "sigslot.h"
|
||||||
|
|
||||||
|
class GuiMainWindowScreen : public GuiFrame
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GuiMainWindowScreen(int w, int h) : GuiFrame(w, h) {}
|
||||||
|
virtual ~GuiMainWindowScreen() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* GUI_MAIN_WINDOW_SCREEN_H_ */
|
128
src/gui/GuiParticleImage.cpp
Normal file
128
src/gui/GuiParticleImage.cpp
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "GuiParticleImage.h"
|
||||||
|
#include "video/CVideo.h"
|
||||||
|
#include "video/shaders/ColorShader.h"
|
||||||
|
|
||||||
|
#define CIRCLE_VERTEX_COUNT 36
|
||||||
|
|
||||||
|
static inline f32 getRandZeroToOneF32()
|
||||||
|
{
|
||||||
|
return (rand() % 10000) * 0.0001f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline f32 getRandMinusOneToOneF32()
|
||||||
|
{
|
||||||
|
return getRandZeroToOneF32() * 2.0f - 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiParticleImage::GuiParticleImage(int w, int h, u32 particleCount)
|
||||||
|
: GuiImage(NULL)
|
||||||
|
{
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
imgType = IMAGE_COLOR;
|
||||||
|
|
||||||
|
posVertexs = (f32 *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ColorShader::cuVertexAttrSize * CIRCLE_VERTEX_COUNT);
|
||||||
|
colorVertexs = (u8 *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ColorShader::cuColorAttrSize * CIRCLE_VERTEX_COUNT);
|
||||||
|
|
||||||
|
for(u32 i = 0; i < CIRCLE_VERTEX_COUNT; i++)
|
||||||
|
{
|
||||||
|
posVertexs[i * 3 + 0] = cosf(DegToRad(i * 360.0f / CIRCLE_VERTEX_COUNT));
|
||||||
|
posVertexs[i * 3 + 1] = sinf(DegToRad(i * 360.0f / CIRCLE_VERTEX_COUNT));
|
||||||
|
posVertexs[i * 3 + 2] = 0.0f;
|
||||||
|
|
||||||
|
colorVertexs[i * 4 + 0] = 0xff;
|
||||||
|
colorVertexs[i * 4 + 1] = 0xff;
|
||||||
|
colorVertexs[i * 4 + 2] = 0xff;
|
||||||
|
colorVertexs[i * 4 + 3] = 0xff;
|
||||||
|
}
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, posVertexs, ColorShader::cuVertexAttrSize * CIRCLE_VERTEX_COUNT);
|
||||||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, colorVertexs, ColorShader::cuColorAttrSize * CIRCLE_VERTEX_COUNT);
|
||||||
|
|
||||||
|
particles.resize(particleCount);
|
||||||
|
|
||||||
|
for(u32 i = 0; i < particleCount; i++)
|
||||||
|
{
|
||||||
|
particles[i].position.x = getRandMinusOneToOneF32() * getWidth() * 0.5f;
|
||||||
|
particles[i].position.y = getRandMinusOneToOneF32() * getHeight() * 0.5f;
|
||||||
|
particles[i].position.z = 0.0f;
|
||||||
|
particles[i].colors = glm::vec4(1.0f, 1.0f, 1.0f, (getRandZeroToOneF32() * 0.6f) + 0.05f);
|
||||||
|
particles[i].radius = getRandZeroToOneF32() * 30.0f + 60.0f;
|
||||||
|
particles[i].speed = (getRandZeroToOneF32() * 0.4f) + 0.6f;
|
||||||
|
particles[i].direction = getRandMinusOneToOneF32();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiParticleImage::~GuiParticleImage()
|
||||||
|
{
|
||||||
|
free(posVertexs);
|
||||||
|
free(colorVertexs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiParticleImage::draw(CVideo *pVideo)
|
||||||
|
{
|
||||||
|
if(!this->isVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
f32 currScaleX = getScaleX();
|
||||||
|
f32 currScaleY = getScaleY();
|
||||||
|
|
||||||
|
positionOffsets[2] = getDepth() * pVideo->getDepthScaleFactor() * 2.0f;
|
||||||
|
|
||||||
|
scaleFactor[2] = getScaleZ();
|
||||||
|
|
||||||
|
//! add other colors intensities parameters
|
||||||
|
colorIntensity[3] = getAlpha();
|
||||||
|
|
||||||
|
for(u32 i = 0; i < particles.size(); ++i)
|
||||||
|
{
|
||||||
|
if(particles[i].position.y > (getHeight() * 0.5f + 30.0f))
|
||||||
|
{
|
||||||
|
particles[i].position.x = getRandMinusOneToOneF32() * getWidth() * 0.5f;
|
||||||
|
particles[i].position.y = -getHeight() * 0.5f - 30.0f;
|
||||||
|
particles[i].colors = glm::vec4(1.0f, 1.0f, 1.0f, (getRandZeroToOneF32() * 0.6f) + 0.05f);
|
||||||
|
particles[i].radius = getRandZeroToOneF32() * 30.0f + 60.0f;
|
||||||
|
particles[i].speed = (getRandZeroToOneF32() * 0.4f) + 0.6f;
|
||||||
|
particles[i].direction = getRandMinusOneToOneF32();
|
||||||
|
}
|
||||||
|
if(particles[i].position.x < (-getWidth() * 0.5f - 50.0f))
|
||||||
|
{
|
||||||
|
particles[i].position.x = -particles[i].position.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
particles[i].direction += getRandMinusOneToOneF32() * 0.03f;
|
||||||
|
particles[i].position.x += particles[i].speed * particles[i].direction;
|
||||||
|
particles[i].position.y += particles[i].speed;
|
||||||
|
|
||||||
|
positionOffsets[0] = (getCenterX() + particles[i].position.x) * pVideo->getWidthScaleFactor() * 2.0f;
|
||||||
|
positionOffsets[1] = (getCenterY() + particles[i].position.y) * pVideo->getHeightScaleFactor() * 2.0f;
|
||||||
|
|
||||||
|
scaleFactor[0] = currScaleX * particles[i].radius * pVideo->getWidthScaleFactor();
|
||||||
|
scaleFactor[1] = currScaleY * particles[i].radius * pVideo->getHeightScaleFactor();
|
||||||
|
|
||||||
|
ColorShader::instance()->setShaders();
|
||||||
|
ColorShader::instance()->setAttributeBuffer(colorVertexs, posVertexs, CIRCLE_VERTEX_COUNT);
|
||||||
|
ColorShader::instance()->setAngle(0.0f);
|
||||||
|
ColorShader::instance()->setOffset(positionOffsets);
|
||||||
|
ColorShader::instance()->setScale(scaleFactor);
|
||||||
|
ColorShader::instance()->setColorIntensity(colorIntensity * particles[i].colors);
|
||||||
|
ColorShader::instance()->draw(GX2_PRIMITIVE_TRIANGLE_FAN, CIRCLE_VERTEX_COUNT);
|
||||||
|
}
|
||||||
|
}
|
45
src/gui/GuiParticleImage.h
Normal file
45
src/gui/GuiParticleImage.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef _GUI_PARTICLE_IMAGE_H_
|
||||||
|
#define _GUI_PARTICLE_IMAGE_H_
|
||||||
|
|
||||||
|
#include "GuiImage.h"
|
||||||
|
|
||||||
|
class GuiParticleImage : public GuiImage, public sigslot::has_slots<>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GuiParticleImage(int w, int h, u32 particleCount);
|
||||||
|
virtual ~GuiParticleImage();
|
||||||
|
|
||||||
|
void draw(CVideo *pVideo);
|
||||||
|
private:
|
||||||
|
f32 *posVertexs;
|
||||||
|
u8 *colorVertexs;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::vec4 colors;
|
||||||
|
f32 radius;
|
||||||
|
f32 speed;
|
||||||
|
f32 direction;
|
||||||
|
} Particle;
|
||||||
|
|
||||||
|
std::vector<Particle> particles;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _GUI_ICON_GRID_H_
|
303
src/gui/GuiSelectBox.cpp
Normal file
303
src/gui/GuiSelectBox.cpp
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "GuiSelectBox.h"
|
||||||
|
#include "GuiImage.h"
|
||||||
|
#include "GuiTrigger.h"
|
||||||
|
#include "GuiImageData.h"
|
||||||
|
#include "utils/StringTools.h"
|
||||||
|
/**
|
||||||
|
* Constructor for the GuiCheckBox class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
GuiSelectBox::GuiSelectBox(std::string caption,GuiFrame *parent)
|
||||||
|
: GuiFrame(300,300,parent)
|
||||||
|
,selected(0)
|
||||||
|
,captionText(caption)
|
||||||
|
,topValueImageData(Resources::GetImageData("gameSettingsButton.png"))
|
||||||
|
,topValueImage(topValueImageData)
|
||||||
|
,topValueImageSelectedData(Resources::GetImageData("gameSettingsButtonSelected.png"))
|
||||||
|
,topValueImageSelected(topValueImageSelectedData)
|
||||||
|
,topValueButton(topValueImage.getWidth(),topValueImage.getHeight())
|
||||||
|
,valueImageData(Resources::GetImageData("gameSettingsButtonEx.png"))
|
||||||
|
,valueSelectedImageData(Resources::GetImageData("gameSettingsButtonExSelected.png"))
|
||||||
|
,valueHighlightedImageData(Resources::GetImageData("gameSettingsButtonExHighlighted.png"))
|
||||||
|
,touchTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::VPAD_TOUCH)
|
||||||
|
,wpadTouchTrigger(GuiTrigger::CHANNEL_2 | GuiTrigger::CHANNEL_3 | GuiTrigger::CHANNEL_4 | GuiTrigger::CHANNEL_5, GuiTrigger::BUTTON_A)
|
||||||
|
,buttonATrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_A, true)
|
||||||
|
,buttonBTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_B, true)
|
||||||
|
,buttonUpTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_UP | GuiTrigger::STICK_L_UP, true)
|
||||||
|
,buttonDownTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_DOWN | GuiTrigger::STICK_L_DOWN, true)
|
||||||
|
,DPADButtons(5,5)
|
||||||
|
,buttonClickSound(Resources::GetSound("settings_click_2.mp3"))
|
||||||
|
{
|
||||||
|
showValues = false;
|
||||||
|
bChanged = false;
|
||||||
|
bSelectedChanged = false;
|
||||||
|
opened = false;
|
||||||
|
topValueText.setFontSize(32);
|
||||||
|
topValueText.setAlignment(ALIGN_LEFT);
|
||||||
|
topValueText.setPosition(10,-7);
|
||||||
|
topValueButton.setLabel(&topValueText);
|
||||||
|
topValueButton.setImage(&topValueImage);
|
||||||
|
topValueButton.setIconOver(&topValueImageSelected);
|
||||||
|
topValueButton.setTrigger(&touchTrigger);
|
||||||
|
topValueButton.setTrigger(&wpadTouchTrigger);
|
||||||
|
topValueButton.setSoundClick(buttonClickSound);
|
||||||
|
topValueButton.clicked.connect(this, &GuiSelectBox::OnTopValueClicked);
|
||||||
|
|
||||||
|
valuesFrame.setState(STATE_HIDDEN);
|
||||||
|
|
||||||
|
DPADButtons.setTrigger(&buttonBTrigger);
|
||||||
|
DPADButtons.setTrigger(&buttonATrigger);
|
||||||
|
DPADButtons.setTrigger(&buttonDownTrigger);
|
||||||
|
DPADButtons.setTrigger(&buttonUpTrigger);
|
||||||
|
DPADButtons.clicked.connect(this, &GuiSelectBox::OnDPADClick);
|
||||||
|
DPADButtons.setState(STATE_DISABLE_INPUT);
|
||||||
|
|
||||||
|
append(&DPADButtons);
|
||||||
|
append(&valuesFrame);
|
||||||
|
append(&topValueButton);
|
||||||
|
|
||||||
|
showValues = false;
|
||||||
|
bChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSelectBox::OnValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < valueButtons.size(); ++i){
|
||||||
|
if(valueButtons[i].valueButton == button){
|
||||||
|
selected = i;
|
||||||
|
SelectValue(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSelectBox::SelectValue(u32 value){
|
||||||
|
if(value < valueButtons.size()){
|
||||||
|
const wchar_t* w_text = valueButtons[value].valueButtonText->getText();
|
||||||
|
std::wstring ws(w_text);
|
||||||
|
std::string text(ws.begin(), ws.end());
|
||||||
|
topValueText.setText(getCaptionWithValue(text).c_str());
|
||||||
|
|
||||||
|
std::string real_value = buttonToValue[valueButtons[value].valueButton];
|
||||||
|
if(real_value.compare(std::string()) == 0) real_value = "<error>";
|
||||||
|
|
||||||
|
valueChanged(this,real_value);
|
||||||
|
ShowHideValues(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string GuiSelectBox::getCaptionWithValue(std::string value){
|
||||||
|
u32 pad = (38 - captionText.size() -2);
|
||||||
|
if(pad > value.size())
|
||||||
|
value.insert(0, pad - value.size(), ' ');
|
||||||
|
return strfmt("%s: %s",captionText.c_str(),value.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSelectBox::OnTopValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger)
|
||||||
|
{
|
||||||
|
ShowHideValues(!showValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSelectBox::ShowHideValues(bool showhide)
|
||||||
|
{
|
||||||
|
showValues = showhide;
|
||||||
|
bChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSelectBox::OnDPADClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger)
|
||||||
|
{
|
||||||
|
if(opened == true){
|
||||||
|
if(trigger == &buttonATrigger)
|
||||||
|
{
|
||||||
|
//! do not auto launch when wiimote is pointing to screen and presses A
|
||||||
|
if((controller->chan & (GuiTrigger::CHANNEL_2 | GuiTrigger::CHANNEL_3 | GuiTrigger::CHANNEL_4 | GuiTrigger::CHANNEL_5)) && controller->data.validPointer)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SelectValue(selected);
|
||||||
|
}
|
||||||
|
else if(trigger == &buttonBTrigger)
|
||||||
|
{
|
||||||
|
if(button == &DPADButtons){
|
||||||
|
ShowHideValues(false);
|
||||||
|
}else{
|
||||||
|
}
|
||||||
|
}else if(trigger == &buttonUpTrigger){
|
||||||
|
if(selected > 0 ) selected--;
|
||||||
|
bSelectedChanged = true;
|
||||||
|
}
|
||||||
|
else if(trigger == &buttonDownTrigger){
|
||||||
|
selected++;
|
||||||
|
if(selected >= valueButtons.size()) selected = valueButtons.size() - 1;
|
||||||
|
bSelectedChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSelectBox::Init(std::map<std::string,std::string> values, int valueID)
|
||||||
|
{
|
||||||
|
if((u32)valueID >= values.size()){
|
||||||
|
valueID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
selected = valueID;
|
||||||
|
bSelectedChanged = true;
|
||||||
|
|
||||||
|
DeleteValueData();
|
||||||
|
|
||||||
|
valueButtons.resize(values.size());
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
f32 imgScale = 1.0f;
|
||||||
|
std::map<std::string, std::string>::iterator itr;
|
||||||
|
for(itr = values.begin(); itr != values.end(); itr++) {
|
||||||
|
if(i == valueID){
|
||||||
|
topValueText.setText(getCaptionWithValue(itr->first).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
valueButtons[i].valueButtonImg = new GuiImage(valueImageData);
|
||||||
|
|
||||||
|
valueButtons[i].valueButtonCheckedImg = new GuiImage(valueSelectedImageData);
|
||||||
|
valueButtons[i].valueButtonHighlightedImg = new GuiImage(valueHighlightedImageData);
|
||||||
|
valueButtons[i].valueButton = new GuiButton(valueButtons[i].valueButtonImg->getWidth() * imgScale, valueButtons[i].valueButtonImg->getHeight() * imgScale);
|
||||||
|
valueButtons[i].valueButtonText = new GuiText(itr->first.c_str(),32,glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
|
valueButtons[i].valueButtonText->setMaxWidth(valueButtons[i].valueButtonImg->getWidth() * imgScale - 20.0f, GuiText::WRAP);
|
||||||
|
valueButtons[i].valueButtonText->setPosition(0, 0);
|
||||||
|
|
||||||
|
valueButtons[i].valueButtonImg->setScale(imgScale);
|
||||||
|
valueButtons[i].valueButtonCheckedImg->setScale(imgScale);
|
||||||
|
|
||||||
|
valueButtons[i].valueButton->setImage(valueButtons[i].valueButtonImg);
|
||||||
|
valueButtons[i].valueButton->setIconOver(valueButtons[i].valueButtonHighlightedImg);
|
||||||
|
valueButtons[i].valueButton->setTrigger(&touchTrigger);
|
||||||
|
valueButtons[i].valueButton->setTrigger(&wpadTouchTrigger);
|
||||||
|
valueButtons[i].valueButton->clicked.connect(this,&GuiSelectBox::OnValueClicked);
|
||||||
|
valueButtons[i].valueButton->setSoundClick(buttonClickSound);
|
||||||
|
valueButtons[i].valueButton->setLabel(valueButtons[i].valueButtonText);
|
||||||
|
|
||||||
|
//valueButtons[i].valueButton->setState(STATE_HIDDEN); //Wont get disabled soon enough
|
||||||
|
|
||||||
|
buttonToValue[valueButtons[i].valueButton] = itr->second;
|
||||||
|
|
||||||
|
valueButtons[i].valueButton->setPosition(0, (((valueButtons[i].valueButtonImg->getHeight()*getScale()) * (i))+ (topValueImage.getHeight()-5)*getScale())*-1.0f);
|
||||||
|
valuesFrame.append(valueButtons[i].valueButton);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
//Collapse the thing!
|
||||||
|
showValues = false;
|
||||||
|
bChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSelectBox::DeleteValueData()
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < valueButtons.size(); ++i)
|
||||||
|
{
|
||||||
|
valuesFrame.remove(valueButtons[i].valueButton);
|
||||||
|
delete valueButtons[i].valueButtonImg;
|
||||||
|
delete valueButtons[i].valueButtonCheckedImg;
|
||||||
|
delete valueButtons[i].valueButtonHighlightedImg;
|
||||||
|
delete valueButtons[i].valueButton;
|
||||||
|
delete valueButtons[i].valueButtonText;
|
||||||
|
}
|
||||||
|
buttonToValue.clear();
|
||||||
|
valueButtons.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor for the GuiButton class.
|
||||||
|
*/
|
||||||
|
GuiSelectBox::~GuiSelectBox()
|
||||||
|
{
|
||||||
|
DeleteValueData();
|
||||||
|
bChanged = false;
|
||||||
|
selected = 0;
|
||||||
|
showValues = false;
|
||||||
|
Resources::RemoveSound(buttonClickSound);
|
||||||
|
Resources::RemoveImageData(topValueImageData);
|
||||||
|
Resources::RemoveImageData(topValueImageSelectedData);
|
||||||
|
Resources::RemoveImageData(valueImageData);
|
||||||
|
Resources::RemoveImageData(valueHighlightedImageData);
|
||||||
|
Resources::RemoveImageData(valueSelectedImageData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GuiSelectBox::setState(int s, int c)
|
||||||
|
{
|
||||||
|
GuiElement::setState(s, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSelectBox::OnValueCloseEffectFinish(GuiElement *element)
|
||||||
|
{
|
||||||
|
valuesFrame.effectFinished.disconnect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 GuiSelectBox::getTopValueHeight() {
|
||||||
|
return topValueImage.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 GuiSelectBox::getTopValueWidth() {
|
||||||
|
return topValueImage.getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSelectBox::OnValueOpenEffectFinish(GuiElement *element)
|
||||||
|
{
|
||||||
|
valuesFrame.effectFinished.disconnect(this);
|
||||||
|
opened = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSelectBox::update(GuiController * c){
|
||||||
|
if(bChanged){
|
||||||
|
showhide(this,showValues);
|
||||||
|
if(showValues){
|
||||||
|
for(u32 i = 0; i < valueButtons.size(); ++i){ //TODO: only set when it really changed
|
||||||
|
if(i == selected){
|
||||||
|
valueButtons[i].valueButton->setImage(valueButtons[i].valueButtonCheckedImg);
|
||||||
|
}else{
|
||||||
|
valueButtons[i].valueButton->setImage(valueButtons[i].valueButtonImg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
valuesFrame.clearState(STATE_HIDDEN);
|
||||||
|
DPADButtons.clearState(STATE_DISABLE_INPUT);
|
||||||
|
valuesFrame.setEffect(EFFECT_FADE, 10, 255);
|
||||||
|
valuesFrame.effectFinished.connect(this, &GuiSelectBox::OnValueCloseEffectFinish);
|
||||||
|
}else{
|
||||||
|
opened = false;
|
||||||
|
valuesFrame.setState(STATE_HIDDEN);
|
||||||
|
DPADButtons.setState(STATE_DISABLE_INPUT);
|
||||||
|
valuesFrame.setEffect(EFFECT_FADE, -10, 0);
|
||||||
|
valuesFrame.effectFinished.connect(this, &GuiSelectBox::OnValueOpenEffectFinish);
|
||||||
|
}
|
||||||
|
|
||||||
|
bChanged = false;
|
||||||
|
}
|
||||||
|
if(bSelectedChanged){
|
||||||
|
for(u32 i = 0; i < valueButtons.size(); ++i){
|
||||||
|
if(i == selected){
|
||||||
|
valueButtons[i].valueButton->setState(STATE_SELECTED);
|
||||||
|
}else{
|
||||||
|
valueButtons[i].valueButton->clearState(STATE_SELECTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
topValueButton.setState(getState());
|
||||||
|
GuiFrame::update(c);
|
||||||
|
}
|
104
src/gui/GuiSelectBox.h
Normal file
104
src/gui/GuiSelectBox.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_SELECTBOX_H_
|
||||||
|
#define GUI_SELECTBOX_H_
|
||||||
|
|
||||||
|
#include "Gui.h"
|
||||||
|
#include "GuiImage.h"
|
||||||
|
#include "GuiImageData.h"
|
||||||
|
|
||||||
|
//!A simple CheckBox
|
||||||
|
class GuiSelectBox : public GuiFrame, public sigslot::has_slots<>
|
||||||
|
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
//!\param checked Checked
|
||||||
|
GuiSelectBox(std::string caption,GuiFrame *parent = 0);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiSelectBox();
|
||||||
|
|
||||||
|
sigslot::signal2<GuiSelectBox *, std::string> valueChanged;
|
||||||
|
sigslot::signal2<GuiSelectBox *, bool> showhide;
|
||||||
|
void OnTopValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger);
|
||||||
|
void Init(std::map<std::string,std::string> values, int valueID);
|
||||||
|
|
||||||
|
void setState(int s, int c = -1);
|
||||||
|
|
||||||
|
virtual f32 getTopValueHeight();
|
||||||
|
virtual f32 getTopValueWidth();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void DeleteValueData();
|
||||||
|
void update(GuiController * c);
|
||||||
|
|
||||||
|
void OnValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger);
|
||||||
|
|
||||||
|
void OnDPADClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger);
|
||||||
|
void OnValueOpenEffectFinish(GuiElement *element);
|
||||||
|
void OnValueCloseEffectFinish(GuiElement *element);
|
||||||
|
void ShowHideValues(bool showhide);
|
||||||
|
void SelectValue(u32 value);
|
||||||
|
|
||||||
|
u32 selected;
|
||||||
|
bool bChanged;
|
||||||
|
bool bSelectedChanged;
|
||||||
|
bool showValues;
|
||||||
|
bool opened;
|
||||||
|
std::string captionText;
|
||||||
|
GuiFrame valuesFrame;
|
||||||
|
GuiImageData *topValueImageData;
|
||||||
|
GuiImage topValueImage;
|
||||||
|
GuiImageData *topValueImageSelectedData;
|
||||||
|
GuiImage topValueImageSelected;
|
||||||
|
|
||||||
|
GuiButton topValueButton;
|
||||||
|
GuiImageData * valueImageData;
|
||||||
|
GuiImageData * valueSelectedImageData;
|
||||||
|
GuiImageData * valueHighlightedImageData;
|
||||||
|
GuiText topValueText;
|
||||||
|
|
||||||
|
GuiTrigger touchTrigger;
|
||||||
|
GuiTrigger wpadTouchTrigger;
|
||||||
|
|
||||||
|
GuiTrigger buttonATrigger;
|
||||||
|
GuiTrigger buttonBTrigger;
|
||||||
|
GuiTrigger buttonLeftTrigger;
|
||||||
|
GuiTrigger buttonRightTrigger;
|
||||||
|
GuiTrigger buttonUpTrigger;
|
||||||
|
GuiTrigger buttonDownTrigger;
|
||||||
|
|
||||||
|
GuiButton DPADButtons;
|
||||||
|
|
||||||
|
GuiSound* buttonClickSound;
|
||||||
|
|
||||||
|
std::string getCaptionWithValue(std::string value);
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GuiImage *valueButtonImg;
|
||||||
|
GuiImage *valueButtonCheckedImg;
|
||||||
|
GuiImage *valueButtonHighlightedImg;
|
||||||
|
GuiButton *valueButton;
|
||||||
|
GuiText *valueButtonText;
|
||||||
|
} SelectBoxValueButton;
|
||||||
|
|
||||||
|
std::map<GuiButton * ,std::string> buttonToValue;
|
||||||
|
std::vector<SelectBoxValueButton> valueButtons;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
193
src/gui/GuiSound.cpp
Normal file
193
src/gui/GuiSound.cpp
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "GuiSound.h"
|
||||||
|
#include "sounds/SoundHandler.hpp"
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
|
||||||
|
GuiSound::GuiSound(const char * filepath)
|
||||||
|
{
|
||||||
|
voice = -1;
|
||||||
|
Load(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiSound::GuiSound(const u8 * snd, s32 length)
|
||||||
|
{
|
||||||
|
voice = -1;
|
||||||
|
Load(snd, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiSound::~GuiSound()
|
||||||
|
{
|
||||||
|
if(voice >= 0)
|
||||||
|
{
|
||||||
|
SoundHandler::instance()->RemoveDecoder(voice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GuiSound::Load(const char * filepath)
|
||||||
|
{
|
||||||
|
if(voice >= 0)
|
||||||
|
{
|
||||||
|
SoundHandler::instance()->RemoveDecoder(voice);
|
||||||
|
voice = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! find next free decoder
|
||||||
|
for(int i = 0; i < MAX_DECODERS; i++)
|
||||||
|
{
|
||||||
|
SoundDecoder * decoder = SoundHandler::instance()->getDecoder(i);
|
||||||
|
if(decoder == NULL)
|
||||||
|
{
|
||||||
|
SoundHandler::instance()->AddDecoder(i, filepath);
|
||||||
|
decoder = SoundHandler::instance()->getDecoder(i);
|
||||||
|
if(decoder)
|
||||||
|
{
|
||||||
|
voice = i;
|
||||||
|
SoundHandler::instance()->ThreadSignal();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(voice < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GuiSound::Load(const u8 * snd, s32 len)
|
||||||
|
{
|
||||||
|
if(voice >= 0)
|
||||||
|
{
|
||||||
|
SoundHandler::instance()->RemoveDecoder(voice);
|
||||||
|
voice = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!snd)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//! find next free decoder
|
||||||
|
for(int i = 0; i < MAX_DECODERS; i++)
|
||||||
|
{
|
||||||
|
SoundDecoder * decoder = SoundHandler::instance()->getDecoder(i);
|
||||||
|
if(decoder == NULL)
|
||||||
|
{
|
||||||
|
SoundHandler::instance()->AddDecoder(i, snd, len);
|
||||||
|
decoder = SoundHandler::instance()->getDecoder(i);
|
||||||
|
if(decoder)
|
||||||
|
{
|
||||||
|
voice = i;
|
||||||
|
SoundHandler::instance()->ThreadSignal();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(voice < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSound::Play()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
|
||||||
|
Voice * v = SoundHandler::instance()->getVoice(voice);
|
||||||
|
if(v)
|
||||||
|
v->setState(Voice::STATE_START);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSound::Stop()
|
||||||
|
{
|
||||||
|
Voice * v = SoundHandler::instance()->getVoice(voice);
|
||||||
|
if(v)
|
||||||
|
{
|
||||||
|
if((v->getState() != Voice::STATE_STOP) && (v->getState() != Voice::STATE_STOPPED))
|
||||||
|
v->setState(Voice::STATE_STOP);
|
||||||
|
|
||||||
|
while(v->getState() != Voice::STATE_STOPPED)
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundDecoder * decoder = SoundHandler::instance()->getDecoder(voice);
|
||||||
|
if(decoder)
|
||||||
|
{
|
||||||
|
decoder->Lock();
|
||||||
|
decoder->Rewind();
|
||||||
|
decoder->ClearBuffer();
|
||||||
|
SoundHandler::instance()->ThreadSignal();
|
||||||
|
decoder->Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSound::Pause()
|
||||||
|
{
|
||||||
|
if(!IsPlaying())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Voice * v = SoundHandler::instance()->getVoice(voice);
|
||||||
|
if(v)
|
||||||
|
v->setState(Voice::STATE_STOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSound::Resume()
|
||||||
|
{
|
||||||
|
if(IsPlaying())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Voice * v = SoundHandler::instance()->getVoice(voice);
|
||||||
|
if(v)
|
||||||
|
v->setState(Voice::STATE_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GuiSound::IsPlaying()
|
||||||
|
{
|
||||||
|
Voice * v = SoundHandler::instance()->getVoice(voice);
|
||||||
|
if(v)
|
||||||
|
return v->getState() == Voice::STATE_PLAYING;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSound::SetVolume(u32 vol)
|
||||||
|
{
|
||||||
|
if(vol > 100)
|
||||||
|
vol = 100;
|
||||||
|
|
||||||
|
u32 volumeConv = ( (0x8000 * vol) / 100 ) << 16;
|
||||||
|
|
||||||
|
Voice * v = SoundHandler::instance()->getVoice(voice);
|
||||||
|
if(v)
|
||||||
|
v->setVolume(volumeConv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSound::SetLoop(bool l)
|
||||||
|
{
|
||||||
|
SoundDecoder * decoder = SoundHandler::instance()->getDecoder(voice);
|
||||||
|
if(decoder)
|
||||||
|
decoder->SetLoop(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSound::Rewind()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
}
|
60
src/gui/GuiSound.h
Normal file
60
src/gui/GuiSound.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_SOUND_H_
|
||||||
|
#define GUI_SOUND_H_
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
|
#include "system/AsyncDeleter.h"
|
||||||
|
|
||||||
|
//!Sound conversion and playback. A wrapper for other sound libraries - ASND, libmad, ltremor, etc
|
||||||
|
class GuiSound : public AsyncDeleter::Element
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
//!\param sound Pointer to the sound data
|
||||||
|
//!\param filesize Length of sound data
|
||||||
|
GuiSound(const char * filepath);
|
||||||
|
GuiSound(const u8 * sound, int length);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiSound();
|
||||||
|
//!Load a file and replace the old one
|
||||||
|
bool Load(const char * filepath);
|
||||||
|
//!Load a file and replace the old one
|
||||||
|
bool Load(const u8 * snd, s32 len);
|
||||||
|
//!Start sound playback
|
||||||
|
void Play();
|
||||||
|
//!Stop sound playback
|
||||||
|
void Stop();
|
||||||
|
//!Pause sound playback
|
||||||
|
void Pause();
|
||||||
|
//!Resume sound playback
|
||||||
|
void Resume();
|
||||||
|
//!Checks if the sound is currently playing
|
||||||
|
//!\return true if sound is playing, false otherwise
|
||||||
|
bool IsPlaying();
|
||||||
|
//!Rewind the music
|
||||||
|
void Rewind();
|
||||||
|
//!Set sound volume
|
||||||
|
//!\param v Sound volume (0-100)
|
||||||
|
void SetVolume(u32 v);
|
||||||
|
//!\param l Loop (true to loop)
|
||||||
|
void SetLoop(bool l);
|
||||||
|
protected:
|
||||||
|
s32 voice; //!< Currently assigned ASND voice channel
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
72
src/gui/GuiSwitch.cpp
Normal file
72
src/gui/GuiSwitch.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "GuiSwitch.h"
|
||||||
|
#include "GuiImage.h"
|
||||||
|
#include "GuiImageData.h"
|
||||||
|
/**
|
||||||
|
* Constructor for the GuiSwitch class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
GuiSwitch::GuiSwitch(bool checked,f32 switchscale)
|
||||||
|
: GuiToggle(checked,90*switchscale,38*switchscale)
|
||||||
|
,switchbase_imgdata(Resources::GetImageData("switchIconBase.png"))
|
||||||
|
,switchbase_img(switchbase_imgdata)
|
||||||
|
,switchbase_highlighted_imgdata(Resources::GetImageData("switchIconBaseHighlighted.png"))
|
||||||
|
,switchbase_highlighted_img(switchbase_highlighted_imgdata)
|
||||||
|
,switchOn_imgdata(Resources::GetImageData("switchIconOn.png"))
|
||||||
|
,switchOn_img(switchOn_imgdata)
|
||||||
|
,switchOff_imgdata(Resources::GetImageData("switchIconOff.png"))
|
||||||
|
,switchOff_img(switchOff_imgdata)
|
||||||
|
{
|
||||||
|
f32 scale = 0.0;
|
||||||
|
if(switchbase_img.getHeight() > switchbase_img.getWidth()){
|
||||||
|
scale = height*switchscale/switchbase_img.getHeight();
|
||||||
|
}else{
|
||||||
|
scale = width/switchbase_img.getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
switchbase_img.setScale(scale);
|
||||||
|
switchbase_highlighted_img.setScale(scale);
|
||||||
|
switchOn_img.setScale(scale);
|
||||||
|
switchOff_img.setScale(scale);
|
||||||
|
|
||||||
|
switchOn_img.setParent(this);
|
||||||
|
switchOn_img.setPosition((width/4.0),0);
|
||||||
|
switchOff_img.setParent(this);
|
||||||
|
switchOff_img.setPosition(-((width/4.0)),0);
|
||||||
|
setImage(&switchbase_img);
|
||||||
|
setIconOver(&switchbase_highlighted_img);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Destructor for the GuiButton class.
|
||||||
|
*/
|
||||||
|
GuiSwitch::~GuiSwitch()
|
||||||
|
{
|
||||||
|
Resources::RemoveImageData(switchbase_imgdata);
|
||||||
|
Resources::RemoveImageData(switchbase_highlighted_imgdata);
|
||||||
|
Resources::RemoveImageData(switchOn_imgdata);
|
||||||
|
Resources::RemoveImageData(switchOff_imgdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiSwitch::draw(CVideo *v){
|
||||||
|
GuiToggle::draw(v);
|
||||||
|
if(getValue()){
|
||||||
|
switchOn_img.draw(v);
|
||||||
|
}else{
|
||||||
|
switchOff_img.draw(v);
|
||||||
|
}
|
||||||
|
}
|
51
src/gui/GuiSwitch.h
Normal file
51
src/gui/GuiSwitch.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_SWTICH_H_
|
||||||
|
#define GUI_SWTICH_H_
|
||||||
|
|
||||||
|
#include "GuiToggle.h"
|
||||||
|
#include "GuiImage.h"
|
||||||
|
#include "GuiImageData.h"
|
||||||
|
|
||||||
|
//!A simple switch
|
||||||
|
class GuiSwitch : public GuiToggle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
//!\param checked Checked
|
||||||
|
GuiSwitch(bool checked,f32 switchscale = 1.0f);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiSwitch();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
GuiImageData * switchbase_imgdata;
|
||||||
|
GuiImage switchbase_img;
|
||||||
|
|
||||||
|
GuiImageData * switchbase_highlighted_imgdata;
|
||||||
|
GuiImage switchbase_highlighted_img;
|
||||||
|
|
||||||
|
GuiImageData * switchOn_imgdata;
|
||||||
|
GuiImage switchOn_img;
|
||||||
|
|
||||||
|
GuiImageData * switchOff_imgdata;
|
||||||
|
GuiImage switchOff_img;
|
||||||
|
|
||||||
|
void draw(CVideo * v);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
615
src/gui/GuiText.cpp
Normal file
615
src/gui/GuiText.cpp
Normal file
@ -0,0 +1,615 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "GuiText.h"
|
||||||
|
#include "FreeTypeGX.h"
|
||||||
|
#include "video/CVideo.h"
|
||||||
|
|
||||||
|
FreeTypeGX * GuiText::presentFont = NULL;
|
||||||
|
int GuiText::presetSize = 28;
|
||||||
|
int GuiText::presetInternalRenderingScale = 2.0f; //Lets render the font at the doubled size. This make it even smoother!
|
||||||
|
int GuiText::presetMaxWidth = 0xFFFF;
|
||||||
|
int GuiText::presetAlignment = ALIGN_CENTER | ALIGN_MIDDLE;
|
||||||
|
GX2ColorF32 GuiText::presetColor = (GX2ColorF32){ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
|
|
||||||
|
#define TEXT_SCROLL_DELAY 6
|
||||||
|
#define TEXT_SCROLL_INITIAL_DELAY 10
|
||||||
|
#define MAX_LINES_TO_DRAW 10
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the GuiText class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
GuiText::GuiText()
|
||||||
|
{
|
||||||
|
text = NULL;
|
||||||
|
size = presetSize;
|
||||||
|
currentSize = size;
|
||||||
|
color = glm::vec4(presetColor.r, presetColor.g, presetColor.b, presetColor.a);
|
||||||
|
alpha = presetColor.a;
|
||||||
|
alignment = presetAlignment;
|
||||||
|
maxWidth = presetMaxWidth;
|
||||||
|
wrapMode = 0;
|
||||||
|
textWidth = 0;
|
||||||
|
font = presentFont;
|
||||||
|
linestodraw = MAX_LINES_TO_DRAW;
|
||||||
|
textScrollPos = 0;
|
||||||
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
|
textScrollDelay = TEXT_SCROLL_DELAY;
|
||||||
|
defaultBlur = 4.0f;
|
||||||
|
blurGlowIntensity = 0.0f;
|
||||||
|
blurAlpha = 0.0f;
|
||||||
|
blurGlowColor = glm::vec4(0.0f);
|
||||||
|
internalRenderingScale = presetInternalRenderingScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiText::GuiText(const char * t, int s, const glm::vec4 & c)
|
||||||
|
{
|
||||||
|
text = NULL;
|
||||||
|
size = s;
|
||||||
|
currentSize = size;
|
||||||
|
color = c;
|
||||||
|
alpha = c[3];
|
||||||
|
alignment = ALIGN_CENTER | ALIGN_MIDDLE;
|
||||||
|
maxWidth = presetMaxWidth;
|
||||||
|
wrapMode = 0;
|
||||||
|
textWidth = 0;
|
||||||
|
font = presentFont;
|
||||||
|
linestodraw = MAX_LINES_TO_DRAW;
|
||||||
|
textScrollPos = 0;
|
||||||
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
|
textScrollDelay = TEXT_SCROLL_DELAY;
|
||||||
|
defaultBlur = 4.0f;
|
||||||
|
blurGlowIntensity = 0.0f;
|
||||||
|
blurAlpha = 0.0f;
|
||||||
|
blurGlowColor = glm::vec4(0.0f);
|
||||||
|
internalRenderingScale = presetInternalRenderingScale;
|
||||||
|
|
||||||
|
if(t)
|
||||||
|
{
|
||||||
|
text = FreeTypeGX::charToWideChar(t);
|
||||||
|
if(!text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
textWidth = font->getWidth(text, currentSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiText::GuiText(const wchar_t * t, int s, const glm::vec4 & c)
|
||||||
|
{
|
||||||
|
text = NULL;
|
||||||
|
size = s;
|
||||||
|
currentSize = size;
|
||||||
|
color = c;
|
||||||
|
alpha = c[3];
|
||||||
|
alignment = ALIGN_CENTER | ALIGN_MIDDLE;
|
||||||
|
maxWidth = presetMaxWidth;
|
||||||
|
wrapMode = 0;
|
||||||
|
textWidth = 0;
|
||||||
|
font = presentFont;
|
||||||
|
linestodraw = MAX_LINES_TO_DRAW;
|
||||||
|
textScrollPos = 0;
|
||||||
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
|
textScrollDelay = TEXT_SCROLL_DELAY;
|
||||||
|
defaultBlur = 4.0f;
|
||||||
|
blurGlowIntensity = 0.0f;
|
||||||
|
blurAlpha = 0.0f;
|
||||||
|
blurGlowColor = glm::vec4(0.0f);
|
||||||
|
internalRenderingScale = presetInternalRenderingScale;
|
||||||
|
|
||||||
|
if(t)
|
||||||
|
{
|
||||||
|
text = new (std::nothrow) wchar_t[wcslen(t)+1];
|
||||||
|
if(!text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wcscpy(text, t);
|
||||||
|
|
||||||
|
textWidth = font->getWidth(text, currentSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the GuiText class, uses presets
|
||||||
|
*/
|
||||||
|
GuiText::GuiText(const char * t)
|
||||||
|
{
|
||||||
|
text = NULL;
|
||||||
|
size = presetSize;
|
||||||
|
currentSize = size;
|
||||||
|
color = glm::vec4(presetColor.r, presetColor.g, presetColor.b, presetColor.a);
|
||||||
|
alpha = presetColor.a;
|
||||||
|
alignment = presetAlignment;
|
||||||
|
maxWidth = presetMaxWidth;
|
||||||
|
wrapMode = 0;
|
||||||
|
textWidth = 0;
|
||||||
|
font = presentFont;
|
||||||
|
linestodraw = MAX_LINES_TO_DRAW;
|
||||||
|
textScrollPos = 0;
|
||||||
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
|
textScrollDelay = TEXT_SCROLL_DELAY;
|
||||||
|
defaultBlur = 4.0f;
|
||||||
|
blurGlowIntensity = 0.0f;
|
||||||
|
blurAlpha = 0.0f;
|
||||||
|
blurGlowColor = glm::vec4(0.0f);
|
||||||
|
internalRenderingScale = presetInternalRenderingScale;
|
||||||
|
|
||||||
|
if(t)
|
||||||
|
{
|
||||||
|
text = FreeTypeGX::charToWideChar(t);
|
||||||
|
if(!text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
textWidth = font->getWidth(text, currentSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor for the GuiText class.
|
||||||
|
*/
|
||||||
|
GuiText::~GuiText()
|
||||||
|
{
|
||||||
|
if(text)
|
||||||
|
delete [] text;
|
||||||
|
text = NULL;
|
||||||
|
|
||||||
|
clearDynamicText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiText::setText(const char * t)
|
||||||
|
{
|
||||||
|
if(text)
|
||||||
|
delete [] text;
|
||||||
|
text = NULL;
|
||||||
|
|
||||||
|
clearDynamicText();
|
||||||
|
|
||||||
|
textScrollPos = 0;
|
||||||
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
|
|
||||||
|
if(t)
|
||||||
|
{
|
||||||
|
text = FreeTypeGX::charToWideChar(t);
|
||||||
|
if(!text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
textWidth = font->getWidth(text, currentSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiText::setTextf(const char *format, ...)
|
||||||
|
{
|
||||||
|
if(!format)
|
||||||
|
{
|
||||||
|
setText((char *) NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int max_len = strlen(format) + 8192;
|
||||||
|
char *tmp = new char[max_len];
|
||||||
|
va_list va;
|
||||||
|
va_start(va, format);
|
||||||
|
if((vsnprintf(tmp, max_len, format, va) >= 0) && tmp)
|
||||||
|
{
|
||||||
|
setText(tmp);
|
||||||
|
}
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
if(tmp)
|
||||||
|
delete [] tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GuiText::setText(const wchar_t * t)
|
||||||
|
{
|
||||||
|
if(text)
|
||||||
|
delete [] text;
|
||||||
|
text = NULL;
|
||||||
|
|
||||||
|
clearDynamicText();
|
||||||
|
|
||||||
|
textScrollPos = 0;
|
||||||
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
|
|
||||||
|
if(t)
|
||||||
|
{
|
||||||
|
text = new (std::nothrow) wchar_t[wcslen(t)+1];
|
||||||
|
if(!text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wcscpy(text, t);
|
||||||
|
|
||||||
|
textWidth = font->getWidth(text, currentSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiText::clearDynamicText()
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < textDyn.size(); i++)
|
||||||
|
{
|
||||||
|
if(textDyn[i])
|
||||||
|
delete [] textDyn[i];
|
||||||
|
}
|
||||||
|
textDyn.clear();
|
||||||
|
textDynWidth.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiText::setPresets(int sz, const glm::vec4 & c, int w, int a)
|
||||||
|
{
|
||||||
|
presetSize = sz;
|
||||||
|
presetColor = (GX2ColorF32) { (f32)c.r / 255.0f, (f32)c.g / 255.0f, (f32)c.b / 255.0f, (f32)c.a / 255.0f };
|
||||||
|
presetMaxWidth = w;
|
||||||
|
presetAlignment = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiText::setPresetFont(FreeTypeGX *f)
|
||||||
|
{
|
||||||
|
presentFont = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiText::setFontSize(int s)
|
||||||
|
{
|
||||||
|
size = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiText::setMaxWidth(int width, int w)
|
||||||
|
{
|
||||||
|
maxWidth = width;
|
||||||
|
wrapMode = w;
|
||||||
|
|
||||||
|
if(w == SCROLL_HORIZONTAL)
|
||||||
|
{
|
||||||
|
textScrollPos = 0;
|
||||||
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
|
textScrollDelay = TEXT_SCROLL_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearDynamicText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiText::setColor(const glm::vec4 & c)
|
||||||
|
{
|
||||||
|
color = c;
|
||||||
|
alpha = c[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiText::setBlurGlowColor(float blur, const glm::vec4 & c)
|
||||||
|
{
|
||||||
|
blurGlowColor = c;
|
||||||
|
blurGlowIntensity = blur;
|
||||||
|
blurAlpha = c[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
int GuiText::getTextWidth(int ind)
|
||||||
|
{
|
||||||
|
if(ind < 0 || ind >= (int) textDyn.size())
|
||||||
|
return this->getTextWidth();
|
||||||
|
|
||||||
|
return font->getWidth(textDyn[ind], currentSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
const wchar_t * GuiText::getDynText(int ind)
|
||||||
|
{
|
||||||
|
if(ind < 0 || ind >= (int) textDyn.size())
|
||||||
|
return text;
|
||||||
|
|
||||||
|
return textDyn[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change font
|
||||||
|
*/
|
||||||
|
bool GuiText::setFont(FreeTypeGX *f)
|
||||||
|
{
|
||||||
|
if(!f)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
font = f;
|
||||||
|
textWidth = font->getWidth(text, currentSize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GuiText::toUTF8(void) const
|
||||||
|
{
|
||||||
|
if(!text)
|
||||||
|
return std::string();
|
||||||
|
|
||||||
|
char *pUtf8 = FreeTypeGX::wideCharToUTF8(text);
|
||||||
|
if(!pUtf8)
|
||||||
|
return std::string();
|
||||||
|
|
||||||
|
std::string strOutput(pUtf8);
|
||||||
|
|
||||||
|
delete [] pUtf8;
|
||||||
|
|
||||||
|
return strOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiText::makeDottedText()
|
||||||
|
{
|
||||||
|
int pos = textDyn.size();
|
||||||
|
textDyn.resize(pos + 1);
|
||||||
|
|
||||||
|
int i = 0, currentWidth = 0;
|
||||||
|
textDyn[pos] = new (std::nothrow) wchar_t[maxWidth];
|
||||||
|
if(!textDyn[pos]) {
|
||||||
|
textDyn.resize(pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (text[i])
|
||||||
|
{
|
||||||
|
currentWidth += font->getCharWidth(text[i], currentSize, i > 0 ? text[i - 1] : 0);
|
||||||
|
if (currentWidth >= maxWidth && i > 2)
|
||||||
|
{
|
||||||
|
textDyn[pos][i - 2] = '.';
|
||||||
|
textDyn[pos][i - 1] = '.';
|
||||||
|
textDyn[pos][i] = '.';
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
textDyn[pos][i] = text[i];
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
textDyn[pos][i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiText::scrollText(u32 frameCount)
|
||||||
|
{
|
||||||
|
if (textDyn.size() == 0)
|
||||||
|
{
|
||||||
|
int pos = textDyn.size();
|
||||||
|
int i = 0, currentWidth = 0;
|
||||||
|
textDyn.resize(pos + 1);
|
||||||
|
|
||||||
|
textDyn[pos] = new (std::nothrow) wchar_t[maxWidth];
|
||||||
|
if(!textDyn[pos]) {
|
||||||
|
textDyn.resize(pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (text[i] && currentWidth < maxWidth)
|
||||||
|
{
|
||||||
|
textDyn[pos][i] = text[i];
|
||||||
|
|
||||||
|
currentWidth += font->getCharWidth(text[i], currentSize, i > 0 ? text[i - 1] : 0);
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
textDyn[pos][i] = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frameCount % textScrollDelay != 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textScrollInitialDelay)
|
||||||
|
{
|
||||||
|
--textScrollInitialDelay;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int stringlen = wcslen(text);
|
||||||
|
|
||||||
|
++textScrollPos;
|
||||||
|
if (textScrollPos > stringlen)
|
||||||
|
{
|
||||||
|
textScrollPos = 0;
|
||||||
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ch = textScrollPos;
|
||||||
|
int pos = textDyn.size() - 1;
|
||||||
|
|
||||||
|
if (!textDyn[pos])
|
||||||
|
textDyn[pos] = new (std::nothrow) wchar_t[maxWidth];
|
||||||
|
|
||||||
|
if(!textDyn[pos]) {
|
||||||
|
textDyn.resize(pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0, currentWidth = 0;
|
||||||
|
|
||||||
|
while (currentWidth < maxWidth)
|
||||||
|
{
|
||||||
|
if (ch > stringlen - 1)
|
||||||
|
{
|
||||||
|
textDyn[pos][i++] = ' ';
|
||||||
|
currentWidth += font->getCharWidth(L' ', currentSize, ch > 0 ? text[ch - 1] : 0);
|
||||||
|
textDyn[pos][i++] = ' ';
|
||||||
|
currentWidth += font->getCharWidth(L' ', currentSize, L' ');
|
||||||
|
textDyn[pos][i++] = ' ';
|
||||||
|
currentWidth += font->getCharWidth(L' ', currentSize, L' ');
|
||||||
|
ch = 0;
|
||||||
|
|
||||||
|
if(currentWidth >= maxWidth)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
textDyn[pos][i] = text[ch];
|
||||||
|
currentWidth += font->getCharWidth(text[ch], currentSize, ch > 0 ? text[ch - 1] : 0);
|
||||||
|
++ch;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
textDyn[pos][i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiText::wrapText()
|
||||||
|
{
|
||||||
|
if (textDyn.size() > 0) return;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int ch = 0;
|
||||||
|
int linenum = 0;
|
||||||
|
int lastSpace = -1;
|
||||||
|
int lastSpaceIndex = -1;
|
||||||
|
int currentWidth = 0;
|
||||||
|
|
||||||
|
while (text[ch] && linenum < linestodraw)
|
||||||
|
{
|
||||||
|
if (linenum >= (int) textDyn.size())
|
||||||
|
{
|
||||||
|
textDyn.resize(linenum + 1);
|
||||||
|
textDyn[linenum] = new (std::nothrow) wchar_t[maxWidth];
|
||||||
|
if(!textDyn[linenum]) {
|
||||||
|
textDyn.resize(linenum);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textDyn[linenum][i] = text[ch];
|
||||||
|
textDyn[linenum][i + 1] = 0;
|
||||||
|
|
||||||
|
currentWidth += font->getCharWidth(text[ch], currentSize, ch > 0 ? text[ch - 1] : 0x0000);
|
||||||
|
|
||||||
|
if (currentWidth >= maxWidth || (text[ch] == '\n'))
|
||||||
|
{
|
||||||
|
if(text[ch] == '\n')
|
||||||
|
{
|
||||||
|
lastSpace = -1;
|
||||||
|
lastSpaceIndex = -1;
|
||||||
|
}
|
||||||
|
else if (lastSpace >= 0)
|
||||||
|
{
|
||||||
|
textDyn[linenum][lastSpaceIndex] = 0; // discard space, and everything after
|
||||||
|
ch = lastSpace; // go backwards to the last space
|
||||||
|
lastSpace = -1; // we have used this space
|
||||||
|
lastSpaceIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linenum + 1 == linestodraw && text[ch + 1] != 0x0000)
|
||||||
|
{
|
||||||
|
if(i < 2)
|
||||||
|
i = 2;
|
||||||
|
|
||||||
|
textDyn[linenum][i - 2] = '.';
|
||||||
|
textDyn[linenum][i - 1] = '.';
|
||||||
|
textDyn[linenum][i] = '.';
|
||||||
|
textDyn[linenum][i + 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentWidth = 0;
|
||||||
|
++linenum;
|
||||||
|
i = -1;
|
||||||
|
}
|
||||||
|
if (text[ch] == ' ' && i >= 0)
|
||||||
|
{
|
||||||
|
lastSpace = ch;
|
||||||
|
lastSpaceIndex = i;
|
||||||
|
}
|
||||||
|
++ch;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the text on screen
|
||||||
|
*/
|
||||||
|
void GuiText::draw(CVideo *pVideo)
|
||||||
|
{
|
||||||
|
if(!text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!isVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
|
color[3] = getAlpha();
|
||||||
|
blurGlowColor[3] = blurAlpha * getAlpha();
|
||||||
|
|
||||||
|
float finalRenderingScale = 2.0f * internalRenderingScale;
|
||||||
|
|
||||||
|
int newSize = size * getScale() * finalRenderingScale;
|
||||||
|
int normal_size = size * getScale();
|
||||||
|
|
||||||
|
if(newSize != currentSize)
|
||||||
|
{
|
||||||
|
currentSize = normal_size;
|
||||||
|
|
||||||
|
if(text)
|
||||||
|
textWidth = font->getWidth(text, normal_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 x_pos = getCenterX() * finalRenderingScale;
|
||||||
|
f32 y_pos = getCenterY() * finalRenderingScale;
|
||||||
|
|
||||||
|
if(maxWidth > 0 && maxWidth <= textWidth)
|
||||||
|
{
|
||||||
|
if(wrapMode == DOTTED) // text dotted
|
||||||
|
{
|
||||||
|
if(textDyn.size() == 0)
|
||||||
|
makeDottedText();
|
||||||
|
|
||||||
|
if(textDynWidth.size() != textDyn.size())
|
||||||
|
{
|
||||||
|
textDynWidth.resize(textDyn.size());
|
||||||
|
|
||||||
|
for(u32 i = 0; i < textDynWidth.size(); i++)
|
||||||
|
textDynWidth[i] = font->getWidth(textDyn[i], newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(textDyn.size() > 0)
|
||||||
|
font->drawText(pVideo, x_pos, y_pos, getDepth(), textDyn[textDyn.size()-1], newSize, color, alignment, textDynWidth[textDyn.size()-1], defaultBlur, blurGlowIntensity, blurGlowColor,finalRenderingScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(wrapMode == SCROLL_HORIZONTAL)
|
||||||
|
{
|
||||||
|
scrollText(pVideo->getFrameCount());
|
||||||
|
|
||||||
|
if(textDyn.size() > 0)
|
||||||
|
font->drawText(pVideo, x_pos, y_pos, getDepth(), textDyn[textDyn.size()-1], newSize, color, alignment, maxWidth*finalRenderingScale, defaultBlur, blurGlowIntensity, blurGlowColor,finalRenderingScale);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(wrapMode == WRAP)
|
||||||
|
{
|
||||||
|
int lineheight = newSize + 6;
|
||||||
|
int yoffset = 0;
|
||||||
|
int voffset = 0;
|
||||||
|
|
||||||
|
if(textDyn.size() == 0)
|
||||||
|
wrapText();
|
||||||
|
|
||||||
|
if(textDynWidth.size() != textDyn.size())
|
||||||
|
{
|
||||||
|
textDynWidth.resize(textDyn.size());
|
||||||
|
|
||||||
|
for(u32 i = 0; i < textDynWidth.size(); i++)
|
||||||
|
textDynWidth[i] = font->getWidth(textDyn[i], newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(alignment & ALIGN_MIDDLE)
|
||||||
|
voffset = (lineheight * (textDyn.size()-1)) >> 1;
|
||||||
|
|
||||||
|
for(u32 i = 0; i < textDyn.size(); i++)
|
||||||
|
{
|
||||||
|
font->drawText(pVideo, x_pos, y_pos + voffset + yoffset, getDepth(), textDyn[i], newSize, color, alignment, textDynWidth[i], defaultBlur, blurGlowIntensity, blurGlowColor,finalRenderingScale);
|
||||||
|
yoffset -= lineheight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint16_t newtextWidth = font->getWidth(text, newSize);
|
||||||
|
font->drawText(pVideo, x_pos, y_pos, getDepth(), text, newSize, color, alignment, newtextWidth, defaultBlur, blurGlowIntensity, blurGlowColor,finalRenderingScale);
|
||||||
|
}
|
||||||
|
}
|
141
src/gui/GuiText.h
Normal file
141
src/gui/GuiText.h
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_TEXT_H_
|
||||||
|
#define GUI_TEXT_H_
|
||||||
|
|
||||||
|
#include "GuiElement.h"
|
||||||
|
//!Forward declaration
|
||||||
|
class FreeTypeGX;
|
||||||
|
|
||||||
|
//!Display, manage, and manipulate text in the GUI
|
||||||
|
class GuiText : public GuiElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
GuiText();
|
||||||
|
//!\param t Text
|
||||||
|
//!\param s Font size
|
||||||
|
//!\param c Font color
|
||||||
|
GuiText(const char * t, int s, const glm::vec4 & c);
|
||||||
|
//!\overload
|
||||||
|
//!\param t Text
|
||||||
|
//!\param s Font size
|
||||||
|
//!\param c Font color
|
||||||
|
GuiText(const wchar_t * t, int s, const glm::vec4 & c);
|
||||||
|
//!\overload
|
||||||
|
//!\Assumes SetPresets() has been called to setup preferred text attributes
|
||||||
|
//!\param t Text
|
||||||
|
GuiText(const char * t);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiText();
|
||||||
|
//!Sets the text of the GuiText element
|
||||||
|
//!\param t Text
|
||||||
|
virtual void setText(const char * t);
|
||||||
|
virtual void setText(const wchar_t * t);
|
||||||
|
virtual void setTextf(const char *format, ...) __attribute__((format(printf,2,3)));
|
||||||
|
//!Sets up preset values to be used by GuiText(t)
|
||||||
|
//!Useful when printing multiple text elements, all with the same attributes set
|
||||||
|
//!\param sz Font size
|
||||||
|
//!\param c Font color
|
||||||
|
//!\param w Maximum width of texture image (for text wrapping)
|
||||||
|
//!\param wrap Wrapmode when w>0
|
||||||
|
//!\param a Text alignment
|
||||||
|
static void setPresets(int sz, const glm::vec4 & c, int w, int a);
|
||||||
|
static void setPresetFont(FreeTypeGX *font);
|
||||||
|
//!Sets the font size
|
||||||
|
//!\param s Font size
|
||||||
|
void setFontSize(int s);
|
||||||
|
//!Sets the maximum width of the drawn texture image
|
||||||
|
//!If the text exceeds this, it is wrapped to the next line
|
||||||
|
//!\param w Maximum width
|
||||||
|
//!\param m WrapMode
|
||||||
|
void setMaxWidth(int w = 0, int m = WRAP);
|
||||||
|
//!Sets the font color
|
||||||
|
//!\param c Font color
|
||||||
|
void setColor(const glm::vec4 & c);
|
||||||
|
|
||||||
|
void setBlurGlowColor(float blurIntensity, const glm::vec4 & c);
|
||||||
|
|
||||||
|
void setTextBlur(float blur) { defaultBlur = blur; }
|
||||||
|
//!Get the original text as char
|
||||||
|
virtual const wchar_t * getText() const { return text; }
|
||||||
|
virtual std::string toUTF8(void) const;
|
||||||
|
//!Get the Horizontal Size of Text
|
||||||
|
int getTextWidth() { return textWidth; }
|
||||||
|
int getTextWidth(int ind);
|
||||||
|
//!Get the max textwidth
|
||||||
|
int getTextMaxWidth() { return maxWidth; }
|
||||||
|
//!Get fontsize
|
||||||
|
int getFontSize() { return size; };
|
||||||
|
//!Set max lines to draw
|
||||||
|
void setLinesToDraw(int l) { linestodraw = l; }
|
||||||
|
//!Get current Textline (for position calculation)
|
||||||
|
const wchar_t * getDynText(int ind = 0);
|
||||||
|
virtual const wchar_t * getTextLine(int ind) { return getDynText(ind); };
|
||||||
|
//!Change the font
|
||||||
|
bool setFont(FreeTypeGX *font);
|
||||||
|
//! virtual function used in child classes
|
||||||
|
virtual int getStartWidth() { return 0; };
|
||||||
|
//!Constantly called to draw the text
|
||||||
|
void draw(CVideo *pVideo);
|
||||||
|
//! text enums
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
WRAP,
|
||||||
|
DOTTED,
|
||||||
|
SCROLL_HORIZONTAL,
|
||||||
|
SCROLL_NONE
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
static FreeTypeGX * presentFont;
|
||||||
|
static int presetSize;
|
||||||
|
static int presetMaxWidth;
|
||||||
|
static int presetInternalRenderingScale;
|
||||||
|
static int presetAlignment;
|
||||||
|
static GX2ColorF32 presetColor;
|
||||||
|
|
||||||
|
//!Clear the dynamic text
|
||||||
|
void clearDynamicText();
|
||||||
|
//!Create a dynamic dotted text if the text is too long
|
||||||
|
void makeDottedText();
|
||||||
|
//!Scroll the text once
|
||||||
|
void scrollText(u32 frameCount);
|
||||||
|
//!Wrap the text to several lines
|
||||||
|
void wrapText();
|
||||||
|
|
||||||
|
wchar_t * text;
|
||||||
|
std::vector<wchar_t *> textDyn;
|
||||||
|
std::vector<uint16_t> textDynWidth;
|
||||||
|
int wrapMode; //!< Wrapping toggle
|
||||||
|
int textScrollPos; //!< Current starting index of text string for scrolling
|
||||||
|
int textScrollInitialDelay; //!< Delay to wait before starting to scroll
|
||||||
|
int textScrollDelay; //!< Scrolling speed
|
||||||
|
int size; //!< Font size
|
||||||
|
int maxWidth; //!< Maximum width of the generated text object (for text wrapping)
|
||||||
|
FreeTypeGX *font;
|
||||||
|
int textWidth;
|
||||||
|
int currentSize;
|
||||||
|
int linestodraw;
|
||||||
|
glm::vec4 color;
|
||||||
|
float defaultBlur;
|
||||||
|
float blurGlowIntensity;
|
||||||
|
float blurAlpha;
|
||||||
|
glm::vec4 blurGlowColor;
|
||||||
|
float internalRenderingScale;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
55
src/gui/GuiToggle.cpp
Normal file
55
src/gui/GuiToggle.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "GuiToggle.h"
|
||||||
|
/**
|
||||||
|
* Constructor for the GuiToggle class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
GuiToggle::GuiToggle(bool checked,f32 width,f32 height)
|
||||||
|
: GuiButton(width,height)
|
||||||
|
{
|
||||||
|
bChanged = false;
|
||||||
|
selected = false;
|
||||||
|
clicked.connect(this,&GuiToggle::OnToggleClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor for the GuiButton class.
|
||||||
|
*/
|
||||||
|
GuiToggle::~GuiToggle()
|
||||||
|
{
|
||||||
|
bChanged = false;
|
||||||
|
selected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiToggle::OnToggleClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger){
|
||||||
|
if(!isStateSet(STATE_DISABLED | STATE_HIDDEN | STATE_DISABLE_INPUT)){
|
||||||
|
log_print("Clicked on Toggle: ");
|
||||||
|
if(selected){
|
||||||
|
log_print("Uncheck\n");
|
||||||
|
setUnchecked();
|
||||||
|
}else{
|
||||||
|
log_print("Check\n");
|
||||||
|
setChecked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiToggle::update(GuiController * c){
|
||||||
|
GuiButton::update(c);
|
||||||
|
}
|
||||||
|
|
59
src/gui/GuiToggle.h
Normal file
59
src/gui/GuiToggle.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_TOGGLE_H_
|
||||||
|
#define GUI_TOGGLE_H_
|
||||||
|
|
||||||
|
#include "GuiButton.h"
|
||||||
|
#include "GuiFrame.h"
|
||||||
|
|
||||||
|
//!A simple CheckBox
|
||||||
|
class GuiToggle : public GuiButton, public sigslot::has_slots<>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
//!\param checked Checked
|
||||||
|
GuiToggle(bool checked,f32 width,f32 height);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiToggle();
|
||||||
|
void setValue(bool checked){
|
||||||
|
if(selected != checked){
|
||||||
|
selected = checked;
|
||||||
|
bChanged=true;
|
||||||
|
valueChanged(this,selected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void setChecked(){
|
||||||
|
setValue(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
void setUnchecked(){
|
||||||
|
setValue(false);
|
||||||
|
}
|
||||||
|
bool getValue(){
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
sigslot::signal2<GuiToggle *, bool> valueChanged;
|
||||||
|
void OnToggleClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger);
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool selected;
|
||||||
|
bool bChanged;
|
||||||
|
|
||||||
|
void update(GuiController * c);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
174
src/gui/GuiTrigger.cpp
Normal file
174
src/gui/GuiTrigger.cpp
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "GuiElement.h"
|
||||||
|
#include "GuiController.h"
|
||||||
|
#include "GuiTrigger.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the GuiTrigger class.
|
||||||
|
*/
|
||||||
|
GuiTrigger::GuiTrigger()
|
||||||
|
: chan(CHANNEL_ALL)
|
||||||
|
, btns(BUTTON_NONE)
|
||||||
|
, bClickEverywhere(false)
|
||||||
|
, bHoldEverywhere(false)
|
||||||
|
, bSelectionClickEverywhere(false)
|
||||||
|
, bLastTouched(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiTrigger::GuiTrigger(u32 ch, u32 btn, bool clickEverywhere, bool holdEverywhere, bool selectionClickEverywhere)
|
||||||
|
: chan(ch)
|
||||||
|
, btns(btn)
|
||||||
|
, bClickEverywhere(clickEverywhere)
|
||||||
|
, bHoldEverywhere(holdEverywhere)
|
||||||
|
, bSelectionClickEverywhere(selectionClickEverywhere)
|
||||||
|
, bLastTouched(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor for the GuiTrigger class.
|
||||||
|
*/
|
||||||
|
GuiTrigger::~GuiTrigger()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a simple trigger. Requires:
|
||||||
|
* - Element is selected
|
||||||
|
* - Trigger button is pressed
|
||||||
|
*/
|
||||||
|
void GuiTrigger::setTrigger(u32 ch, u32 btn)
|
||||||
|
{
|
||||||
|
chan = ch;
|
||||||
|
btns = btn;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GuiTrigger::left(const GuiController *controller) const
|
||||||
|
{
|
||||||
|
if((controller->chan & chan) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_LEFT | STICK_L_LEFT))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GuiTrigger::right(const GuiController *controller) const
|
||||||
|
{
|
||||||
|
if((controller->chan & chan) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_RIGHT | STICK_L_RIGHT))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GuiTrigger::up(const GuiController *controller) const
|
||||||
|
{
|
||||||
|
if((controller->chan & chan) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_UP | STICK_L_UP))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GuiTrigger::down(const GuiController *controller) const
|
||||||
|
{
|
||||||
|
if((controller->chan & chan) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_DOWN | STICK_L_DOWN))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GuiTrigger::clicked(const GuiController *controller) const
|
||||||
|
{
|
||||||
|
if((controller->chan & chan) == 0) {
|
||||||
|
return CLICKED_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bResult = CLICKED_NONE;
|
||||||
|
|
||||||
|
if(controller->data.touched && controller->data.validPointer && (btns & VPAD_TOUCH) && !controller->lastData.touched)
|
||||||
|
{
|
||||||
|
bResult = CLICKED_TOUCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(controller->data.buttons_d & btns)
|
||||||
|
{
|
||||||
|
bResult = CLICKED_BUTTON;
|
||||||
|
}
|
||||||
|
return bResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GuiTrigger::held(const GuiController *controller) const
|
||||||
|
{
|
||||||
|
if((controller->chan & chan) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bResult = false;
|
||||||
|
|
||||||
|
if(controller->data.touched && (btns & VPAD_TOUCH) && controller->data.validPointer && controller->lastData.touched && controller->lastData.validPointer)
|
||||||
|
{
|
||||||
|
bResult = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(controller->data.buttons_h & btns)
|
||||||
|
{
|
||||||
|
bResult = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GuiTrigger::released(const GuiController *controller) const
|
||||||
|
{
|
||||||
|
if((controller->chan & chan) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(clicked(controller) || held(controller))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool bResult = false;
|
||||||
|
|
||||||
|
if(!controller->data.touched && (btns & VPAD_TOUCH) && controller->lastData.touched && controller->lastData.validPointer)
|
||||||
|
{
|
||||||
|
bResult = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(controller->data.buttons_r & btns)
|
||||||
|
{
|
||||||
|
bResult = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bResult;
|
||||||
|
}
|
||||||
|
|
106
src/gui/GuiTrigger.h
Normal file
106
src/gui/GuiTrigger.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef GUI_TRIGGER_H_
|
||||||
|
#define GUI_TRIGGER_H_
|
||||||
|
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
|
||||||
|
|
||||||
|
//!Menu input trigger management. Determine if action is neccessary based on input data by comparing controller input data to a specific trigger element.
|
||||||
|
class GuiTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum eClicked{
|
||||||
|
CLICKED_NONE = 0x00,
|
||||||
|
CLICKED_TOUCH = 0x01,
|
||||||
|
CLICKED_BUTTON = 0x02,
|
||||||
|
};
|
||||||
|
enum eChannels {
|
||||||
|
CHANNEL_1 = 0x01,
|
||||||
|
CHANNEL_2 = 0x02,
|
||||||
|
CHANNEL_3 = 0x04,
|
||||||
|
CHANNEL_4 = 0x08,
|
||||||
|
CHANNEL_5 = 0x10,
|
||||||
|
CHANNEL_ALL = 0xFF
|
||||||
|
};
|
||||||
|
enum eButtons {
|
||||||
|
BUTTON_NONE = 0x0000,
|
||||||
|
VPAD_TOUCH = 0x80000000,
|
||||||
|
BUTTON_Z = 0x20000,
|
||||||
|
BUTTON_C = 0x10000,
|
||||||
|
BUTTON_A = 0x8000,
|
||||||
|
BUTTON_B = 0x4000,
|
||||||
|
BUTTON_X = 0x2000,
|
||||||
|
BUTTON_Y = 0x1000,
|
||||||
|
BUTTON_1 = BUTTON_Y,
|
||||||
|
BUTTON_2 = BUTTON_X,
|
||||||
|
BUTTON_LEFT = 0x0800,
|
||||||
|
BUTTON_RIGHT = 0x0400,
|
||||||
|
BUTTON_UP = 0x0200,
|
||||||
|
BUTTON_DOWN = 0x0100,
|
||||||
|
BUTTON_ZL = 0x0080,
|
||||||
|
BUTTON_ZR = 0x0040,
|
||||||
|
BUTTON_L = 0x0020,
|
||||||
|
BUTTON_R = 0x0010,
|
||||||
|
BUTTON_PLUS = 0x0008,
|
||||||
|
BUTTON_MINUS = 0x0004,
|
||||||
|
BUTTON_HOME = 0x0002,
|
||||||
|
BUTTON_SYNC = 0x0001,
|
||||||
|
STICK_R_LEFT = 0x04000000,
|
||||||
|
STICK_R_RIGHT = 0x02000000,
|
||||||
|
STICK_R_UP = 0x01000000,
|
||||||
|
STICK_R_DOWN = 0x00800000,
|
||||||
|
STICK_L_LEFT = 0x40000000,
|
||||||
|
STICK_L_RIGHT = 0x20000000,
|
||||||
|
STICK_L_UP = 0x10000000,
|
||||||
|
STICK_L_DOWN = 0x08000000
|
||||||
|
};
|
||||||
|
|
||||||
|
//!Constructor
|
||||||
|
GuiTrigger();
|
||||||
|
//!Constructor
|
||||||
|
GuiTrigger(u32 ch, u32 btns, bool clickEverywhere = false, bool holdEverywhere = false, bool selectionClickEverywhere = false);
|
||||||
|
//!Destructor
|
||||||
|
virtual ~GuiTrigger();
|
||||||
|
//!Sets a simple trigger. Requires: element is selected, and trigger button is pressed
|
||||||
|
void setTrigger(u32 ch, u32 btns);
|
||||||
|
|
||||||
|
void setClickEverywhere(bool b) { bClickEverywhere = b; }
|
||||||
|
void setHoldOnly(bool b) { bHoldEverywhere = b; }
|
||||||
|
void setSelectionClickEverywhere(bool b) { bSelectionClickEverywhere = b; }
|
||||||
|
|
||||||
|
bool isClickEverywhere() const { return bClickEverywhere; }
|
||||||
|
bool isHoldEverywhere() const { return bHoldEverywhere; }
|
||||||
|
bool isSelectionClickEverywhere() const { return bSelectionClickEverywhere; }
|
||||||
|
|
||||||
|
bool left(const GuiController *controller) const;
|
||||||
|
bool right(const GuiController *controller) const;
|
||||||
|
bool up(const GuiController *controller) const;
|
||||||
|
bool down(const GuiController *controller) const;
|
||||||
|
int clicked(const GuiController *controller) const;
|
||||||
|
bool held(const GuiController *controller) const;
|
||||||
|
bool released(const GuiController *controller) const;
|
||||||
|
private:
|
||||||
|
u32 chan;
|
||||||
|
u32 btns;
|
||||||
|
bool bClickEverywhere;
|
||||||
|
bool bHoldEverywhere;
|
||||||
|
bool bSelectionClickEverywhere;
|
||||||
|
bool bLastTouched;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
277
src/gui/Scrollbar.cpp
Normal file
277
src/gui/Scrollbar.cpp
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2011
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
***************************************************************************/
|
||||||
|
#include "Scrollbar.h"
|
||||||
|
#include "resources/Resources.h"
|
||||||
|
|
||||||
|
Scrollbar::Scrollbar(int h)
|
||||||
|
: touchTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::VPAD_TOUCH)
|
||||||
|
, wpadTouchTrigger(GuiTrigger::CHANNEL_2 | GuiTrigger::CHANNEL_3 | GuiTrigger::CHANNEL_4 | GuiTrigger::CHANNEL_5, GuiTrigger::BUTTON_A)
|
||||||
|
{
|
||||||
|
SelItem = 0;
|
||||||
|
SelInd = 0;
|
||||||
|
PageSize = 0;
|
||||||
|
EntrieCount = 0;
|
||||||
|
ScrollSpeed = 15;
|
||||||
|
ScrollState = 0;
|
||||||
|
|
||||||
|
listChanged.connect(this, &Scrollbar::setScrollboxPosition);
|
||||||
|
|
||||||
|
btnSoundClick = Resources::GetSound("button_click.mp3");
|
||||||
|
scrollbarLine = Resources::GetImageData("scrollbarLine.png");
|
||||||
|
arrowDown = Resources::GetImageData("scrollbarArrowDown.png");
|
||||||
|
arrowUp = Resources::GetImageData("scrollbarArrowUp.png");
|
||||||
|
scrollbarBox = Resources::GetImageData("scrollbarButton.png");
|
||||||
|
|
||||||
|
height = h;
|
||||||
|
width = scrollbarBox->getWidth();
|
||||||
|
|
||||||
|
MaxHeight = height * 0.5f - (scrollbarBox ? (scrollbarBox->getHeight() * 0.5f) : 0) - (arrowUp ? arrowUp->getHeight() : 0);
|
||||||
|
MinHeight = -height * 0.5f + (scrollbarBox ? (scrollbarBox->getHeight() * 0.5f) : 0) + (arrowDown ? arrowDown->getHeight() : 0);
|
||||||
|
|
||||||
|
scrollbarLineImg = new GuiImage(scrollbarLine);
|
||||||
|
scrollbarLineImg->setParent(this);
|
||||||
|
scrollbarLineImg->setAlignment(ALIGN_CENTER | ALIGN_MIDDLE);
|
||||||
|
scrollbarLineImg->setPosition(0, 0);
|
||||||
|
|
||||||
|
arrowDownImg = new GuiImage(arrowDown);
|
||||||
|
arrowUpImg = new GuiImage(arrowUp);
|
||||||
|
scrollbarBoxImg = new GuiImage(scrollbarBox);
|
||||||
|
|
||||||
|
arrowUpBtn = new GuiButton(arrowUpImg->getWidth(), arrowUpImg->getHeight());
|
||||||
|
arrowUpBtn->setParent(this);
|
||||||
|
arrowUpBtn->setImage(arrowUpImg);
|
||||||
|
arrowUpBtn->setAlignment(ALIGN_CENTER | ALIGN_TOP);
|
||||||
|
arrowUpBtn->setPosition(0, 0);
|
||||||
|
arrowUpBtn->setTrigger(&touchTrigger, 0);
|
||||||
|
arrowUpBtn->setTrigger(&wpadTouchTrigger, 1);
|
||||||
|
arrowUpBtn->setSoundClick(btnSoundClick);
|
||||||
|
arrowUpBtn->setEffectGrow();
|
||||||
|
arrowUpBtn->clicked.connect(this, &Scrollbar::OnUpButtonClick);
|
||||||
|
|
||||||
|
arrowDownBtn = new GuiButton(arrowDownImg->getWidth(), arrowDownImg->getHeight());
|
||||||
|
arrowDownBtn->setParent(this);
|
||||||
|
arrowDownBtn->setImage(arrowDownImg);
|
||||||
|
arrowDownBtn->setAlignment(ALIGN_CENTER | ALIGN_BOTTOM);
|
||||||
|
arrowDownBtn->setPosition(0, 0);
|
||||||
|
arrowDownBtn->setTrigger(&touchTrigger, 0);
|
||||||
|
arrowDownBtn->setTrigger(&wpadTouchTrigger, 1);
|
||||||
|
arrowDownBtn->setSoundClick(btnSoundClick);
|
||||||
|
arrowDownBtn->setEffectGrow();
|
||||||
|
arrowDownBtn->clicked.connect(this, &Scrollbar::OnDownButtonClick);
|
||||||
|
|
||||||
|
scrollbarBoxBtn = new GuiButton(scrollbarBoxImg->getWidth(), height);
|
||||||
|
scrollbarBoxBtn->setParent(this);
|
||||||
|
scrollbarBoxBtn->setImage(scrollbarBoxImg);
|
||||||
|
scrollbarBoxBtn->setAlignment(ALIGN_CENTER | ALIGN_TOP);
|
||||||
|
scrollbarBoxBtn->setPosition(0, MaxHeight);
|
||||||
|
scrollbarBoxBtn->setHoldable(true);
|
||||||
|
scrollbarBoxBtn->setTrigger(&touchTrigger, 0);
|
||||||
|
scrollbarBoxBtn->setTrigger(&wpadTouchTrigger, 1);
|
||||||
|
scrollbarBoxBtn->setEffectGrow();
|
||||||
|
scrollbarBoxBtn->held.connect(this, &Scrollbar::OnBoxButtonHold);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scrollbar::~Scrollbar()
|
||||||
|
{
|
||||||
|
Resources::RemoveSound(btnSoundClick);
|
||||||
|
Resources::RemoveImageData(scrollbarLine);
|
||||||
|
Resources::RemoveImageData(arrowDown);
|
||||||
|
Resources::RemoveImageData(arrowUp);
|
||||||
|
Resources::RemoveImageData(scrollbarBox);
|
||||||
|
|
||||||
|
delete arrowUpBtn;
|
||||||
|
delete arrowDownBtn;
|
||||||
|
delete scrollbarBoxBtn;
|
||||||
|
|
||||||
|
delete scrollbarLineImg;
|
||||||
|
|
||||||
|
delete arrowDownImg;
|
||||||
|
delete arrowUpImg;
|
||||||
|
delete scrollbarBoxImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scrollbar::ScrollOneUp()
|
||||||
|
{
|
||||||
|
if(SelItem == 0 && SelInd > 0)
|
||||||
|
{
|
||||||
|
// move list up by 1
|
||||||
|
--SelInd;
|
||||||
|
}
|
||||||
|
else if(SelInd+SelItem > 0)
|
||||||
|
{
|
||||||
|
--SelItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scrollbar::ScrollOneDown()
|
||||||
|
{
|
||||||
|
if(SelInd+SelItem + 1 < EntrieCount)
|
||||||
|
{
|
||||||
|
if(SelItem == PageSize-1)
|
||||||
|
{
|
||||||
|
// move list down by 1
|
||||||
|
SelInd++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SelItem++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scrollbar::OnUpButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger)
|
||||||
|
{
|
||||||
|
if(ScrollState < ScrollSpeed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ScrollOneUp();
|
||||||
|
|
||||||
|
ScrollState = 0;
|
||||||
|
listChanged(SelItem, SelInd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scrollbar::OnDownButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger)
|
||||||
|
{
|
||||||
|
if(ScrollState < ScrollSpeed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ScrollOneDown();
|
||||||
|
|
||||||
|
ScrollState = 0;
|
||||||
|
listChanged(SelItem, SelInd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scrollbar::OnBoxButtonHold(GuiButton *button, const GuiController *controller, GuiTrigger *trigger)
|
||||||
|
{
|
||||||
|
if(EntrieCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!controller->data.validPointer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int y = controller->data.y - this->getCenterY();
|
||||||
|
|
||||||
|
int positionWiimote = LIMIT(y - MinHeight, 0, MaxHeight - MinHeight);
|
||||||
|
|
||||||
|
int newSelected = (EntrieCount - 1) - (int) ((float) positionWiimote / (float) (MaxHeight-MinHeight) * (float) (EntrieCount-1));
|
||||||
|
|
||||||
|
int diff = newSelected-SelInd-SelItem;
|
||||||
|
|
||||||
|
if(newSelected <= 0)
|
||||||
|
{
|
||||||
|
SelItem = 0;
|
||||||
|
SelInd = 0;
|
||||||
|
}
|
||||||
|
else if(newSelected >= EntrieCount-1)
|
||||||
|
{
|
||||||
|
SelItem = (PageSize-1 < EntrieCount-1) ? PageSize-1 : EntrieCount-1;
|
||||||
|
SelInd = EntrieCount-PageSize;
|
||||||
|
}
|
||||||
|
else if(newSelected < PageSize && SelInd == 0 && diff < 0)
|
||||||
|
{
|
||||||
|
SelItem = std::max(SelItem+diff, 0);
|
||||||
|
}
|
||||||
|
else if(EntrieCount-newSelected < PageSize && SelInd == EntrieCount-PageSize && diff > 0)
|
||||||
|
{
|
||||||
|
SelItem = std::min(SelItem+diff, PageSize-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SelInd = LIMIT(SelInd+diff, 0, ((EntrieCount-PageSize < 0) ? 0 : EntrieCount-PageSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollState = 0;
|
||||||
|
listChanged(SelItem, SelInd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scrollbar::SetPageSize(int size)
|
||||||
|
{
|
||||||
|
if(PageSize == size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PageSize = size;
|
||||||
|
listChanged(SelItem, SelInd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scrollbar::SetSelectedItem(int pos)
|
||||||
|
{
|
||||||
|
if(SelItem == pos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SelItem = LIMIT(pos, 0, EntrieCount-1);
|
||||||
|
listChanged(SelItem, SelInd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scrollbar::SetSelectedIndex(int pos)
|
||||||
|
{
|
||||||
|
if(SelInd == pos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SelInd = pos;
|
||||||
|
listChanged(SelItem, SelInd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scrollbar::SetEntrieCount(int cnt)
|
||||||
|
{
|
||||||
|
if(EntrieCount == cnt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
EntrieCount = cnt;
|
||||||
|
listChanged(SelItem, SelInd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scrollbar::setScrollboxPosition(int SelItem, int SelInd)
|
||||||
|
{
|
||||||
|
int position = MaxHeight-(MaxHeight-MinHeight)*(SelInd+SelItem)/(EntrieCount-1);
|
||||||
|
|
||||||
|
if(position < MinHeight || (SelInd+SelItem >= EntrieCount-1))
|
||||||
|
position = MinHeight;
|
||||||
|
else if(position > MaxHeight || (SelInd+SelItem) == 0)
|
||||||
|
position = MaxHeight;
|
||||||
|
|
||||||
|
scrollbarBoxBtn->setPosition(0, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scrollbar::draw(CVideo * video)
|
||||||
|
{
|
||||||
|
scrollbarLineImg->draw(video);
|
||||||
|
arrowUpBtn->draw(video);
|
||||||
|
arrowDownBtn->draw(video);
|
||||||
|
scrollbarBoxBtn->draw(video);
|
||||||
|
|
||||||
|
updateEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scrollbar::update(GuiController * t)
|
||||||
|
{
|
||||||
|
if(this->isStateSet(STATE_DISABLED))
|
||||||
|
return;
|
||||||
|
|
||||||
|
arrowUpBtn->update(t);
|
||||||
|
arrowDownBtn->update(t);
|
||||||
|
scrollbarBoxBtn->update(t);
|
||||||
|
|
||||||
|
++ScrollState;
|
||||||
|
}
|
||||||
|
|
84
src/gui/Scrollbar.h
Normal file
84
src/gui/Scrollbar.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2011
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
***************************************************************************/
|
||||||
|
#ifndef SCROLLBAR_HPP_
|
||||||
|
#define SCROLLBAR_HPP_
|
||||||
|
|
||||||
|
#include "gui/GuiElement.h"
|
||||||
|
#include "gui/GuiButton.h"
|
||||||
|
|
||||||
|
class Scrollbar : public GuiElement, public sigslot::has_slots<>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Scrollbar(int height);
|
||||||
|
virtual ~Scrollbar();
|
||||||
|
void ScrollOneUp();
|
||||||
|
void ScrollOneDown();
|
||||||
|
int GetSelectedItem() { return SelItem; }
|
||||||
|
int GetSelectedIndex() { return SelInd; }
|
||||||
|
void draw(CVideo * video);
|
||||||
|
void update(GuiController * t);
|
||||||
|
|
||||||
|
//! Signals
|
||||||
|
sigslot::signal2<int, int> listChanged;
|
||||||
|
//! Slots
|
||||||
|
void SetPageSize(int size);
|
||||||
|
void SetRowSize(int size);
|
||||||
|
void SetSelectedItem(int pos);
|
||||||
|
void SetSelectedIndex(int pos);
|
||||||
|
void SetEntrieCount(int cnt);
|
||||||
|
protected:
|
||||||
|
void setScrollboxPosition(int SelItem, int SelInd);
|
||||||
|
void OnUpButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger);
|
||||||
|
void OnDownButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger);
|
||||||
|
void OnBoxButtonHold(GuiButton *button, const GuiController *controller, GuiTrigger *trigger);
|
||||||
|
|
||||||
|
u32 ScrollState;
|
||||||
|
u16 ScrollSpeed;
|
||||||
|
|
||||||
|
int MinHeight;
|
||||||
|
int MaxHeight;
|
||||||
|
int SelItem;
|
||||||
|
int SelInd;
|
||||||
|
int PageSize;
|
||||||
|
int EntrieCount;
|
||||||
|
int pressedChan;
|
||||||
|
|
||||||
|
GuiButton * arrowUpBtn;
|
||||||
|
GuiButton * arrowDownBtn;
|
||||||
|
GuiButton * scrollbarBoxBtn;
|
||||||
|
GuiImage * scrollbarLineImg;
|
||||||
|
GuiImage * arrowDownImg;
|
||||||
|
GuiImage * arrowUpImg;
|
||||||
|
GuiImage * scrollbarBoxImg;
|
||||||
|
GuiImageData * scrollbarLine;
|
||||||
|
GuiImageData * arrowDown;
|
||||||
|
GuiImageData * arrowUp;
|
||||||
|
GuiImageData * scrollbarBox;
|
||||||
|
GuiSound * btnSoundClick;
|
||||||
|
|
||||||
|
GuiTrigger touchTrigger;
|
||||||
|
GuiTrigger wpadTouchTrigger;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
63
src/gui/VPadController.h
Normal file
63
src/gui/VPadController.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef VPAD_CONTROLLER_H_
|
||||||
|
#define VPAD_CONTROLLER_H_
|
||||||
|
|
||||||
|
#include "GuiController.h"
|
||||||
|
#include "dynamic_libs/vpad_functions.h"
|
||||||
|
|
||||||
|
class VPadController : public GuiController
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
VPadController(int channel)
|
||||||
|
: GuiController(channel)
|
||||||
|
{
|
||||||
|
memset(&vpad, 0, sizeof(vpad));
|
||||||
|
}
|
||||||
|
|
||||||
|
//!Destructor
|
||||||
|
virtual ~VPadController() {}
|
||||||
|
|
||||||
|
bool update(int width, int height)
|
||||||
|
{
|
||||||
|
lastData = data;
|
||||||
|
|
||||||
|
int vpadError = -1;
|
||||||
|
VPADRead(0, &vpad, 1, &vpadError);
|
||||||
|
|
||||||
|
if(vpadError == 0)
|
||||||
|
{
|
||||||
|
data.buttons_r = vpad.btns_r;
|
||||||
|
data.buttons_h = vpad.btns_h;
|
||||||
|
data.buttons_d = vpad.btns_d;
|
||||||
|
data.validPointer = !vpad.tpdata.invalid;
|
||||||
|
data.touched = vpad.tpdata.touched;
|
||||||
|
//! calculate the screen offsets
|
||||||
|
data.x = -(width >> 1) + ((int)(vpad.tpdata1.x * ((width)/1211.0f)*width) >> 12)-30;
|
||||||
|
data.y = -(height >> 1) + ((int)(vpad.tpdata1.y * ((height)/653.0f)*height) >> 12)-35;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
VPADData vpad;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
179
src/gui/WPadController.h
Normal file
179
src/gui/WPadController.h
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef WPAD_CONTROLLER_H_
|
||||||
|
#define WPAD_CONTROLLER_H_
|
||||||
|
|
||||||
|
#include "GuiController.h"
|
||||||
|
#include "dynamic_libs/padscore_functions.h"
|
||||||
|
|
||||||
|
class WPadController : public GuiController
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
WPadController(int channel)
|
||||||
|
: GuiController(channel)
|
||||||
|
{
|
||||||
|
memset(&kpadData, 0, sizeof(kpadData));
|
||||||
|
}
|
||||||
|
|
||||||
|
//!Destructor
|
||||||
|
virtual ~WPadController() {}
|
||||||
|
|
||||||
|
u32 remapWiiMoteButtons(u32 buttons)
|
||||||
|
{
|
||||||
|
u32 conv_buttons = 0;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_LEFT)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_LEFT;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_RIGHT)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_RIGHT;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_DOWN)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_DOWN;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_UP)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_UP;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_PLUS)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_PLUS;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_2)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_2;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_1)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_1;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_B)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_B;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_A)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_A;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_MINUS)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_MINUS;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_Z)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_Z;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_C)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_C;
|
||||||
|
|
||||||
|
if(buttons & WPAD_BUTTON_HOME)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_HOME;
|
||||||
|
|
||||||
|
return conv_buttons;
|
||||||
|
}
|
||||||
|
u32 remapClassicButtons(u32 buttons)
|
||||||
|
{
|
||||||
|
u32 conv_buttons = 0;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_LEFT)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_LEFT;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_RIGHT)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_RIGHT;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_DOWN)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_DOWN;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_UP)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_UP;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_PLUS)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_PLUS;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_X)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_X;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_Y)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_Y;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_B)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_B;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_A)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_A;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_MINUS)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_MINUS;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_HOME)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_HOME;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_ZR)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_ZR;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_ZL)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_ZL;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_R)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_R;
|
||||||
|
|
||||||
|
if(buttons & WPAD_CLASSIC_BUTTON_L)
|
||||||
|
conv_buttons |= GuiTrigger::BUTTON_L;
|
||||||
|
|
||||||
|
return conv_buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool update(int width, int height)
|
||||||
|
{
|
||||||
|
lastData = data;
|
||||||
|
|
||||||
|
u32 controller_type;
|
||||||
|
|
||||||
|
//! check if the controller is connected
|
||||||
|
if(WPADProbe(chanIdx-1, &controller_type) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
KPADRead(chanIdx-1, &kpadData, 1);
|
||||||
|
|
||||||
|
if(kpadData.device_type <= 1)
|
||||||
|
{
|
||||||
|
data.buttons_r = remapWiiMoteButtons(kpadData.btns_r);
|
||||||
|
data.buttons_h = remapWiiMoteButtons(kpadData.btns_h);
|
||||||
|
data.buttons_d = remapWiiMoteButtons(kpadData.btns_d);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.buttons_r = remapClassicButtons(kpadData.classic.btns_r);
|
||||||
|
data.buttons_h = remapClassicButtons(kpadData.classic.btns_h);
|
||||||
|
data.buttons_d = remapClassicButtons(kpadData.classic.btns_d);
|
||||||
|
}
|
||||||
|
|
||||||
|
data.validPointer = (kpadData.pos_valid == 1 || kpadData.pos_valid == 2) && (kpadData.pos_x >= -1.0f && kpadData.pos_x <= 1.0f) && (kpadData.pos_y >= -1.0f && kpadData.pos_y <= 1.0f);
|
||||||
|
//! calculate the screen offsets if pointer is valid else leave old value
|
||||||
|
if(data.validPointer)
|
||||||
|
{
|
||||||
|
data.x = (width >> 1) * kpadData.pos_x;
|
||||||
|
data.y = (height >> 1) * (-kpadData.pos_y);
|
||||||
|
|
||||||
|
if(kpadData.angle_y > 0.0f)
|
||||||
|
data.pointerAngle = (-kpadData.angle_x + 1.0f) * 0.5f * 180.0f;
|
||||||
|
else
|
||||||
|
data.pointerAngle = (kpadData.angle_x + 1.0f) * 0.5f * 180.0f - 180.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
KPADData kpadData;
|
||||||
|
u32 lastButtons;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
2731
src/gui/sigslot.h
Normal file
2731
src/gui/sigslot.h
Normal file
File diff suppressed because it is too large
Load Diff
49
src/kernel/kernel_functions.c
Normal file
49
src/kernel/kernel_functions.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include "common/common.h"
|
||||||
|
#include "common/kernel_defs.h"
|
||||||
|
#include "kernel/kernel_functions.h"
|
||||||
|
#include "kernel/syscalls.h"
|
||||||
|
|
||||||
|
/* our retain data */
|
||||||
|
ReducedCosAppXmlInfo cosAppXmlInfoStruct __attribute__((section(".data")));
|
||||||
|
/*
|
||||||
|
* This function is a kernel hook function. It is called directly from kernel code at position 0xFFF18558.
|
||||||
|
*/
|
||||||
|
void my_PrepareTitle(CosAppXmlInfo *xmlKernelInfo)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* DBAT for access to our data region is setup at this point for the 0xC0000000 area.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! Copy all data from the XML info
|
||||||
|
strncpy(cosAppXmlInfoStruct.rpx_name, xmlKernelInfo->rpx_name, FS_MAX_ENTNAME_SIZE);
|
||||||
|
|
||||||
|
cosAppXmlInfoStruct.version_cos_xml = xmlKernelInfo->version_cos_xml;
|
||||||
|
cosAppXmlInfoStruct.os_version = xmlKernelInfo->os_version;
|
||||||
|
cosAppXmlInfoStruct.title_id = xmlKernelInfo->title_id;
|
||||||
|
cosAppXmlInfoStruct.app_type = xmlKernelInfo->app_type;
|
||||||
|
cosAppXmlInfoStruct.cmdFlags = xmlKernelInfo->cmdFlags;
|
||||||
|
cosAppXmlInfoStruct.max_size = xmlKernelInfo->max_size;
|
||||||
|
cosAppXmlInfoStruct.avail_size = xmlKernelInfo->avail_size;
|
||||||
|
cosAppXmlInfoStruct.codegen_size = xmlKernelInfo->codegen_size;
|
||||||
|
cosAppXmlInfoStruct.codegen_core = xmlKernelInfo->codegen_core;
|
||||||
|
cosAppXmlInfoStruct.max_codesize = xmlKernelInfo->max_codesize;
|
||||||
|
cosAppXmlInfoStruct.overlay_arena = xmlKernelInfo->overlay_arena;
|
||||||
|
cosAppXmlInfoStruct.default_stack0_size = xmlKernelInfo->default_stack0_size;
|
||||||
|
cosAppXmlInfoStruct.default_stack1_size = xmlKernelInfo->default_stack1_size;
|
||||||
|
cosAppXmlInfoStruct.default_stack2_size = xmlKernelInfo->default_stack2_size;
|
||||||
|
cosAppXmlInfoStruct.default_redzone0_size = xmlKernelInfo->default_redzone0_size;
|
||||||
|
cosAppXmlInfoStruct.default_redzone1_size = xmlKernelInfo->default_redzone1_size;
|
||||||
|
cosAppXmlInfoStruct.default_redzone2_size = xmlKernelInfo->default_redzone2_size;
|
||||||
|
cosAppXmlInfoStruct.exception_stack0_size = xmlKernelInfo->exception_stack0_size;
|
||||||
|
cosAppXmlInfoStruct.exception_stack1_size = xmlKernelInfo->exception_stack1_size;
|
||||||
|
cosAppXmlInfoStruct.exception_stack2_size = xmlKernelInfo->exception_stack2_size;
|
||||||
|
cosAppXmlInfoStruct.sdk_version = xmlKernelInfo->sdk_version;
|
||||||
|
cosAppXmlInfoStruct.title_version = xmlKernelInfo->title_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupKernelCallback(void)
|
||||||
|
{
|
||||||
|
KernelSetupSyscalls();
|
||||||
|
}
|
||||||
|
|
19
src/kernel/kernel_functions.h
Normal file
19
src/kernel/kernel_functions.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef __KERNEL_FUNCTIONS_H_
|
||||||
|
#define __KERNEL_FUNCTIONS_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "common/kernel_defs.h"
|
||||||
|
#include "syscalls.h"
|
||||||
|
|
||||||
|
void SetupKernelCallback(void);
|
||||||
|
|
||||||
|
extern ReducedCosAppXmlInfo cosAppXmlInfoStruct;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __KERNEL_FUNCTIONS_H_
|
136
src/kernel/kernel_hooks.S
Normal file
136
src/kernel/kernel_hooks.S
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
# Created by dimok
|
||||||
|
# This stuff may need a change in different kernel versions
|
||||||
|
# This is only needed when launched directly through browser and not SD card.
|
||||||
|
|
||||||
|
.section ".kernel_code"
|
||||||
|
.globl SaveAndResetDataBATs_And_SRs_hook
|
||||||
|
SaveAndResetDataBATs_And_SRs_hook:
|
||||||
|
# setup CTR to the position we need to return to
|
||||||
|
mflr r5
|
||||||
|
mtctr r5
|
||||||
|
# set link register to its original value
|
||||||
|
mtlr r7
|
||||||
|
# setup us a nice DBAT for our code data with same region as our code
|
||||||
|
mfspr r5, 560
|
||||||
|
mtspr 570, r5
|
||||||
|
mfspr r5, 561
|
||||||
|
mtspr 571, r5
|
||||||
|
# restore the original kernel instructions that we replaced
|
||||||
|
lwz r5, 0x34(r3)
|
||||||
|
lwz r6, 0x38(r3)
|
||||||
|
lwz r7, 0x3C(r3)
|
||||||
|
lwz r8, 0x40(r3)
|
||||||
|
lwz r9, 0x44(r3)
|
||||||
|
lwz r10, 0x48(r3)
|
||||||
|
lwz r11, 0x4C(r3)
|
||||||
|
lwz r3, 0x50(r3)
|
||||||
|
isync
|
||||||
|
mtsr 7, r5
|
||||||
|
# jump back to the position in kernel after our patch (from LR)
|
||||||
|
bctr
|
||||||
|
|
||||||
|
.extern my_PrepareTitle
|
||||||
|
.globl my_PrepareTitle_hook
|
||||||
|
my_PrepareTitle_hook:
|
||||||
|
# store all registers on stack to avoid issues with the call to C functions
|
||||||
|
stwu r1, -0x90(r1)
|
||||||
|
# registers for our own usage
|
||||||
|
# only need r31 and rest is from tests before, just leaving it for later tests
|
||||||
|
stw r28, 0x20(r1)
|
||||||
|
stw r29, 0x24(r1)
|
||||||
|
stw r30, 0x28(r1)
|
||||||
|
stw r31, 0x2C(r1)
|
||||||
|
|
||||||
|
stw r3, 0x30(r1)
|
||||||
|
stw r4, 0x34(r1)
|
||||||
|
stw r5, 0x38(r1)
|
||||||
|
stw r6, 0x3C(r1)
|
||||||
|
stw r7, 0x40(r1)
|
||||||
|
stw r8, 0x44(r1)
|
||||||
|
stw r9, 0x48(r1)
|
||||||
|
stw r10, 0x4C(r1)
|
||||||
|
stw r11, 0x50(r1)
|
||||||
|
stw r12, 0x54(r1)
|
||||||
|
stw r13, 0x58(r1)
|
||||||
|
stw r14, 0x5C(r1)
|
||||||
|
stw r15, 0x60(r1)
|
||||||
|
stw r16, 0x64(r1)
|
||||||
|
stw r17, 0x68(r1)
|
||||||
|
stw r18, 0x6C(r1)
|
||||||
|
stw r19, 0x70(r1)
|
||||||
|
stw r20, 0x74(r1)
|
||||||
|
stw r21, 0x78(r1)
|
||||||
|
stw r22, 0x7C(r1)
|
||||||
|
|
||||||
|
# save original DBAT registers
|
||||||
|
mfdbatu r28, 0
|
||||||
|
mfdbatl r29, 0
|
||||||
|
|
||||||
|
# setup access to our data memory range
|
||||||
|
lis r3, 0xC000
|
||||||
|
ori r3, r3, 0x1FFF
|
||||||
|
mtdbatu 0, r3
|
||||||
|
lis r3, 0x3000
|
||||||
|
ori r3, r3, 0x0012
|
||||||
|
mtdbatl 0, r3
|
||||||
|
|
||||||
|
# memory barrier
|
||||||
|
eieio
|
||||||
|
isync
|
||||||
|
|
||||||
|
# save the LR from where we came
|
||||||
|
mflr r31
|
||||||
|
|
||||||
|
# the cos.xml/app.xml structure is at the location 0x68 of r11
|
||||||
|
# there are actually many places that can be hooked for it
|
||||||
|
# e.g. 0xFFF16130 and r27 points to this structure
|
||||||
|
addi r3, r11, 0x68
|
||||||
|
|
||||||
|
bl my_PrepareTitle
|
||||||
|
|
||||||
|
# restore original DBAT registers
|
||||||
|
mtdbatu 0, r28
|
||||||
|
mtdbatl 0, r29
|
||||||
|
|
||||||
|
# memory barrier
|
||||||
|
eieio
|
||||||
|
isync
|
||||||
|
|
||||||
|
# setup LR to jump back to kernel code
|
||||||
|
mtlr r31
|
||||||
|
|
||||||
|
# restore all original values of registers from stack
|
||||||
|
lwz r28, 0x20(r1)
|
||||||
|
lwz r29, 0x24(r1)
|
||||||
|
lwz r30, 0x28(r1)
|
||||||
|
lwz r31, 0x2C(r1)
|
||||||
|
|
||||||
|
lwz r3, 0x30(r1)
|
||||||
|
lwz r4, 0x34(r1)
|
||||||
|
lwz r5, 0x38(r1)
|
||||||
|
lwz r6, 0x3C(r1)
|
||||||
|
lwz r7, 0x40(r1)
|
||||||
|
lwz r8, 0x44(r1)
|
||||||
|
lwz r9, 0x48(r1)
|
||||||
|
lwz r10, 0x4C(r1)
|
||||||
|
lwz r11, 0x50(r1)
|
||||||
|
lwz r12, 0x54(r1)
|
||||||
|
lwz r13, 0x58(r1)
|
||||||
|
lwz r14, 0x5C(r1)
|
||||||
|
lwz r15, 0x60(r1)
|
||||||
|
lwz r16, 0x64(r1)
|
||||||
|
lwz r17, 0x68(r1)
|
||||||
|
lwz r18, 0x6C(r1)
|
||||||
|
lwz r19, 0x70(r1)
|
||||||
|
lwz r20, 0x74(r1)
|
||||||
|
lwz r21, 0x78(r1)
|
||||||
|
lwz r22, 0x7C(r1)
|
||||||
|
|
||||||
|
# restore the stack
|
||||||
|
addi r1, r1, 0x90
|
||||||
|
|
||||||
|
# restore original instruction that we replaced in the kernel
|
||||||
|
clrlwi r7, r12, 0
|
||||||
|
|
||||||
|
# jump back
|
||||||
|
blr
|
255
src/kernel/syscalls.c
Normal file
255
src/kernel/syscalls.c
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
#include "common/os_defs.h"
|
||||||
|
#include "common/kernel_defs.h"
|
||||||
|
#include "common/common.h"
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
#include "utils/utils.h"
|
||||||
|
#include "syscalls.h"
|
||||||
|
|
||||||
|
extern void my_PrepareTitle_hook(void);
|
||||||
|
|
||||||
|
static unsigned int origPrepareTitleInstr __attribute__((section(".data"))) = 0;
|
||||||
|
|
||||||
|
static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Setup a DBAT access with cache inhibited to write through and read directly from memory
|
||||||
|
*/
|
||||||
|
unsigned int dbatu0, dbatl0, dbatu1, dbatl1;
|
||||||
|
// save the original DBAT value
|
||||||
|
asm volatile("mfdbatu %0, 0" : "=r" (dbatu0));
|
||||||
|
asm volatile("mfdbatl %0, 0" : "=r" (dbatl0));
|
||||||
|
asm volatile("mfdbatu %0, 1" : "=r" (dbatu1));
|
||||||
|
asm volatile("mfdbatl %0, 1" : "=r" (dbatl1));
|
||||||
|
|
||||||
|
unsigned int target_dbatu0 = 0;
|
||||||
|
unsigned int target_dbatl0 = 0;
|
||||||
|
unsigned int target_dbatu1 = 0;
|
||||||
|
unsigned int target_dbatl1 = 0;
|
||||||
|
|
||||||
|
unsigned char *dst_p = (unsigned char*)addr;
|
||||||
|
unsigned char *src_p = (unsigned char*)src;
|
||||||
|
|
||||||
|
// we only need DBAT modification for addresses out of our own DBAT range
|
||||||
|
// as our own DBAT is available everywhere for user and supervisor
|
||||||
|
// since our own DBAT is on DBAT5 position we don't collide here
|
||||||
|
if(addr < 0x00800000 || addr >= 0x01000000)
|
||||||
|
{
|
||||||
|
target_dbatu0 = (addr & 0x00F00000) | 0xC0000000 | 0x1F;
|
||||||
|
target_dbatl0 = (addr & 0xFFF00000) | 0x32;
|
||||||
|
asm volatile("mtdbatu 0, %0" : : "r" (target_dbatu0));
|
||||||
|
asm volatile("mtdbatl 0, %0" : : "r" (target_dbatl0));
|
||||||
|
dst_p = (unsigned char*)((addr & 0xFFFFFF) | 0xC0000000);
|
||||||
|
}
|
||||||
|
if(src < 0x00800000 || src >= 0x01000000)
|
||||||
|
{
|
||||||
|
target_dbatu1 = (src & 0x00F00000) | 0xB0000000 | 0x1F;
|
||||||
|
target_dbatl1 = (src & 0xFFF00000) | 0x32;
|
||||||
|
|
||||||
|
asm volatile("mtdbatu 1, %0" : : "r" (target_dbatu1));
|
||||||
|
asm volatile("mtdbatl 1, %0" : : "r" (target_dbatl1));
|
||||||
|
src_p = (unsigned char*)((src & 0xFFFFFF) | 0xB0000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
|
||||||
|
unsigned int i;
|
||||||
|
for(i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
// if we are on the edge to next chunk
|
||||||
|
if((target_dbatu0 != 0) && (((unsigned int)dst_p & 0x00F00000) != (target_dbatu0 & 0x00F00000)))
|
||||||
|
{
|
||||||
|
target_dbatu0 = ((addr + i) & 0x00F00000) | 0xC0000000 | 0x1F;
|
||||||
|
target_dbatl0 = ((addr + i) & 0xFFF00000) | 0x32;
|
||||||
|
dst_p = (unsigned char*)(((addr + i) & 0xFFFFFF) | 0xC0000000);
|
||||||
|
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
asm volatile("mtdbatu 0, %0" : : "r" (target_dbatu0));
|
||||||
|
asm volatile("mtdbatl 0, %0" : : "r" (target_dbatl0));
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
}
|
||||||
|
if((target_dbatu1 != 0) && (((unsigned int)src_p & 0x00F00000) != (target_dbatu1 & 0x00F00000)))
|
||||||
|
{
|
||||||
|
target_dbatu1 = ((src + i) & 0x00F00000) | 0xB0000000 | 0x1F;
|
||||||
|
target_dbatl1 = ((src + i) & 0xFFF00000) | 0x32;
|
||||||
|
src_p = (unsigned char*)(((src + i) & 0xFFFFFF) | 0xB0000000);
|
||||||
|
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
asm volatile("mtdbatu 1, %0" : : "r" (target_dbatu1));
|
||||||
|
asm volatile("mtdbatl 1, %0" : : "r" (target_dbatl1));
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst_p = *src_p;
|
||||||
|
|
||||||
|
++dst_p;
|
||||||
|
++src_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restore original DBAT value
|
||||||
|
*/
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
asm volatile("mtdbatu 0, %0" : : "r" (dbatu0));
|
||||||
|
asm volatile("mtdbatl 0, %0" : : "r" (dbatl0));
|
||||||
|
asm volatile("mtdbatu 1, %0" : : "r" (dbatu1));
|
||||||
|
asm volatile("mtdbatl 1, %0" : : "r" (dbatl1));
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void KernelReadDBATs(bat_table_t * table)
|
||||||
|
{
|
||||||
|
u32 i = 0;
|
||||||
|
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
|
||||||
|
asm volatile("mfspr %0, 536" : "=r" (table->bat[i].h));
|
||||||
|
asm volatile("mfspr %0, 537" : "=r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
asm volatile("mfspr %0, 538" : "=r" (table->bat[i].h));
|
||||||
|
asm volatile("mfspr %0, 539" : "=r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
asm volatile("mfspr %0, 540" : "=r" (table->bat[i].h));
|
||||||
|
asm volatile("mfspr %0, 541" : "=r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
asm volatile("mfspr %0, 542" : "=r" (table->bat[i].h));
|
||||||
|
asm volatile("mfspr %0, 543" : "=r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
|
||||||
|
asm volatile("mfspr %0, 568" : "=r" (table->bat[i].h));
|
||||||
|
asm volatile("mfspr %0, 569" : "=r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
asm volatile("mfspr %0, 570" : "=r" (table->bat[i].h));
|
||||||
|
asm volatile("mfspr %0, 571" : "=r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
asm volatile("mfspr %0, 572" : "=r" (table->bat[i].h));
|
||||||
|
asm volatile("mfspr %0, 573" : "=r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
asm volatile("mfspr %0, 574" : "=r" (table->bat[i].h));
|
||||||
|
asm volatile("mfspr %0, 575" : "=r" (table->bat[i].l));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void KernelWriteDBATs(bat_table_t * table)
|
||||||
|
{
|
||||||
|
u32 i = 0;
|
||||||
|
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
|
||||||
|
asm volatile("mtspr 536, %0" : : "r" (table->bat[i].h));
|
||||||
|
asm volatile("mtspr 537, %0" : : "r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
asm volatile("mtspr 538, %0" : : "r" (table->bat[i].h));
|
||||||
|
asm volatile("mtspr 539, %0" : : "r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
asm volatile("mtspr 540, %0" : : "r" (table->bat[i].h));
|
||||||
|
asm volatile("mtspr 541, %0" : : "r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
asm volatile("mtspr 542, %0" : : "r" (table->bat[i].h));
|
||||||
|
asm volatile("mtspr 543, %0" : : "r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
|
||||||
|
asm volatile("mtspr 568, %0" : : "r" (table->bat[i].h));
|
||||||
|
asm volatile("mtspr 569, %0" : : "r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
asm volatile("mtspr 570, %0" : : "r" (table->bat[i].h));
|
||||||
|
asm volatile("mtspr 571, %0" : : "r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
asm volatile("mtspr 572, %0" : : "r" (table->bat[i].h));
|
||||||
|
asm volatile("mtspr 573, %0" : : "r" (table->bat[i].l));
|
||||||
|
i++;
|
||||||
|
asm volatile("mtspr 574, %0" : : "r" (table->bat[i].h));
|
||||||
|
asm volatile("mtspr 575, %0" : : "r" (table->bat[i].l));
|
||||||
|
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read a 32-bit word with kernel permissions */
|
||||||
|
uint32_t __attribute__ ((noinline)) kern_read(const void *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
asm volatile (
|
||||||
|
"li 3,1\n"
|
||||||
|
"li 4,0\n"
|
||||||
|
"li 5,0\n"
|
||||||
|
"li 6,0\n"
|
||||||
|
"li 7,0\n"
|
||||||
|
"lis 8,1\n"
|
||||||
|
"mr 9,%1\n"
|
||||||
|
"li 0,0x3400\n"
|
||||||
|
"mr %0,1\n"
|
||||||
|
"sc\n"
|
||||||
|
"nop\n"
|
||||||
|
"mr 1,%0\n"
|
||||||
|
"mr %0,3\n"
|
||||||
|
: "=r"(result)
|
||||||
|
: "b"(addr)
|
||||||
|
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
|
||||||
|
"11", "12"
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write a 32-bit word with kernel permissions */
|
||||||
|
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value)
|
||||||
|
{
|
||||||
|
asm volatile (
|
||||||
|
"li 3,1\n"
|
||||||
|
"li 4,0\n"
|
||||||
|
"mr 5,%1\n"
|
||||||
|
"li 6,0\n"
|
||||||
|
"li 7,0\n"
|
||||||
|
"lis 8,1\n"
|
||||||
|
"mr 9,%0\n"
|
||||||
|
"mr %1,1\n"
|
||||||
|
"li 0,0x3500\n"
|
||||||
|
"sc\n"
|
||||||
|
"nop\n"
|
||||||
|
"mr 1,%1\n"
|
||||||
|
:
|
||||||
|
: "r"(addr), "r"(value)
|
||||||
|
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
|
||||||
|
"11", "12"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernelSetupSyscalls(void)
|
||||||
|
{
|
||||||
|
//! assign 1 so that this variable gets into the retained .data section
|
||||||
|
static uint8_t ucSyscallsSetupRequired = 1;
|
||||||
|
if(!ucSyscallsSetupRequired)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ucSyscallsSetupRequired = 0;
|
||||||
|
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl1 + (0x36 * 4)), (unsigned int)KernelReadDBATs);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl2 + (0x36 * 4)), (unsigned int)KernelReadDBATs);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl3 + (0x36 * 4)), (unsigned int)KernelReadDBATs);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl4 + (0x36 * 4)), (unsigned int)KernelReadDBATs);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl5 + (0x36 * 4)), (unsigned int)KernelReadDBATs);
|
||||||
|
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl1 + (0x37 * 4)), (unsigned int)KernelWriteDBATs);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl2 + (0x37 * 4)), (unsigned int)KernelWriteDBATs);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl3 + (0x37 * 4)), (unsigned int)KernelWriteDBATs);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl4 + (0x37 * 4)), (unsigned int)KernelWriteDBATs);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl5 + (0x37 * 4)), (unsigned int)KernelWriteDBATs);
|
||||||
|
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl1 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl2 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl3 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl4 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl5 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||||
|
|
||||||
|
//! write our hook to the
|
||||||
|
u32 addr_my_PrepareTitle_hook = ((u32)my_PrepareTitle_hook) | 0x48000003;
|
||||||
|
DCFlushRange(&addr_my_PrepareTitle_hook, sizeof(addr_my_PrepareTitle_hook));
|
||||||
|
|
||||||
|
SC0x25_KernelCopyData((u32)&origPrepareTitleInstr, (u32)addr_PrepareTitle_hook, 4);
|
||||||
|
SC0x25_KernelCopyData((u32)addr_PrepareTitle_hook, (u32)OSEffectiveToPhysical(&addr_my_PrepareTitle_hook), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void KernelRestoreInstructions(void)
|
||||||
|
{
|
||||||
|
if(origPrepareTitleInstr != 0)
|
||||||
|
SC0x25_KernelCopyData((u32)addr_PrepareTitle_hook, (u32)&origPrepareTitleInstr, 4);
|
||||||
|
}
|
26
src/kernel/syscalls.h
Normal file
26
src/kernel/syscalls.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
#ifndef __SYSCALLS_H_
|
||||||
|
#define __SYSCALLS_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
|
#include "common/kernel_defs.h"
|
||||||
|
|
||||||
|
void KernelSetupSyscalls(void);
|
||||||
|
void KernelRestoreInstructions(void);
|
||||||
|
|
||||||
|
void SC0x25_KernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
|
||||||
|
void SC0x36_KernelReadDBATs(bat_table_t * table);
|
||||||
|
void SC0x37_KernelWriteDBATs(bat_table_t * table);
|
||||||
|
|
||||||
|
uint32_t __attribute__ ((noinline)) kern_read(const void *addr);
|
||||||
|
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __KERNEL_FUNCTIONS_H_
|
20
src/kernel/syscalls_asm.S
Normal file
20
src/kernel/syscalls_asm.S
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Created by dimok
|
||||||
|
# Syscalls for kernel that we use
|
||||||
|
|
||||||
|
.globl SC0x36_KernelReadDBATs
|
||||||
|
SC0x36_KernelReadDBATs:
|
||||||
|
li r0, 0x3600
|
||||||
|
sc
|
||||||
|
blr
|
||||||
|
|
||||||
|
.globl SC0x37_KernelWriteDBATs
|
||||||
|
SC0x37_KernelWriteDBATs:
|
||||||
|
li r0, 0x3700
|
||||||
|
sc
|
||||||
|
blr
|
||||||
|
|
||||||
|
.globl SC0x25_KernelCopyData
|
||||||
|
SC0x25_KernelCopyData:
|
||||||
|
li r0, 0x2500
|
||||||
|
sc
|
||||||
|
blr
|
43
src/link.ld
Normal file
43
src/link.ld
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
OUTPUT(hidtovpad.elf);
|
||||||
|
|
||||||
|
/* Tell linker where our application entry is so the garbage collect can work correct */
|
||||||
|
ENTRY(__entry_menu);
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
. = 0x00802000;
|
||||||
|
.text : {
|
||||||
|
*(.kernel_code*);
|
||||||
|
*(.text*);
|
||||||
|
/* Tell linker to not garbage collect this section as it is not referenced anywhere */
|
||||||
|
KEEP(*(.kernel_code*));
|
||||||
|
}
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata*);
|
||||||
|
}
|
||||||
|
.data : {
|
||||||
|
*(.data*);
|
||||||
|
|
||||||
|
__sdata_start = .;
|
||||||
|
*(.sdata*);
|
||||||
|
__sdata_end = .;
|
||||||
|
|
||||||
|
__sdata2_start = .;
|
||||||
|
*(.sdata2*);
|
||||||
|
__sdata2_end = .;
|
||||||
|
}
|
||||||
|
.bss : {
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss*);
|
||||||
|
*(.sbss*);
|
||||||
|
*(COMMON);
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
__CODE_END = .;
|
||||||
|
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(*);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************** FS ********************************************************/
|
||||||
|
/* coreinit.rpl difference in addresses 0xFE3C00 */
|
65
src/main.cpp
Normal file
65
src/main.cpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include "Application.h"
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
#include "dynamic_libs/gx2_functions.h"
|
||||||
|
#include "dynamic_libs/syshid_functions.h"
|
||||||
|
#include "dynamic_libs/vpad_functions.h"
|
||||||
|
#include "dynamic_libs/padscore_functions.h"
|
||||||
|
#include "dynamic_libs/socket_functions.h"
|
||||||
|
#include "dynamic_libs/sys_functions.h"
|
||||||
|
#include "dynamic_libs/ax_functions.h"
|
||||||
|
#include "dynamic_libs/fs_functions.h"
|
||||||
|
#include "fs/fs_utils.h"
|
||||||
|
#include "fs/sd_fat_devoptab.h"
|
||||||
|
#include "system/memory.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
#include "utils/utils.h"
|
||||||
|
#include "common/common.h"
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "common/common.h"
|
||||||
|
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
|
#include "system/memory.h"
|
||||||
|
|
||||||
|
/* Entry point */
|
||||||
|
extern "C" int Menu_Main(void){
|
||||||
|
//!*******************************************************************
|
||||||
|
//! Initialize function pointers *
|
||||||
|
//!*******************************************************************
|
||||||
|
//! do OS (for acquire) and sockets first so we got logging
|
||||||
|
InitOSFunctionPointers();
|
||||||
|
InitSocketFunctionPointers();
|
||||||
|
InitGX2FunctionPointers();
|
||||||
|
InitSysFunctionPointers();
|
||||||
|
InitVPadFunctionPointers();
|
||||||
|
InitPadScoreFunctionPointers();
|
||||||
|
InitAXFunctionPointers();
|
||||||
|
InitFSFunctionPointers();
|
||||||
|
|
||||||
|
log_init("192.168.0.181");
|
||||||
|
|
||||||
|
//Otherwise apply the patches!!!
|
||||||
|
log_printf("GX2_template\n\n");
|
||||||
|
|
||||||
|
//!*******************************************************************
|
||||||
|
//! Initialize heap memory *
|
||||||
|
//!*******************************************************************
|
||||||
|
log_print("Initialize memory management\n");
|
||||||
|
memoryInitialize();
|
||||||
|
|
||||||
|
log_printf("Mount SD partition\n");
|
||||||
|
mount_sd_fat("sd");
|
||||||
|
log_printf("Start main application\n");
|
||||||
|
Application::instance()->exec();
|
||||||
|
|
||||||
|
Application::destroyInstance();
|
||||||
|
log_printf("Unmount SD\n");
|
||||||
|
unmount_sd_fat("sd");
|
||||||
|
memoryRelease();
|
||||||
|
|
||||||
|
log_print("Going back to the Homebrew launcher\n");
|
||||||
|
|
||||||
|
log_deinit();
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
19
src/main.h
Normal file
19
src/main.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef _MAIN_H_
|
||||||
|
#define _MAIN_H_
|
||||||
|
|
||||||
|
#include "common/types.h"
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
|
||||||
|
/* Main */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! C wrapper for our C++ functions
|
||||||
|
int Menu_Main(void);
|
||||||
|
void deInit(void);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
222
src/menu/MainWindow.cpp
Normal file
222
src/menu/MainWindow.cpp
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
* Modified by Maschell, 2016 for GX2_GUI_Template
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "MainWindow.h"
|
||||||
|
#include "MainWindowTV.h"
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
#include "dynamic_libs/socket_functions.h"
|
||||||
|
#include "Application.h"
|
||||||
|
#include "utils/StringTools.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
|
MainWindow::MainWindow(int w, int h)
|
||||||
|
: width(w)
|
||||||
|
, height(h)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
std::string filename = strfmt("player%i_point.png", i+1);
|
||||||
|
pointerImgData[i] = Resources::GetImageData(filename.c_str());
|
||||||
|
pointerImg[i] = new GuiImage(pointerImgData[i]);
|
||||||
|
pointerImg[i]->setScale(1.5f);
|
||||||
|
pointerValid[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupMainView();
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
|
||||||
|
while(!tvElements.empty())
|
||||||
|
{
|
||||||
|
delete tvElements[0];
|
||||||
|
remove(tvElements[0]);
|
||||||
|
}
|
||||||
|
while(!drcElements.empty())
|
||||||
|
{
|
||||||
|
delete drcElements[0];
|
||||||
|
remove(drcElements[0]);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
delete pointerImg[i];
|
||||||
|
Resources::RemoveImageData(pointerImgData[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateEffects()
|
||||||
|
{
|
||||||
|
//! dont read behind the initial elements in case one was added
|
||||||
|
u32 tvSize = tvElements.size();
|
||||||
|
u32 drcSize = drcElements.size();
|
||||||
|
|
||||||
|
for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i)
|
||||||
|
{
|
||||||
|
drcElements[i]->updateEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! only update TV elements that are not updated yet because they are on DRC
|
||||||
|
for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i)
|
||||||
|
{
|
||||||
|
u32 n;
|
||||||
|
for(n = 0; (n < drcSize) && (n < drcElements.size()); n++)
|
||||||
|
{
|
||||||
|
if(tvElements[i] == drcElements[n])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(n == drcElements.size())
|
||||||
|
{
|
||||||
|
tvElements[i]->updateEffects();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::process(){
|
||||||
|
//! dont read behind the initial elements in case one was added
|
||||||
|
u32 tvSize = tvElements.size();
|
||||||
|
u32 drcSize = drcElements.size();
|
||||||
|
|
||||||
|
for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i)
|
||||||
|
{
|
||||||
|
drcElements[i]->process();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! only update TV elements that are not updated yet because they are on DRC
|
||||||
|
for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i)
|
||||||
|
{
|
||||||
|
u32 n;
|
||||||
|
for(n = 0; (n < drcSize) && (n < drcElements.size()); n++)
|
||||||
|
{
|
||||||
|
if(tvElements[i] == drcElements[n])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(n == drcElements.size())
|
||||||
|
{
|
||||||
|
tvElements[i]->process();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::update(GuiController *controller)
|
||||||
|
{
|
||||||
|
//! dont read behind the initial elements in case one was added
|
||||||
|
//u32 tvSize = tvElements.size();
|
||||||
|
|
||||||
|
if(controller->chan & GuiTrigger::CHANNEL_1)
|
||||||
|
{
|
||||||
|
u32 drcSize = drcElements.size();
|
||||||
|
|
||||||
|
for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i)
|
||||||
|
{
|
||||||
|
drcElements[i]->update(controller);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u32 tvSize = tvElements.size();
|
||||||
|
|
||||||
|
for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i)
|
||||||
|
{
|
||||||
|
tvElements[i]->update(controller);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// //! only update TV elements that are not updated yet because they are on DRC
|
||||||
|
// for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i)
|
||||||
|
// {
|
||||||
|
// u32 n;
|
||||||
|
// for(n = 0; (n < drcSize) && (n < drcElements.size()); n++)
|
||||||
|
// {
|
||||||
|
// if(tvElements[i] == drcElements[n])
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// if(n == drcElements.size())
|
||||||
|
// {
|
||||||
|
// tvElements[i]->update(controller);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
if(controller->chanIdx >= 1 && controller->chanIdx <= 4 && controller->data.validPointer)
|
||||||
|
{
|
||||||
|
int wpadIdx = controller->chanIdx - 1;
|
||||||
|
f32 posX = controller->data.x;
|
||||||
|
f32 posY = controller->data.y;
|
||||||
|
pointerImg[wpadIdx]->setPosition(posX, posY);
|
||||||
|
pointerImg[wpadIdx]->setAngle(controller->data.pointerAngle);
|
||||||
|
pointerValid[wpadIdx] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::drawDrc(CVideo *video)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < drcElements.size(); ++i)
|
||||||
|
{
|
||||||
|
drcElements[i]->draw(video);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if(pointerValid[i])
|
||||||
|
{
|
||||||
|
pointerImg[i]->setAlpha(0.5f);
|
||||||
|
pointerImg[i]->draw(video);
|
||||||
|
pointerImg[i]->setAlpha(1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::drawTv(CVideo *video)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < tvElements.size(); ++i)
|
||||||
|
{
|
||||||
|
tvElements[i]->draw(video);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if(pointerValid[i])
|
||||||
|
{
|
||||||
|
pointerImg[i]->draw(video);
|
||||||
|
pointerValid[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::SetupMainView()
|
||||||
|
{
|
||||||
|
|
||||||
|
//DrcFrame = new MainWindowDRC(width,height);
|
||||||
|
TvFrame = new MainWindowTV(width,height);
|
||||||
|
DrcFrame = TvFrame;
|
||||||
|
appendTv(TvFrame);
|
||||||
|
appendDrc(DrcFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::OnOpenEffectFinish(GuiElement *element)
|
||||||
|
{
|
||||||
|
//! once the menu is open reset its state and allow it to be "clicked/hold"
|
||||||
|
element->effectFinished.disconnect(this);
|
||||||
|
element->clearState(GuiElement::STATE_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::OnCloseEffectFinish(GuiElement *element)
|
||||||
|
{
|
||||||
|
//! remove element from draw list and push to delete queue
|
||||||
|
remove(element);
|
||||||
|
AsyncDeleter::pushForDelete(element);
|
||||||
|
}
|
153
src/menu/MainWindow.h
Normal file
153
src/menu/MainWindow.h
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
* Modified by Maschell, 2016 for GX2_GUI_Template
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef _MAIN_WINDOW_H_
|
||||||
|
#define _MAIN_WINDOW_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <queue>
|
||||||
|
#include "gui/Gui.h"
|
||||||
|
#include "system/CMutex.h"
|
||||||
|
#include "gui/GuiMainWindowScreen.h"
|
||||||
|
|
||||||
|
class CVideo;
|
||||||
|
|
||||||
|
class MainWindow : public sigslot::has_slots<>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MainWindow(int w, int h);
|
||||||
|
virtual ~MainWindow();
|
||||||
|
|
||||||
|
void appendTv(GuiElement *e)
|
||||||
|
{
|
||||||
|
if(!e)
|
||||||
|
return;
|
||||||
|
|
||||||
|
removeTv(e);
|
||||||
|
tvElements.push_back(e);
|
||||||
|
}
|
||||||
|
void appendDrc(GuiElement *e)
|
||||||
|
{
|
||||||
|
if(!e)
|
||||||
|
return;
|
||||||
|
|
||||||
|
removeDrc(e);
|
||||||
|
drcElements.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void append(GuiElement *e)
|
||||||
|
{
|
||||||
|
appendTv(e);
|
||||||
|
appendDrc(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertTv(u32 pos, GuiElement *e)
|
||||||
|
{
|
||||||
|
if(!e)
|
||||||
|
return;
|
||||||
|
|
||||||
|
removeTv(e);
|
||||||
|
tvElements.insert(tvElements.begin() + pos, e);
|
||||||
|
}
|
||||||
|
void insertDrc(u32 pos, GuiElement *e)
|
||||||
|
{
|
||||||
|
if(!e)
|
||||||
|
return;
|
||||||
|
|
||||||
|
removeDrc(e);
|
||||||
|
drcElements.insert(drcElements.begin() + pos, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(u32 pos, GuiElement *e)
|
||||||
|
{
|
||||||
|
insertTv(pos, e);
|
||||||
|
insertDrc(pos, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeTv(GuiElement *e)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < tvElements.size(); ++i)
|
||||||
|
{
|
||||||
|
if(e == tvElements[i])
|
||||||
|
{
|
||||||
|
tvElements.erase(tvElements.begin() + i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void removeDrc(GuiElement *e)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < drcElements.size(); ++i)
|
||||||
|
{
|
||||||
|
if(e == drcElements[i])
|
||||||
|
{
|
||||||
|
drcElements.erase(drcElements.begin() + i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove(GuiElement *e)
|
||||||
|
{
|
||||||
|
removeTv(e);
|
||||||
|
removeDrc(e);
|
||||||
|
}
|
||||||
|
void removeAll()
|
||||||
|
{
|
||||||
|
tvElements.clear();
|
||||||
|
drcElements.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawDrc(CVideo *video);
|
||||||
|
void drawTv(CVideo *video);
|
||||||
|
void update(GuiController *controller);
|
||||||
|
void updateEffects();
|
||||||
|
|
||||||
|
void process();
|
||||||
|
|
||||||
|
void lockGUI()
|
||||||
|
{
|
||||||
|
guiMutex.lock();
|
||||||
|
}
|
||||||
|
void unlockGUI()
|
||||||
|
{
|
||||||
|
guiMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetupMainView(void);
|
||||||
|
|
||||||
|
void OnOpenEffectFinish(GuiElement *element);
|
||||||
|
void OnCloseEffectFinish(GuiElement *element);
|
||||||
|
|
||||||
|
int width, height;
|
||||||
|
std::vector<GuiElement *> drcElements;
|
||||||
|
std::vector<GuiElement *> tvElements;
|
||||||
|
|
||||||
|
GuiSound *ClickSound;
|
||||||
|
|
||||||
|
GuiMainWindowScreen * TvFrame;
|
||||||
|
GuiMainWindowScreen * DrcFrame;
|
||||||
|
|
||||||
|
GuiImageData *pointerImgData[4];
|
||||||
|
GuiImage *pointerImg[4];
|
||||||
|
bool pointerValid[4];
|
||||||
|
|
||||||
|
CMutex guiMutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_MAIN_WINDOW_H_
|
53
src/menu/MainWindowTV.cpp
Normal file
53
src/menu/MainWindowTV.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
* Modified by Maschell, 2016 for GX2_GUI_Template
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "MainWindowTV.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
|
MainWindowTV::MainWindowTV(int w, int h)
|
||||||
|
: GuiMainWindowScreen(w, h)
|
||||||
|
, width(w)
|
||||||
|
, height(h)
|
||||||
|
,bgImageColor(w, h, (GX2Color){ 0, 0, 0, 0 })
|
||||||
|
{
|
||||||
|
bgImageColor.setImageColor((GX2Color){ 248, 248, 249, 255 }, 0);
|
||||||
|
bgImageColor.setImageColor((GX2Color){ 248, 248, 249, 255 }, 1);
|
||||||
|
bgImageColor.setImageColor((GX2Color){ 248, 248, 249, 255 }, 2);
|
||||||
|
bgImageColor.setImageColor((GX2Color){ 248, 248, 249, 255 }, 3);
|
||||||
|
append(&bgImageColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindowTV::~MainWindowTV()
|
||||||
|
{
|
||||||
|
remove(&bgImageColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindowTV::draw(CVideo *v){
|
||||||
|
GuiMainWindowScreen::draw(v);
|
||||||
|
//gets called on every frame fro drawing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindowTV::update(GuiController * c){
|
||||||
|
GuiMainWindowScreen::update(c);
|
||||||
|
//CONTROLLER UPDATE!!!
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindowTV::process(){
|
||||||
|
GuiMainWindowScreen::process();
|
||||||
|
//gets called on every frame
|
||||||
|
}
|
40
src/menu/MainWindowTV.h
Normal file
40
src/menu/MainWindowTV.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
* Modified by Maschell, 2016 for GX2_GUI_Template
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef _MAIN_WINDOW_TV_H_
|
||||||
|
#define _MAIN_WINDOW_TV_H_
|
||||||
|
|
||||||
|
#include "gui/Gui.h"
|
||||||
|
#include "gui/GuiMainWindowScreen.h"
|
||||||
|
|
||||||
|
class CVideo;
|
||||||
|
|
||||||
|
class MainWindowTV : public GuiMainWindowScreen{
|
||||||
|
public:
|
||||||
|
MainWindowTV(int w, int h);
|
||||||
|
virtual ~MainWindowTV();
|
||||||
|
private:
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
GuiImage bgImageColor;
|
||||||
|
|
||||||
|
void draw(CVideo *v);
|
||||||
|
void update(GuiController * c);
|
||||||
|
void process();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_MAIN_WINDOW_TV_H_
|
189
src/resources/Resources.cpp
Normal file
189
src/resources/Resources.cpp
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
#include <gctypes.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "Resources.h"
|
||||||
|
#include "filelist.h"
|
||||||
|
#include "system/AsyncDeleter.h"
|
||||||
|
#include "fs/fs_utils.h"
|
||||||
|
#include "gui/GuiImageAsync.h"
|
||||||
|
#include "gui/GuiSound.h"
|
||||||
|
|
||||||
|
Resources * Resources::instance = NULL;
|
||||||
|
|
||||||
|
void Resources::Clear()
|
||||||
|
{
|
||||||
|
for(int i = 0; RecourceList[i].filename != NULL; ++i)
|
||||||
|
{
|
||||||
|
if(RecourceList[i].CustomFile)
|
||||||
|
{
|
||||||
|
free(RecourceList[i].CustomFile);
|
||||||
|
RecourceList[i].CustomFile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(RecourceList[i].CustomFileSize != 0)
|
||||||
|
RecourceList[i].CustomFileSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(instance)
|
||||||
|
delete instance;
|
||||||
|
|
||||||
|
instance = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Resources::LoadFiles(const char * path)
|
||||||
|
{
|
||||||
|
if(!path)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
Clear();
|
||||||
|
|
||||||
|
for(int i = 0; RecourceList[i].filename != NULL; ++i)
|
||||||
|
{
|
||||||
|
std::string fullpath(path);
|
||||||
|
fullpath += "/";
|
||||||
|
fullpath += RecourceList[i].filename;
|
||||||
|
|
||||||
|
u8 * buffer = NULL;
|
||||||
|
u32 filesize = 0;
|
||||||
|
|
||||||
|
LoadFileToMem(fullpath.c_str(), &buffer, &filesize);
|
||||||
|
|
||||||
|
RecourceList[i].CustomFile = buffer;
|
||||||
|
RecourceList[i].CustomFileSize = (u32) filesize;
|
||||||
|
result |= (buffer != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8 * Resources::GetFile(const char * filename)
|
||||||
|
{
|
||||||
|
for(int i = 0; RecourceList[i].filename != NULL; ++i)
|
||||||
|
{
|
||||||
|
if(strcasecmp(filename, RecourceList[i].filename) == 0)
|
||||||
|
{
|
||||||
|
return (RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 Resources::GetFileSize(const char * filename)
|
||||||
|
{
|
||||||
|
for(int i = 0; RecourceList[i].filename != NULL; ++i)
|
||||||
|
{
|
||||||
|
if(strcasecmp(filename, RecourceList[i].filename) == 0)
|
||||||
|
{
|
||||||
|
return (RecourceList[i].CustomFile ? RecourceList[i].CustomFileSize : RecourceList[i].DefaultFileSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiImageData * Resources::GetImageData(const char * filename)
|
||||||
|
{
|
||||||
|
if(!instance)
|
||||||
|
instance = new Resources;
|
||||||
|
|
||||||
|
std::map<std::string, std::pair<unsigned int, GuiImageData *> >::iterator itr = instance->imageDataMap.find(std::string(filename));
|
||||||
|
if(itr != instance->imageDataMap.end())
|
||||||
|
{
|
||||||
|
itr->second.first++;
|
||||||
|
return itr->second.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; RecourceList[i].filename != NULL; ++i)
|
||||||
|
{
|
||||||
|
if(strcasecmp(filename, RecourceList[i].filename) == 0)
|
||||||
|
{
|
||||||
|
const u8 * buff = RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile;
|
||||||
|
const u32 size = RecourceList[i].CustomFile ? RecourceList[i].CustomFileSize : RecourceList[i].DefaultFileSize;
|
||||||
|
|
||||||
|
if(buff == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
GuiImageData * image = new GuiImageData(buff, size);
|
||||||
|
instance->imageDataMap[std::string(filename)].first = 1;
|
||||||
|
instance->imageDataMap[std::string(filename)].second = image;
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Resources::RemoveImageData(GuiImageData * image)
|
||||||
|
{
|
||||||
|
std::map<std::string, std::pair<unsigned int, GuiImageData *> >::iterator itr;
|
||||||
|
|
||||||
|
for(itr = instance->imageDataMap.begin(); itr != instance->imageDataMap.end(); itr++)
|
||||||
|
{
|
||||||
|
if(itr->second.second == image)
|
||||||
|
{
|
||||||
|
itr->second.first--;
|
||||||
|
|
||||||
|
if(itr->second.first == 0)
|
||||||
|
{
|
||||||
|
AsyncDeleter::pushForDelete( itr->second.second );
|
||||||
|
instance->imageDataMap.erase(itr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiSound * Resources::GetSound(const char * filename)
|
||||||
|
{
|
||||||
|
if(!instance)
|
||||||
|
instance = new Resources;
|
||||||
|
|
||||||
|
std::map<std::string, std::pair<unsigned int, GuiSound *> >::iterator itr = instance->soundDataMap.find(std::string(filename));
|
||||||
|
if(itr != instance->soundDataMap.end())
|
||||||
|
{
|
||||||
|
itr->second.first++;
|
||||||
|
return itr->second.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; RecourceList[i].filename != NULL; ++i)
|
||||||
|
{
|
||||||
|
if(strcasecmp(filename, RecourceList[i].filename) == 0)
|
||||||
|
{
|
||||||
|
const u8 * buff = RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile;
|
||||||
|
const u32 size = RecourceList[i].CustomFile ? RecourceList[i].CustomFileSize : RecourceList[i].DefaultFileSize;
|
||||||
|
|
||||||
|
if(buff == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
GuiSound * sound = new GuiSound(buff, size);
|
||||||
|
instance->soundDataMap[std::string(filename)].first = 1;
|
||||||
|
instance->soundDataMap[std::string(filename)].second = sound;
|
||||||
|
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Resources::RemoveSound(GuiSound * sound)
|
||||||
|
{
|
||||||
|
std::map<std::string, std::pair<unsigned int, GuiSound *> >::iterator itr;
|
||||||
|
|
||||||
|
for(itr = instance->soundDataMap.begin(); itr != instance->soundDataMap.end(); itr++)
|
||||||
|
{
|
||||||
|
if(itr->second.second == sound)
|
||||||
|
{
|
||||||
|
itr->second.first--;
|
||||||
|
|
||||||
|
if(itr->second.first == 0)
|
||||||
|
{
|
||||||
|
AsyncDeleter::pushForDelete( itr->second.second );
|
||||||
|
instance->soundDataMap.erase(itr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
src/resources/Resources.h
Normal file
34
src/resources/Resources.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef RECOURCES_H_
|
||||||
|
#define RECOURCES_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
//! forward declaration
|
||||||
|
class GuiImageData;
|
||||||
|
class GuiSound;
|
||||||
|
|
||||||
|
class Resources
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void Clear();
|
||||||
|
static bool LoadFiles(const char * path);
|
||||||
|
static const u8 * GetFile(const char * filename);
|
||||||
|
static u32 GetFileSize(const char * filename);
|
||||||
|
|
||||||
|
static GuiImageData * GetImageData(const char * filename);
|
||||||
|
static void RemoveImageData(GuiImageData * image);
|
||||||
|
|
||||||
|
static GuiSound * GetSound(const char * filename);
|
||||||
|
static void RemoveSound(GuiSound * sound);
|
||||||
|
private:
|
||||||
|
static Resources *instance;
|
||||||
|
|
||||||
|
Resources() {}
|
||||||
|
~Resources() {}
|
||||||
|
|
||||||
|
std::map<std::string, std::pair<unsigned int, GuiImageData *> > imageDataMap;
|
||||||
|
std::map<std::string, std::pair<unsigned int, GuiSound *> > soundDataMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
40
src/resources/filelist.h
Normal file
40
src/resources/filelist.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Loadiine resource files.
|
||||||
|
* This file is generated automatically.
|
||||||
|
* Includes 3 files.
|
||||||
|
*
|
||||||
|
* NOTE:
|
||||||
|
* Any manual modification of this file will be overwriten by the generation.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef _FILELIST_H_
|
||||||
|
#define _FILELIST_H_
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
|
|
||||||
|
typedef struct _RecourceFile
|
||||||
|
{
|
||||||
|
const char *filename;
|
||||||
|
const u8 *DefaultFile;
|
||||||
|
const u32 &DefaultFileSize;
|
||||||
|
u8 *CustomFile;
|
||||||
|
u32 CustomFileSize;
|
||||||
|
} RecourceFile;
|
||||||
|
|
||||||
|
extern const u8 bgMusic_ogg[];
|
||||||
|
extern const u32 bgMusic_ogg_size;
|
||||||
|
|
||||||
|
extern const u8 button_click_mp3[];
|
||||||
|
extern const u32 button_click_mp3_size;
|
||||||
|
|
||||||
|
extern const u8 font_ttf[];
|
||||||
|
extern const u32 font_ttf_size;
|
||||||
|
|
||||||
|
static RecourceFile RecourceList[] =
|
||||||
|
{
|
||||||
|
{"bgMusic.ogg", bgMusic_ogg, bgMusic_ogg_size, NULL, 0},
|
||||||
|
{"button_click.mp3", button_click_mp3, button_click_mp3_size, NULL, 0},
|
||||||
|
{"font.ttf", font_ttf, font_ttf_size, NULL, 0},
|
||||||
|
{NULL, NULL, 0, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
142
src/sounds/BufferCircle.cpp
Normal file
142
src/sounds/BufferCircle.cpp
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2010
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* for WiiXplorer 2010
|
||||||
|
***************************************************************************/
|
||||||
|
#include <malloc.h>
|
||||||
|
#include "utils/utils.h"
|
||||||
|
#include "BufferCircle.hpp"
|
||||||
|
|
||||||
|
BufferCircle::BufferCircle()
|
||||||
|
{
|
||||||
|
which = 0;
|
||||||
|
BufferBlockSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferCircle::~BufferCircle()
|
||||||
|
{
|
||||||
|
FreeBuffer();
|
||||||
|
SoundBuffer.clear();
|
||||||
|
BufferSize.clear();
|
||||||
|
BufferReady.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferCircle::SetBufferBlockSize(int size)
|
||||||
|
{
|
||||||
|
if(size < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BufferBlockSize = size;
|
||||||
|
|
||||||
|
for(int i = 0; i < Size(); i++)
|
||||||
|
{
|
||||||
|
if(SoundBuffer[i] != NULL)
|
||||||
|
free(SoundBuffer[i]);
|
||||||
|
|
||||||
|
SoundBuffer[i] = (u8 *) memalign(32, ALIGN32(BufferBlockSize));
|
||||||
|
BufferSize[i] = 0;
|
||||||
|
BufferReady[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferCircle::Resize(int size)
|
||||||
|
{
|
||||||
|
while(size < Size())
|
||||||
|
RemoveBuffer(Size()-1);
|
||||||
|
|
||||||
|
int oldSize = Size();
|
||||||
|
|
||||||
|
SoundBuffer.resize(size);
|
||||||
|
BufferSize.resize(size);
|
||||||
|
BufferReady.resize(size);
|
||||||
|
|
||||||
|
for(int i = oldSize; i < Size(); i++)
|
||||||
|
{
|
||||||
|
if(BufferBlockSize > 0)
|
||||||
|
SoundBuffer[i] = (u8 *) memalign(32, ALIGN32(BufferBlockSize));
|
||||||
|
else
|
||||||
|
SoundBuffer[i] = NULL;
|
||||||
|
BufferSize[i] = 0;
|
||||||
|
BufferReady[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferCircle::RemoveBuffer(int pos)
|
||||||
|
{
|
||||||
|
if(!Valid(pos))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(SoundBuffer[pos] != NULL)
|
||||||
|
free(SoundBuffer[pos]);
|
||||||
|
|
||||||
|
SoundBuffer.erase(SoundBuffer.begin()+pos);
|
||||||
|
BufferSize.erase(BufferSize.begin()+pos);
|
||||||
|
BufferReady.erase(BufferReady.begin()+pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferCircle::ClearBuffer()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < Size(); i++)
|
||||||
|
{
|
||||||
|
BufferSize[i] = 0;
|
||||||
|
BufferReady[i] = false;
|
||||||
|
}
|
||||||
|
which = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferCircle::FreeBuffer()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < Size(); i++)
|
||||||
|
{
|
||||||
|
if(SoundBuffer[i] != NULL)
|
||||||
|
free(SoundBuffer[i]);
|
||||||
|
|
||||||
|
SoundBuffer[i] = NULL;
|
||||||
|
BufferSize[i] = 0;
|
||||||
|
BufferReady[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferCircle::LoadNext()
|
||||||
|
{
|
||||||
|
BufferReady[which] = false;
|
||||||
|
BufferSize[which] = 0;
|
||||||
|
|
||||||
|
which = Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferCircle::SetBufferReady(int pos, bool state)
|
||||||
|
{
|
||||||
|
if(!Valid(pos))
|
||||||
|
return;
|
||||||
|
|
||||||
|
BufferReady[pos] = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferCircle::SetBufferSize(int pos, int size)
|
||||||
|
{
|
||||||
|
if(!Valid(pos))
|
||||||
|
return;
|
||||||
|
|
||||||
|
BufferSize[pos] = size;
|
||||||
|
}
|
86
src/sounds/BufferCircle.hpp
Normal file
86
src/sounds/BufferCircle.hpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2010
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* for WiiXplorer 2010
|
||||||
|
***************************************************************************/
|
||||||
|
#ifndef BUFFER_CIRCLE_HPP_
|
||||||
|
#define BUFFER_CIRCLE_HPP_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <gctypes.h>
|
||||||
|
|
||||||
|
class BufferCircle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!> Constructor
|
||||||
|
BufferCircle();
|
||||||
|
//!> Destructor
|
||||||
|
~BufferCircle();
|
||||||
|
//!> Set circle size
|
||||||
|
void Resize(int size);
|
||||||
|
//!> Get the circle size
|
||||||
|
int Size() { return SoundBuffer.size(); };
|
||||||
|
//!> Set/resize the buffer size
|
||||||
|
void SetBufferBlockSize(int size);
|
||||||
|
//!> Remove a buffer
|
||||||
|
void RemoveBuffer(int pos);
|
||||||
|
//!> Set all buffers clear
|
||||||
|
void ClearBuffer();
|
||||||
|
//!> Free all buffers
|
||||||
|
void FreeBuffer();
|
||||||
|
//!> Switch to next buffer
|
||||||
|
void LoadNext();
|
||||||
|
//!> Get the current buffer
|
||||||
|
u8 * GetBuffer() { return GetBuffer(which); };
|
||||||
|
//!> Get a buffer at a position
|
||||||
|
u8 * GetBuffer(int pos) { if(!Valid(pos)) return NULL; else return SoundBuffer[pos]; };
|
||||||
|
//!> Get current buffer size
|
||||||
|
u32 GetBufferSize() { return GetBufferSize(which); };
|
||||||
|
//!> Get buffer size at position
|
||||||
|
u32 GetBufferSize(int pos) { if(!Valid(pos)) return 0; else return BufferSize[pos]; };
|
||||||
|
//!> Is current buffer ready
|
||||||
|
bool IsBufferReady() { return IsBufferReady(which); };
|
||||||
|
//!> Is a buffer at a position ready
|
||||||
|
bool IsBufferReady(int pos) { if(!Valid(pos)) return false; else return BufferReady[pos]; };
|
||||||
|
//!> Set a buffer at a position to a ready state
|
||||||
|
void SetBufferReady(int pos, bool st);
|
||||||
|
//!> Set the buffersize at a position
|
||||||
|
void SetBufferSize(int pos, int size);
|
||||||
|
//!> Get the current position in the circle
|
||||||
|
u16 Which() { return which; };
|
||||||
|
|
||||||
|
//!> Get the next location
|
||||||
|
inline u16 Next() { return (which+1 >= Size()) ? 0 : which+1; }
|
||||||
|
inline u16 Prev() { if(Size() == 0) return 0; else return ((int)which-1 < 0) ? Size()-1 : which-1; }
|
||||||
|
protected:
|
||||||
|
//!> Check if the position is a valid position in the vector
|
||||||
|
bool Valid(int pos) { return !(pos < 0 || pos >= Size()); };
|
||||||
|
|
||||||
|
u16 which;
|
||||||
|
u32 BufferBlockSize;
|
||||||
|
std::vector<u8 *> SoundBuffer;
|
||||||
|
std::vector<u32> BufferSize;
|
||||||
|
std::vector<bool> BufferReady;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
217
src/sounds/Mp3Decoder.cpp
Normal file
217
src/sounds/Mp3Decoder.cpp
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2010
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* for WiiXplorer 2010
|
||||||
|
***************************************************************************/
|
||||||
|
#include <string>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
#include "Mp3Decoder.hpp"
|
||||||
|
|
||||||
|
Mp3Decoder::Mp3Decoder(const char * filepath)
|
||||||
|
: SoundDecoder(filepath)
|
||||||
|
{
|
||||||
|
SoundType = SOUND_MP3;
|
||||||
|
ReadBuffer = NULL;
|
||||||
|
mad_timer_reset(&Timer);
|
||||||
|
mad_stream_init(&Stream);
|
||||||
|
mad_frame_init(&Frame);
|
||||||
|
mad_synth_init(&Synth);
|
||||||
|
|
||||||
|
if(!file_fd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OpenFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
Mp3Decoder::Mp3Decoder(const u8 * snd, int len)
|
||||||
|
: SoundDecoder(snd, len)
|
||||||
|
{
|
||||||
|
SoundType = SOUND_MP3;
|
||||||
|
ReadBuffer = NULL;
|
||||||
|
mad_timer_reset(&Timer);
|
||||||
|
mad_stream_init(&Stream);
|
||||||
|
mad_frame_init(&Frame);
|
||||||
|
mad_synth_init(&Synth);
|
||||||
|
|
||||||
|
if(!file_fd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OpenFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
Mp3Decoder::~Mp3Decoder()
|
||||||
|
{
|
||||||
|
ExitRequested = true;
|
||||||
|
while(Decoding)
|
||||||
|
usleep(100);
|
||||||
|
|
||||||
|
mad_synth_finish(&Synth);
|
||||||
|
mad_frame_finish(&Frame);
|
||||||
|
mad_stream_finish(&Stream);
|
||||||
|
|
||||||
|
if(ReadBuffer)
|
||||||
|
free(ReadBuffer);
|
||||||
|
ReadBuffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mp3Decoder::OpenFile()
|
||||||
|
{
|
||||||
|
GuardPtr = NULL;
|
||||||
|
ReadBuffer = (u8 *) memalign(32, SoundBlockSize*SoundBlocks);
|
||||||
|
if(!ReadBuffer)
|
||||||
|
{
|
||||||
|
if(file_fd)
|
||||||
|
delete file_fd;
|
||||||
|
file_fd = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 dummybuff[4096];
|
||||||
|
int ret = Read(dummybuff, 4096, 0);
|
||||||
|
if(ret <= 0)
|
||||||
|
{
|
||||||
|
if(file_fd)
|
||||||
|
delete file_fd;
|
||||||
|
file_fd = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SampleRate = (u32) Frame.header.samplerate;
|
||||||
|
Format = ((MAD_NCHANNELS(&Frame.header) == 2) ? (FORMAT_PCM_16_BIT | CHANNELS_STEREO) : (FORMAT_PCM_16_BIT | CHANNELS_MONO));
|
||||||
|
Rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Mp3Decoder::Rewind()
|
||||||
|
{
|
||||||
|
mad_synth_finish(&Synth);
|
||||||
|
mad_frame_finish(&Frame);
|
||||||
|
mad_stream_finish(&Stream);
|
||||||
|
mad_timer_reset(&Timer);
|
||||||
|
mad_stream_init(&Stream);
|
||||||
|
mad_frame_init(&Frame);
|
||||||
|
mad_synth_init(&Synth);
|
||||||
|
SynthPos = 0;
|
||||||
|
GuardPtr = NULL;
|
||||||
|
|
||||||
|
if(!file_fd)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return SoundDecoder::Rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline s16 FixedToShort(mad_fixed_t Fixed)
|
||||||
|
{
|
||||||
|
/* Clipping */
|
||||||
|
if(Fixed>=MAD_F_ONE)
|
||||||
|
return(SHRT_MAX);
|
||||||
|
if(Fixed<=-MAD_F_ONE)
|
||||||
|
return(-SHRT_MAX);
|
||||||
|
|
||||||
|
Fixed=Fixed>>(MAD_F_FRACBITS-15);
|
||||||
|
return((s16)Fixed);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Mp3Decoder::Read(u8 * buffer, int buffer_size, int pos)
|
||||||
|
{
|
||||||
|
if(!file_fd)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(Format == (FORMAT_PCM_16_BIT | CHANNELS_STEREO))
|
||||||
|
buffer_size &= ~0x0003;
|
||||||
|
else
|
||||||
|
buffer_size &= ~0x0001;
|
||||||
|
|
||||||
|
u8 * write_pos = buffer;
|
||||||
|
u8 * write_end = buffer+buffer_size;
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
while(SynthPos < Synth.pcm.length)
|
||||||
|
{
|
||||||
|
if(write_pos >= write_end)
|
||||||
|
return write_pos-buffer;
|
||||||
|
|
||||||
|
*((s16 *) write_pos) = FixedToShort(Synth.pcm.samples[0][SynthPos]);
|
||||||
|
write_pos += 2;
|
||||||
|
|
||||||
|
if(MAD_NCHANNELS(&Frame.header) == 2)
|
||||||
|
{
|
||||||
|
*((s16 *) write_pos) = FixedToShort(Synth.pcm.samples[1][SynthPos]);
|
||||||
|
write_pos += 2;
|
||||||
|
}
|
||||||
|
SynthPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Stream.buffer == NULL || Stream.error == MAD_ERROR_BUFLEN)
|
||||||
|
{
|
||||||
|
u8 * ReadStart = ReadBuffer;
|
||||||
|
int ReadSize = SoundBlockSize*SoundBlocks;
|
||||||
|
int Remaining = 0;
|
||||||
|
|
||||||
|
if(Stream.next_frame != NULL)
|
||||||
|
{
|
||||||
|
Remaining = Stream.bufend - Stream.next_frame;
|
||||||
|
memmove(ReadBuffer, Stream.next_frame, Remaining);
|
||||||
|
ReadStart += Remaining;
|
||||||
|
ReadSize -= Remaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadSize = file_fd->read(ReadStart, ReadSize);
|
||||||
|
if(ReadSize <= 0)
|
||||||
|
{
|
||||||
|
GuardPtr = ReadStart;
|
||||||
|
memset(GuardPtr, 0, MAD_BUFFER_GUARD);
|
||||||
|
ReadSize = MAD_BUFFER_GUARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurPos += ReadSize;
|
||||||
|
mad_stream_buffer(&Stream, ReadBuffer, Remaining+ReadSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mad_frame_decode(&Frame,&Stream))
|
||||||
|
{
|
||||||
|
if(MAD_RECOVERABLE(Stream.error))
|
||||||
|
{
|
||||||
|
if(Stream.error != MAD_ERROR_LOSTSYNC || !GuardPtr)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(Stream.error != MAD_ERROR_BUFLEN)
|
||||||
|
return -1;
|
||||||
|
else if(Stream.error == MAD_ERROR_BUFLEN && GuardPtr)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mad_timer_add(&Timer,Frame.header.duration);
|
||||||
|
mad_synth_frame(&Synth,&Frame);
|
||||||
|
SynthPos = 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
47
src/sounds/Mp3Decoder.hpp
Normal file
47
src/sounds/Mp3Decoder.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2010
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* for WiiXplorer 2010
|
||||||
|
***************************************************************************/
|
||||||
|
#include <mad.h>
|
||||||
|
|
||||||
|
#include "SoundDecoder.hpp"
|
||||||
|
|
||||||
|
class Mp3Decoder : public SoundDecoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Mp3Decoder(const char * filepath);
|
||||||
|
Mp3Decoder(const u8 * sound, int len);
|
||||||
|
virtual ~Mp3Decoder();
|
||||||
|
int Rewind();
|
||||||
|
int Read(u8 * buffer, int buffer_size, int pos);
|
||||||
|
protected:
|
||||||
|
void OpenFile();
|
||||||
|
struct mad_stream Stream;
|
||||||
|
struct mad_frame Frame;
|
||||||
|
struct mad_synth Synth;
|
||||||
|
mad_timer_t Timer;
|
||||||
|
u8 * GuardPtr;
|
||||||
|
u8 * ReadBuffer;
|
||||||
|
u32 SynthPos;
|
||||||
|
};
|
138
src/sounds/OggDecoder.cpp
Normal file
138
src/sounds/OggDecoder.cpp
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2010
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* for WiiXplorer 2010
|
||||||
|
***************************************************************************/
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
#include "OggDecoder.hpp"
|
||||||
|
|
||||||
|
static int ogg_read(void * punt, int bytes, int blocks, int *f)
|
||||||
|
{
|
||||||
|
return ((CFile *) f)->read((u8 *) punt, bytes*blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ogg_seek(int *f, ogg_int64_t offset, int mode)
|
||||||
|
{
|
||||||
|
return ((CFile *) f)->seek((u64) offset, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ogg_close(int *f)
|
||||||
|
{
|
||||||
|
((CFile *) f)->close();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long ogg_tell(int *f)
|
||||||
|
{
|
||||||
|
return (long) ((CFile *) f)->tell();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ov_callbacks callbacks = {
|
||||||
|
(size_t (*)(void *, size_t, size_t, void *)) ogg_read,
|
||||||
|
(int (*)(void *, ogg_int64_t, int)) ogg_seek,
|
||||||
|
(int (*)(void *)) ogg_close,
|
||||||
|
(long (*)(void *)) ogg_tell
|
||||||
|
};
|
||||||
|
|
||||||
|
OggDecoder::OggDecoder(const char * filepath)
|
||||||
|
: SoundDecoder(filepath)
|
||||||
|
{
|
||||||
|
SoundType = SOUND_OGG;
|
||||||
|
|
||||||
|
if(!file_fd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OpenFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
OggDecoder::OggDecoder(const u8 * snd, int len)
|
||||||
|
: SoundDecoder(snd, len)
|
||||||
|
{
|
||||||
|
SoundType = SOUND_OGG;
|
||||||
|
|
||||||
|
if(!file_fd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OpenFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
OggDecoder::~OggDecoder()
|
||||||
|
{
|
||||||
|
ExitRequested = true;
|
||||||
|
while(Decoding)
|
||||||
|
usleep(100);
|
||||||
|
|
||||||
|
if(file_fd)
|
||||||
|
ov_clear(&ogg_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OggDecoder::OpenFile()
|
||||||
|
{
|
||||||
|
if (ov_open_callbacks(file_fd, &ogg_file, NULL, 0, callbacks) < 0)
|
||||||
|
{
|
||||||
|
delete file_fd;
|
||||||
|
file_fd = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ogg_info = ov_info(&ogg_file, -1);
|
||||||
|
if(!ogg_info)
|
||||||
|
{
|
||||||
|
ov_clear(&ogg_file);
|
||||||
|
delete file_fd;
|
||||||
|
file_fd = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Format = ((ogg_info->channels == 2) ? (FORMAT_PCM_16_BIT | CHANNELS_STEREO) : (FORMAT_PCM_16_BIT | CHANNELS_MONO));
|
||||||
|
SampleRate = ogg_info->rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OggDecoder::Rewind()
|
||||||
|
{
|
||||||
|
if(!file_fd)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int ret = ov_time_seek(&ogg_file, 0);
|
||||||
|
CurPos = 0;
|
||||||
|
EndOfFile = false;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OggDecoder::Read(u8 * buffer, int buffer_size, int pos)
|
||||||
|
{
|
||||||
|
if(!file_fd)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int bitstream = 0;
|
||||||
|
|
||||||
|
int read = ov_read(&ogg_file, (char *) buffer, buffer_size, &bitstream);
|
||||||
|
|
||||||
|
if(read > 0)
|
||||||
|
CurPos += read;
|
||||||
|
|
||||||
|
return read;
|
||||||
|
}
|
43
src/sounds/OggDecoder.hpp
Normal file
43
src/sounds/OggDecoder.hpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2010
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* for WiiXplorer 2010
|
||||||
|
***************************************************************************/
|
||||||
|
#include <tremor/ivorbiscodec.h>
|
||||||
|
#include <tremor/ivorbisfile.h>
|
||||||
|
|
||||||
|
#include "SoundDecoder.hpp"
|
||||||
|
|
||||||
|
class OggDecoder : public SoundDecoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OggDecoder(const char * filepath);
|
||||||
|
OggDecoder(const u8 * snd, int len);
|
||||||
|
virtual ~OggDecoder();
|
||||||
|
int Rewind();
|
||||||
|
int Read(u8 * buffer, int buffer_size, int pos);
|
||||||
|
protected:
|
||||||
|
void OpenFile();
|
||||||
|
OggVorbis_File ogg_file;
|
||||||
|
vorbis_info *ogg_info;
|
||||||
|
};
|
225
src/sounds/SoundDecoder.cpp
Normal file
225
src/sounds/SoundDecoder.cpp
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2009-2013 Dimok
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include <gctypes.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
#include "SoundDecoder.hpp"
|
||||||
|
|
||||||
|
static const u32 FixedPointShift = 15;
|
||||||
|
static const u32 FixedPointScale = 1 << FixedPointShift;
|
||||||
|
|
||||||
|
SoundDecoder::SoundDecoder()
|
||||||
|
{
|
||||||
|
file_fd = NULL;
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundDecoder::SoundDecoder(const std::string & filepath)
|
||||||
|
{
|
||||||
|
file_fd = new CFile(filepath, CFile::ReadOnly);
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundDecoder::SoundDecoder(const u8 * buffer, int size)
|
||||||
|
{
|
||||||
|
file_fd = new CFile(buffer, size);
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundDecoder::~SoundDecoder()
|
||||||
|
{
|
||||||
|
ExitRequested = true;
|
||||||
|
while(Decoding)
|
||||||
|
usleep(1000);
|
||||||
|
|
||||||
|
//! lock unlock once to make sure it's really not decoding
|
||||||
|
Lock();
|
||||||
|
Unlock();
|
||||||
|
|
||||||
|
if(file_fd)
|
||||||
|
delete file_fd;
|
||||||
|
file_fd = NULL;
|
||||||
|
|
||||||
|
if(ResampleBuffer)
|
||||||
|
free(ResampleBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundDecoder::Init()
|
||||||
|
{
|
||||||
|
SoundType = SOUND_RAW;
|
||||||
|
SoundBlocks = 8;
|
||||||
|
SoundBlockSize = 0x4000;
|
||||||
|
ResampleTo48kHz = false;
|
||||||
|
CurPos = 0;
|
||||||
|
whichLoad = 0;
|
||||||
|
Loop = false;
|
||||||
|
EndOfFile = false;
|
||||||
|
Decoding = false;
|
||||||
|
ExitRequested = false;
|
||||||
|
SoundBuffer.SetBufferBlockSize(SoundBlockSize);
|
||||||
|
SoundBuffer.Resize(SoundBlocks);
|
||||||
|
ResampleBuffer = NULL;
|
||||||
|
ResampleRatio = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SoundDecoder::Rewind()
|
||||||
|
{
|
||||||
|
CurPos = 0;
|
||||||
|
EndOfFile = false;
|
||||||
|
file_fd->rewind();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SoundDecoder::Read(u8 * buffer, int buffer_size, int pos)
|
||||||
|
{
|
||||||
|
int ret = file_fd->read(buffer, buffer_size);
|
||||||
|
CurPos += ret;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundDecoder::EnableUpsample(void)
|
||||||
|
{
|
||||||
|
if( (ResampleBuffer == NULL)
|
||||||
|
&& IsStereo() && Is16Bit()
|
||||||
|
&& SampleRate != 32000
|
||||||
|
&& SampleRate != 48000)
|
||||||
|
{
|
||||||
|
ResampleBuffer = (u8*)memalign(32, SoundBlockSize);
|
||||||
|
ResampleRatio = ( FixedPointScale * SampleRate ) / 48000;
|
||||||
|
SoundBlockSize = ( SoundBlockSize * ResampleRatio ) / FixedPointScale;
|
||||||
|
SoundBlockSize &= ~0x03;
|
||||||
|
// set new sample rate
|
||||||
|
SampleRate = 48000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundDecoder::Upsample(s16 *src, s16 *dst, u32 nr_src_samples, u32 nr_dst_samples)
|
||||||
|
{
|
||||||
|
int timer = 0;
|
||||||
|
|
||||||
|
for(u32 i = 0, n = 0; i < nr_dst_samples; i += 2)
|
||||||
|
{
|
||||||
|
if((n+3) < nr_src_samples) {
|
||||||
|
// simple fixed point linear interpolation
|
||||||
|
dst[i] = src[n] + ( ((src[n+2] - src[n] ) * timer) >> FixedPointShift );
|
||||||
|
dst[i+1] = src[n+1] + ( ((src[n+3] - src[n+1]) * timer) >> FixedPointShift );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dst[i] = src[n];
|
||||||
|
dst[i+1] = src[n+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
timer += ResampleRatio;
|
||||||
|
|
||||||
|
if(timer >= (int)FixedPointScale) {
|
||||||
|
n += 2;
|
||||||
|
timer -= FixedPointScale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundDecoder::Decode()
|
||||||
|
{
|
||||||
|
if(!file_fd || ExitRequested || EndOfFile)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// check if we are not at the pre-last buffer (last buffer is playing)
|
||||||
|
u16 whichPlaying = SoundBuffer.Which();
|
||||||
|
if( ((whichPlaying == 0) && (whichLoad == SoundBuffer.Size()-2))
|
||||||
|
|| ((whichPlaying == 1) && (whichLoad == SoundBuffer.Size()-1))
|
||||||
|
|| (whichLoad == (whichPlaying-2)))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Decoding = true;
|
||||||
|
|
||||||
|
int done = 0;
|
||||||
|
u8 * write_buf = SoundBuffer.GetBuffer(whichLoad);
|
||||||
|
if(!write_buf)
|
||||||
|
{
|
||||||
|
ExitRequested = true;
|
||||||
|
Decoding = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ResampleTo48kHz && !ResampleBuffer)
|
||||||
|
EnableUpsample();
|
||||||
|
|
||||||
|
while(done < SoundBlockSize)
|
||||||
|
{
|
||||||
|
int ret = Read(&write_buf[done], SoundBlockSize-done, Tell());
|
||||||
|
|
||||||
|
if(ret <= 0)
|
||||||
|
{
|
||||||
|
if(Loop)
|
||||||
|
{
|
||||||
|
Rewind();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EndOfFile = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done += ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(done > 0)
|
||||||
|
{
|
||||||
|
// check if we need to resample
|
||||||
|
if(ResampleBuffer && ResampleRatio)
|
||||||
|
{
|
||||||
|
memcpy(ResampleBuffer, write_buf, done);
|
||||||
|
|
||||||
|
int src_samples = done >> 1;
|
||||||
|
int dest_samples = ( src_samples * FixedPointScale ) / ResampleRatio;
|
||||||
|
dest_samples &= ~0x01;
|
||||||
|
Upsample((s16*)ResampleBuffer, (s16*)write_buf, src_samples, dest_samples);
|
||||||
|
done = dest_samples << 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! TODO: remove this later and add STEREO support with two voices, for now we convert to MONO
|
||||||
|
if(IsStereo())
|
||||||
|
{
|
||||||
|
s16* monoBuf = (s16*)write_buf;
|
||||||
|
done = done >> 1;
|
||||||
|
|
||||||
|
for(int i = 0; i < done; i++)
|
||||||
|
monoBuf[i] = monoBuf[i << 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
DCFlushRange(write_buf, done);
|
||||||
|
SoundBuffer.SetBufferSize(whichLoad, done);
|
||||||
|
SoundBuffer.SetBufferReady(whichLoad, true);
|
||||||
|
if(++whichLoad >= SoundBuffer.Size())
|
||||||
|
whichLoad = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if next in queue needs to be filled as well and do so
|
||||||
|
if(!SoundBuffer.IsBufferReady(whichLoad))
|
||||||
|
Decode();
|
||||||
|
|
||||||
|
Decoding = false;
|
||||||
|
}
|
||||||
|
|
105
src/sounds/SoundDecoder.hpp
Normal file
105
src/sounds/SoundDecoder.hpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2010
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* for WiiXplorer 2010
|
||||||
|
***************************************************************************/
|
||||||
|
#ifndef SOUND_DECODER_HPP
|
||||||
|
#define SOUND_DECODER_HPP
|
||||||
|
|
||||||
|
#include "fs/CFile.hpp"
|
||||||
|
#include "system/CMutex.h"
|
||||||
|
#include "BufferCircle.hpp"
|
||||||
|
|
||||||
|
class SoundDecoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoundDecoder();
|
||||||
|
SoundDecoder(const std::string & filepath);
|
||||||
|
SoundDecoder(const u8 * buffer, int size);
|
||||||
|
virtual ~SoundDecoder();
|
||||||
|
virtual void Lock() { mutex.lock(); }
|
||||||
|
virtual void Unlock() { mutex.unlock(); }
|
||||||
|
virtual int Read(u8 * buffer, int buffer_size, int pos);
|
||||||
|
virtual int Tell() { return CurPos; }
|
||||||
|
virtual int Seek(int pos) { CurPos = pos; return file_fd->seek(CurPos, SEEK_SET); }
|
||||||
|
virtual int Rewind();
|
||||||
|
virtual u16 GetFormat() { return Format; }
|
||||||
|
virtual u16 GetSampleRate() { return SampleRate; }
|
||||||
|
virtual void Decode();
|
||||||
|
virtual bool IsBufferReady() { return SoundBuffer.IsBufferReady(); }
|
||||||
|
virtual u8 * GetBuffer() { return SoundBuffer.GetBuffer(); }
|
||||||
|
virtual u32 GetBufferSize() { return SoundBuffer.GetBufferSize(); }
|
||||||
|
virtual void LoadNext() { SoundBuffer.LoadNext(); }
|
||||||
|
virtual bool IsEOF() { return EndOfFile; }
|
||||||
|
virtual void SetLoop(bool l) { Loop = l; EndOfFile = false; }
|
||||||
|
virtual u8 GetSoundType() { return SoundType; }
|
||||||
|
virtual void ClearBuffer() { SoundBuffer.ClearBuffer(); whichLoad = 0; }
|
||||||
|
virtual bool IsStereo() { return (GetFormat() & CHANNELS_STEREO) != 0; }
|
||||||
|
virtual bool Is16Bit() { return ((GetFormat() & 0xFF) == FORMAT_PCM_16_BIT); }
|
||||||
|
virtual bool IsDecoding() { return Decoding; }
|
||||||
|
|
||||||
|
void EnableUpsample(void);
|
||||||
|
|
||||||
|
enum SoundFormats
|
||||||
|
{
|
||||||
|
FORMAT_PCM_16_BIT = 0x0A,
|
||||||
|
FORMAT_PCM_8_BIT = 0x19,
|
||||||
|
};
|
||||||
|
enum SoundChannels
|
||||||
|
{
|
||||||
|
CHANNELS_MONO = 0x100,
|
||||||
|
CHANNELS_STEREO = 0x200
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SoundType
|
||||||
|
{
|
||||||
|
SOUND_RAW = 0,
|
||||||
|
SOUND_MP3,
|
||||||
|
SOUND_OGG,
|
||||||
|
SOUND_WAV
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
void Init();
|
||||||
|
void Upsample(s16 *src, s16 *dst, u32 nr_src_samples, u32 nr_dst_samples);
|
||||||
|
|
||||||
|
CFile * file_fd;
|
||||||
|
BufferCircle SoundBuffer;
|
||||||
|
u8 SoundType;
|
||||||
|
u16 whichLoad;
|
||||||
|
u16 SoundBlocks;
|
||||||
|
int SoundBlockSize;
|
||||||
|
int CurPos;
|
||||||
|
bool ResampleTo48kHz;
|
||||||
|
bool Loop;
|
||||||
|
bool EndOfFile;
|
||||||
|
bool Decoding;
|
||||||
|
bool ExitRequested;
|
||||||
|
u16 Format;
|
||||||
|
u16 SampleRate;
|
||||||
|
u8 *ResampleBuffer;
|
||||||
|
u32 ResampleRatio;
|
||||||
|
CMutex mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
351
src/sounds/SoundHandler.cpp
Normal file
351
src/sounds/SoundHandler.cpp
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2010
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* for WiiXplorer 2010
|
||||||
|
***************************************************************************/
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include "common/common.h"
|
||||||
|
#include "dynamic_libs/ax_functions.h"
|
||||||
|
#include "fs/CFile.hpp"
|
||||||
|
#include "SoundHandler.hpp"
|
||||||
|
#include "WavDecoder.hpp"
|
||||||
|
#include "Mp3Decoder.hpp"
|
||||||
|
#include "OggDecoder.hpp"
|
||||||
|
|
||||||
|
SoundHandler * SoundHandler::handlerInstance = NULL;
|
||||||
|
|
||||||
|
SoundHandler::SoundHandler()
|
||||||
|
: CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 0, 0x8000)
|
||||||
|
{
|
||||||
|
Decoding = false;
|
||||||
|
ExitRequested = false;
|
||||||
|
for(u32 i = 0; i < MAX_DECODERS; ++i)
|
||||||
|
{
|
||||||
|
DecoderList[i] = NULL;
|
||||||
|
voiceList[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
resumeThread();
|
||||||
|
|
||||||
|
//! wait for initialization
|
||||||
|
while(!isThreadSuspended())
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundHandler::~SoundHandler()
|
||||||
|
{
|
||||||
|
ExitRequested = true;
|
||||||
|
ThreadSignal();
|
||||||
|
|
||||||
|
ClearDecoderList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundHandler::AddDecoder(int voice, const char * filepath)
|
||||||
|
{
|
||||||
|
if(voice < 0 || voice >= MAX_DECODERS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(DecoderList[voice] != NULL)
|
||||||
|
RemoveDecoder(voice);
|
||||||
|
|
||||||
|
DecoderList[voice] = GetSoundDecoder(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundHandler::AddDecoder(int voice, const u8 * snd, int len)
|
||||||
|
{
|
||||||
|
if(voice < 0 || voice >= MAX_DECODERS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(DecoderList[voice] != NULL)
|
||||||
|
RemoveDecoder(voice);
|
||||||
|
|
||||||
|
DecoderList[voice] = GetSoundDecoder(snd, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundHandler::RemoveDecoder(int voice)
|
||||||
|
{
|
||||||
|
if(voice < 0 || voice >= MAX_DECODERS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(DecoderList[voice] != NULL)
|
||||||
|
{
|
||||||
|
if(voiceList[voice] && voiceList[voice]->getState() != Voice::STATE_STOPPED)
|
||||||
|
{
|
||||||
|
if(voiceList[voice]->getState() != Voice::STATE_STOP)
|
||||||
|
voiceList[voice]->setState(Voice::STATE_STOP);
|
||||||
|
|
||||||
|
while(voiceList[voice]->getState() != Voice::STATE_STOPPED)
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
SoundDecoder *decoder = DecoderList[voice];
|
||||||
|
decoder->Lock();
|
||||||
|
DecoderList[voice] = NULL;
|
||||||
|
decoder->Unlock();
|
||||||
|
delete decoder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundHandler::ClearDecoderList()
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < MAX_DECODERS; ++i)
|
||||||
|
RemoveDecoder(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool CheckMP3Signature(const u8 * buffer)
|
||||||
|
{
|
||||||
|
const char MP3_Magic[][3] =
|
||||||
|
{
|
||||||
|
{'I', 'D', '3'}, //'ID3'
|
||||||
|
{0xff, 0xfe}, //'MPEG ADTS, layer III, v1.0 [protected]', 'mp3', 'audio/mpeg'),
|
||||||
|
{0xff, 0xff}, //'MPEG ADTS, layer III, v1.0', 'mp3', 'audio/mpeg'),
|
||||||
|
{0xff, 0xfa}, //'MPEG ADTS, layer III, v1.0 [protected]', 'mp3', 'audio/mpeg'),
|
||||||
|
{0xff, 0xfb}, //'MPEG ADTS, layer III, v1.0', 'mp3', 'audio/mpeg'),
|
||||||
|
{0xff, 0xf2}, //'MPEG ADTS, layer III, v2.0 [protected]', 'mp3', 'audio/mpeg'),
|
||||||
|
{0xff, 0xf3}, //'MPEG ADTS, layer III, v2.0', 'mp3', 'audio/mpeg'),
|
||||||
|
{0xff, 0xf4}, //'MPEG ADTS, layer III, v2.0 [protected]', 'mp3', 'audio/mpeg'),
|
||||||
|
{0xff, 0xf5}, //'MPEG ADTS, layer III, v2.0', 'mp3', 'audio/mpeg'),
|
||||||
|
{0xff, 0xf6}, //'MPEG ADTS, layer III, v2.0 [protected]', 'mp3', 'audio/mpeg'),
|
||||||
|
{0xff, 0xf7}, //'MPEG ADTS, layer III, v2.0', 'mp3', 'audio/mpeg'),
|
||||||
|
{0xff, 0xe2}, //'MPEG ADTS, layer III, v2.5 [protected]', 'mp3', 'audio/mpeg'),
|
||||||
|
{0xff, 0xe3}, //'MPEG ADTS, layer III, v2.5', 'mp3', 'audio/mpeg'),
|
||||||
|
};
|
||||||
|
|
||||||
|
if(buffer[0] == MP3_Magic[0][0] && buffer[1] == MP3_Magic[0][1] &&
|
||||||
|
buffer[2] == MP3_Magic[0][2])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 1; i < 13; i++)
|
||||||
|
{
|
||||||
|
if(buffer[0] == MP3_Magic[i][0] && buffer[1] == MP3_Magic[i][1])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundDecoder * SoundHandler::GetSoundDecoder(const char * filepath)
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
CFile f(filepath, CFile::ReadOnly);
|
||||||
|
if(f.size() == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
f.read((u8 *) &magic, 1);
|
||||||
|
}
|
||||||
|
while(((u8 *) &magic)[0] == 0 && f.tell() < f.size());
|
||||||
|
|
||||||
|
if(f.tell() == f.size())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
f.seek(f.tell()-1, SEEK_SET);
|
||||||
|
f.read((u8 *) &magic, 4);
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
if(magic == 0x4f676753) // 'OggS'
|
||||||
|
{
|
||||||
|
return new OggDecoder(filepath);
|
||||||
|
}
|
||||||
|
else if(magic == 0x52494646) // 'RIFF'
|
||||||
|
{
|
||||||
|
return new WavDecoder(filepath);
|
||||||
|
}
|
||||||
|
else if(CheckMP3Signature((u8 *) &magic) == true)
|
||||||
|
{
|
||||||
|
return new Mp3Decoder(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SoundDecoder(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundDecoder * SoundHandler::GetSoundDecoder(const u8 * sound, int length)
|
||||||
|
{
|
||||||
|
const u8 * check = sound;
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
while(check[0] == 0 && counter < length)
|
||||||
|
{
|
||||||
|
check++;
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(counter >= length)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
u32 * magic = (u32 *) check;
|
||||||
|
|
||||||
|
if(magic[0] == 0x4f676753) // 'OggS'
|
||||||
|
{
|
||||||
|
return new OggDecoder(sound, length);
|
||||||
|
}
|
||||||
|
else if(magic[0] == 0x52494646) // 'RIFF'
|
||||||
|
{
|
||||||
|
return new WavDecoder(sound, length);
|
||||||
|
}
|
||||||
|
else if(CheckMP3Signature(check) == true)
|
||||||
|
{
|
||||||
|
return new Mp3Decoder(sound, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SoundDecoder(sound, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundHandler::executeThread()
|
||||||
|
{
|
||||||
|
// v2 sound lib can not properly end transition audio on old firmwares
|
||||||
|
if (OS_FIRMWARE >= 400 && OS_FIRMWARE <= 410)
|
||||||
|
{
|
||||||
|
ProperlyEndTransitionAudio();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! initialize 48 kHz renderer
|
||||||
|
u32 params[3] = { 1, 0, 0 };
|
||||||
|
|
||||||
|
if(AXInitWithParams != 0)
|
||||||
|
AXInitWithParams(params);
|
||||||
|
else
|
||||||
|
AXInit();
|
||||||
|
|
||||||
|
// The problem with last voice on 500 was caused by it having priority 0
|
||||||
|
// We would need to change this priority distribution if for some reason
|
||||||
|
// we would need MAX_DECODERS > Voice::PRIO_MAX
|
||||||
|
for(u32 i = 0; i < MAX_DECODERS; ++i)
|
||||||
|
{
|
||||||
|
int priority = (MAX_DECODERS - i) * Voice::PRIO_MAX / MAX_DECODERS;
|
||||||
|
voiceList[i] = new Voice(priority); // allocate voice 0 with highest priority
|
||||||
|
}
|
||||||
|
|
||||||
|
AXRegisterFrameCallback((void*)&axFrameCallback);
|
||||||
|
|
||||||
|
|
||||||
|
u16 i = 0;
|
||||||
|
while (!ExitRequested)
|
||||||
|
{
|
||||||
|
suspendThread();
|
||||||
|
|
||||||
|
for(i = 0; i < MAX_DECODERS; ++i)
|
||||||
|
{
|
||||||
|
if(DecoderList[i] == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Decoding = true;
|
||||||
|
if(DecoderList[i])
|
||||||
|
DecoderList[i]->Lock();
|
||||||
|
if(DecoderList[i])
|
||||||
|
DecoderList[i]->Decode();
|
||||||
|
if(DecoderList[i])
|
||||||
|
DecoderList[i]->Unlock();
|
||||||
|
}
|
||||||
|
Decoding = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(u32 i = 0; i < MAX_DECODERS; ++i)
|
||||||
|
voiceList[i]->stop();
|
||||||
|
|
||||||
|
AXRegisterFrameCallback(NULL);
|
||||||
|
AXQuit();
|
||||||
|
|
||||||
|
for(u32 i = 0; i < MAX_DECODERS; ++i)
|
||||||
|
{
|
||||||
|
delete voiceList[i];
|
||||||
|
voiceList[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundHandler::axFrameCallback(void)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < MAX_DECODERS; i++)
|
||||||
|
{
|
||||||
|
Voice *voice = handlerInstance->getVoice(i);
|
||||||
|
|
||||||
|
switch (voice->getState())
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case Voice::STATE_STOPPED:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Voice::STATE_START: {
|
||||||
|
SoundDecoder * decoder = handlerInstance->getDecoder(i);
|
||||||
|
decoder->Lock();
|
||||||
|
if(decoder->IsBufferReady())
|
||||||
|
{
|
||||||
|
const u8 *buffer = decoder->GetBuffer();
|
||||||
|
const u32 bufferSize = decoder->GetBufferSize();
|
||||||
|
decoder->LoadNext();
|
||||||
|
|
||||||
|
const u8 *nextBuffer = NULL;
|
||||||
|
u32 nextBufferSize = 0;
|
||||||
|
|
||||||
|
if(decoder->IsBufferReady())
|
||||||
|
{
|
||||||
|
nextBuffer = decoder->GetBuffer();
|
||||||
|
nextBufferSize = decoder->GetBufferSize();
|
||||||
|
decoder->LoadNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
voice->play(buffer, bufferSize, nextBuffer, nextBufferSize, decoder->GetFormat() & 0xff, decoder->GetSampleRate());
|
||||||
|
|
||||||
|
handlerInstance->ThreadSignal();
|
||||||
|
|
||||||
|
voice->setState(Voice::STATE_PLAYING);
|
||||||
|
}
|
||||||
|
decoder->Unlock();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Voice::STATE_PLAYING:
|
||||||
|
if(voice->getInternState() == 1)
|
||||||
|
{
|
||||||
|
if(voice->isBufferSwitched())
|
||||||
|
{
|
||||||
|
SoundDecoder * decoder = handlerInstance->getDecoder(i);
|
||||||
|
decoder->Lock();
|
||||||
|
if(decoder->IsBufferReady())
|
||||||
|
{
|
||||||
|
voice->setNextBuffer(decoder->GetBuffer(), decoder->GetBufferSize());
|
||||||
|
decoder->LoadNext();
|
||||||
|
handlerInstance->ThreadSignal();
|
||||||
|
}
|
||||||
|
else if(decoder->IsEOF())
|
||||||
|
{
|
||||||
|
voice->setState(Voice::STATE_STOP);
|
||||||
|
}
|
||||||
|
decoder->Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
voice->setState(Voice::STATE_STOPPED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Voice::STATE_STOP:
|
||||||
|
if(voice->getInternState() != 0)
|
||||||
|
voice->stop();
|
||||||
|
voice->setState(Voice::STATE_STOPPED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
78
src/sounds/SoundHandler.hpp
Normal file
78
src/sounds/SoundHandler.hpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2010
|
||||||
|
* by Dimok
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* for WiiXplorer 2010
|
||||||
|
***************************************************************************/
|
||||||
|
#ifndef SOUNDHANDLER_H_
|
||||||
|
#define SOUNDHANDLER_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <gctypes.h>
|
||||||
|
#include "system/CThread.h"
|
||||||
|
#include "SoundDecoder.hpp"
|
||||||
|
#include "Voice.h"
|
||||||
|
|
||||||
|
#define MAX_DECODERS 16 // can be increased up to 96
|
||||||
|
|
||||||
|
class SoundHandler : public CThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static SoundHandler * instance() {
|
||||||
|
if (!handlerInstance)
|
||||||
|
handlerInstance = new SoundHandler();
|
||||||
|
return handlerInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DestroyInstance() { delete handlerInstance; handlerInstance = NULL; }
|
||||||
|
|
||||||
|
void AddDecoder(int voice, const char * filepath);
|
||||||
|
void AddDecoder(int voice, const u8 * snd, int len);
|
||||||
|
void RemoveDecoder(int voice);
|
||||||
|
|
||||||
|
SoundDecoder * getDecoder(int i) { return ((i < 0 || i >= MAX_DECODERS) ? NULL : DecoderList[i]); };
|
||||||
|
Voice * getVoice(int i) { return ((i < 0 || i >= MAX_DECODERS) ? NULL : voiceList[i]); };
|
||||||
|
|
||||||
|
void ThreadSignal() { resumeThread(); };
|
||||||
|
bool IsDecoding() { return Decoding; };
|
||||||
|
protected:
|
||||||
|
SoundHandler();
|
||||||
|
~SoundHandler();
|
||||||
|
|
||||||
|
static void axFrameCallback(void);
|
||||||
|
|
||||||
|
void executeThread(void);
|
||||||
|
void ClearDecoderList();
|
||||||
|
|
||||||
|
SoundDecoder * GetSoundDecoder(const char * filepath);
|
||||||
|
SoundDecoder * GetSoundDecoder(const u8 * sound, int length);
|
||||||
|
|
||||||
|
static SoundHandler * handlerInstance;
|
||||||
|
|
||||||
|
bool Decoding;
|
||||||
|
bool ExitRequested;
|
||||||
|
|
||||||
|
Voice * voiceList[MAX_DECODERS];
|
||||||
|
SoundDecoder * DecoderList[MAX_DECODERS];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user