Add first commit on wut branch

This commit is contained in:
Maschell 2018-06-21 20:44:58 +02:00
parent 21d120bc82
commit e8f1942db4
101 changed files with 8082 additions and 8678 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
build/*
release/*
libgui.cbp

View File

@ -6,14 +6,14 @@ dist: trusty
env:
global:
- DEVKITPRO=/opt/devkitpro
- DEVKITPRO=/opt/devkitpro
- WUT_ROOT=/opt/devkitpro/wut
- DEVKITPPC=/opt/devkitpro/devkitPPC
- PORTLIBREPOS=$HOME/portlibrepos
cache:
directories:
- "$HOME/.local"
- "$PORTLIBREPOS"
- "$DEVKITPRO"
addons:
@ -27,17 +27,23 @@ before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman.deb -O /tmp/devkitpro-pacman.deb; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo dpkg -i /tmp/devkitpro-pacman.deb; fi
- yes | sudo dkp-pacman -Syu devkitPPC --needed
- wget $(curl -s https://api.github.com/repos/decaf-emu/wut/releases/latest | grep 'browser_' | grep 'linux' | cut -d\" -f4)
install:
- 7z x -y $(ls | grep "linux") -o${WUT_ROOT}
- 7z x -y ./libs/portlibs.zip -o${DEVKITPRO}
- cd $PORTLIBREPOS
- ((git clone https://github.com/Maschell/dynamic_libs.git -b lib && (7z x -y ./dynamic_libs/libs/portlibs.zip -o${DEVKITPRO})) || (cd dynamic_libs && git pull))
- (git clone https://github.com/Maschell/libutils.git || (cd libutils && git pull))
- (cd dynamic_libs && ((make -j8 | grep -c "built ... ") && make install && echo "installed" ) || (echo "no need for make install" && make))
- (cd libutils && ((make -j8 | grep -c "built ... ") && make install && echo "installed" ) || (echo "no need for make install" && make))
- git clone https://github.com/Maschell/libutils.git -b wut
- cd libutils
- mkdir build && cd build
- cmake -DCMAKE_TOOLCHAIN_FILE=$WUT_ROOT/share/wut.toolchain.cmake -DCMAKE_INSTALL_PREFIX=$WUT_ROOT ../
- make install
- cd $PORTLIBREPOS
before_script:
- cd $TRAVIS_BUILD_DIR/
script:
- make && make install
- mkdir build && cd build
- cmake -DCMAKE_TOOLCHAIN_FILE=$WUT_ROOT/share/wut.toolchain.cmake -DCMAKE_INSTALL_PREFIX=$WUT_ROOT ../
- make install

31
CMakeLists.txt Normal file
View File

@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.2)
project(gui)
include("${WUT_ROOT}/share/wut.cmake" REQUIRED)
file(GLOB_RECURSE SOURCE_FILES *.c *.cpp)
file(GLOB_RECURSE HEADER_FILES *.h*)
add_library(gui STATIC ${SOURCE_FILES} ${HEADER_FILES})
target_link_libraries(gui
utilswut)
include_directories("$ENV{WUT_ROOT}/include/libutils" REQUIRED)
include_directories("$ENV{DEVKITPRO}/portlibs/ppc/include" REQUIRED)
include_directories("$ENV{DEVKITPRO}/portlibs/ppc/include/freetype2" REQUIRED)
target_include_directories(gui PUBLIC "include")
target_include_directories(gui PRIVATE "src")
wut_enable_stdcpp(gui)
wut_default_malloc(gui)
target_include_directories(gui PUBLIC "include")
target_compile_options(gui PUBLIC "-D__LOGGING__")
install(TARGETS gui
ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/
DESTINATION "${CMAKE_INSTALL_PREFIX}/include/libgui"
FILES_MATCHING PATTERN "*.h*")

151
Makefile
View File

@ -1,151 +0,0 @@
DO_LOGGING := 0
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC)
endif
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
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
include $(DEVKITPPC)/base_rules
#---------------------------------------------------------------------------------
# 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
# DATA is a list of directories containing binary files
# LIBDIR is where the built library will be placed
# all directories are relative to this makefile
#---------------------------------------------------------------------------------
BUILD ?= release
SOURCES := source \
source/gui \
source/resources \
source/sounds \
source/video \
source/video/shaders
INCLUDES := source \
include
DATA :=
LIB := lib
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -Os -Wall -D__wiiu__ -D_GNU_SOURCE $(MACHDEP) $(INCLUDE)
CXXFLAGS = $(CFLAGS)
ifeq ($(DO_LOGGING), 1)
CFLAGS += -D__LOGGING__
CXXFLAGS += -D__LOGGING__
endif
ASFLAGS := -mregnames
export WIIUBIN := $(LIB)/libgui.a
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lutils -ldynamiclibs -lfreetype -lgd -lpng -ljpeg -lz -lmad -lvorbisidec
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS :=
#---------------------------------------------------------------------------------
# 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 TOPDIR ?= $(CURDIR)/..
export DEPSDIR := $(CURDIR)/$(BUILD)
export INCLUDEDIR := $(PORTLIBS)/include/libgui
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
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)/*.*)))
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) $(sFILES:.s=.o)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) -I$(LIBOGC_INC) \
-I$(CURDIR)/$(BUILD) -I$(PORTLIBS)/include \
-I$(PORTLIBS)/include/freetype2 -I$(PORTLIBS)/include/libutils
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) $(PORTLIBS)/lib
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr debug release $(LIB) include
all: $(WIIUBIN)
install:
@cp $(BUILD)/lib/libgui.a $(PORTLIBS)/lib
@mkdir -p $(INCLUDEDIR)/gui/
@mkdir -p $(INCLUDEDIR)/resources/
@mkdir -p $(INCLUDEDIR)/sounds/
@mkdir -p $(INCLUDEDIR)/video/shaders
@cp source/gui/*.h $(INCLUDEDIR)/gui/
@cp source/resources/*.h $(INCLUDEDIR)/resources/
@cp source/sounds/*.h $(INCLUDEDIR)/sounds/
@cp source/sounds/*.hpp $(INCLUDEDIR)/sounds/
@cp source/video/*.h $(INCLUDEDIR)/video/
@cp source/video/shaders/*.h $(INCLUDEDIR)/video/shaders/
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(WIIUBIN) : $(OFILES) $(LIB)
@rm -f "$(WIIUBIN)"
@$(AR) rcs "$(WIIUBIN)" $(OFILES)
@echo built ... $(notdir $@)
$(LIB):
mkdir $(LIB)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@ -1,35 +1,26 @@
# libgui
[![Build Status](https://travis-ci.org/Maschell/libgui.svg?branch=master)](https://travis-ci.org/Maschell/libgui)
[![Build Status](https://travis-ci.org/Maschell/libgui.svg?branch=wut)](https://travis-ci.org/Maschell/libgui/tree/wut)
## Usage
Following steps are required for initialization:
```C
InitOSFunctionPointers(); // Load OS functions
InitPadScoreFunctionPointers();
InitVPadFunctionPointers(); // Input functions for GUI control
InitFSFunctionPointers(); // To load file from the SD Card
InitGX2FunctionPointers(); // For rendering
InitAXFunctionPointers(); // For sound
mount_sd_fat("sd"); // Mounting the SD Card
memoryInitialize(); // Initialize memory management
//DO GUI STUFF HERE!
memoryRelease();
unmount_sd_fat("sd");
```
Link the application with:
```Makefile
-lgui -lutils -ldynamiclibs -lfreetype -lgd -lpng -ljpeg -lz -lmad -lvorbisidec
-lgui -lutilswut -lfreetype -lgd -lpng -ljpeg -lz -lmad -lvorbisidec
```
You also need to add the include path to your Makefile. Example:
```Makefile
export INCLUDE := [...] -I$(PORTLIBS)/include/freetype2 \
-I$(PORTLIBS)/include/libgui \
-I$(WUT_ROOT)/include/libgui \
-I$(PORTLIBS)/include
```
@ -39,10 +30,11 @@ TODO: provide more information
To be able to use libgui, you need to install the following dependencies:
- Application needs to be loaded from the [homebrew_launcher](https://github.com/dimok789/homebrew_launcher)
- [libutils](https://github.com/Maschell/libutils) for common functions.
- [dynamic_libs](https://github.com/Maschell/dynamic_libs/tree/lib) for access to the functions.
- [libutils](https://github.com/Maschell/libutils/tree/wut) (WUT branch) for common functions.
- [wut](https://github.com/decaf-emu/wut)
And other portable libraries that can be found in the "libs" folder of this repository. Extract the "portlibs.zip" into your devkitPro directory.
And other portable libraries that can be found in the "libs" folder of this repository. Extract the "portlibs.zip" into your devkitPro directory.
`7z x -y ./libs/portlibs.zip -o${DEVKITPRO}`
This package includes:
- freetype2

View File

@ -34,17 +34,20 @@
#include <wchar.h>
#include <map>
#include <gui/gx2_ext.h>
#include <gx2/sampler.h>
#include <gx2/texture.h>
#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_
{
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. */
@ -61,8 +64,7 @@ typedef struct ftgxCharData_
*
* Offset structure which hold both a maximum and minimum value.
*/
typedef struct ftgxDataOffset_
{
typedef struct ftgxDataOffset_ {
int16_t ascender; /**< Maximum data offset. */
int16_t descender; /**< Minimum data offset. */
int16_t max; /**< Maximum data offset. */
@ -93,7 +95,9 @@ typedef struct ftgxDataOffset_ ftgxDataOffset;
#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 };
static const GX2ColorF32 ftgxWhite = (GX2ColorF32) {
1.0f, 1.0f, 1.0f, 1.0f
};
//! forward declaration
@ -108,48 +112,46 @@ class CVideo;
* 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;
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;
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. */
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);
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 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);
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();
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 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);
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);
static wchar_t* charToWideChar(const char* p);
static char* wideCharToUTF8(const wchar_t* strChar);
};
#endif /* FREETYPEGX_H_ */

View File

@ -1,11 +1,10 @@
#ifndef _GAME_BG_IMAGE_H_
#define _GAME_BG_IMAGE_H_
#include "GuiImageAsync.h"
#include "video/shaders/Shader3D.h"
#include <gui/GuiImageAsync.h>
#include <video/shaders/Shader3D.h>
class GameBgImage : public GuiImageAsync
{
class GameBgImage : public GuiImageAsync {
public:
GameBgImage(const std::string & filename, GuiImageData *preloadImage);
virtual ~GameBgImage();

View File

@ -1,11 +1,10 @@
#ifndef _GRID_BACKGROUND_H_
#define _GRID_BACKGROUND_H_
#include "GuiImage.h"
#include "video/shaders/Shader.h"
#include <gui/GuiImage.h>
#include <video/shaders/Shader.h>
class GridBackground : public GuiImage
{
class GridBackground : public GuiImage {
public:
GridBackground(GuiImageData *imgData);
virtual ~GridBackground();

View File

@ -17,27 +17,27 @@
#ifndef __GUI_H
#define __GUI_H
#include "FreeTypeGX.h"
#include "GameBgImage.h"
#include "GridBackground.h"
#include "GuiButton.h"
#include "GuiCheckBox.h"
#include "GuiController.h"
#include "GuiDragListener.h"
#include "GuiElement.h"
#include "GuiFrame.h"
#include "GuiImage.h"
#include "GuiImageAsync.h"
#include "GuiImageData.h"
#include "GuiParticleImage.h"
#include "GuiSelectBox.h"
#include "GuiSound.h"
#include "GuiSwitch.h"
#include "GuiText.h"
#include "GuiToggle.h"
#include "GuiTrigger.h"
#include "GuiScrollbar.h"
#include "VPadController.h"
#include "WPadController.h"
#include <gui/FreeTypeGX.h>
#include <gui/GameBgImage.h>
#include <gui/GridBackground.h>
#include <gui/GuiButton.h>
#include <gui/GuiCheckBox.h>
#include <gui/GuiController.h>
#include <gui/GuiDragListener.h>
#include <gui/GuiElement.h>
#include <gui/GuiFrame.h>
#include <gui/GuiImage.h>
#include <gui/GuiImageAsync.h>
#include <gui/GuiImageData.h>
#include <gui/GuiParticleImage.h>
#include <gui/GuiSelectBox.h>
#include <gui/GuiSound.h>
#include <gui/GuiSwitch.h>
#include <gui/GuiText.h>
#include <gui/GuiToggle.h>
#include <gui/GuiTrigger.h>
#include <gui/GuiScrollbar.h>
#include <gui/VPadController.h>
#include <gui/WPadController.h>
#endif

117
include/gui/GuiButton.h Normal file
View 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 <gui/GuiElement.h>
#include <gui/GuiText.h>
#include <gui/GuiController.h>
#include <gui/GuiImage.h>
#include <gui/GuiSound.h>
#include <gui/GuiTrigger.h>
#include <gui/gx2_ext.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(float w, float 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, int32_t 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, int32_t 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, int32_t 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, int32_t 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, int32_t 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 int32_t 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

View File

@ -17,32 +17,32 @@
#ifndef GUI_CHECKBOX_H_
#define GUI_CHECKBOX_H_
#include "GuiToggle.h"
#include "GuiImage.h"
#include "GuiImageData.h"
#include <gui/GuiToggle.h>
#include <gui/GuiImage.h>
#include <gui/GuiImageData.h>
//!A simple CheckBox
class GuiCheckBox : public GuiToggle{
public:
//!Constructor
//!\param checked Checked
GuiCheckBox(GuiImage * background, bool checked, f32 width = 0.0f,f32 height= 0.0f);
class GuiCheckBox : public GuiToggle {
public:
//!Constructor
//!\param checked Checked
GuiCheckBox(GuiImage * background, bool checked, float width = 0.0f,float height= 0.0f);
//!Destructor
virtual ~GuiCheckBox();
//!Destructor
virtual ~GuiCheckBox();
void setImageBackground(GuiImage* img);
void setImageBackground(GuiImage* img);
void setImageSelected(GuiImage* img);
void setImageSelected(GuiImage* img);
void setImageHighlighted(GuiImage* img);
void setImageHighlighted(GuiImage* img);
protected:
GuiImage * backgroundImg = NULL;
GuiImage * selectedImg = NULL;
GuiImage * highlightedImg = NULL;
protected:
GuiImage * backgroundImg = NULL;
GuiImage * selectedImg = NULL;
GuiImage * highlightedImg = NULL;
void update(GuiController * c);
void update(GuiController * c);
};
#endif

View File

@ -18,20 +18,17 @@
#define GUI_CONTROLLER_H_
#include <string.h>
#include "GuiTrigger.h"
#include <gui/GuiTrigger.h>
class GuiController
{
class GuiController {
public:
//!Constructor
GuiController(s32 channel)
: chan(channel)
{
GuiController(int32_t channel)
: chan(channel) {
memset(&lastData, 0, sizeof(lastData));
memset(&data, 0, sizeof(data));
switch(chan)
{
switch(chan) {
default:
case GuiTrigger::CHANNEL_1:
chanIdx = 0;
@ -54,22 +51,21 @@ public:
//!Destructor
virtual ~GuiController() {}
virtual bool update(s32 width, s32 height) = 0;
virtual bool update(int32_t width, int32_t height) = 0;
typedef struct
{
u32 buttons_h;
u32 buttons_d;
u32 buttons_r;
typedef struct {
uint32_t buttons_h;
uint32_t buttons_d;
uint32_t buttons_r;
bool validPointer;
bool touched;
float pointerAngle;
s32 x;
s32 y;
int32_t x;
int32_t y;
} PadData;
s32 chan;
s32 chanIdx;
int32_t chan;
int32_t chanIdx;
PadData data;
PadData lastData;

View File

@ -0,0 +1,52 @@
/****************************************************************************
* 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 <gui/GuiElement.h>
#include <gui/GuiController.h>
#include <gui/GuiTrigger.h>
#include <gui/GuiButton.h>
class GuiDragListener : public GuiElement {
public:
//!Constructor
//!\param w Width
//!\param h Height
GuiDragListener(float w,float h);
//!Destructor
virtual ~GuiDragListener();
void setState(int32_t i, int32_t c);
//!Set a new GuiTrigger for the element
//!\param i Index of trigger array to set
//!\param t Pointer to GuiTrigger
void setTrigger(GuiTrigger * t, int32_t 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 *,int32_t,int32_t> dragged;
protected:
static const int32_t iMaxGuiTriggers = 10;
GuiTrigger * trigger[iMaxGuiTriggers]; //!< GuiTriggers (input actions) that this element responds to
};
#endif

542
include/gui/GuiElement.h Normal file
View File

@ -0,0 +1,542 @@
/****************************************************************************
* 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 <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <wchar.h>
#include <math.h>
#include <gui/gx2_ext.h>
#include <gui/sigslot.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <system/AsyncDeleter.h>
#include <utils/logger.h>
#include <resources/Resources.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 float 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 float getTop();
//!Gets the current Z coordinate of the element
//!\return Z coordinate
virtual float getDepth() {
float zParent = 0.0f;
if(parentElement)
zParent = parentElement->getDepth();
return zParent+zoffset;
}
virtual float getCenterX(void) {
float pCenterX = 0.0f;
if(parentElement)
pCenterX = parentElement->getCenterX();
pCenterX += xoffset + xoffsetDyn;
if(alignment & ALIGN_LEFT) {
float pWidth = 0.0f;
float 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) {
float pWidth = 0.0f;
float pScale = 0.0f;
if(parentElement) {
pWidth = parentElement->getWidth();
pScale = parentElement->getScaleX();
}
pCenterX += pWidth * 0.5f * pScale - width * 0.5f * getScaleX();
}
return pCenterX;
}
virtual float getCenterY(void) {
float pCenterY = 0.0f;
if(parentElement)
pCenterY = parentElement->getCenterY();
pCenterY += yoffset + yoffsetDyn;
if(alignment & ALIGN_TOP) {
float pHeight = 0.0f;
float pScale = 0.0f;
if(parentElement) {
pHeight = parentElement->getHeight();
pScale = parentElement->getScaleY();
}
pCenterY += pHeight * 0.5f * pScale - getHeight() * 0.5f * getScaleY();
} else if(alignment & ALIGN_BOTTOM) {
float pHeight = 0.0f;
float pScale = 0.0f;
if(parentElement) {
pHeight = parentElement->getHeight();
pScale = parentElement->getScaleY();
}
pCenterY -= pHeight * 0.5f * pScale - getHeight() * 0.5f * getScaleY();
}
return pCenterY;
}
//!Gets elements xoffset
virtual float getOffsetX() {
return xoffset;
}
//!Gets elements yoffset
virtual float getOffsetY() {
return yoffset;
}
//!Gets the current width of the element. Does not currently consider the scale
//!\return width
virtual float getWidth() {
return width;
};
//!Gets the height of the element. Does not currently consider the scale
//!\return height
virtual float getHeight() {
return height;
}
//!Sets the size (width/height) of the element
//!\param w Width of element
//!\param h Height of element
virtual void setSize(float w, float 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(int32_t s, int32_t c = -1) {
if(c >= 0 && c < 4) {
state[c] |= s;
} else {
for(int32_t i = 0; i < 4; i++)
state[i] |= s;
}
stateChan = c;
stateChanged(this, s, c);
}
virtual void clearState(int32_t s, int32_t c = -1) {
if(c >= 0 && c < 4) {
state[c] &= ~s;
} else {
for(int32_t i = 0; i < 4; i++)
state[i] &= ~s;
}
stateChan = c;
stateChanged(this, s, c);
}
virtual bool isStateSet(int32_t s, int32_t c = -1) const {
if(c >= 0 && c < 4) {
return (state[c] & s) != 0;
} else {
for(int32_t i = 0; i < 4; i++)
if((state[i] & s) != 0)
return true;
return false;
}
}
//!Gets the element's current state
//!\return state
virtual int32_t getState(int32_t 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 int32_t getStateChan() {
return stateChan;
};
//!Resets the element's state to STATE_DEFAULT
virtual void resetState() {
for(int32_t i = 0; i < 4; i++)
state[i] = STATE_DEFAULT;
stateChan = -1;
}
//!Sets the element's alpha value
//!\param a alpha value
virtual void setAlpha(float a) {
alpha = a;
}
//!Gets the element's alpha value
//!Considers alpha, alphaDyn, and the parent element's getAlpha() value
//!\return alpha
virtual float getAlpha() {
float 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(int32_t e, int32_t a, int32_t 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(int32_t e, int32_t a, int32_t 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 int32_t 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(float x, float 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(float x, float 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(float x, float y, float z) {
xoffset = x;
yoffset = y;
zoffset = z;
}
//!Gets whether or not the element is in STATE_SELECTED
//!\return true if selected, false otherwise
virtual int32_t 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(int32_t a) {
alignment = a;
}
//!Gets the element's alignment
virtual int32_t getAlignment() const {
return alignment;
}
//!Angle of the object
virtual void setAngle(float a) {
angle = a;
}
//!Angle of the object
virtual float getAngle() const {
float 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 {
int32_t x;
int32_t 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 *, int32_t, int32_t> 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)
float width; //!< Element width
float height; //!< Element height
float xoffset; //!< Element X offset
float yoffset; //!< Element Y offset
float zoffset; //!< Element Z offset
float alpha; //!< Element alpha value (0-255)
float angle; //!< Angle of the object (0-360)
float scaleX; //!< Element scale (1 = 100%)
float scaleY; //!< Element scale (1 = 100%)
float scaleZ; //!< Element scale (1 = 100%)
int32_t alignment; //!< Horizontal element alignment, respective to parent element
int32_t state[4]; //!< Element state (DEFAULT, SELECTED, CLICKED, DISABLED)
int32_t stateChan; //!< Which controller channel is responsible for the last change in state
GuiElement * parentElement; //!< Parent element
//! TODO: Move me to some Animator class
int32_t xoffsetDyn; //!< Element X offset, dynamic (added to xoffset value for animation effects)
int32_t yoffsetDyn; //!< Element Y offset, dynamic (added to yoffset value for animation effects)
float alphaDyn; //!< Element alpha, dynamic (multiplied by alpha value for blending/fading effects)
float scaleDyn; //!< Element scale, dynamic (multiplied by alpha value for blending/fading effects)
int32_t effects; //!< Currently enabled effect(s). 0 when no effects are enabled
int32_t effectAmount; //!< Effect amount. Used by different effects for different purposes
int32_t effectTarget; //!< Effect target amount. Used by different effects for different purposes
int32_t effectsOver; //!< Effects to enable when wiimote cursor is over this element. Copied to effects variable on over event
int32_t effectAmountOver; //!< EffectAmount to set when wiimote cursor is over this element
int32_t effectTargetOver; //!< EffectTarget to set when wiimote cursor is over this element
};
#endif

100
include/gui/GuiFrame.h Normal file
View File

@ -0,0 +1,100 @@
/****************************************************************************
* 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 <gui/GuiElement.h>
#include <gui/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(float w, float 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, uint32_t 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(uint32_t index) const;
//!Returns the size of the list of elements
//!\return The size of the current element list
uint32_t 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(int32_t s, int32_t c = -1);
void clearState(int32_t s, int32_t c = -1);
//!Gets the index of the GuiElement inside the window that is currently selected
//!\return index of selected GuiElement
int32_t 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

View File

@ -17,16 +17,15 @@
#ifndef GUI_IMAGE_H_
#define GUI_IMAGE_H_
#include "video/shaders/Shader.h"
#include "GuiElement.h"
#include "GuiImageData.h"
#include <video/shaders/Shader.h>
#include <gui/GuiElement.h>
#include <gui/GuiImageData.h>
#include <gui/gx2_ext.h>
//!Display, manage, and manipulate images in the GUI
class GuiImage : public GuiElement
{
class GuiImage : public GuiElement {
public:
enum ImageTypes
{
enum ImageTypes {
IMAGE_TEXTURE,
IMAGE_COLOR
};
@ -39,72 +38,76 @@ public:
//!\param w Image width
//!\param h Image height
//!\param c Array with 4 x image color (BL, BR, TL, TR)
GuiImage(s32 w, s32 h, const GX2Color & c, s32 imgType = IMAGE_COLOR);
GuiImage(s32 w, s32 h, const GX2Color * c, u32 colorCount = 1, s32 imgType = IMAGE_COLOR);
GuiImage(int32_t w, int32_t h, const GX2Color & c, int32_t imgType = IMAGE_COLOR);
GuiImage(int32_t w, int32_t h, const GX2Color * c, uint32_t colorCount = 1, int32_t 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(s32 t) { tileHorizontal = t; }
void setTileHorizontal(int32_t t) {
tileHorizontal = t;
}
//!Sets the number of times to draw the image vertically
//!\param t Number of times to draw the image
void setTileVertical(s32 t) { tileVertical = t; }
void setTileVertical(int32_t 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; }
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(s32 x, s32 y);
GX2Color getPixel(int32_t x, int32_t 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(s32 x, s32 y, const GX2Color & color);
void setPixel(int32_t x, int32_t y, const GX2Color & color);
//!Change ImageColor
void setImageColor(const GX2Color & c, s32 idx = -1);
void setImageColor(const GX2Color & c, int32_t idx = -1);
//!Change ImageColor
void setSize(s32 w, s32 h);
void setSize(int32_t w, int32_t h);
void setPrimitiveVertex(s32 prim, const f32 *pos, const f32 *tex, u32 count);
void setPrimitiveVertex(int32_t prim, const float *pos, const float *tex, uint32_t count);
void setBlurDirection(u8 dir, f32 value)
{
void setBlurDirection(uint8_t dir, float value) {
if(dir < 2) {
blurDirection[dir] = value;
}
}
void setColorIntensity(const glm::vec4 & col)
{
void setColorIntensity(const glm::vec4 & col) {
colorIntensity = col;
}
protected:
void internalInit(s32 w, s32 h);
void internalInit(int32_t w, int32_t h);
s32 imgType; //!< Type of image data (IMAGE_TEXTURE, IMAGE_COLOR, IMAGE_DATA)
int32_t imgType; //!< Type of image data (IMAGE_TEXTURE, IMAGE_COLOR, IMAGE_DATA)
GuiImageData * imageData; //!< Poiner to image data. May be shared with GuiImageData data
s32 tileHorizontal; //!< Number of times to draw (tile) the image horizontally
s32 tileVertical; //!< Number of times to draw (tile) the image vertically
int32_t tileHorizontal; //!< Number of times to draw (tile) the image horizontally
int32_t tileVertical; //!< Number of times to draw (tile) the image vertically
//! Internally used variables for rendering
u8 *colorVtxs;
u32 colorCount;
uint8_t *colorVtxs;
uint32_t colorCount;
bool colorVtxsDirty;
glm::vec3 positionOffsets;
glm::vec3 scaleFactor;
glm::vec4 colorIntensity;
f32 imageAngle;
float imageAngle;
glm::vec3 blurDirection;
const f32 * posVtxs;
const f32 * texCoords;
u32 vtxCount;
s32 primitive;
const float * posVtxs;
const float * texCoords;
uint32_t vtxCount;
int32_t primitive;
};
#endif

View 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 _GUIIMAGEASYNC_H_
#define _GUIIMAGEASYNC_H_
#include <vector>
#include <gui/GuiImage.h>
#include <system/CThread.h>
#include <system/CMutex.h>
class GuiImageAsync : public GuiImage {
public:
GuiImageAsync(const uint8_t *imageBuffer, const uint32_t & 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 uint8_t *imgBuffer;
const uint32_t 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 uint32_t threadRefCounter;
static GuiImageAsync * pInUse;
static bool bExitRequested;
};
#endif /*_GUIIMAGEASYNC_H_*/

View File

@ -17,51 +17,59 @@
#ifndef GUI_IMAGEDATA_H_
#define GUI_IMAGEDATA_H_
#include <gd.h>
#include <dynamic_libs/gx2_functions.h>
#include <system/AsyncDeleter.h>
#include <gui/gx2_ext.h>
#include <gx2/texture.h>
class GuiImageData : public AsyncDeleter::Element
{
class GuiImageData : public AsyncDeleter::Element {
public:
//!Constructor
GuiImageData();
//!\param img Image data
//!\param imgSize The image size
GuiImageData(const u8 * img, s32 imgSize, s32 textureClamp = GX2_TEX_CLAMP_CLAMP, s32 textureFormat = GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM);
GuiImageData(const uint8_t * img, int32_t imgSize, GX2TexClampMode textureClamp = GX2_TEX_CLAMP_MODE_CLAMP, GX2SurfaceFormat textureFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8);
//!Destructor
virtual ~GuiImageData();
//!Load image from buffer
//!\param img Image data
//!\param imgSize The image size
void loadImage(const u8 * img, s32 imgSize, s32 textureClamp = GX2_TEX_CLAMP_CLAMP, s32 textureFormat = GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM);
void loadImage(const uint8_t * img, int32_t imgSize, GX2TexClampMode textureClamp = GX2_TEX_CLAMP_MODE_CLAMP, GX2SurfaceFormat textureFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8);
//! getter functions
const GX2Texture * getTexture() const { return texture; };
const GX2Sampler * getSampler() const { return sampler; };
const GX2Texture * getTexture() const {
return texture;
};
const GX2Sampler * getSampler() const {
return sampler;
};
//!Gets the image width
//!\return image width
s32 getWidth() const { if(texture) return texture->surface.width; else return 0; };
int32_t getWidth() const {
if(texture) return texture->surface.width;
else return 0;
};
//!Gets the image height
//!\return image height
s32 getHeight() const { if(texture) return texture->surface.height; else return 0; };
int32_t 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);
void gdImageToUnormR8G8B8A8(gdImagePtr gdImg, uint32_t *imgBuffer, uint32_t width, uint32_t height, uint32_t pitch);
void gdImageToUnormR5G6B5(gdImagePtr gdImg, uint16_t *imgBuffer, uint32_t width, uint32_t height, uint32_t pitch);
GX2Texture *texture;
GX2Sampler *sampler;
enum eMemoryTypes
{
enum eMemoryTypes {
eMemTypeMEM2,
eMemTypeMEM1,
eMemTypeMEMBucket
};
u8 memoryType;
uint8_t memoryType;
};
#endif

View File

@ -17,31 +17,29 @@
#ifndef _GUI_PARTICLE_IMAGE_H_
#define _GUI_PARTICLE_IMAGE_H_
#include "GuiImage.h"
#include <gui/GuiImage.h>
class GuiParticleImage : public GuiImage, public sigslot::has_slots<>
{
class GuiParticleImage : public GuiImage, public sigslot::has_slots<> {
public:
GuiParticleImage(s32 w, s32 h, u32 particleCount, f32 minRadius, f32 maxRadius, f32 minSpeed, f32 maxSpeed);
GuiParticleImage(int32_t w, int32_t h, uint32_t particleCount, float minRadius, float maxRadius, float minSpeed, float maxSpeed);
virtual ~GuiParticleImage();
void draw(CVideo *pVideo);
private:
f32 *posVertexs;
u8 *colorVertexs;
float *posVertexs;
uint8_t *colorVertexs;
f32 minRadius;
f32 maxRadius;
f32 minSpeed;
f32 maxSpeed;
float minRadius;
float maxRadius;
float minSpeed;
float maxSpeed;
typedef struct
{
typedef struct {
glm::vec3 position;
glm::vec4 colors;
f32 radius;
f32 speed;
f32 direction;
float radius;
float speed;
float direction;
} Particle;
std::vector<Particle> particles;

134
include/gui/GuiScrollbar.h Normal file
View File

@ -0,0 +1,134 @@
/***************************************************************************
* 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 GUI_SCROLLBAR_HPP_
#define GUI_SCROLLBAR_HPP_
#include <gui/GuiElement.h>
#include <gui/GuiButton.h>
class GuiScrollbar : public GuiElement, public sigslot::has_slots<> {
public:
GuiScrollbar(int32_t height);
virtual ~GuiScrollbar();
void ScrollOneUp();
void ScrollOneDown();
int32_t GetSelectedItem() {
return SelItem;
}
int32_t GetSelectedIndex() {
return SelInd;
}
void draw(CVideo * video);
void update(GuiController * t);
//! Signals
sigslot::signal2<int32_t, int32_t> listChanged;
//! Slots
void SetScrollSpeed(int32_t speed) {
ScrollSpeed = speed;
};
void SetPageSize(int32_t size);
void SetRowSize(int32_t size);
void SetSelectedItem(int32_t pos);
void SetSelectedIndex(int32_t pos);
void SetEntrieCount(int32_t cnt);
void setSoundClick(GuiSound * snd) {
clickSound = snd;
arrowUpBtn->setSoundClick(snd);
arrowDownBtn->setSoundClick(snd);
}
void setImageScrollbarLine(GuiImage * img) {
if(img) {
scrollbarLineImage = img;
scrollbarLineImage->setParent(this);
scrollbarLineImage->setParent(this);
scrollbarLineImage->setAlignment(ALIGN_CENTER | ALIGN_MIDDLE);
scrollbarLineImage->setPosition(0, 0);
}
}
void setImageArrowDown(GuiImage * img) {
if(img) {
arrowDownImage = img;
arrowDownBtn->setSize(img->getWidth(), img->getHeight());
arrowDownBtn->setImage(img);
}
}
void setImageArrowUp(GuiImage * img) {
if(img) {
arrowUpImage = img;
arrowUpBtn->setSize(img->getWidth(), img->getHeight());
arrowUpBtn->setImage(img);
}
}
void setImageScrollbarBox(GuiImage * img) {
if(img) {
scrollbarBoxImage = img;
scrollbarBoxBtn->setSize(img->getWidth(), height);
scrollbarBoxBtn->setImage(img);
width = img->getWidth();
MaxHeight = height * 0.5f - (img ? (img->getHeight() * 0.5f) : 0) - (arrowUpImage ? arrowUpImage->getHeight() : 0);
MinHeight = -height * 0.5f + (img ? (img->getHeight() * 0.5f) : 0) + (arrowDownImage ? arrowDownImage->getHeight() : 0);
}
}
protected:
void setScrollboxPosition(int32_t SelItem, int32_t 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);
uint32_t ScrollState;
uint16_t ScrollSpeed;
int32_t MinHeight;
int32_t MaxHeight;
int32_t SelItem;
int32_t SelInd;
int32_t PageSize;
int32_t EntrieCount;
int32_t pressedChan;
GuiButton * arrowUpBtn;
GuiButton * arrowDownBtn;
GuiButton * scrollbarBoxBtn;
GuiSound * clickSound = NULL;
GuiImage * scrollbarLineImage = NULL;
GuiImage * arrowDownImage = NULL;
GuiImage * arrowUpImage = NULL;
GuiImage * scrollbarBoxImage = NULL;
GuiTrigger touchTrigger;
GuiTrigger wpadTouchTrigger;
};
#endif

130
include/gui/GuiSelectBox.h Normal file
View File

@ -0,0 +1,130 @@
/****************************************************************************
* 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/Gui.h>
#include <gui/GuiImage.h>
#include <gui/GuiImageData.h>
//!A simple CheckBox
class GuiSelectBox : public GuiFrame, public sigslot::has_slots<> {
public:
//!Constructor
//!\param checked Checked
GuiSelectBox(GuiImage * background, std::string caption,float width = 0.0f, float height = 0.0f,GuiFrame *parent = 0);
//!Destructor
virtual ~GuiSelectBox();
sigslot::signal2<GuiSelectBox *, std::string> valueChanged;
sigslot::signal2<GuiSelectBox *, bool> showhide;
void setImageTopBackground(GuiImage * img) {
topBackgroundImg = img;
topValueButton.setImage(img);
}
void setImageTopHighlighted(GuiImage * img) {
topHighlightedImg = img;
topValueButton.setIconOver(img);
}
void setImageValueBackground(GuiImageData * img) {
valueImageData = img;
}
void setImageValueHighlighted(GuiImageData * img) {
valueHighlightedImageData = img;
}
void setImageValueSelected(GuiImageData * img) {
valueSelectedImageData = img;
}
void setSoundClick(GuiSound * snd) {
buttonClickSound = snd;
topValueButton.setSoundClick(snd);
}
void OnTopValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger);
void Init(std::map<std::string,std::string> values, int32_t valueID);
void setState(int32_t s, int32_t c = -1);
virtual void setSize(float width, float height);
virtual float getTopValueHeight();
virtual float getTopValueWidth();
virtual float getHeight();
virtual float getWidth();
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(uint32_t value);
uint32_t selected;
bool bChanged;
bool bSelectedChanged;
bool showValues;
bool opened;
std::string captionText;
GuiFrame valuesFrame;
GuiImage* topBackgroundImg = NULL;
GuiImage* topHighlightedImg = NULL;
GuiButton topValueButton;
GuiImageData * valueImageData = NULL;
GuiImageData * valueSelectedImageData = NULL;
GuiImageData * valueHighlightedImageData = NULL;
GuiText topValueText;
GuiTrigger touchTrigger;
GuiTrigger wpadTouchTrigger;
GuiTrigger buttonATrigger;
GuiTrigger buttonBTrigger;
GuiTrigger buttonLeftTrigger;
GuiTrigger buttonRightTrigger;
GuiTrigger buttonUpTrigger;
GuiTrigger buttonDownTrigger;
GuiButton DPADButtons;
GuiSound* buttonClickSound;
typedef struct {
GuiImage *valueButtonImg;
GuiImage *valueButtonCheckedImg;
GuiImage *valueButtonHighlightedImg;
GuiButton *valueButton;
GuiText *valueButtonText;
} SelectBoxValueButton;
std::map<GuiButton * ,std::string> buttonToValue;
std::vector<SelectBoxValueButton> valueButtons;
};
#endif

58
include/gui/GuiSound.h Normal file
View File

@ -0,0 +1,58 @@
/****************************************************************************
* 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 <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 uint8_t * sound, int32_t 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 uint8_t * snd, int32_t 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(uint32_t v);
//!\param l Loop (true to loop)
void SetLoop(bool l);
protected:
int32_t voice; //!< Currently assigned ASND voice channel
};
#endif

View File

@ -17,34 +17,34 @@
#ifndef GUI_SWTICH_H_
#define GUI_SWTICH_H_
#include "GuiToggle.h"
#include "GuiImage.h"
#include "GuiImageData.h"
#include <gui/GuiToggle.h>
#include <gui/GuiImage.h>
#include <gui/GuiImageData.h>
//!A simple switch
class GuiSwitch : public GuiToggle{
public:
//!Constructor
//!\param checked Checked
GuiSwitch(GuiImage * background, bool checked, f32 w = 0.0f, f32 h = 0.0f);
//!Destructor
virtual ~GuiSwitch();
class GuiSwitch : public GuiToggle {
public:
//!Constructor
//!\param checked Checked
GuiSwitch(GuiImage * background, bool checked, float w = 0.0f, float h = 0.0f);
//!Destructor
virtual ~GuiSwitch();
void setImageBackground(GuiImage* img);
void setImageBackground(GuiImage* img);
void setImageOn(GuiImage* img);
void setImageOn(GuiImage* img);
void setImageOff(GuiImage* img);
void setImageOff(GuiImage* img);
void setImageHighlighted(GuiImage* img);
protected:
void setImageHighlighted(GuiImage* img);
protected:
GuiImage * backgroundImg = NULL;
GuiImage * onImg = NULL;
GuiImage * offImg = NULL;
GuiImage * highlightedImg = NULL;
GuiImage * backgroundImg = NULL;
GuiImage * onImg = NULL;
GuiImage * offImg = NULL;
GuiImage * highlightedImg = NULL;
void draw(CVideo * v);
void draw(CVideo * v);
};
#endif

View File

@ -17,25 +17,24 @@
#ifndef GUI_TEXT_H_
#define GUI_TEXT_H_
#include "GuiElement.h"
#include <gui/GuiElement.h>
//!Forward declaration
class FreeTypeGX;
//!Display, manage, and manipulate text in the GUI
class GuiText : public GuiElement
{
class GuiText : public GuiElement {
public:
//!Constructor
GuiText();
//!\param t Text
//!\param s Font size
//!\param c Font color
GuiText(const char * t, s32 s, const glm::vec4 & c);
GuiText(const char * t, int32_t s, const glm::vec4 & c);
//!\overload
//!\param t Text
//!\param s Font size
//!\param c Font color
GuiText(const wchar_t * t, s32 s, const glm::vec4 & c);
GuiText(const wchar_t * t, int32_t s, const glm::vec4 & c);
//!\overload
//!\Assumes SetPresets() has been called to setup preferred text attributes
//!\param t Text
@ -54,47 +53,62 @@ public:
//!\param w Maximum width of texture image (for text wrapping)
//!\param wrap Wrapmode when w>0
//!\param a Text alignment
static void setPresets(s32 sz, const glm::vec4 & c, s32 w, s32 a);
static void setPresets(int32_t sz, const glm::vec4 & c, int32_t w, int32_t a);
static void setPresetFont(FreeTypeGX *font);
//!Sets the font size
//!\param s Font size
void setFontSize(s32 s);
void setFontSize(int32_t 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(s32 w = 0, s32 m = WRAP);
void setMaxWidth(int32_t w = 0, int32_t 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; }
void setTextBlur(float blur) {
defaultBlur = blur;
}
//!Get the original text as char
virtual const wchar_t * getText() const { return text; }
virtual const wchar_t * getText() const {
return text;
}
virtual std::string toUTF8(void) const;
//!Get the Horizontal Size of Text
s32 getTextWidth() { return textWidth; }
s32 getTextWidth(s32 ind);
int32_t getTextWidth() {
return textWidth;
}
int32_t getTextWidth(int32_t ind);
//!Get the max textwidth
s32 getTextMaxWidth() { return maxWidth; }
int32_t getTextMaxWidth() {
return maxWidth;
}
//!Get fontsize
s32 getFontSize() { return size; };
int32_t getFontSize() {
return size;
};
//!Set max lines to draw
void setLinesToDraw(s32 l) { linestodraw = l; }
void setLinesToDraw(int32_t l) {
linestodraw = l;
}
//!Get current Textline (for position calculation)
const wchar_t * getDynText(s32 ind = 0);
virtual const wchar_t * getTextLine(s32 ind) { return getDynText(ind); };
const wchar_t * getDynText(int32_t ind = 0);
virtual const wchar_t * getTextLine(int32_t ind) {
return getDynText(ind);
};
//!Change the font
bool setFont(FreeTypeGX *font);
//! virtual function used in child classes
virtual s32 getStartWidth() { return 0; };
virtual int32_t getStartWidth() {
return 0;
};
//!Constantly called to draw the text
void draw(CVideo *pVideo);
//! text enums
enum
{
enum {
WRAP,
DOTTED,
SCROLL_HORIZONTAL,
@ -102,10 +116,10 @@ public:
};
protected:
static FreeTypeGX * presentFont;
static s32 presetSize;
static s32 presetMaxWidth;
static int32_t presetSize;
static int32_t presetMaxWidth;
static float presetInternalRenderingScale;
static s32 presetAlignment;
static int32_t presetAlignment;
static GX2ColorF32 presetColor;
//!Clear the dynamic text
@ -113,23 +127,23 @@ protected:
//!Create a dynamic dotted text if the text is too long
void makeDottedText();
//!Scroll the text once
void scrollText(u32 frameCount);
void scrollText(uint32_t frameCount);
//!Wrap the text to several lines
void wrapText();
wchar_t * text;
std::vector<wchar_t *> textDyn;
std::vector<uint16_t> textDynWidth;
s32 wrapMode; //!< Wrapping toggle
s32 textScrollPos; //!< Current starting index of text string for scrolling
s32 textScrollInitialDelay; //!< Delay to wait before starting to scroll
s32 textScrollDelay; //!< Scrolling speed
s32 size; //!< Font size
s32 maxWidth; //!< Maximum width of the generated text object (for text wrapping)
int32_t wrapMode; //!< Wrapping toggle
int32_t textScrollPos; //!< Current starting index of text string for scrolling
int32_t textScrollInitialDelay; //!< Delay to wait before starting to scroll
int32_t textScrollDelay; //!< Scrolling speed
int32_t size; //!< Font size
int32_t maxWidth; //!< Maximum width of the generated text object (for text wrapping)
FreeTypeGX *font;
s32 textWidth;
s32 currentSize;
s32 linestodraw;
int32_t textWidth;
int32_t currentSize;
int32_t linestodraw;
glm::vec4 color;
float defaultBlur;
float blurGlowIntensity;

View File

@ -17,8 +17,8 @@
#ifndef GUI_TOGGLE_H_
#define GUI_TOGGLE_H_
#include "GuiButton.h"
#include "GuiFrame.h"
#include <gui/GuiButton.h>
#include <gui/GuiFrame.h>
//!A simple CheckBox
class GuiToggle : public GuiButton, public sigslot::has_slots<>
@ -26,7 +26,7 @@ class GuiToggle : public GuiButton, public sigslot::has_slots<>
public:
//!Constructor
//!\param checked Checked
GuiToggle(bool checked,f32 width,f32 height);
GuiToggle(bool checked,float width,float height);
//!Destructor
virtual ~GuiToggle();
void setValue(bool checked){

View File

@ -17,14 +17,10 @@
#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
{
class GuiTrigger {
public:
enum eClicked{
enum eClicked {
CLICKED_NONE = 0x00,
CLICKED_TOUCH = 0x01,
CLICKED_BUTTON = 0x02,
@ -73,30 +69,42 @@ public:
//!Constructor
GuiTrigger();
//!Constructor
GuiTrigger(u32 ch, u32 btns, bool clickEverywhere = false, bool holdEverywhere = false, bool selectionClickEverywhere = false);
GuiTrigger(uint32_t ch, uint32_t 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 setTrigger(uint32_t ch, uint32_t btns);
void setClickEverywhere(bool b) { bClickEverywhere = b; }
void setHoldOnly(bool b) { bHoldEverywhere = b; }
void setSelectionClickEverywhere(bool b) { bSelectionClickEverywhere = b; }
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 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;
s32 clicked(const GuiController *controller) const;
int32_t clicked(const GuiController *controller) const;
bool held(const GuiController *controller) const;
bool released(const GuiController *controller) const;
private:
u32 chan;
u32 btns;
uint32_t chan;
uint32_t btns;
bool bClickEverywhere;
bool bHoldEverywhere;
bool bSelectionClickEverywhere;

View File

@ -17,41 +17,38 @@
#ifndef VPAD_CONTROLLER_H_
#define VPAD_CONTROLLER_H_
#include "GuiController.h"
#include <dynamic_libs/vpad_functions.h>
#include <gui/GuiController.h>
#include <vpad/input.h>
class VPadController : public GuiController
{
class VPadController : public GuiController {
public:
//!Constructor
VPadController(s32 channel)
: GuiController(channel)
{
VPadController(int32_t channel)
: GuiController(channel) {
memset(&vpad, 0, sizeof(vpad));
}
//!Destructor
virtual ~VPadController() {}
bool update(s32 width, s32 height)
{
bool update(int32_t width, int32_t height) {
lastData = data;
s32 vpadError = -1;
VPADRead(0, &vpad, 1, &vpadError);
VPADReadError vpadError = VPAD_READ_NO_SAMPLES;
VPADRead(VPAD_CHAN_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;
if(vpadError == VPAD_READ_SUCCESS) {
data.buttons_r = vpad.release;
data.buttons_h = vpad.hold;
data.buttons_d = vpad.trigger;
data.validPointer = !vpad.tpNormal.validity;
data.touched = vpad.tpNormal.touched;
VPADGetTPCalibratedPoint(0, &tpCalib, &vpad.tpdata1);
VPADGetTPCalibratedPoint(VPAD_CHAN_0, &tpCalib, &vpad.tpFiltered1);
//! calculate the screen offsets
data.x = -(width >> 1) + (s32)(((float)tpCalib.x / 1280.0f) * (float)width);
data.y = -(height >> 1) + (s32)(float)height - (((float)tpCalib.y / 720.0f) * (float)height);
data.x = -(width >> 1) + (int32_t)(((float)tpCalib.x / 1280.0f) * (float)width);
data.y = -(height >> 1) + (int32_t)(float)height - (((float)tpCalib.y / 720.0f) * (float)height);
return true;
}
@ -59,8 +56,8 @@ public:
}
private:
VPADData vpad;
VPADTPData tpCalib;
VPADStatus vpad;
VPADTouchData tpCalib;
};
#endif

View File

@ -17,25 +17,23 @@
#ifndef WPAD_CONTROLLER_H_
#define WPAD_CONTROLLER_H_
#include "GuiController.h"
#include <dynamic_libs/padscore_functions.h>
#include <gui/GuiController.h>
#include <padscore/kpad.h>
#include <padscore/wpad.h>
class WPadController : public GuiController
{
class WPadController : public GuiController {
public:
//!Constructor
WPadController(s32 channel)
: GuiController(channel)
{
WPadController(int32_t channel)
: GuiController(channel) {
memset(&kpadData, 0, sizeof(kpadData));
}
//!Destructor
virtual ~WPadController() {}
u32 remapWiiMoteButtons(u32 buttons)
{
u32 conv_buttons = 0;
uint32_t remapWiiMoteButtons(uint32_t buttons) {
uint32_t conv_buttons = 0;
if(buttons & WPAD_BUTTON_LEFT)
conv_buttons |= GuiTrigger::BUTTON_LEFT;
@ -78,9 +76,8 @@ public:
return conv_buttons;
}
u32 remapClassicButtons(u32 buttons)
{
u32 conv_buttons = 0;
uint32_t remapClassicButtons(uint32_t buttons) {
uint32_t conv_buttons = 0;
if(buttons & WPAD_CLASSIC_BUTTON_LEFT)
conv_buttons |= GuiTrigger::BUTTON_LEFT;
@ -130,50 +127,60 @@ public:
return conv_buttons;
}
bool update(s32 width, s32 height)
{
lastData = data;
WPADChan getChanByInt(int32_t chan) {
if(chan == 0) {
return WPAD_CHAN_0;
}
if(chan == 1) {
return WPAD_CHAN_1;
}
if(chan == 2) {
return WPAD_CHAN_3;
}
if(chan == 3) {
return WPAD_CHAN_3;
}
return WPAD_CHAN_0;
}
u32 controller_type;
bool update(int32_t width, int32_t height) {
lastData = data;
WPADExtensionType controller_type;
//! check if the controller is connected
if(WPADProbe(chanIdx-1, &controller_type) != 0)
if(WPADProbe(getChanByInt(chanIdx-1), &controller_type) != 0)
return false;
KPADRead(chanIdx-1, &kpadData, 1);
KPADRead(getChanByInt(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);
if(kpadData.extensionType <= 1) {
data.buttons_r = remapWiiMoteButtons(kpadData.release);
data.buttons_h = remapWiiMoteButtons(kpadData.hold);
data.buttons_d = remapWiiMoteButtons(kpadData.trigger);
} else {
data.buttons_r = remapClassicButtons(kpadData.classic.release);
data.buttons_h = remapClassicButtons(kpadData.classic.hold);
data.buttons_d = remapClassicButtons(kpadData.classic.trigger);
}
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);
data.validPointer = (kpadData.posValid == 1 || kpadData.posValid == 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(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;
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;
data.pointerAngle = (kpadData.angle.x + 1.0f) * 0.5f * 180.0f - 180.0f;
}
return true;
}
private:
KPADData kpadData;
u32 lastButtons;
KPADStatus kpadData;
uint32_t lastButtons;
};
#endif

171
include/gui/gx2_ext.h Normal file
View File

@ -0,0 +1,171 @@
#ifndef __GX2_EXTENSION_H
#define __GX2_EXTENSION_H
#ifdef __cplusplus
extern "C" {
#endif
#include <gx2/draw.h>
#include <gx2/enum.h>
#include <gx2/mem.h>
#include <gx2/registers.h>
#include <gx2/sampler.h>
#include <gx2/shaders.h>
#include <gx2/surface.h>
#include <gx2/texture.h>
#define GX2_FALSE 0
#define GX2_TRUE 1
#define GX2_DISABLE 0
#define GX2_ENABLE 1
#define GX2_COMMAND_BUFFER_SIZE 0x400000
#define GX2_SHADER_ALIGNMENT 0x100
#define GX2_VERTEX_BUFFER_ALIGNMENT 0x40
#define GX2_INDEX_BUFFER_ALIGNMENT 0x20
#define GX2_AA_BUFFER_CLEAR_VALUE 0xCC
#define GX2_COMP_SEL_NONE 0x04040405
#define GX2_COMP_SEL_X001 0x00040405
#define GX2_COMP_SEL_XY01 0x00010405
#define GX2_COMP_SEL_XYZ1 0x00010205
#define GX2_COMP_SEL_XYZW 0x00010203
#define GX2_COMP_SEL_XXXX 0x00000000
#define GX2_COMP_SEL_YYYY 0x01010101
#define GX2_COMP_SEL_ZZZZ 0x02020202
#define GX2_COMP_SEL_WWWW 0x03030303
#define GX2_COMP_SEL_WZYX 0x03020100
#define GX2_COMP_SEL_WXYZ 0x03000102
static const uint32_t attribute_dest_comp_selector[20] = {
GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_X001, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_X001,
GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW,
GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZ1,
GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW
};
static const uint32_t texture_comp_selector[54] = {
GX2_COMP_SEL_NONE, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_X001,
GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW,
GX2_COMP_SEL_WZYX, GX2_COMP_SEL_X001, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_NONE,
GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_NONE,
GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_WZYX, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01,
GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW,
GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_X001,
GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZ1,
GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01
};
typedef struct _GX2Color {
uint8_t r, g, b, a;
} GX2Color;
typedef struct _GX2ColorF32 {
float r, g, b, a;
} GX2ColorF32;
static inline void GX2InitDepthBuffer(GX2DepthBuffer *depthBuffer, GX2SurfaceDim dim, uint32_t width, uint32_t height, uint32_t depth, GX2SurfaceFormat format, GX2AAMode aa) {
depthBuffer->surface.dim = dim;
depthBuffer->surface.width = width;
depthBuffer->surface.height = height;
depthBuffer->surface.depth = depth;
depthBuffer->surface.mipLevels = 1;
depthBuffer->surface.format = format;
depthBuffer->surface.aa = aa;
depthBuffer->surface.use = (GX2SurfaceUse)(((format==GX2_SURFACE_FORMAT_UNORM_R24_X8) || (format==GX2_SURFACE_FORMAT_FLOAT_D24_S8)) ?
GX2_SURFACE_USE_DEPTH_BUFFER : (GX2_SURFACE_USE_DEPTH_BUFFER | GX2_SURFACE_USE_TEXTURE));
depthBuffer->surface.tileMode = GX2_TILE_MODE_DEFAULT;
depthBuffer->surface.swizzle = 0;
depthBuffer->viewMip = 0;
depthBuffer->viewFirstSlice = 0;
depthBuffer->viewNumSlices = depth;
depthBuffer->depthClear = 1.0f;
depthBuffer->stencilClear = 0;
depthBuffer->hiZPtr = NULL;
depthBuffer->hiZSize = 0;
GX2CalcSurfaceSizeAndAlignment(&depthBuffer->surface);
GX2InitDepthBufferRegs(depthBuffer);
}
static inline void GX2InitColorBuffer(GX2ColorBuffer *colorBuffer, GX2SurfaceDim dim, uint32_t width, uint32_t height, uint32_t depth, GX2SurfaceFormat format, GX2AAMode aa) {
colorBuffer->surface.dim = dim;
colorBuffer->surface.width = width;
colorBuffer->surface.height = height;
colorBuffer->surface.depth = depth;
colorBuffer->surface.mipLevels = 1;
colorBuffer->surface.format = format;
colorBuffer->surface.aa = aa;
colorBuffer->surface.use = GX2_SURFACE_USE_TEXTURE_COLOR_BUFFER_TV;
colorBuffer->surface.imageSize = 0;
colorBuffer->surface.image = NULL;
colorBuffer->surface.mipmapSize = 0;
colorBuffer->surface.mipmaps = NULL;
colorBuffer->surface.tileMode = GX2_TILE_MODE_DEFAULT;
colorBuffer->surface.swizzle = 0;
colorBuffer->surface.alignment = 0;
colorBuffer->surface.pitch = 0;
uint32_t i;
for(i = 0; i < 13; i++)
colorBuffer->surface.mipLevelOffset[i] = 0;
colorBuffer->viewMip = 0;
colorBuffer->viewFirstSlice = 0;
colorBuffer->viewNumSlices = depth;
colorBuffer->aaBuffer = NULL;
colorBuffer->aaSize = 0;
for(i = 0; i < 5; i++)
colorBuffer->regs[i] = 0;
GX2CalcSurfaceSizeAndAlignment(&colorBuffer->surface);
GX2InitColorBufferRegs(colorBuffer);
}
static inline void GX2InitAttribStream(GX2AttribStream* attr, uint32_t location, uint32_t buffer, uint32_t offset, GX2AttribFormat format) {
attr->location = location;
attr->buffer = buffer;
attr->offset = offset;
attr->format = format;
attr->type = GX2_ATTRIB_INDEX_PER_VERTEX;
attr->aluDivisor = 0;
attr->mask = attribute_dest_comp_selector[format & 0xff];
attr->endianSwap = GX2_ENDIAN_SWAP_DEFAULT;
}
static inline void GX2InitTexture(GX2Texture *tex, uint32_t width, uint32_t height, uint32_t depth, uint32_t mipLevels, GX2SurfaceFormat format, GX2SurfaceDim dim, GX2TileMode tile) {
tex->surface.dim = dim;
tex->surface.width = width;
tex->surface.height = height;
tex->surface.depth = depth;
tex->surface.mipLevels = mipLevels;
tex->surface.format = format;
tex->surface.aa = GX2_AA_MODE1X;
tex->surface.use = GX2_SURFACE_USE_TEXTURE;
tex->surface.imageSize = 0;
tex->surface.image = NULL;
tex->surface.mipmapSize = 0;
tex->surface.mipmaps = NULL;
tex->surface.tileMode = tile;
tex->surface.swizzle = 0;
tex->surface.alignment = 0;
tex->surface.pitch = 0;
uint32_t i;
for(i = 0; i < 13; i++)
tex->surface.mipLevelOffset[i] = 0;
tex->viewFirstMip = 0;
tex->viewNumMips = mipLevels;
tex->viewFirstSlice = 0;
tex->viewNumSlices = depth;
tex->compMap = texture_comp_selector[format & 0x3f];
for(i = 0; i < 5; i++)
tex->regs[i] = 0;
GX2CalcSurfaceSizeAndAlignment(&tex->surface);
GX2InitTextureRegs(tex);
}
#ifdef __cplusplus
}
#endif
#endif /* COMMON_H */

2377
include/gui/sigslot.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2,19 +2,18 @@
#define RECOURCES_H_
#include <map>
#include <dynamic_libs/os_types.h>
#include <stdint.h>
//! forward declaration
class GuiImageData;
class GuiSound;
class Resources
{
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 const uint8_t * GetFile(const char * filename);
static uint32_t GetFileSize(const char * filename);
static GuiImageData * GetImageData(const char * filename);
static void RemoveImageData(GuiImageData * image);
@ -27,8 +26,8 @@ private:
Resources() {}
~Resources() {}
std::map<std::string, std::pair<u32, GuiImageData *> > imageDataMap;
std::map<std::string, std::pair<u32, GuiSound *> > soundDataMap;
std::map<std::string, std::pair<uint32_t, GuiImageData *> > imageDataMap;
std::map<std::string, std::pair<uint32_t, GuiSound *> > soundDataMap;
};
#endif

View File

@ -0,0 +1,16 @@
#ifndef _FILELIST_H_
#define _FILELIST_H_
#include <stdint.h>
typedef struct _ResourceFile {
const char *filename;
const uint8_t *DefaultFile;
const uint32_t &DefaultFileSize;
uint8_t *CustomFile;
uint32_t CustomFileSize;
} ResourceFile;
ResourceFile * getResourceList();
#endif

View File

@ -0,0 +1,111 @@
/***************************************************************************
* 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 <stdint.h>
class BufferCircle {
public:
//!> Constructor
BufferCircle();
//!> Destructor
~BufferCircle();
//!> Set circle size
void Resize(int32_t size);
//!> Get the circle size
int32_t Size() {
return SoundBuffer.size();
};
//!> Set/resize the buffer size
void SetBufferBlockSize(int32_t size);
//!> Remove a buffer
void RemoveBuffer(int32_t pos);
//!> Set all buffers clear
void ClearBuffer();
//!> Free all buffers
void FreeBuffer();
//!> Switch to next buffer
void LoadNext();
//!> Get the current buffer
uint8_t * GetBuffer() {
return GetBuffer(which);
};
//!> Get a buffer at a position
uint8_t * GetBuffer(int32_t pos) {
if(!Valid(pos)) return NULL;
else return SoundBuffer[pos];
};
//!> Get current buffer size
uint32_t GetBufferSize() {
return GetBufferSize(which);
};
//!> Get buffer size at position
uint32_t GetBufferSize(int32_t 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(int32_t pos) {
if(!Valid(pos)) return false;
else return BufferReady[pos];
};
//!> Set a buffer at a position to a ready state
void SetBufferReady(int32_t pos, bool st);
//!> Set the buffersize at a position
void SetBufferSize(int32_t pos, int32_t size);
//!> Get the current position in the circle
uint16_t Which() {
return which;
};
//!> Get the next location
inline uint16_t Next() {
return (which+1 >= Size()) ? 0 : which+1;
}
inline uint16_t Prev() {
if(Size() == 0) return 0;
else return ((int32_t)which-1 < 0) ? Size()-1 : which-1;
}
protected:
//!> Check if the position is a valid position in the vector
bool Valid(int32_t pos) {
return !(pos < 0 || pos >= Size());
};
uint16_t which;
uint32_t BufferBlockSize;
std::vector<uint8_t *> SoundBuffer;
std::vector<uint32_t> BufferSize;
std::vector<bool> BufferReady;
};
#endif

View File

@ -25,23 +25,22 @@
***************************************************************************/
#include <mad.h>
#include "SoundDecoder.hpp"
#include <sounds/SoundDecoder.hpp>
class Mp3Decoder : public SoundDecoder
{
public:
Mp3Decoder(const char * filepath);
Mp3Decoder(const u8 * sound, s32 len);
virtual ~Mp3Decoder();
s32 Rewind();
s32 Read(u8 * buffer, s32 buffer_size, s32 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;
class Mp3Decoder : public SoundDecoder {
public:
Mp3Decoder(const char * filepath);
Mp3Decoder(const uint8_t * sound, int32_t len);
virtual ~Mp3Decoder();
int32_t Rewind();
int32_t Read(uint8_t * buffer, int32_t buffer_size, int32_t pos);
protected:
void OpenFile();
struct mad_stream Stream;
struct mad_frame Frame;
struct mad_synth Synth;
mad_timer_t Timer;
uint8_t * GuardPtr;
uint8_t * ReadBuffer;
uint32_t SynthPos;
};

View File

@ -26,18 +26,17 @@
#include <tremor/ivorbiscodec.h>
#include <tremor/ivorbisfile.h>
#include "SoundDecoder.hpp"
#include <sounds/SoundDecoder.hpp>
class OggDecoder : public SoundDecoder
{
public:
OggDecoder(const char * filepath);
OggDecoder(const u8 * snd, s32 len);
virtual ~OggDecoder();
s32 Rewind();
s32 Read(u8 * buffer, s32 buffer_size, s32 pos);
protected:
void OpenFile();
OggVorbis_File ogg_file;
vorbis_info *ogg_info;
class OggDecoder : public SoundDecoder {
public:
OggDecoder(const char * filepath);
OggDecoder(const uint8_t * snd, int32_t len);
virtual ~OggDecoder();
int32_t Rewind();
int32_t Read(uint8_t * buffer, int32_t buffer_size, int32_t pos);
protected:
void OpenFile();
OggVorbis_File ogg_file;
vorbis_info *ogg_info;
};

View 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
***************************************************************************/
#ifndef SOUND_DECODER_HPP
#define SOUND_DECODER_HPP
#include <fs/CFile.hpp>
#include <system/CMutex.h>
#include <sounds/BufferCircle.hpp>
class SoundDecoder {
public:
SoundDecoder();
SoundDecoder(const std::string & filepath);
SoundDecoder(const uint8_t * buffer, int32_t size);
virtual ~SoundDecoder();
virtual void Lock() {
mutex.lock();
}
virtual void Unlock() {
mutex.unlock();
}
virtual int32_t Read(uint8_t * buffer, int32_t buffer_size, int32_t pos);
virtual int32_t Tell() {
return CurPos;
}
virtual int32_t Seek(int32_t pos) {
CurPos = pos;
return file_fd->seek(CurPos, SEEK_SET);
}
virtual int32_t Rewind();
virtual uint16_t GetFormat() {
return Format;
}
virtual uint16_t GetSampleRate() {
return SampleRate;
}
virtual void Decode();
virtual bool IsBufferReady() {
return SoundBuffer.IsBufferReady();
}
virtual uint8_t * GetBuffer() {
return SoundBuffer.GetBuffer();
}
virtual uint32_t GetBufferSize() {
return SoundBuffer.GetBufferSize();
}
virtual void LoadNext() {
SoundBuffer.LoadNext();
}
virtual bool IsEOF() {
return EndOfFile;
}
virtual void SetLoop(bool l) {
Loop = l;
EndOfFile = false;
}
virtual uint8_t 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(int16_t *src, int16_t *dst, uint32_t nr_src_samples, uint32_t nr_dst_samples);
CFile * file_fd;
BufferCircle SoundBuffer;
uint8_t SoundType;
uint16_t whichLoad;
uint16_t SoundBlocks;
int32_t SoundBlockSize;
int32_t CurPos;
bool ResampleTo48kHz;
bool Loop;
bool EndOfFile;
bool Decoding;
bool ExitRequested;
uint16_t Format;
uint16_t SampleRate;
uint8_t *ResampleBuffer;
uint32_t ResampleRatio;
CMutex mutex;
};
#endif

View File

@ -29,50 +29,61 @@
#include <vector>
#include <system/CThread.h>
#include "SoundDecoder.hpp"
#include "Voice.h"
#include <sounds/SoundDecoder.hpp>
#include <sounds/Voice.h>
#include <sndcore2/voice.h>
#define MAX_DECODERS 16 // can be increased up to 96
class SoundHandler : public CThread
{
class SoundHandler : public CThread {
public:
static SoundHandler * instance() {
if (!handlerInstance)
static SoundHandler * instance() {
if (!handlerInstance)
handlerInstance = new SoundHandler();
return handlerInstance;
}
static void DestroyInstance() { delete handlerInstance; handlerInstance = NULL; }
static void DestroyInstance() {
delete handlerInstance;
handlerInstance = NULL;
}
void AddDecoder(s32 voice, const char * filepath);
void AddDecoder(s32 voice, const u8 * snd, s32 len);
void RemoveDecoder(s32 voice);
void AddDecoder(int32_t voice, const char * filepath);
void AddDecoder(int32_t voice, const uint8_t * snd, int32_t len);
void RemoveDecoder(int32_t voice);
SoundDecoder * getDecoder(s32 i) { return ((i < 0 || i >= MAX_DECODERS) ? NULL : DecoderList[i]); };
Voice * getVoice(s32 i) { return ((i < 0 || i >= MAX_DECODERS) ? NULL : voiceList[i]); };
SoundDecoder * getDecoder(int32_t i) {
return ((i < 0 || i >= MAX_DECODERS) ? NULL : DecoderList[i]);
};
Voice * getVoice(int32_t i) {
return ((i < 0 || i >= MAX_DECODERS) ? NULL : voiceList[i]);
};
void ThreadSignal() { resumeThread(); };
bool IsDecoding() { return Decoding; };
void ThreadSignal() {
resumeThread();
};
bool IsDecoding() {
return Decoding;
};
protected:
SoundHandler();
~SoundHandler();
SoundHandler();
~SoundHandler();
static void axFrameCallback(void);
void executeThread(void);
void ClearDecoderList();
void ClearDecoderList();
SoundDecoder * GetSoundDecoder(const char * filepath);
SoundDecoder * GetSoundDecoder(const u8 * sound, s32 length);
SoundDecoder * GetSoundDecoder(const char * filepath);
SoundDecoder * GetSoundDecoder(const uint8_t * sound, int32_t length);
static SoundHandler * handlerInstance;
static SoundHandler * handlerInstance;
bool Decoding;
bool ExitRequested;
bool Decoding;
bool ExitRequested;
Voice * voiceList[MAX_DECODERS];
SoundDecoder * DecoderList[MAX_DECODERS];
Voice * voiceList[MAX_DECODERS];
SoundDecoder * DecoderList[MAX_DECODERS];
};
#endif

154
include/sounds/Voice.h Normal file
View File

@ -0,0 +1,154 @@
/****************************************************************************
* 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 _AXSOUND_H_
#define _AXSOUND_H_
#include <sndcore2/voice.h>
#include <sndcore2/core.h>
class Voice {
public:
enum VoicePriorities {
PRIO_MIN = 1,
PRIO_MAX = 31
};
enum VoiceStates {
STATE_STOPPED,
STATE_START,
STATE_PLAYING,
STATE_STOP,
};
Voice(int32_t prio)
: state(STATE_STOPPED) {
lastLoopCounter = 0;
nextBufferSize = 0;
voice = AXAcquireVoice(prio, 0, 0);
if(voice) {
AXVoiceBegin(voice);
AXSetVoiceType(voice, 0);
setVolume(0x80000000);
AXVoiceDeviceMixData mix[6];
memset(mix, 0, sizeof(mix));
mix[0].bus[0].volume = 0x8000;
mix[0].bus[0].delta = 0;
mix[1].bus[0].volume = 0x8000;
mix[1].bus[0].delta = 0;
AXSetVoiceDeviceMix(voice, 0, 0, mix);
AXSetVoiceDeviceMix(voice, 1, 0, mix);
AXVoiceEnd(voice);
}
}
~Voice() {
if(voice) {
AXFreeVoice(voice);
}
}
void play(const uint8_t *buffer, uint32_t bufferSize, const uint8_t *nextBuffer, uint32_t nextBufSize, uint16_t format, uint32_t sampleRate) {
if(!voice)
return;
memset(&voiceBuffer, 0, sizeof(voiceBuffer));
voiceBuffer.data = buffer;
voiceBuffer.dataType = format;
voiceBuffer.loopingEnabled = (nextBuffer == NULL) ? 0 : 1;
voiceBuffer.currentOffset = 0;
voiceBuffer.endOffset = (bufferSize >> 1) - 1;
voiceBuffer.loopOffset = ((nextBuffer - buffer) >> 1);
nextBufferSize = nextBufSize;
// TODO: handle support for 3.1.0 with dynamic libs instead of static linking it
//uint32_t samplesPerSec = (AXGetInputSamplesPerSec != 0) ? AXGetInputSamplesPerSec() : 32000;
uint32_t samplesPerSec = AXGetInputSamplesPerSec();
memset(&ratioBits, 0, sizeof(ratioBits));
ratioBits.ratio = (uint32_t)(0x00010000 * ((float)sampleRate / (float)samplesPerSec));
AXSetVoiceOffsets(voice, &voiceBuffer);
AXSetVoiceSrc(voice, &ratioBits);
AXSetVoiceSrcType(voice, 1);
AXSetVoiceState(voice, 1);
}
void stop() {
if(voice)
AXSetVoiceState(voice, 0);
}
void setVolume(uint32_t vol) {
if(voice) {
AXVoiceVeData data;
data.volume = vol >> 16;
data.delta = vol & 0xFFFF;
AXSetVoiceVe(voice, &data);
}
}
void setNextBuffer(const uint8_t *buffer, uint32_t bufferSize) {
voiceBuffer.loopOffset = ((buffer - (const uint8_t*)voiceBuffer.data) >> 1);
nextBufferSize = bufferSize;
AXSetVoiceLoopOffset(voice, voiceBuffer.loopOffset);
}
bool isBufferSwitched() {
uint32_t loopCounter = AXGetVoiceLoopCount(voice);
if(lastLoopCounter != loopCounter) {
lastLoopCounter = loopCounter;
AXSetVoiceEndOffset(voice, voiceBuffer.loopOffset + (nextBufferSize >> 1) - 1);
return true;
}
return false;
}
uint32_t getInternState() const {
if(voice)
return ((uint32_t *)voice)[1];
return 0;
}
uint32_t getState() const {
return state;
}
void setState(uint32_t s) {
state = s;
}
void * getVoice() const {
return voice;
}
private:
AXVoice *voice;
AXVoiceSrc ratioBits;
AXVoiceOffsets voiceBuffer;
uint32_t state;
uint32_t nextBufferSize;
uint32_t lastLoopCounter;
};
#endif // _AXSOUND_H_

View File

@ -26,46 +26,42 @@
#ifndef WAVDECODER_HPP_
#define WAVDECODER_HPP_
#include "SoundDecoder.hpp"
#include <sounds/SoundDecoder.hpp>
typedef struct
{
u32 magicRIFF;
u32 size;
u32 magicWAVE;
typedef struct {
uint32_t magicRIFF;
uint32_t size;
uint32_t magicWAVE;
} SWaveHdr;
typedef struct
{
u32 magicFMT;
u32 size;
u16 format;
u16 channels;
u32 freq;
u32 avgBps;
u16 alignment;
u16 bps;
typedef struct {
uint32_t magicFMT;
uint32_t size;
uint16_t format;
uint16_t channels;
uint32_t freq;
uint32_t avgBps;
uint16_t alignment;
uint16_t bps;
} SWaveFmtChunk;
typedef struct
{
u32 magicDATA;
u32 size;
typedef struct {
uint32_t magicDATA;
uint32_t size;
} SWaveChunk;
class WavDecoder : public SoundDecoder
{
public:
WavDecoder(const char * filepath);
WavDecoder(const u8 * snd, s32 len);
virtual ~WavDecoder();
s32 Read(u8 * buffer, s32 buffer_size, s32 pos);
protected:
void OpenFile();
void CloseFile();
u32 DataOffset;
u32 DataSize;
bool Is16Bit;
class WavDecoder : public SoundDecoder {
public:
WavDecoder(const char * filepath);
WavDecoder(const uint8_t * snd, int32_t len);
virtual ~WavDecoder();
int32_t Read(uint8_t * buffer, int32_t buffer_size, int32_t pos);
protected:
void OpenFile();
void CloseFile();
uint32_t DataOffset;
uint32_t DataSize;
bool Is16Bit;
};
#endif

View File

@ -17,13 +17,22 @@
#ifndef __CVIDEO_H_
#define __CVIDEO_H_
#include <dynamic_libs/gx2_functions.h>
#include "shaders/Shader.h"
#include <gx2/sampler.h>
#include <gx2/draw.h>
#include <gx2/registers.h>
#include <gx2/context.h>
#include <gx2/clear.h>
#include <gx2/swap.h>
#include <gx2/state.h>
#include <gx2/event.h>
#include <gx2/display.h>
#include <gui/gx2_ext.h>
class CVideo
{
#include <video/shaders/Shader.h>
class CVideo {
public:
CVideo(s32 forceTvScanMode = -1, s32 forceDrcScanMode = -1);
CVideo(int32_t forceTvScanMode = -1, int32_t forceDrcScanMode = -1);
virtual ~CVideo();
void prepareTvRendering(void) {
@ -42,38 +51,34 @@ public:
void prepareRendering(void) {
GX2ClearColor(currColorBuffer, 0.0f, 0.0f, 0.0f, 1.0f);
GX2ClearDepthStencilEx(currDepthBuffer, currDepthBuffer->clear_depth, currDepthBuffer->clear_stencil, GX2_CLEAR_BOTH);
GX2ClearDepthStencilEx(currDepthBuffer, currDepthBuffer->depthClear, currDepthBuffer->stencilClear, GX2_CLEAR_FLAGS_BOTH);
GX2SetContextState(currContextState);
GX2SetViewport(0.0f, 0.0f, currColorBuffer->surface.width, currColorBuffer->surface.height, 0.0f, 1.0f);
GX2SetScissor(0, 0, currColorBuffer->surface.width, currColorBuffer->surface.height);
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL);
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_FUNC_LEQUAL);
GX2SetColorControl(GX2_LOGIC_OP_COPY, 1, GX2_DISABLE, GX2_ENABLE);
GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_SRC_ALPHA, GX2_BLEND_ONE_MINUS_SRC_ALPHA, GX2_BLEND_COMBINE_ADD, GX2_ENABLE, GX2_BLEND_SRC_ALPHA, GX2_BLEND_ONE_MINUS_SRC_ALPHA, GX2_BLEND_COMBINE_ADD);
GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD, GX2_ENABLE, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD);
GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_DISABLE, GX2_ENABLE);
}
void setStencilRender(bool bEnable)
{
if(bEnable)
{
void setStencilRender(bool bEnable) {
if(bEnable) {
GX2SetStencilMask(0xff, 0xff, 0x01, 0xff, 0xff, 0x01);
GX2SetDepthStencilControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_LEQUAL, GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_ALWAYS, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP, GX2_STENCIL_REPLACE,
GX2_COMPARE_ALWAYS, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP, GX2_STENCIL_REPLACE);
}
else
{
GX2SetDepthStencilControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_LEQUAL, GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_FUNC_ALWAYS, GX2_STENCIL_FUNCTION_KEEP, GX2_STENCIL_FUNCTION_KEEP, GX2_STENCIL_FUNCTION_REPLACE,
GX2_COMPARE_FUNC_ALWAYS, GX2_STENCIL_FUNCTION_KEEP, GX2_STENCIL_FUNCTION_KEEP, GX2_STENCIL_FUNCTION_REPLACE);
} else {
GX2SetStencilMask(0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
GX2SetDepthStencilControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL, GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_NEVER, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP,
GX2_COMPARE_NEVER, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP);
GX2SetDepthStencilControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_FUNC_LEQUAL, GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_NEVER, GX2_STENCIL_FUNCTION_KEEP, GX2_STENCIL_FUNCTION_KEEP, GX2_STENCIL_FUNCTION_KEEP,
GX2_COMPARE_FUNC_NEVER, GX2_STENCIL_FUNCTION_KEEP, GX2_STENCIL_FUNCTION_KEEP, GX2_STENCIL_FUNCTION_KEEP);
}
}
void drcDrawDone(void) {
//! on DRC we do a hardware AA because FXAA does not look good
//renderFXAA(&drcAaTexture, &aaSampler);
GX2CopyColorBufferToScanBuffer(&drcColorBuffer, GX2_SCAN_TARGET_DRC_FIRST);
GX2CopyColorBufferToScanBuffer(&drcColorBuffer, GX2_SCAN_TARGET_DRC);
}
void tvDrawDone(void) {
@ -89,35 +94,33 @@ public:
}
void tvEnable(bool bEnable) {
if(tvEnabled != bEnable)
{
if(tvEnabled != bEnable) {
GX2SetTVEnable(bEnable ? GX2_ENABLE : GX2_DISABLE);
tvEnabled = bEnable;
}
}
void drcEnable(bool bEnable) {
if(drcEnabled != bEnable)
{
if(drcEnabled != bEnable) {
GX2SetDRCEnable(bEnable ? GX2_ENABLE : GX2_DISABLE);
drcEnabled = bEnable;
}
}
u32 getFrameCount(void) const {
uint32_t getFrameCount(void) const {
return frameCount;
}
u32 getTvWidth(void) const {
uint32_t getTvWidth(void) const {
return tvColorBuffer.surface.width;
}
u32 getTvHeight(void) const {
uint32_t getTvHeight(void) const {
return tvColorBuffer.surface.height;
}
u32 getDrcWidth(void) const {
uint32_t getDrcWidth(void) const {
return drcColorBuffer.surface.width;
}
u32 getDrcHeight(void) const {
uint32_t getDrcHeight(void) const {
return drcColorBuffer.surface.height;
}
@ -128,18 +131,17 @@ public:
return viewMtx;
}
f32 getWidthScaleFactor(void) const {
float getWidthScaleFactor(void) const {
return widthScaleFactor;
}
f32 getHeightScaleFactor(void) const {
float getHeightScaleFactor(void) const {
return heightScaleFactor;
}
f32 getDepthScaleFactor(void) const {
float getDepthScaleFactor(void) const {
return depthScaleFactor;
}
void screenPosToWorldRay(f32 posX, f32 posY, glm::vec3 & rayOrigin, glm::vec3 & rayDirection)
{
void screenPosToWorldRay(float posX, float posY, glm::vec3 & rayOrigin, glm::vec3 & rayDirection) {
//! normalize positions
posX = 2.0f * posX * getWidthScaleFactor();
posY = 2.0f * posY * getHeightScaleFactor();
@ -161,8 +163,8 @@ public:
rayDirection = glm::normalize(rayDirectionWorld);
}
private:
static void *GX2RAlloc(u32 flags, u32 size, u32 align);
static void GX2RFree(u32 flags, void* p);
static void *GX2RAlloc(uint32_t flags, uint32_t size, uint32_t align);
static void GX2RFree(uint32_t flags, void* p);
void renderFXAA(const GX2Texture * texture, const GX2Sampler *sampler);
@ -171,10 +173,10 @@ private:
void *tvScanBuffer;
void *drcScanBuffer;
u32 frameCount;
f32 widthScaleFactor;
f32 heightScaleFactor;
f32 depthScaleFactor;
uint32_t frameCount;
float widthScaleFactor;
float heightScaleFactor;
float depthScaleFactor;
bool tvEnabled;
bool drcEnabled;

View File

@ -20,11 +20,9 @@
#include <string>
#include <stdio.h>
#include <stdint.h>
#include <dynamic_libs/gx2_types.h>
class CursorDrawer
{
class CursorDrawer {
public:
static CursorDrawer *getInstance() {
@ -34,14 +32,13 @@ public:
}
static void destroyInstance() {
if(instance){
if(instance) {
delete instance;
instance = NULL;
}
}
static void draw(f32 x, f32 y)
{
static void draw(float x, float y) {
CursorDrawer * cur_instance = getInstance();
if(cur_instance == NULL) return;
cur_instance->draw_Cursor(x,y);
@ -53,10 +50,10 @@ private:
//!Destructor
~CursorDrawer();
static CursorDrawer *instance;
void draw_Cursor(f32 x, f32 y);
void draw_Cursor(float x, float y);
void init_colorVtxs();
u8 * colorVtxs = NULL;
uint8_t * colorVtxs = NULL;
};
#endif

View File

@ -17,18 +17,17 @@
#ifndef __COLOR_SHADER_H_
#define __COLOR_SHADER_H_
#include "VertexShader.h"
#include "PixelShader.h"
#include "FetchShader.h"
#include <video/shaders/VertexShader.h>
#include <video/shaders/PixelShader.h>
#include <video/shaders/FetchShader.h>
class ColorShader : public Shader
{
class ColorShader : public Shader {
private:
ColorShader();
virtual ~ColorShader();
static const u32 cuAttributeCount = 2;
static const u32 cuPositionVtxsSize = 4 * cuVertexAttrSize;
static const uint32_t cuAttributeCount = 2;
static const uint32_t cuPositionVtxsSize = 4 * cuVertexAttrSize;
static ColorShader *shaderInstance;
@ -36,16 +35,16 @@ private:
VertexShader vertexShader;
PixelShader pixelShader;
f32 *positionVtxs;
float *positionVtxs;
u32 angleLocation;
u32 offsetLocation;
u32 scaleLocation;
u32 colorLocation;
u32 colorIntensityLocation;
u32 positionLocation;
uint32_t angleLocation;
uint32_t offsetLocation;
uint32_t scaleLocation;
uint32_t colorLocation;
uint32_t colorIntensityLocation;
uint32_t positionLocation;
public:
static const u32 cuColorVtxsSize = 4 * cuColorAttrSize;
static const uint32_t cuColorVtxsSize = 4 * cuColorAttrSize;
static ColorShader *instance() {
if(!shaderInstance) {
@ -60,39 +59,32 @@ public:
}
}
void setShaders(void) const
{
void setShaders(void) const {
fetchShader->setShader();
vertexShader.setShader();
pixelShader.setShader();
}
void setAttributeBuffer(const u8 * colorAttr, const f32 * posVtxs_in = NULL, const u32 & vtxCount = 0) const
{
void setAttributeBuffer(const uint8_t * colorAttr, const float * posVtxs_in = NULL, const uint32_t & vtxCount = 0) const {
if(posVtxs_in && vtxCount) {
VertexShader::setAttributeBuffer(0, vtxCount * cuVertexAttrSize, cuVertexAttrSize, posVtxs_in);
VertexShader::setAttributeBuffer(1, vtxCount * cuColorAttrSize, cuColorAttrSize, colorAttr);
}
else {
} else {
VertexShader::setAttributeBuffer(0, cuPositionVtxsSize, cuVertexAttrSize, positionVtxs);
VertexShader::setAttributeBuffer(1, cuColorVtxsSize, cuColorAttrSize, colorAttr);
}
}
void setAngle(const float & val)
{
void setAngle(const float & val) {
VertexShader::setUniformReg(angleLocation, 4, &val);
}
void setOffset(const glm::vec3 & vec)
{
void setOffset(const glm::vec3 & vec) {
VertexShader::setUniformReg(offsetLocation, 4, &vec[0]);
}
void setScale(const glm::vec3 & vec)
{
void setScale(const glm::vec3 & vec) {
VertexShader::setUniformReg(scaleLocation, 4, &vec[0]);
}
void setColorIntensity(const glm::vec4 & vec)
{
void setColorIntensity(const glm::vec4 & vec) {
PixelShader::setUniformReg(colorIntensityLocation, 4, &vec[0]);
}
};

View File

@ -17,12 +17,11 @@
#ifndef __FXAA_SHADER_H_
#define __FXAA_SHADER_H_
#include "VertexShader.h"
#include "PixelShader.h"
#include "FetchShader.h"
#include <video/shaders/VertexShader.h>
#include <video/shaders/PixelShader.h>
#include <video/shaders/FetchShader.h>
class FXAAShader : public Shader
{
class FXAAShader : public Shader {
public:
static FXAAShader *instance() {
if(!shaderInstance) {
@ -37,36 +36,33 @@ public:
}
}
void setShaders(void) const
{
void setShaders(void) const {
fetchShader->setShader();
vertexShader.setShader();
pixelShader.setShader();
}
void setAttributeBuffer() const
{
void setAttributeBuffer() const {
VertexShader::setAttributeBuffer(0, ciPositionVtxsSize, cuVertexAttrSize, posVtxs);
VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords);
}
void setResolution(const glm::vec2 & vec)
{
void setResolution(const glm::vec2 & vec) {
PixelShader::setUniformReg(resolutionLocation, 4, &vec[0]);
}
void setTextureAndSampler(const GX2Texture *texture, const GX2Sampler *sampler) const {
GX2SetPixelTexture(texture, samplerLocation);
GX2SetPixelSampler(sampler, samplerLocation);
GX2SetPixelTexture((GX2Texture*)texture, samplerLocation);
GX2SetPixelSampler((GX2Sampler*)sampler, samplerLocation);
}
private:
FXAAShader();
virtual ~FXAAShader();
static const u32 cuAttributeCount = 2;
static const u32 ciPositionVtxsSize = 4 * cuVertexAttrSize;
static const u32 ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
static const uint32_t cuAttributeCount = 2;
static const uint32_t ciPositionVtxsSize = 4 * cuVertexAttrSize;
static const uint32_t ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
static FXAAShader *shaderInstance;
@ -74,13 +70,13 @@ private:
VertexShader vertexShader;
PixelShader pixelShader;
f32 *posVtxs;
f32 *texCoords;
float *posVtxs;
float *texCoords;
u32 samplerLocation;
u32 positionLocation;
u32 texCoordLocation;
u32 resolutionLocation;
uint32_t samplerLocation;
uint32_t positionLocation;
uint32_t texCoordLocation;
uint32_t resolutionLocation;
};
#endif // __FXAA_SHADER_H_

View File

@ -17,22 +17,19 @@
#ifndef FETCH_SHADER_H
#define FETCH_SHADER_H
#include "Shader.h"
#include <video/shaders/Shader.h>
class FetchShader : public Shader
{
class FetchShader : public Shader {
public:
FetchShader(GX2AttribStream * attributes, u32 attrCount, s32 type = GX2_FETCH_SHADER_TESSELATION_NONE, s32 tess = GX2_TESSELLATION_MODE_DISCRETE)
FetchShader(GX2AttribStream * attributes, uint32_t attrCount, GX2FetchShaderType type = GX2_FETCH_SHADER_TESSELLATION_NONE, GX2TessellationMode tess = GX2_TESSELLATION_MODE_DISCRETE)
: fetchShader(NULL)
, fetchShaderProgramm(NULL)
{
u32 shaderSize = GX2CalcFetchShaderSizeEx(attrCount, type, tess);
fetchShaderProgramm = memalign(GX2_SHADER_ALIGNMENT, shaderSize);
if(fetchShaderProgramm)
{
, fetchShaderProgramm(NULL) {
uint32_t shaderSize = GX2CalcFetchShaderSizeEx(attrCount, type, tess);
fetchShaderProgramm = (uint8_t*)memalign(GX2_SHADER_ALIGNMENT, shaderSize);
if(fetchShaderProgramm) {
fetchShader = new GX2FetchShader;
GX2InitFetchShaderEx(fetchShader, fetchShaderProgramm, attrCount, attributes, type, tess);
GX2Invalidate(GX2_INVALIDATE_CPU_SHADER, fetchShaderProgramm, shaderSize);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, fetchShaderProgramm, shaderSize);
}
}
virtual ~FetchShader() {
@ -52,7 +49,7 @@ public:
protected:
GX2FetchShader *fetchShader;
void *fetchShaderProgramm;
uint8_t *fetchShaderProgramm;
};
#endif // FETCH_SHADER_H

View File

@ -0,0 +1,137 @@
/****************************************************************************
* 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 PIXEL_SHADER_H
#define PIXEL_SHADER_H
#include <video/shaders/Shader.h>
class PixelShader : public Shader {
public:
PixelShader()
: pixelShader((GX2PixelShader*) memalign(0x40, sizeof(GX2PixelShader))) {
if(pixelShader) {
memset(pixelShader, 0, sizeof(GX2PixelShader));
pixelShader->mode = GX2_SHADER_MODE_UNIFORM_REGISTER;
}
}
virtual ~PixelShader() {
if(pixelShader) {
if(pixelShader->program)
free(pixelShader->program);
for(uint32_t i = 0; i < pixelShader->uniformBlockCount; i++)
free((void*)pixelShader->uniformBlocks[i].name);
if(pixelShader->uniformBlocks)
free((void*)pixelShader->uniformBlocks);
for(uint32_t i = 0; i < pixelShader->uniformVarCount; i++)
free((void*)pixelShader->uniformVars[i].name);
if(pixelShader->uniformVars)
free((void*)pixelShader->uniformVars);
if(pixelShader->initialValues)
free((void*)pixelShader->initialValues);
for(uint32_t i = 0; i < pixelShader->samplerVarCount; i++)
free((void*)pixelShader->samplerVars[i].name);
if(pixelShader->samplerVars)
free((void*)pixelShader->samplerVars);
if(pixelShader->loopVars)
free((void*)pixelShader->loopVars);
free(pixelShader);
}
}
void setProgram(const uint32_t * program, const uint32_t & programSize, const uint32_t * regs, const uint32_t & regsSize) {
if(!pixelShader)
return;
//! this must be moved into an area where the graphic engine has access to and must be aligned to 0x100
pixelShader->size = programSize;
pixelShader->program = (uint8_t*)memalign(GX2_SHADER_ALIGNMENT, pixelShader->size);
if(pixelShader->program) {
memcpy(pixelShader->program, program, pixelShader->size);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, pixelShader->program, pixelShader->size);
}
memcpy(&pixelShader->regs, regs, regsSize);
}
void addUniformVar(const GX2UniformVar & var) {
if(!pixelShader)
return;
uint32_t idx = pixelShader->uniformVarCount;
GX2UniformVar* newVar = (GX2UniformVar*) malloc((pixelShader->uniformVarCount + 1) * sizeof(GX2UniformVar));
if(newVar) {
if(pixelShader->uniformVars) {
memcpy(newVar, pixelShader->uniformVars, pixelShader->uniformVarCount * sizeof(GX2UniformVar));
free(pixelShader->uniformVars);
}
pixelShader->uniformVars = newVar;
memcpy(pixelShader->uniformVars + idx, &var, sizeof(GX2UniformVar));
pixelShader->uniformVars[idx].name = (char*) malloc(strlen(var.name) + 1);
strcpy((char*)pixelShader->uniformVars[idx].name, var.name);
pixelShader->uniformVarCount++;
}
}
void addSamplerVar(const GX2SamplerVar & var) {
if(!pixelShader)
return;
uint32_t idx = pixelShader->samplerVarCount;
GX2SamplerVar* newVar = (GX2SamplerVar*) malloc((pixelShader->samplerVarCount + 1) * sizeof(GX2SamplerVar));
if(newVar) {
if(pixelShader->samplerVars) {
memcpy(newVar, pixelShader->samplerVars, pixelShader->samplerVarCount * sizeof(GX2SamplerVar));
free(pixelShader->samplerVars);
}
pixelShader->samplerVars = newVar;
memcpy(pixelShader->samplerVars + idx, &var, sizeof(GX2SamplerVar));
pixelShader->samplerVars[idx].name = (char*) malloc(strlen(var.name) + 1);
strcpy((char*)pixelShader->samplerVars[idx].name, var.name);
pixelShader->samplerVarCount++;
}
}
GX2PixelShader * getPixelShader() const {
return pixelShader;
}
void setShader(void) const {
GX2SetPixelShader(pixelShader);
}
static inline void setUniformReg(uint32_t location, uint32_t size, const void * reg) {
GX2SetPixelUniformReg(location, size, (uint32_t *)reg);
}
protected:
GX2PixelShader *pixelShader;
};
#endif // PIXEL_SHADER_H

View File

@ -0,0 +1,69 @@
/****************************************************************************
* 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 SHADER_H_
#define SHADER_H_
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <utils/utils.h>
#include <gx2/shaders.h>
#include <gx2/mem.h>
#include <gx2/registers.h>
#include <gx2/draw.h>
class Shader {
protected:
Shader() {}
virtual ~Shader() {}
public:
static const uint16_t cuVertexAttrSize = sizeof(float) * 3;
static const uint16_t cuTexCoordAttrSize = sizeof(float) * 2;
static const uint16_t cuColorAttrSize = sizeof(uint8_t) * 4;
static void setLineWidth(const float & width) {
GX2SetLineWidth(width);
}
static void draw(int32_t primitive = GX2_PRIMITIVE_MODE_QUADS, uint32_t vtxCount = 4) {
switch(primitive) {
default:
case GX2_PRIMITIVE_MODE_QUADS: {
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, vtxCount, 0, 1);
break;
}
case GX2_PRIMITIVE_MODE_TRIANGLES: {
GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLES, vtxCount, 0, 1);
break;
}
case GX2_PRIMITIVE_MODE_TRIANGLE_FAN: {
GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLE_FAN, vtxCount, 0, 1);
break;
}
case GX2_PRIMITIVE_MODE_LINES: {
GX2DrawEx(GX2_PRIMITIVE_MODE_LINES, vtxCount, 0, 1);
break;
}
case GX2_PRIMITIVE_MODE_LINE_STRIP: {
GX2DrawEx(GX2_PRIMITIVE_MODE_LINE_STRIP, vtxCount, 0, 1);
break;
}
//! TODO: add other primitives later
};
}
};
#endif // SHADER_H_

View File

@ -17,12 +17,11 @@
#ifndef SHADER_3D_H_
#define SHADER_3D_H_
#include "VertexShader.h"
#include "PixelShader.h"
#include "FetchShader.h"
#include <video/shaders/VertexShader.h>
#include <video/shaders/PixelShader.h>
#include <video/shaders/FetchShader.h>
class Shader3D : public Shader
{
class Shader3D : public Shader {
private:
Shader3D();
virtual ~Shader3D();
@ -30,26 +29,26 @@ private:
static Shader3D * shaderInstance;
static const unsigned char cuAttributeCount = 2;
static const u32 ciPositionVtxsSize = 4 * cuVertexAttrSize;
static const u32 ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
static const uint32_t ciPositionVtxsSize = 4 * cuVertexAttrSize;
static const uint32_t ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
FetchShader *fetchShader;
VertexShader vertexShader;
PixelShader pixelShader;
f32 *posVtxs;
f32 *texCoords;
float *posVtxs;
float *texCoords;
u32 modelMatrixLocation;
u32 viewMatrixLocation;
u32 projectionMatrixLocation;
u32 positionLocation;
u32 texCoordLocation;
uint32_t modelMatrixLocation;
uint32_t viewMatrixLocation;
uint32_t projectionMatrixLocation;
uint32_t positionLocation;
uint32_t texCoordLocation;
u32 colorIntensityLocation;
u32 fadeDistanceLocation;
u32 fadeOutLocation;
u32 samplerLocation;
uint32_t colorIntensityLocation;
uint32_t fadeDistanceLocation;
uint32_t fadeOutLocation;
uint32_t samplerLocation;
public:
static Shader3D *instance() {
if(!shaderInstance) {
@ -64,55 +63,45 @@ public:
}
}
void setShaders(void) const
{
void setShaders(void) const {
fetchShader->setShader();
vertexShader.setShader();
pixelShader.setShader();
}
void setAttributeBuffer(const u32 & vtxCount = 0, const f32 * posVtxs_in = NULL, const f32 * texCoords_in = NULL) const
{
if(posVtxs_in && texCoords_in && vtxCount)
{
void setAttributeBuffer(const uint32_t & vtxCount = 0, const float * posVtxs_in = NULL, const float * texCoords_in = NULL) const {
if(posVtxs_in && texCoords_in && vtxCount) {
VertexShader::setAttributeBuffer(0, vtxCount * cuVertexAttrSize, cuVertexAttrSize, posVtxs_in);
VertexShader::setAttributeBuffer(1, vtxCount * cuTexCoordAttrSize, cuTexCoordAttrSize, texCoords_in);
}
else {
} else {
//! use default quad vertex and texture coordinates if nothing is passed
VertexShader::setAttributeBuffer(0, ciPositionVtxsSize, cuVertexAttrSize, posVtxs);
VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords);
}
}
void setProjectionMtx(const glm::mat4 & mtx)
{
void setProjectionMtx(const glm::mat4 & mtx) {
VertexShader::setUniformReg(projectionMatrixLocation, 16, &mtx[0][0]);
}
void setViewMtx(const glm::mat4 & mtx)
{
void setViewMtx(const glm::mat4 & mtx) {
VertexShader::setUniformReg(viewMatrixLocation, 16, &mtx[0][0]);
}
void setModelViewMtx(const glm::mat4 & mtx)
{
void setModelViewMtx(const glm::mat4 & mtx) {
VertexShader::setUniformReg(modelMatrixLocation, 16, &mtx[0][0]);
}
void setColorIntensity(const glm::vec4 & vec)
{
void setColorIntensity(const glm::vec4 & vec) {
PixelShader::setUniformReg(colorIntensityLocation, 4, &vec[0]);
}
void setAlphaFadeOut(const glm::vec4 & vec)
{
void setAlphaFadeOut(const glm::vec4 & vec) {
PixelShader::setUniformReg(fadeOutLocation, 4, &vec[0]);
}
void setDistanceFadeOut(const float & value)
{
void setDistanceFadeOut(const float & value) {
PixelShader::setUniformReg(fadeDistanceLocation, 4, &value);
}
void setTextureAndSampler(const GX2Texture *texture, const GX2Sampler *sampler) const {
GX2SetPixelTexture(texture, samplerLocation);
GX2SetPixelSampler(sampler, samplerLocation);
GX2SetPixelTexture((GX2Texture*)texture, samplerLocation);
GX2SetPixelSampler((GX2Sampler*)sampler, samplerLocation);
}
};

View File

@ -17,12 +17,10 @@
#ifndef SHADER_FRACTAL_COLOR_H_
#define SHADER_FRACTAL_COLOR_H_
#include "VertexShader.h"
#include "PixelShader.h"
#include "FetchShader.h"
class ShaderFractalColor : public Shader
{
#include <video/shaders/VertexShader.h>
#include <video/shaders/PixelShader.h>
#include <video/shaders/FetchShader.h>
class ShaderFractalColor : public Shader {
private:
ShaderFractalColor();
virtual ~ShaderFractalColor();
@ -30,29 +28,29 @@ private:
static ShaderFractalColor * shaderInstance;
static const unsigned char cuAttributeCount = 3;
static const u32 ciPositionVtxsSize = 4 * cuVertexAttrSize;
static const u32 ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
static const u32 ciColorVtxsSize = 4 * cuColorAttrSize;
static const uint32_t ciPositionVtxsSize = 4 * cuVertexAttrSize;
static const uint32_t ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
static const uint32_t ciColorVtxsSize = 4 * cuColorAttrSize;
FetchShader *fetchShader;
VertexShader vertexShader;
PixelShader pixelShader;
f32 *posVtxs;
f32 *texCoords;
u8 *colorVtxs;
float *posVtxs;
float *texCoords;
uint8_t *colorVtxs;
u32 modelMatrixLocation;
u32 viewMatrixLocation;
u32 projectionMatrixLocation;
u32 positionLocation;
u32 colorLocation;
u32 texCoordLocation;
uint32_t modelMatrixLocation;
uint32_t viewMatrixLocation;
uint32_t projectionMatrixLocation;
uint32_t positionLocation;
uint32_t colorLocation;
uint32_t texCoordLocation;
u32 blurLocation;
u32 colorIntensityLocation;
u32 fadeOutLocation;
u32 fractalLocation;
uint32_t blurLocation;
uint32_t colorIntensityLocation;
uint32_t fadeOutLocation;
uint32_t fractalLocation;
public:
static ShaderFractalColor *instance() {
if(!shaderInstance) {
@ -67,22 +65,18 @@ public:
}
}
void setShaders(void) const
{
void setShaders(void) const {
fetchShader->setShader();
vertexShader.setShader();
pixelShader.setShader();
}
void setAttributeBuffer(const u32 & vtxCount = 0, const f32 * posVtxs_in = NULL, const f32 * texCoords_in = NULL, const u8 * colorVtxs_in = NULL) const
{
if(posVtxs_in && texCoords_in && vtxCount)
{
void setAttributeBuffer(const uint32_t & vtxCount = 0, const float * posVtxs_in = NULL, const float * texCoords_in = NULL, const uint8_t * colorVtxs_in = NULL) const {
if(posVtxs_in && texCoords_in && vtxCount) {
VertexShader::setAttributeBuffer(0, vtxCount * cuVertexAttrSize, cuVertexAttrSize, posVtxs_in);
VertexShader::setAttributeBuffer(1, vtxCount * cuTexCoordAttrSize, cuTexCoordAttrSize, texCoords_in);
VertexShader::setAttributeBuffer(2, vtxCount * cuColorAttrSize, cuColorAttrSize, colorVtxs_in);
}
else {
} else {
//! use default quad vertex and texture coordinates if nothing is passed
VertexShader::setAttributeBuffer(0, ciPositionVtxsSize, cuVertexAttrSize, posVtxs);
VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords);
@ -90,33 +84,26 @@ public:
}
}
void setProjectionMtx(const glm::mat4 & mtx)
{
void setProjectionMtx(const glm::mat4 & mtx) {
VertexShader::setUniformReg(projectionMatrixLocation, 16, &mtx[0][0]);
}
void setViewMtx(const glm::mat4 & mtx)
{
void setViewMtx(const glm::mat4 & mtx) {
VertexShader::setUniformReg(viewMatrixLocation, 16, &mtx[0][0]);
}
void setModelViewMtx(const glm::mat4 & mtx)
{
void setModelViewMtx(const glm::mat4 & mtx) {
VertexShader::setUniformReg(modelMatrixLocation, 16, &mtx[0][0]);
}
void setBlurBorder(const float & blurBorderSize)
{
void setBlurBorder(const float & blurBorderSize) {
PixelShader::setUniformReg(blurLocation, 4, &blurBorderSize);
}
void setColorIntensity(const glm::vec4 & vec)
{
void setColorIntensity(const glm::vec4 & vec) {
PixelShader::setUniformReg(colorIntensityLocation, 4, &vec[0]);
}
void setAlphaFadeOut(const glm::vec4 & vec)
{
void setAlphaFadeOut(const glm::vec4 & vec) {
PixelShader::setUniformReg(fadeOutLocation, 4, &vec[0]);
}
void setFractalColor(const int & fractalColorEnable)
{
void setFractalColor(const int & fractalColorEnable) {
PixelShader::setUniformReg(fractalLocation, 4, &fractalColorEnable);
}
};

View File

@ -17,19 +17,19 @@
#ifndef __TEXTURE_2D_SHADER_H_
#define __TEXTURE_2D_SHADER_H_
#include "VertexShader.h"
#include "PixelShader.h"
#include "FetchShader.h"
#include <video/shaders/VertexShader.h>
#include <video/shaders/PixelShader.h>
#include <video/shaders/FetchShader.h>
class Texture2DShader : public Shader
{
class Texture2DShader : public Shader {
private:
Texture2DShader();
virtual ~Texture2DShader();
static const u32 cuAttributeCount = 2;
static const u32 ciPositionVtxsSize = 4 * cuVertexAttrSize;
static const u32 ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
static const uint32_t cuAttributeCount = 2;
static const uint32_t ciPositionVtxsSize = 4 * cuVertexAttrSize;
static const uint32_t ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
static Texture2DShader *shaderInstance;
@ -37,17 +37,17 @@ private:
VertexShader vertexShader;
PixelShader pixelShader;
f32 *posVtxs;
f32 *texCoords;
float *posVtxs;
float *texCoords;
u32 angleLocation;
u32 offsetLocation;
u32 scaleLocation;
u32 colorIntensityLocation;
u32 blurLocation;
u32 samplerLocation;
u32 positionLocation;
u32 texCoordLocation;
uint32_t angleLocation;
uint32_t offsetLocation;
uint32_t scaleLocation;
uint32_t colorIntensityLocation;
uint32_t blurLocation;
uint32_t samplerLocation;
uint32_t positionLocation;
uint32_t texCoordLocation;
public:
static Texture2DShader *instance() {
if(!shaderInstance) {
@ -62,50 +62,41 @@ public:
}
}
void setShaders(void) const
{
void setShaders(void) const {
fetchShader->setShader();
vertexShader.setShader();
pixelShader.setShader();
}
void setAttributeBuffer(const f32 * texCoords_in = NULL, const f32 * posVtxs_in = NULL, const u32 & vtxCount = 0) const
{
if(posVtxs_in && texCoords_in && vtxCount)
{
void setAttributeBuffer(const float * texCoords_in = NULL, const float * posVtxs_in = NULL, const uint32_t & vtxCount = 0) const {
if(posVtxs_in && texCoords_in && vtxCount) {
VertexShader::setAttributeBuffer(0, vtxCount * cuVertexAttrSize, cuVertexAttrSize, posVtxs_in);
VertexShader::setAttributeBuffer(1, vtxCount * cuTexCoordAttrSize, cuTexCoordAttrSize, texCoords_in);
}
else {
} else {
VertexShader::setAttributeBuffer(0, ciPositionVtxsSize, cuVertexAttrSize, posVtxs);
VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords);
}
}
void setAngle(const float & val)
{
void setAngle(const float & val) {
VertexShader::setUniformReg(angleLocation, 4, &val);
}
void setOffset(const glm::vec3 & vec)
{
void setOffset(const glm::vec3 & vec) {
VertexShader::setUniformReg(offsetLocation, 4, &vec[0]);
}
void setScale(const glm::vec3 & vec)
{
void setScale(const glm::vec3 & vec) {
VertexShader::setUniformReg(scaleLocation, 4, &vec[0]);
}
void setColorIntensity(const glm::vec4 & vec)
{
void setColorIntensity(const glm::vec4 & vec) {
PixelShader::setUniformReg(colorIntensityLocation, 4, &vec[0]);
}
void setBlurring(const glm::vec3 & vec)
{
void setBlurring(const glm::vec3 & vec) {
PixelShader::setUniformReg(blurLocation, 4, &vec[0]);
}
void setTextureAndSampler(const GX2Texture *texture, const GX2Sampler *sampler) const {
GX2SetPixelTexture(texture, samplerLocation);
GX2SetPixelSampler(sampler, samplerLocation);
GX2SetPixelTexture((GX2Texture*)texture, samplerLocation);
GX2SetPixelSampler((GX2Sampler*)sampler, samplerLocation);
}
};

View File

@ -0,0 +1,167 @@
/****************************************************************************
* 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 VERTEX_SHADER_H
#define VERTEX_SHADER_H
#include <string.h>
#include <video/shaders/Shader.h>
#include <gui/gx2_ext.h>
class VertexShader : public Shader {
public:
VertexShader(uint32_t numAttr)
: attributesCount( numAttr )
, attributes( new GX2AttribStream[attributesCount] )
, vertexShader( (GX2VertexShader*) memalign(0x40, sizeof(GX2VertexShader)) ) {
if(vertexShader) {
memset(vertexShader, 0, sizeof(GX2VertexShader));
vertexShader->mode = GX2_SHADER_MODE_UNIFORM_REGISTER;
}
}
virtual ~VertexShader() {
delete [] attributes;
if(vertexShader) {
if(vertexShader->program)
free(vertexShader->program);
for(uint32_t i = 0; i < vertexShader->uniformBlockCount; i++)
free((void*)vertexShader->uniformBlocks[i].name);
if(vertexShader->uniformBlocks)
free((void*)vertexShader->uniformBlocks);
for(uint32_t i = 0; i < vertexShader->uniformVarCount; i++)
free((void*)vertexShader->uniformVars[i].name);
if(vertexShader->uniformVars)
free((void*)vertexShader->uniformVars);
if(vertexShader->initialValues)
free((void*)vertexShader->initialValues);
for(uint32_t i = 0; i < vertexShader->samplerVarCount; i++)
free((void*)vertexShader->samplerVars[i].name);
if(vertexShader->samplerVars)
free((void*)vertexShader->samplerVars);
for(uint32_t i = 0; i < vertexShader->attribVarCount; i++)
free((void*)vertexShader->attribVars[i].name);
if(vertexShader->attribVars)
free((void*)vertexShader->attribVars);
if(vertexShader->loopVars)
free((void*)vertexShader->loopVars);
free(vertexShader);
}
}
void setProgram(const uint32_t * program, const uint32_t & programSize, const uint32_t * regs, const uint32_t & regsSize) {
if(!vertexShader)
return;
//! this must be moved into an area where the graphic engine has access to and must be aligned to 0x100
vertexShader->size = programSize;
vertexShader->program = (uint8_t*) memalign(GX2_SHADER_ALIGNMENT, vertexShader->size);
if(vertexShader->program) {
memcpy(vertexShader->program, program, vertexShader->size);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, vertexShader->program, vertexShader->size);
}
memcpy(&vertexShader->regs, regs, regsSize);
}
void addUniformVar(const GX2UniformVar & var) {
if(!vertexShader)
return;
uint32_t idx = vertexShader->uniformVarCount;
GX2UniformVar* newVar = (GX2UniformVar*) malloc((vertexShader->uniformVarCount + 1) * sizeof(GX2UniformVar));
if(newVar) {
if(vertexShader->uniformVarCount > 0) {
memcpy(newVar, vertexShader->uniformVars, vertexShader->uniformVarCount * sizeof(GX2UniformVar));
free(vertexShader->uniformVars);
}
vertexShader->uniformVars = newVar;
memcpy(vertexShader->uniformVars + idx, &var, sizeof(GX2UniformVar));
vertexShader->uniformVars[idx].name = (char*) malloc(strlen(var.name) + 1);
strcpy((char*)vertexShader->uniformVars[idx].name, var.name);
vertexShader->uniformVarCount++;
}
}
void addAttribVar(const GX2AttribVar & var) {
if(!vertexShader)
return;
uint32_t idx = vertexShader->attribVarCount;
GX2AttribVar* newVar = (GX2AttribVar*) malloc((vertexShader->attribVarCount + 1) * sizeof(GX2AttribVar));
if(newVar) {
if(vertexShader->attribVarCount > 0) {
memcpy(newVar, vertexShader->attribVars, vertexShader->attribVarCount * sizeof(GX2AttribVar));
free(vertexShader->attribVars);
}
vertexShader->attribVars = newVar;
memcpy(vertexShader->attribVars + idx, &var, sizeof(GX2AttribVar));
vertexShader->attribVars[idx].name = (char*) malloc(strlen(var.name) + 1);
strcpy((char*)vertexShader->attribVars[idx].name, var.name);
vertexShader->attribVarCount++;
}
}
static inline void setAttributeBuffer(uint32_t bufferIdx, uint32_t bufferSize, uint32_t stride, const void * buffer) {
GX2SetAttribBuffer(bufferIdx, bufferSize, stride, (void*)buffer);
}
GX2VertexShader *getVertexShader() const {
return vertexShader;
}
void setShader(void) const {
GX2SetVertexShader(vertexShader);
}
GX2AttribStream * getAttributeBuffer(uint32_t idx = 0) const {
if(idx >= attributesCount) {
return NULL;
}
return &attributes[idx];
}
uint32_t getAttributesCount() const {
return attributesCount;
}
static void setUniformReg(uint32_t location, uint32_t size, const void * reg) {
GX2SetVertexUniformReg(location, size, (uint32_t*)reg);
}
protected:
uint32_t attributesCount;
GX2AttribStream *attributes;
GX2VertexShader *vertexShader;
};
#endif // VERTEX_SHADER_H

169
libgui.layout Normal file
View File

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_layout_file>
<ActiveTarget name="build" />
<File name="source\gui\GuiDragListener.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="23" />
</Cursor>
</File>
<File name="source\video\shaders\ColorShader.h" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1984" topLine="19" />
</Cursor>
</File>
<File name="source\gui\GuiFrame.cpp" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="1" zoom_2="0">
<Cursor>
<Cursor1 position="4169" topLine="190" />
</Cursor>
</File>
<File name="source\gui\GameBgImage.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1407" topLine="0" />
</Cursor>
</File>
<File name="source\gui\GuiImage.cpp" open="0" top="0" tabpos="12" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3968" topLine="73" />
</Cursor>
</File>
<File name="source\gui\GuiFrame.h" open="0" top="0" tabpos="19" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="44" />
</Cursor>
</File>
<File name="source\gui\GridBackground.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="37" />
</Cursor>
</File>
<File name="source\video\shaders\PixelShader.h" open="0" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="5101" topLine="87" />
</Cursor>
</File>
<File name="source\gui\GuiImageData.cpp" open="0" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="908" topLine="12" />
</Cursor>
</File>
<File name="source\gui\GuiButton.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="60" />
</Cursor>
</File>
<File name="source\gui\FreeTypeGX.cpp" open="0" top="0" tabpos="21" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="18556" topLine="535" />
</Cursor>
</File>
<File name="source\resources\Resources.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="98" />
</Cursor>
</File>
<File name="source\gui\GuiImageData.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="4" />
</Cursor>
</File>
<File name="source\gui\GuiParticleImage.cpp" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="5191" topLine="69" />
</Cursor>
</File>
<File name="source\gui\GuiScrollbar.cpp" open="0" top="0" tabpos="16" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="0" />
</Cursor>
</File>
<File name="source\gui\GuiSelectBox.cpp" open="0" top="0" tabpos="17" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="10209" topLine="6" />
</Cursor>
</File>
<File name="source\gui\GuiSelectBox.h" open="0" top="0" tabpos="18" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1029" topLine="0" />
</Cursor>
</File>
<File name="source\gui\GuiText.cpp" open="0" top="0" tabpos="20" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="13325" topLine="552" />
</Cursor>
</File>
<File name="source\video\shaders\Texture2DShader.h" open="0" top="0" tabpos="13" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2033" topLine="16" />
</Cursor>
</File>
<File name="source\video\shaders\ColorShader.cpp" open="0" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="4960" topLine="104" />
</Cursor>
</File>
<File name="source\video\shaders\FXAAShader.cpp" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="161" />
</Cursor>
</File>
<File name="source\video\shaders\Shader3D.cpp" open="0" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="10122" topLine="182" />
</Cursor>
</File>
<File name="source\gui\GuiParticleImage.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1339" topLine="0" />
</Cursor>
</File>
<File name="source\video\shaders\ShaderFractalColor.cpp" open="0" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="81" />
</Cursor>
</File>
<File name="source\video\shaders\FXAAShader.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1894" topLine="0" />
</Cursor>
</File>
<File name="source\video\shaders\Shader3D.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1445" topLine="26" />
</Cursor>
</File>
<File name="source\video\CVideo.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="5104" topLine="227" />
</Cursor>
</File>
<File name="source\video\shaders\Texture2DShader.cpp" open="0" top="0" tabpos="10" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="10378" topLine="181" />
</Cursor>
</File>
<File name="source\video\shaders\FetchShader.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1964" topLine="0" />
</Cursor>
</File>
<File name="source\video\CursorDrawer.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2609" topLine="25" />
</Cursor>
</File>
<File name="source\video\CVideo.h" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="4936" topLine="99" />
</Cursor>
</File>
<File name="source\video\shaders\VertexShader.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="5756" topLine="115" />
</Cursor>
</File>
<File name="source\video\shaders\Shader.h" open="0" top="0" tabpos="14" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2281" topLine="11" />
</Cursor>
</File>
</CodeBlocks_layout_file>

Binary file not shown.

View File

@ -20,9 +20,9 @@
* along with FreeTypeGX. If not, see <http://www.gnu.org/licenses/>.
*/
#include "FreeTypeGX.h"
#include "video/CVideo.h"
#include "video/shaders/Texture2DShader.h"
#include <gui/FreeTypeGX.h>
#include <video/CVideo.h>
#include <video/shaders/Texture2DShader.h>
using namespace std;
@ -31,33 +31,30 @@ using namespace std;
/**
* Default constructor for the FreeTypeGX class for WiiXplorer.
*/
FreeTypeGX::FreeTypeGX(const uint8_t* fontBuffer, FT_Long bufferSize, bool lastFace)
{
int32_t faceIndex = 0;
ftPointSize = 0;
GX2InitSampler(&ftSampler, GX2_TEX_CLAMP_CLAMP_BORDER, GX2_TEX_XY_FILTER_BILINEAR);
FreeTypeGX::FreeTypeGX(const uint8_t* fontBuffer, FT_Long bufferSize, bool lastFace) {
int32_t faceIndex = 0;
ftPointSize = 0;
GX2InitSampler(&ftSampler, GX2_TEX_CLAMP_MODE_CLAMP_BORDER, GX2_TEX_XY_FILTER_MODE_LINEAR);
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);
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);
ftKerningEnabled = FT_HAS_KERNING(ftFace);
}
/**
* Default destructor for the FreeTypeGX class.
*/
FreeTypeGX::~FreeTypeGX()
{
unloadFont();
FT_Done_Face(ftFace);
FT_Done_FreeType(ftLibrary);
FreeTypeGX::~FreeTypeGX() {
unloadFont();
FT_Done_Face(ftFace);
FT_Done_FreeType(ftLibrary);
}
/**
@ -70,48 +67,44 @@ FreeTypeGX::~FreeTypeGX()
* @return Wide character representation of supplied character string.
*/
wchar_t* FreeTypeGX::charToWideChar(const char* strChar)
{
if (!strChar) return NULL;
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;
wchar_t *strWChar = new (std::nothrow) wchar_t[strlen(strChar) + 1];
if (!strWChar) return NULL;
int32_t bt = mbstowcs(strWChar, strChar, strlen(strChar));
if (bt > 0)
{
strWChar[bt] = 0;
return strWChar;
}
int32_t bt = mbstowcs(strWChar, strChar, strlen(strChar));
if (bt > 0) {
strWChar[bt] = 0;
return strWChar;
}
wchar_t *tempDest = strWChar;
while ((*tempDest++ = *strChar++))
;
wchar_t *tempDest = strWChar;
while ((*tempDest++ = *strChar++))
;
return strWChar;
return strWChar;
}
char *FreeTypeGX::wideCharToUTF8(const wchar_t* strChar)
{
char *FreeTypeGX::wideCharToUTF8(const wchar_t* strChar) {
if(!strChar) {
return NULL;
}
size_t len = 0;
wchar_t wc;
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;
}
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)
@ -119,31 +112,25 @@ char *FreeTypeGX::wideCharToUTF8(const wchar_t* strChar)
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;
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;
}
/**
@ -151,27 +138,23 @@ char *FreeTypeGX::wideCharToUTF8(const wchar_t* strChar)
*
* 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;
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);
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)
free(itr2->second.texture->surface.image);
delete itr2->second.texture;
itr2->second.texture = NULL;
}
}
}
}
fontData.clear();
fontData.clear();
}
/**
@ -183,24 +166,20 @@ void FreeTypeGX::unloadFont()
* @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;
}
}
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)
{
if (ftPointSize != pixelSize) {
ftPointSize = pixelSize;
FT_Set_Pixel_Sizes(ftFace, 0, ftPointSize);
ftData->ftgxAlign.ascender = (int16_t) ftFace->size->metrics.ascender >> 6;
@ -209,39 +188,37 @@ ftgxCharData * FreeTypeGX::cacheGlyphData(wchar_t charCode, int16_t pixelSize)
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;
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;
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;
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);
GX2InitTexture(charData->texture, textureWidth, textureHeight, 1, 0, GX2_SURFACE_FORMAT_UNORM_R5_G5_B5_A1, GX2_SURFACE_DIM_TEXTURE_2D, GX2_TILE_MODE_LINEAR_ALIGNED);
loadGlyphData(glyphBitmap, charData);
loadGlyphData(glyphBitmap, charData);
return charData;
}
}
return NULL;
return charData;
}
}
return NULL;
}
/**
@ -250,18 +227,16 @@ ftgxCharData * FreeTypeGX::cacheGlyphData(wchar_t charCode, int16_t pixelSize)
* 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;
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);
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);
}
/**
@ -274,27 +249,24 @@ uint16_t FreeTypeGX::cacheGlyphDataComplete(int16_t pixelSize)
* @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)
void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData) {
charData->texture->surface.image = (uint8_t *) memalign(charData->texture->surface.alignment, charData->texture->surface.imageSize);
if(!charData->texture->surface.image)
return;
memset(charData->texture->surface.image_data, 0x00, charData->texture->surface.image_size);
memset(charData->texture->surface.image, 0x00, charData->texture->surface.imageSize);
uint8_t *src = (uint8_t *)bmp->buffer;
uint16_t *dst = (uint16_t *)charData->texture->surface.image_data;
int32_t x, y;
uint8_t *src = (uint8_t *)bmp->buffer;
uint16_t *dst = (uint16_t *)charData->texture->surface.image;
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;
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);
}
}
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, charData->texture->surface.image, charData->texture->surface.imageSize);
}
/**
@ -305,14 +277,13 @@ void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData)
* @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;
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;
}
/**
@ -323,36 +294,34 @@ int16_t FreeTypeGX::getStyleOffsetWidth(uint16_t width, uint16_t format)
* @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;
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;
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_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_BOTTOM:
return itr->second.ftgxAlign.ascender;
case FTGX_ALIGN_BASELINE:
return 0;
case FTGX_ALIGN_BASELINE:
return 0;
case FTGX_ALIGN_GLYPH_TOP:
return itr->second.ftgxAlign.max;
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_MIDDLE:
return (itr->second.ftgxAlign.max + itr->second.ftgxAlign.min + 1) >> 1;
case FTGX_ALIGN_GLYPH_BOTTOM:
return itr->second.ftgxAlign.min;
}
return 0;
case FTGX_ALIGN_GLYPH_BOTTOM:
return itr->second.ftgxAlign.min;
}
return 0;
}
/**
@ -369,47 +338,41 @@ int16_t FreeTypeGX::getStyleOffsetHeight(int16_t format, uint16_t pixelSize)
* @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)
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;
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);
}
if (textStyle & FTGX_JUSTIFY_MASK) {
x_offset = getStyleOffsetWidth(fullTextWidth, textStyle);
}
if (textStyle & FTGX_ALIGN_MASK) {
y_offset = getStyleOffsetHeight(textStyle, pixelSize);
}
int32_t i = 0;
while (text[i])
{
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
int32_t 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);
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);
}
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;
}
x_pos += glyphData->glyphAdvanceX;
++printed;
}
++i;
}
return printed;
return printed;
}
@ -422,53 +385,46 @@ uint16_t FreeTypeGX::drawText(CVideo *video, int16_t x, int16_t y, int16_t z, co
* @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 FreeTypeGX::getWidth(const wchar_t *text, int16_t pixelSize) {
if (!text) return 0;
uint16_t strWidth = 0;
FT_Vector pairDelta;
int32_t i = 0;
uint16_t strWidth = 0;
FT_Vector pairDelta;
int32_t i = 0;
while (text[i])
{
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
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;
}
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;
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);
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;
}
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;
return strWidth;
}
/**
@ -480,10 +436,9 @@ uint16_t FreeTypeGX::getCharWidth(const wchar_t wChar, int16_t pixelSize, const
* @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;
uint16_t FreeTypeGX::getHeight(const wchar_t *text, int16_t pixelSize) {
getOffset(text, pixelSize);
return fontData[pixelSize].ftgxAlign.max - fontData[pixelSize].ftgxAlign.min;
}
/**
@ -496,42 +451,38 @@ uint16_t FreeTypeGX::getHeight(const wchar_t *text, int16_t pixelSize)
* @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())
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;
int16_t strMax = 0, strMin = 9999;
uint16_t currWidth = 0;
int32_t i = 0;
int32_t i = 0;
while (text[i])
{
if (widthLimit > 0 && currWidth >= widthLimit) break;
while (text[i]) {
if (widthLimit > 0 && currWidth >= widthLimit) break;
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
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;
}
if (glyphData != NULL) {
strMax = glyphData->renderOffsetMax > strMax ? glyphData->renderOffsetMax : strMax;
strMin = glyphData->renderOffsetMin < strMin ? glyphData->renderOffsetMin : strMin;
currWidth += glyphData->glyphAdvanceX;
}
++i;
}
++i;
}
if (ftPointSize != pixelSize)
{
ftPointSize = pixelSize;
FT_Set_Pixel_Sizes(ftFace, 0, ftPointSize);
}
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;
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;
}
/**
@ -546,20 +497,19 @@ void FreeTypeGX::getOffset(const wchar_t *text, int16_t pixelSize, uint16_t widt
* @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));
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 float imageAngle = 0.0f;
static const float 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();
float offsetLeft = blurScale * ((float)x + 0.5f * (float)texture->surface.width) * (float)pVideo->getWidthScaleFactor();
float offsetTop = blurScale * ((float)y - 0.5f * (float)texture->surface.height) * (float)pVideo->getHeightScaleFactor();
f32 widthScale = blurScale * (f32)texture->surface.width * pVideo->getWidthScaleFactor();
f32 heightScale = blurScale * (f32)texture->surface.height * pVideo->getHeightScaleFactor();
float widthScale = blurScale * (float)texture->surface.width * pVideo->getWidthScaleFactor();
float heightScale = blurScale * (float)texture->surface.height * pVideo->getHeightScaleFactor();
glm::vec3 positionOffsets( offsetLeft, offsetTop, (f32)z );
glm::vec3 positionOffsets( offsetLeft, offsetTop, (float)z );
//! blur doubles due to blur we have to scale the texture
//! blur doubles due to blur we have to scale the texture
glm::vec3 scaleFactor( widthScale, heightScale, 1.0f );
glm::vec3 blurDirection;
@ -572,8 +522,7 @@ void FreeTypeGX::copyTextureToFramebuffer(CVideo *pVideo, GX2Texture *texture, i
Texture2DShader::instance()->setScale(scaleFactor);
Texture2DShader::instance()->setTextureAndSampler(texture, &ftSampler);
if(blurIntensity > 0.0f)
{
if(blurIntensity > 0.0f) {
//! glow blur color
Texture2DShader::instance()->setColorIntensity(blurColor);

View File

@ -1,30 +1,27 @@
#include "GameBgImage.h"
#include "video/CVideo.h"
#include "video/shaders/Shader3D.h"
#include <gui/GameBgImage.h>
#include <video/CVideo.h>
#include <video/shaders/Shader3D.h>
GameBgImage::GameBgImage(const std::string & filename, GuiImageData *preloadImage)
: GuiImageAsync(filename, preloadImage)
{
: GuiImageAsync(filename, preloadImage) {
identity = glm::mat4(1.0f);
alphaFadeOut = glm::vec4(1.0f, 0.075f, 5.305f, 2.0f);
}
GameBgImage::~GameBgImage()
{
GameBgImage::~GameBgImage() {
}
void GameBgImage::draw(CVideo *pVideo)
{
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();
float currPosX = getCenterX();
float currPosY = getCenterY();
float currPosZ = getDepth();
float currScaleX = getScaleX() * (float)getWidth() * pVideo->getWidthScaleFactor();
float currScaleY = getScaleY() * (float)getHeight() * pVideo->getHeightScaleFactor();
float currScaleZ = getScaleZ() * (float)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));

View File

@ -1,13 +1,12 @@
#include "GridBackground.h"
#include "video/CVideo.h"
#include "video/shaders/Shader3D.h"
#include <gui/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)
{
: GuiImage(img) {
colorIntensity = glm::vec4(1.0f, 1.0f, 1.0f, 0.9f);
alphaFadeOut = glm::vec4(0.0f);
distanceFadeOut = 0.15f;
@ -15,26 +14,36 @@ GridBackground::GridBackground(GuiImageData *img)
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);
float *m_posVtxs = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, vtxCount * Shader3D::cuVertexAttrSize);
float *m_texCoords = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, vtxCount * Shader3D::cuTexCoordAttrSize);
if(m_posVtxs)
{
s32 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_posVtxs) {
int32_t 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_MODE_CPU_ATTRIBUTE_BUFFER, m_posVtxs, vtxCount * Shader3D::cuVertexAttrSize);
}
if(m_texCoords)
{
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;
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));
@ -44,13 +53,13 @@ GridBackground::GridBackground(GuiImageData *img)
sinRot, cosRot
});
for(s32 i = 0; i < 4; i++) {
for(int32_t 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);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, m_texCoords, vtxCount * Shader3D::cuTexCoordAttrSize);
}
//! assign to internal variables which are const but oh well
@ -58,30 +67,26 @@ GridBackground::GridBackground(GuiImageData *img)
texCoords = m_texCoords;
}
GridBackground::~GridBackground()
{
GridBackground::~GridBackground() {
//! remove image so it can not be drawn anymore from this point on
imageData = NULL;
//! main image vertexes
if(posVtxs)
{
if(posVtxs) {
free((void*)posVtxs);
posVtxs = NULL;
}
if(texCoords)
{
if(texCoords) {
free((void*)texCoords);
texCoords = NULL;
}
}
void GridBackground::draw(CVideo *pVideo, const glm::mat4 & modelView)
{
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();
float currScaleX = bgRepeat * scaleX * (float)getWidth() * pVideo->getWidthScaleFactor();
float currScaleY = 1.0f;
float currScaleZ = bgRepeat * scaleZ * (float)getHeight() * pVideo->getDepthScaleFactor();
m_modelView = glm::scale(modelView, glm::vec3(currScaleX, currScaleY, currScaleZ));
@ -96,5 +101,5 @@ void GridBackground::draw(CVideo *pVideo, const glm::mat4 & modelView)
Shader3D::instance()->setAlphaFadeOut(alphaFadeOut);
Shader3D::instance()->setColorIntensity(colorIntensity);
Shader3D::instance()->setAttributeBuffer(vtxCount, posVtxs, texCoords);
Shader3D::instance()->draw(GX2_PRIMITIVE_QUADS, vtxCount);
Shader3D::instance()->draw(GX2_PRIMITIVE_MODE_QUADS, vtxCount);
}

View File

@ -14,131 +14,108 @@
* 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"
#include <gui/GuiButton.h>
#include <gui/GuiTrigger.h>
#include <gui/GuiController.h>
/**
* Constructor for the GuiButton class.
*/
GuiButton::GuiButton(f32 w, f32 h)
{
GuiButton::GuiButton(float w, float h) {
width = w;
height = h;
image = NULL;
imageOver = NULL;
imageHold = NULL;
imageClick = NULL;
icon = NULL;
iconOver = NULL;
image = NULL;
imageOver = NULL;
imageHold = NULL;
imageClick = NULL;
icon = NULL;
iconOver = NULL;
for(s32 i = 0; i < 4; i++)
{
label[i] = NULL;
labelOver[i] = NULL;
labelHold[i] = NULL;
labelClick[i] = NULL;
}
for(s32 i = 0; i < iMaxGuiTriggers; i++)
{
trigger[i] = NULL;
}
for(int32_t i = 0; i < 4; i++) {
label[i] = NULL;
labelOver[i] = NULL;
labelHold[i] = NULL;
labelClick[i] = NULL;
}
for(int32_t i = 0; i < iMaxGuiTriggers; i++) {
trigger[i] = NULL;
}
soundOver = NULL;
soundHold = NULL;
soundClick = NULL;
clickedTrigger = NULL;
heldTrigger = NULL;
selectable = true;
holdable = false;
clickable = true;
soundOver = NULL;
soundHold = NULL;
soundClick = NULL;
clickedTrigger = NULL;
heldTrigger = NULL;
selectable = true;
holdable = false;
clickable = true;
}
/**
* Destructor for the GuiButton class.
*/
GuiButton::~GuiButton()
{
GuiButton::~GuiButton() {
}
void GuiButton::setImage(GuiImage* img)
{
image = img;
if(img) img->setParent(this);
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::setImageOver(GuiImage* img) {
imageOver = img;
if(img) img->setParent(this);
}
void GuiButton::setImageHold(GuiImage* img)
{
imageHold = 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::setImageClick(GuiImage* img) {
imageClick = img;
if(img) img->setParent(this);
}
void GuiButton::setIcon(GuiImage* img)
{
icon = 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::setIconOver(GuiImage* img) {
iconOver = img;
if(img) img->setParent(this);
}
void GuiButton::setLabel(GuiText* txt, s32 n)
{
label[n] = txt;
if(txt) txt->setParent(this);
void GuiButton::setLabel(GuiText* txt, int32_t n) {
label[n] = txt;
if(txt) txt->setParent(this);
}
void GuiButton::setLabelOver(GuiText* txt, s32 n)
{
labelOver[n] = txt;
if(txt) txt->setParent(this);
void GuiButton::setLabelOver(GuiText* txt, int32_t n) {
labelOver[n] = txt;
if(txt) txt->setParent(this);
}
void GuiButton::setLabelHold(GuiText* txt, s32 n)
{
labelHold[n] = txt;
if(txt) txt->setParent(this);
void GuiButton::setLabelHold(GuiText* txt, int32_t n) {
labelHold[n] = txt;
if(txt) txt->setParent(this);
}
void GuiButton::setLabelClick(GuiText* txt, s32 n)
{
labelClick[n] = txt;
if(txt) txt->setParent(this);
void GuiButton::setLabelClick(GuiText* txt, int32_t n) {
labelClick[n] = txt;
if(txt) txt->setParent(this);
}
void GuiButton::setSoundOver(GuiSound * snd)
{
soundOver = snd;
void GuiButton::setSoundOver(GuiSound * snd) {
soundOver = snd;
}
void GuiButton::setSoundHold(GuiSound * snd)
{
soundHold = snd;
void GuiButton::setSoundHold(GuiSound * snd) {
soundHold = snd;
}
void GuiButton::setSoundClick(GuiSound * snd)
{
soundClick = snd;
void GuiButton::setSoundClick(GuiSound * snd) {
soundClick = snd;
}
void GuiButton::setTrigger(GuiTrigger * t, s32 idx)
{
if(idx >= 0 && idx < iMaxGuiTriggers)
{
void GuiButton::setTrigger(GuiTrigger * t, int32_t idx) {
if(idx >= 0 && idx < iMaxGuiTriggers) {
trigger[idx] = t;
}
else
{
for(s32 i = 0; i < iMaxGuiTriggers; i++)
{
if(!trigger[i])
{
} else {
for(int32_t i = 0; i < iMaxGuiTriggers; i++) {
if(!trigger[i]) {
trigger[i] = t;
break;
}
@ -146,9 +123,8 @@ void GuiButton::setTrigger(GuiTrigger * t, s32 idx)
}
}
void GuiButton::resetState(void)
{
clickedTrigger = NULL;
void GuiButton::resetState(void) {
clickedTrigger = NULL;
heldTrigger = NULL;
GuiElement::resetState();
}
@ -156,113 +132,98 @@ void GuiButton::resetState(void)
/**
* Draw the button on screen
*/
void GuiButton::draw(CVideo *v)
{
if(!this->isVisible())
return;
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);
// 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);
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(s32 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);
}
// draw text
for(int32_t 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;
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(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(this->isRumbleActive())
// this->rumble(t->chan);
if(soundOver)
soundOver->Play();
if(soundOver)
soundOver->Play();
if(effectsOver && !effects)
{
// initiate effects
effects = effectsOver;
effectAmount = effectAmountOver;
effectTarget = effectTargetOver;
}
if(effectsOver && !effects) {
// initiate effects
effects = effectsOver;
effectAmount = effectAmountOver;
effectTarget = effectTargetOver;
}
pointedOn(this, c);
}
}
else if(isStateSet(STATE_OVER, c->chan))
{
}
} 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;
}
if(effectTarget == effectTargetOver && effectAmount == effectAmountOver) {
// initiate effects (in reverse)
effects = effectsOver;
effectAmount = -effectAmountOver;
effectTarget = 100;
}
}
}
for(s32 i = 0; i < iMaxGuiTriggers; i++)
{
for(int32_t i = 0; i < iMaxGuiTriggers; i++) {
if(!trigger[i])
continue;
// button triggers
if(clickable)
{
if(clickable) {
s32 isClicked = trigger[i]->clicked(c);
int32_t 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)))
{
&& (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){
if(!isStateSet(STATE_CLICKED, c->chan)) {
if(isClicked == GuiTrigger::CLICKED_TOUCH) {
setState(STATE_CLICKED_TOUCH, c->chan);
}else{
} 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))){
} 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]);
@ -270,25 +231,20 @@ void GuiButton::update(GuiController * c)
}
}
if(holdable)
{
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)))
{
&& (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)))
{
} 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])
{
if(clickedTrigger == trigger[i]) {
clickedTrigger = NULL;
clearState(STATE_CLICKED, c->chan);
}

View File

@ -1,117 +0,0 @@
/****************************************************************************
* 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, s32 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, s32 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, s32 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, s32 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, s32 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 s32 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

View File

@ -14,49 +14,55 @@
* 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"
#include <gui/GuiCheckBox.h>
#include <gui/GuiImage.h>
#include <gui/GuiImageData.h>
/**
* Constructor for the GuiCheckBox class.
*/
GuiCheckBox::GuiCheckBox(GuiImage * background, bool checked, f32 width,f32 height)
: GuiToggle(checked,width,height){
GuiCheckBox::GuiCheckBox(GuiImage * background, bool checked, float width,float height)
: GuiToggle(checked,width,height) {
setImageBackground(background);
}
/**
* Destructor for the GuiCheckBox class.
*/
GuiCheckBox::~GuiCheckBox(){
GuiCheckBox::~GuiCheckBox() {
}
void GuiCheckBox::setImageBackground(GuiImage* img){
backgroundImg = img;
if(img){ img->setParent(this); }
void GuiCheckBox::setImageBackground(GuiImage* img) {
backgroundImg = img;
if(img) {
img->setParent(this);
}
}
void GuiCheckBox::setImageSelected(GuiImage* img){
selectedImg = img;
if(img){ img->setParent(this); }
void GuiCheckBox::setImageSelected(GuiImage* img) {
selectedImg = img;
if(img) {
img->setParent(this);
}
}
void GuiCheckBox::setImageHighlighted(GuiImage* img){
void GuiCheckBox::setImageHighlighted(GuiImage* img) {
highlightedImg = img;
if(img){ img->setParent(this); }
setIconOver(img);
if(img) {
img->setParent(this);
}
setIconOver(img);
}
void GuiCheckBox::update(GuiController * c){
if(bChanged){
if(selected){
void GuiCheckBox::update(GuiController * c) {
if(bChanged) {
if(selected) {
GuiButton::setImage(selectedImg);
}else{
} else {
GuiButton::setImage(backgroundImg);
}
bChanged = false;
}
GuiToggle::update(c);
GuiToggle::update(c);
}

View File

@ -15,44 +15,38 @@
* 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 <gui/GuiDragListener.h>
#include <gui/GuiController.h>
#include <utils/logger.h>
/**
* Constructor for the GuiDragListener class.
*/
GuiDragListener::GuiDragListener(f32 w,f32 h){
GuiDragListener::GuiDragListener(float w,float h) {
width = w;
height = h;
for(s32 i = 0; i < iMaxGuiTriggers; i++)
{
trigger[i] = NULL;
}
for(int32_t i = 0; i < iMaxGuiTriggers; i++) {
trigger[i] = NULL;
}
}
/**
* Destructor for the GuiDragListener class.
*/
GuiDragListener::~GuiDragListener(){
GuiDragListener::~GuiDragListener() {
}
void GuiDragListener::setState(s32 i, s32 c){
void GuiDragListener::setState(int32_t i, int32_t c) {
GuiElement::setState(i,c);
}
void GuiDragListener::setTrigger(GuiTrigger * t, s32 idx){
if(idx >= 0 && idx < iMaxGuiTriggers)
{
void GuiDragListener::setTrigger(GuiTrigger * t, int32_t idx) {
if(idx >= 0 && idx < iMaxGuiTriggers) {
trigger[idx] = t;
}
else
{
for(s32 i = 0; i < iMaxGuiTriggers; i++)
{
if(!trigger[i])
{
} else {
for(int32_t i = 0; i < iMaxGuiTriggers; i++) {
if(!trigger[i]) {
trigger[i] = t;
break;
}
@ -60,23 +54,23 @@ void GuiDragListener::setTrigger(GuiTrigger * t, s32 idx){
}
}
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;
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(s32 i = 0; i < iMaxGuiTriggers; i++){
if(!trigger[i]){
for(int32_t 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)){
s32 dx = c->data.x - c->lastData.x;
s32 dy = c->data.y - c->lastData.y;
if(isHeld && this->isInside(c->data.x, c->data.y)) {
int32_t dx = c->data.x - c->lastData.x;
int32_t dy = c->data.y - c->lastData.y;
if(dx == 0 && dy == 0) continue;

View File

@ -1,53 +0,0 @@
/****************************************************************************
* 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();
void setState(s32 i, s32 c);
//!Set a new GuiTrigger for the element
//!\param i Index of trigger array to set
//!\param t Pointer to GuiTrigger
void setTrigger(GuiTrigger * t, s32 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 *,s32,s32> dragged;
protected:
static const s32 iMaxGuiTriggers = 10;
GuiTrigger * trigger[iMaxGuiTriggers]; //!< GuiTriggers (input actions) that this element responds to
};
#endif

View File

@ -14,50 +14,49 @@
* 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 <gui/GuiElement.h>
//! TODO remove this!
static s32 screenwidth = 1280;
static s32 screenheight = 720;
static int32_t screenwidth = 1280;
static int32_t 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(s32 i = 0; i < 4; i++)
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(int32_t 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;
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);
// default alignment - align to top left
alignment = (ALIGN_CENTER | ALIGN_MIDDLE);
}
/**
@ -65,34 +64,29 @@ GuiElement::GuiElement()
* @see SetLeft()
* @return Left position in pixel.
*/
f32 GuiElement::getLeft()
{
f32 pWidth = 0;
f32 pLeft = 0;
f32 pScaleX = 1.0f;
float GuiElement::getLeft() {
float pWidth = 0;
float pLeft = 0;
float pScaleX = 1.0f;
if(parentElement)
{
pWidth = parentElement->getWidth();
pLeft = parentElement->getLeft();
pScaleX = parentElement->getScaleX();
}
if(parentElement) {
pWidth = parentElement->getWidth();
pLeft = parentElement->getLeft();
pScaleX = parentElement->getScaleX();
}
pLeft += xoffsetDyn;
pLeft += xoffsetDyn;
f32 x = pLeft;
float 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();
}
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;
return x + xoffset;
}
/**
@ -100,244 +94,190 @@ f32 GuiElement::getLeft()
* @see SetTop()
* @return Top position in pixel.
*/
f32 GuiElement::getTop()
{
f32 pHeight = 0;
f32 pTop = 0;
f32 pScaleY = 1.0f;
float GuiElement::getTop() {
float pHeight = 0;
float pTop = 0;
float pScaleY = 1.0f;
if(parentElement)
{
pHeight = parentElement->getHeight();
pTop = parentElement->getTop();
pScaleY = parentElement->getScaleY();
}
if(parentElement) {
pHeight = parentElement->getHeight();
pTop = parentElement->getTop();
pScaleY = parentElement->getScaleY();
}
pTop += yoffsetDyn;
pTop += yoffsetDyn;
f32 y = pTop;
float 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 - getHeight() * 0.5f * getScaleY();
}
else if(alignment & ALIGN_BOTTOM)
{
y = pTop + pHeight * pScaleY - getHeight() * getScaleY();
}
if(alignment & ALIGN_MIDDLE) {
y = pTop + pHeight * 0.5f * pScaleY - getHeight() * 0.5f * getScaleY();
} else if(alignment & ALIGN_BOTTOM) {
y = pTop + pHeight * pScaleY - getHeight() * getScaleY();
}
return y + yoffset;
return y + yoffset;
}
void GuiElement::setEffect(s32 eff, s32 amount, s32 target)
{
if(eff & EFFECT_SLIDE_IN)
{
// these calculations overcompensate a little
if(eff & EFFECT_SLIDE_TOP)
{
if(eff & EFFECT_SLIDE_FROM)
yoffsetDyn = (s32) -getHeight()*scaleY;
else
yoffsetDyn = -screenheight;
}
else if(eff & EFFECT_SLIDE_LEFT)
{
if(eff & EFFECT_SLIDE_FROM)
xoffsetDyn = (s32) -getWidth()*scaleX;
else
xoffsetDyn = -screenwidth;
}
else if(eff & EFFECT_SLIDE_BOTTOM)
{
if(eff & EFFECT_SLIDE_FROM)
yoffsetDyn = (s32) getHeight()*scaleY;
else
yoffsetDyn = screenheight;
}
else if(eff & EFFECT_SLIDE_RIGHT)
{
if(eff & EFFECT_SLIDE_FROM)
xoffsetDyn = (s32) 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;
void GuiElement::setEffect(int32_t eff, int32_t amount, int32_t target) {
if(eff & EFFECT_SLIDE_IN) {
// these calculations overcompensate a little
if(eff & EFFECT_SLIDE_TOP) {
if(eff & EFFECT_SLIDE_FROM)
yoffsetDyn = (int32_t) -getHeight()*scaleY;
else
yoffsetDyn = -screenheight;
} else if(eff & EFFECT_SLIDE_LEFT) {
if(eff & EFFECT_SLIDE_FROM)
xoffsetDyn = (int32_t) -getWidth()*scaleX;
else
xoffsetDyn = -screenwidth;
} else if(eff & EFFECT_SLIDE_BOTTOM) {
if(eff & EFFECT_SLIDE_FROM)
yoffsetDyn = (int32_t) getHeight()*scaleY;
else
yoffsetDyn = screenheight;
} else if(eff & EFFECT_SLIDE_RIGHT) {
if(eff & EFFECT_SLIDE_FROM)
xoffsetDyn = (int32_t) 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(s32 e, s32 a, s32 t)
{
effectsOver |= e;
effectAmountOver = a;
effectTargetOver = t;
void GuiElement::setEffectOnOver(int32_t e, int32_t a, int32_t 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::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;
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(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;
if(xoffsetDyn >= 0) {
xoffsetDyn = 0;
effects = 0;
effectFinished(this);
}
}
else if(effects & EFFECT_SLIDE_RIGHT)
{
xoffsetDyn -= effectAmount;
}
} else if(effects & EFFECT_SLIDE_RIGHT) {
xoffsetDyn -= effectAmount;
if(xoffsetDyn <= 0)
{
xoffsetDyn = 0;
effects = 0;
if(xoffsetDyn <= 0) {
xoffsetDyn = 0;
effects = 0;
effectFinished(this);
}
}
else if(effects & EFFECT_SLIDE_TOP)
{
yoffsetDyn += effectAmount;
}
} else if(effects & EFFECT_SLIDE_TOP) {
yoffsetDyn += effectAmount;
if(yoffsetDyn >= 0)
{
yoffsetDyn = 0;
effects = 0;
if(yoffsetDyn >= 0) {
yoffsetDyn = 0;
effects = 0;
effectFinished(this);
}
}
else if(effects & EFFECT_SLIDE_BOTTOM)
{
yoffsetDyn -= effectAmount;
}
} else if(effects & EFFECT_SLIDE_BOTTOM) {
yoffsetDyn -= effectAmount;
if(yoffsetDyn <= 0)
{
yoffsetDyn = 0;
effects = 0;
if(yoffsetDyn <= 0) {
yoffsetDyn = 0;
effects = 0;
effectFinished(this);
}
}
}
else
{
if(effects & EFFECT_SLIDE_LEFT)
{
xoffsetDyn -= effectAmount;
}
}
} else {
if(effects & EFFECT_SLIDE_LEFT) {
xoffsetDyn -= effectAmount;
if(xoffsetDyn <= -screenwidth) {
effects = 0; // shut off effect
if(xoffsetDyn <= -screenwidth) {
effects = 0; // shut off effect
effectFinished(this);
}
else if((effects & EFFECT_SLIDE_FROM) && xoffsetDyn <= -getWidth()) {
effects = 0; // shut off effect
} else if((effects & EFFECT_SLIDE_FROM) && xoffsetDyn <= -getWidth()) {
effects = 0; // shut off effect
effectFinished(this);
}
}
else if(effects & EFFECT_SLIDE_RIGHT)
{
xoffsetDyn += effectAmount;
}
} else if(effects & EFFECT_SLIDE_RIGHT) {
xoffsetDyn += effectAmount;
if(xoffsetDyn >= screenwidth) {
effects = 0; // shut off effect
if(xoffsetDyn >= screenwidth) {
effects = 0; // shut off effect
effectFinished(this);
}
else if((effects & EFFECT_SLIDE_FROM) && xoffsetDyn >= getWidth()*scaleX) {
effects = 0; // shut off effect
} else if((effects & EFFECT_SLIDE_FROM) && xoffsetDyn >= getWidth()*scaleX) {
effects = 0; // shut off effect
effectFinished(this);
}
}
else if(effects & EFFECT_SLIDE_TOP)
{
yoffsetDyn -= effectAmount;
}
} else if(effects & EFFECT_SLIDE_TOP) {
yoffsetDyn -= effectAmount;
if(yoffsetDyn <= -screenheight) {
effects = 0; // shut off effect
if(yoffsetDyn <= -screenheight) {
effects = 0; // shut off effect
effectFinished(this);
}
else if((effects & EFFECT_SLIDE_FROM) && yoffsetDyn <= -getHeight()) {
effects = 0; // shut off effect
} else if((effects & EFFECT_SLIDE_FROM) && yoffsetDyn <= -getHeight()) {
effects = 0; // shut off effect
effectFinished(this);
}
}
else if(effects & EFFECT_SLIDE_BOTTOM)
{
yoffsetDyn += effectAmount;
}
} else if(effects & EFFECT_SLIDE_BOTTOM) {
yoffsetDyn += effectAmount;
if(yoffsetDyn >= screenheight) {
effects = 0; // shut off effect
if(yoffsetDyn >= screenheight) {
effects = 0; // shut off effect
effectFinished(this);
}
else if((effects & EFFECT_SLIDE_FROM) && yoffsetDyn >= getHeight()) {
effects = 0; // shut off effect
} 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);
}
}
}
} 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 && 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);
}
}
if((effectAmount < 0 && scaleDyn <= (effectTarget * 0.01f))
|| (effectAmount > 0 && scaleDyn >= (effectTarget * 0.01f))) {
scaleDyn = effectTarget * 0.01f;
effects = 0; // shut off effect
effectFinished(this);
}
}
}

View File

@ -1,529 +0,0 @@
/****************************************************************************
* 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 <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 <system/AsyncDeleter.h>
#include <utils/logger.h>
#include "resources/Resources.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 - getHeight() * 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 - getHeight() * 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(s32 s, s32 c = -1)
{
if(c >= 0 && c < 4)
{
state[c] |= s;
}
else
{
for(s32 i = 0; i < 4; i++)
state[i] |= s;
}
stateChan = c;
stateChanged(this, s, c);
}
virtual void clearState(s32 s, s32 c = -1)
{
if(c >= 0 && c < 4)
{
state[c] &= ~s;
}
else
{
for(s32 i = 0; i < 4; i++)
state[i] &= ~s;
}
stateChan = c;
stateChanged(this, s, c);
}
virtual bool isStateSet(s32 s, s32 c = -1) const
{
if(c >= 0 && c < 4)
{
return (state[c] & s) != 0;
}
else
{
for(s32 i = 0; i < 4; i++)
if((state[i] & s) != 0)
return true;
return false;
}
}
//!Gets the element's current state
//!\return state
virtual s32 getState(s32 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 s32 getStateChan() { return stateChan; };
//!Resets the element's state to STATE_DEFAULT
virtual void resetState()
{
for(s32 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(s32 e, s32 a, s32 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(s32 e, s32 a, s32 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 s32 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 s32 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(s32 a) { alignment = a; }
//!Gets the element's alignment
virtual s32 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 *, s32, s32> 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%)
s32 alignment; //!< Horizontal element alignment, respective to parent element
s32 state[4]; //!< Element state (DEFAULT, SELECTED, CLICKED, DISABLED)
s32 stateChan; //!< Which controller channel is responsible for the last change in state
GuiElement * parentElement; //!< Parent element
//! TODO: Move me to some Animator class
s32 xoffsetDyn; //!< Element X offset, dynamic (added to xoffset value for animation effects)
s32 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)
s32 effects; //!< Currently enabled effect(s). 0 when no effects are enabled
s32 effectAmount; //!< Effect amount. Used by different effects for different purposes
s32 effectTarget; //!< Effect target amount. Used by different effects for different purposes
s32 effectsOver; //!< Effects to enable when wiimote cursor is over this element. Copied to effects variable on over event
s32 effectAmountOver; //!< EffectAmount to set when wiimote cursor is over this element
s32 effectTargetOver; //!< EffectTarget to set when wiimote cursor is over this element
};
#endif

View File

@ -14,10 +14,9 @@
* 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"
#include <gui/GuiFrame.h>
GuiFrame::GuiFrame(GuiFrame *p)
{
GuiFrame::GuiFrame(GuiFrame *p) {
parent = p;
width = 0;
height = 0;
@ -27,8 +26,7 @@ GuiFrame::GuiFrame(GuiFrame *p)
parent->append(this);
}
GuiFrame::GuiFrame(f32 w, f32 h, GuiFrame *p)
{
GuiFrame::GuiFrame(float w, float h, GuiFrame *p) {
parent = p;
width = w;
height = h;
@ -38,16 +36,14 @@ GuiFrame::GuiFrame(f32 w, f32 h, GuiFrame *p)
parent->append(this);
}
GuiFrame::~GuiFrame()
{
GuiFrame::~GuiFrame() {
closing(this);
if(parent)
parent->remove(this);
}
void GuiFrame::append(GuiElement* e)
{
void GuiFrame::append(GuiElement* e) {
if (e == NULL)
return;
@ -56,8 +52,7 @@ void GuiFrame::append(GuiElement* e)
e->setParent(this);
}
void GuiFrame::insert(GuiElement* e, u32 index)
{
void GuiFrame::insert(GuiElement* e, uint32_t index) {
if (e == NULL || (index >= elements.size()))
return;
@ -66,96 +61,77 @@ void GuiFrame::insert(GuiElement* e, u32 index)
e->setParent(this);
}
void GuiFrame::remove(GuiElement* e)
{
void GuiFrame::remove(GuiElement* e) {
if (e == NULL)
return;
for (u32 i = 0; i < elements.size(); ++i)
{
if(e == elements[i])
{
for (uint32_t i = 0; i < elements.size(); ++i) {
if(e == elements[i]) {
elements.erase(elements.begin()+i);
break;
}
}
}
void GuiFrame::removeAll()
{
void GuiFrame::removeAll() {
elements.clear();
}
void GuiFrame::close()
{
void GuiFrame::close() {
//Application::instance()->pushForDelete(this);
}
void GuiFrame::dimBackground(bool d)
{
void GuiFrame::dimBackground(bool d) {
dim = d;
}
GuiElement* GuiFrame::getGuiElementAt(u32 index) const
{
GuiElement* GuiFrame::getGuiElementAt(uint32_t index) const {
if (index >= elements.size())
return NULL;
return elements[index];
}
u32 GuiFrame::getSize()
{
uint32_t GuiFrame::getSize() {
return elements.size();
}
void GuiFrame::resetState()
{
void GuiFrame::resetState() {
GuiElement::resetState();
for (u32 i = 0; i < elements.size(); ++i)
{
for (uint32_t i = 0; i < elements.size(); ++i) {
elements[i]->resetState();
}
}
void GuiFrame::setState(s32 s, s32 c)
{
void GuiFrame::setState(int32_t s, int32_t c) {
GuiElement::setState(s, c);
for (u32 i = 0; i < elements.size(); ++i)
{
for (uint32_t i = 0; i < elements.size(); ++i) {
elements[i]->setState(s, c);
}
}
void GuiFrame::clearState(s32 s, s32 c)
{
void GuiFrame::clearState(int32_t s, int32_t c) {
GuiElement::clearState(s, c);
for (u32 i = 0; i < elements.size(); ++i)
{
for (uint32_t i = 0; i < elements.size(); ++i) {
elements[i]->clearState(s, c);
}
}
void GuiFrame::setVisible(bool v)
{
void GuiFrame::setVisible(bool v) {
visible = v;
for (u32 i = 0; i < elements.size(); ++i)
{
for (uint32_t i = 0; i < elements.size(); ++i) {
elements[i]->setVisible(v);
}
}
s32 GuiFrame::getSelected()
{
int32_t GuiFrame::getSelected() {
// find selected element
s32 found = -1;
for (u32 i = 0; i < elements.size(); ++i)
{
if(elements[i]->isStateSet(STATE_SELECTED | STATE_OVER))
{
int32_t found = -1;
for (uint32_t i = 0; i < elements.size(); ++i) {
if(elements[i]->isStateSet(STATE_SELECTED | STATE_OVER)) {
found = i;
break;
}
@ -163,68 +139,59 @@ s32 GuiFrame::getSelected()
return found;
}
void GuiFrame::draw(CVideo * v)
{
void GuiFrame::draw(CVideo * v) {
if(!this->isVisible() && parentElement)
return;
if(parentElement && dim == true)
{
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();
uint32_t size = elements.size();
for (u32 i = 0; i < size && i < elements.size(); ++i)
{
for (uint32_t i = 0; i < size && i < elements.size(); ++i) {
elements[i]->draw(v);
}
}
void GuiFrame::updateEffects()
{
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();
uint32_t size = elements.size();
for (u32 i = 0; i < size && i < elements.size(); ++i)
{
for (uint32_t i = 0; i < size && i < elements.size(); ++i) {
elements[i]->updateEffects();
}
}
void GuiFrame::process()
{
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();
uint32_t size = elements.size();
for (u32 i = 0; i < size && i < elements.size(); ++i)
{
for (uint32_t i = 0; i < size && i < elements.size(); ++i) {
elements[i]->process();
}
}
void GuiFrame::update(GuiController * c)
{
void GuiFrame::update(GuiController * c) {
if(isStateSet(STATE_DISABLED) && parentElement)
return;
//! update appended items next frame
u32 size = elements.size();
uint32_t size = elements.size();
for (u32 i = 0; i < size && i < elements.size(); ++i)
{
for (uint32_t i = 0; i < size && i < elements.size(); ++i) {
elements[i]->update(c);
}
}

View File

@ -1,98 +0,0 @@
/****************************************************************************
* 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(s32 s, s32 c = -1);
void clearState(s32 s, s32 c = -1);
//!Gets the index of the GuiElement inside the window that is currently selected
//!\return index of selected GuiElement
s32 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

View File

@ -14,54 +14,47 @@
* 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"
#include <gui/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);
static const float fPiDiv180 = ((float)M_PI / 180.0f);
GuiImage::GuiImage(GuiImageData * img)
{
if(img && img->getTexture())
{
width = img->getWidth();
height = img->getHeight();
}
GuiImage::GuiImage(GuiImageData * img) {
if(img && img->getTexture()) {
width = img->getWidth();
height = img->getHeight();
}
internalInit(width, height);
imageData = img;
internalInit(width, height);
imageData = img;
}
GuiImage::GuiImage(s32 w, s32 h, const GX2Color & c, s32 type)
{
internalInit(w, h);
imgType = type;
colorCount = ColorShader::cuColorVtxsSize / ColorShader::cuColorAttrSize;
GuiImage::GuiImage(int32_t w, int32_t h, const GX2Color & c, int32_t 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++)
colorVtxs = (uint8_t *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, colorCount * ColorShader::cuColorAttrSize);
if(colorVtxs) {
for(uint32_t i = 0; i < colorCount; i++)
setImageColor(c, i);
}
}
GuiImage::GuiImage(s32 w, s32 h, const GX2Color *c, u32 color_count, s32 type)
{
internalInit(w, h);
imgType = type;
colorCount = ColorShader::cuColorVtxsSize / ColorShader::cuColorAttrSize;
if(colorCount < color_count)
GuiImage::GuiImage(int32_t w, int32_t h, const GX2Color *c, uint32_t color_count, int32_t 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++)
{
colorVtxs = (uint8_t *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, colorCount * ColorShader::cuColorAttrSize);
if(colorVtxs) {
for(uint32_t i = 0; i < colorCount; i++) {
// take the last as reference if not enough colors defined
s32 idx = (i < color_count) ? i : (color_count - 1);
int32_t idx = (i < color_count) ? i : (color_count - 1);
setImageColor(c[idx], i);
}
}
@ -70,29 +63,27 @@ GuiImage::GuiImage(s32 w, s32 h, const GX2Color *c, u32 color_count, s32 type)
/**
* Destructor for the GuiImage class.
*/
GuiImage::~GuiImage()
{
GuiImage::~GuiImage() {
if(colorVtxs) {
free(colorVtxs);
colorVtxs = NULL;
}
}
void GuiImage::internalInit(s32 w, s32 h)
{
imageData = NULL;
width = w;
height = h;
tileHorizontal = -1;
tileVertical = -1;
imgType = IMAGE_TEXTURE;
colorVtxsDirty = false;
colorVtxs = NULL;
colorCount = 0;
void GuiImage::internalInit(int32_t w, int32_t 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;
primitive = GX2_PRIMITIVE_MODE_QUADS;
imageAngle = 0.0f;
blurDirection = glm::vec3(0.0f);
@ -101,65 +92,58 @@ void GuiImage::internalInit(s32 w, s32 h)
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;
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(s32 x, s32 y)
{
if(!imageData || this->getWidth() <= 0 || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight())
return (GX2Color){0, 0, 0, 0};
GX2Color GuiImage::getPixel(int32_t x, int32_t 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;
uint32_t pitch = imageData->getTexture()->surface.pitch;
uint32_t *imagePtr = (uint32_t*)imageData->getTexture()->surface.image;
u32 color_u32 = imagePtr[y * pitch + x];
uint32_t 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;
return color;
}
void GuiImage::setPixel(s32 x, s32 y, const GX2Color & color)
{
if(!imageData || this->getWidth() <= 0 || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight())
return;
void GuiImage::setPixel(int32_t x, int32_t 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;
uint32_t pitch = imageData->getTexture()->surface.pitch;
uint32_t *imagePtr = (uint32_t*)imageData->getTexture()->surface.image;
imagePtr[y * pitch + x] = (color.r << 24) | (color.g << 16) | (color.b << 8) | (color.a << 0);
}
void GuiImage::setImageColor(const GX2Color & c, s32 idx)
{
void GuiImage::setImageColor(const GX2Color & c, int32_t idx) {
if(!colorVtxs) {
return;
}
if(idx >= 0 && idx < (s32)colorCount)
{
if(idx >= 0 && idx < (int32_t)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)
{
} else if(colorVtxs) {
for(uint32_t i = 0; i < (ColorShader::cuColorVtxsSize / sizeof(uint8_t)); i += 4) {
colorVtxs[i + 0] = c.r;
colorVtxs[i + 1] = c.g;
colorVtxs[i + 2] = c.b;
@ -169,27 +153,23 @@ void GuiImage::setImageColor(const GX2Color & c, s32 idx)
}
}
void GuiImage::setSize(s32 w, s32 h)
{
width = w;
height = h;
void GuiImage::setSize(int32_t w, int32_t h) {
width = w;
height = h;
}
void GuiImage::setPrimitiveVertex(s32 prim, const f32 *posVtx, const f32 *texCoord, u32 vtxcount)
{
void GuiImage::setPrimitiveVertex(int32_t prim, const float *posVtx, const float *texCoord, uint32_t vtxcount) {
primitive = prim;
vtxCount = vtxcount;
posVtxs = posVtx;
texCoords = texCoord;
if(imgType == IMAGE_COLOR)
{
u8 * newColorVtxs = (u8 *) memalign(0x40, ColorShader::cuColorAttrSize * vtxCount);
if(imgType == IMAGE_COLOR) {
uint8_t * newColorVtxs = (uint8_t *) memalign(0x40, ColorShader::cuColorAttrSize * vtxCount);
for(u32 i = 0; i < vtxCount; i++)
{
s32 newColorIdx = (i << 2);
s32 colorIdx = (i < colorCount) ? (newColorIdx) : ((colorCount - 1) << 2);
for(uint32_t i = 0; i < vtxCount; i++) {
int32_t newColorIdx = (i << 2);
int32_t colorIdx = (i < colorCount) ? (newColorIdx) : ((colorCount - 1) << 2);
newColorVtxs[newColorIdx + 0] = colorVtxs[colorIdx + 0];
newColorVtxs[newColorIdx + 1] = colorVtxs[colorIdx + 1];
@ -204,13 +184,12 @@ void GuiImage::setPrimitiveVertex(s32 prim, const f32 *posVtx, const f32 *texCoo
}
}
void GuiImage::draw(CVideo *pVideo)
{
if(!this->isVisible() || tileVertical == 0 || tileHorizontal == 0)
return;
void GuiImage::draw(CVideo *pVideo) {
if(!this->isVisible() || tileVertical == 0 || tileHorizontal == 0)
return;
f32 currScaleX = getScaleX();
f32 currScaleY = getScaleY();
float currScaleX = getScaleX();
float currScaleY = getScaleY();
positionOffsets[0] = getCenterX() * pVideo->getWidthScaleFactor() * 2.0f;
positionOffsets[1] = getCenterY() * pVideo->getHeightScaleFactor() * 2.0f;
@ -228,8 +207,8 @@ void GuiImage::draw(CVideo *pVideo)
// if(image && tileHorizontal > 0 && tileVertical > 0)
// {
// for(s32 n=0; n<tileVertical; n++)
// for(s32 i=0; i<tileHorizontal; i++)
// for(int32_t n=0; n<tileVertical; n++)
// for(int32_t i=0; i<tileHorizontal; i++)
// {
// if(bUnCut)
// Menu_DrawImg(image, width, height, format, currLeft+width*i, currTop+width*n, currZ, imageangle, currScaleX, currScaleY, currAlpha);
@ -239,9 +218,9 @@ void GuiImage::draw(CVideo *pVideo)
// }
// else if(image && tileHorizontal > 0)
// {
// for(s32 i=0; i<tileHorizontal; i++)
// for(int32_t i=0; i<tileHorizontal; i++)
// {
// s32 widthTile = (imageangle == 90 || imageangle == 270) ? height : width;
// int32_t 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
@ -250,7 +229,7 @@ void GuiImage::draw(CVideo *pVideo)
// }
// else if(image && tileVertical > 0)
// {
// for(s32 i=0; i<tileVertical; i++)
// for(int32_t i=0; i<tileVertical; i++)
// {
// if(bUnCut)
// Menu_DrawImg(image, width, height, format, currLeft, currTop+height*i, currZ, imageangle, currScaleX, currScaleY, currAlpha);
@ -260,12 +239,11 @@ void GuiImage::draw(CVideo *pVideo)
// }
if(colorVtxsDirty && colorVtxs) {
//! flush color vertex only on main GX2 thread
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, colorVtxs, colorCount * ColorShader::cuColorAttrSize);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, colorVtxs, colorCount * ColorShader::cuColorAttrSize);
colorVtxsDirty = false;
}
if(imgType == IMAGE_COLOR && colorVtxs)
{
if(imgType == IMAGE_COLOR && colorVtxs) {
ColorShader::instance()->setShaders();
ColorShader::instance()->setAttributeBuffer(colorVtxs, posVtxs, vtxCount);
ColorShader::instance()->setAngle(imageAngle);
@ -273,9 +251,7 @@ void GuiImage::draw(CVideo *pVideo)
ColorShader::instance()->setScale(scaleFactor);
ColorShader::instance()->setColorIntensity(colorIntensity);
ColorShader::instance()->draw(primitive, vtxCount);
}
else if(imageData)
{
} else if(imageData) {
Texture2DShader::instance()->setShaders();
Texture2DShader::instance()->setAttributeBuffer(texCoords, posVtxs, vtxCount);
Texture2DShader::instance()->setAngle(imageAngle);
@ -285,5 +261,5 @@ void GuiImage::draw(CVideo *pVideo)
Texture2DShader::instance()->setBlurring(blurDirection);
Texture2DShader::instance()->setTextureAndSampler(imageData->getTexture(), imageData->getSampler());
Texture2DShader::instance()->draw(primitive, vtxCount);
}
}
}

View File

@ -15,160 +15,137 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <unistd.h>
#include "GuiImageAsync.h"
#include <gui/GuiImageAsync.h>
#include <fs/FSUtils.h>
std::vector<GuiImageAsync *> GuiImageAsync::imageQueue;
CThread * GuiImageAsync::pThread = NULL;
CMutex * GuiImageAsync::pMutex = NULL;
u32 GuiImageAsync::threadRefCounter = 0;
uint32_t GuiImageAsync::threadRefCounter = 0;
bool GuiImageAsync::bExitRequested = false;
GuiImageAsync * GuiImageAsync::pInUse = NULL;
GuiImageAsync::GuiImageAsync(const u8 *imageBuffer, const u32 & imageBufferSize, GuiImageData * preloadImg)
GuiImageAsync::GuiImageAsync(const uint8_t *imageBuffer, const uint32_t & imageBufferSize, GuiImageData * preloadImg)
: GuiImage(preloadImg)
, imgData(NULL)
, imgBuffer(imageBuffer)
, imgBufferSize(imageBufferSize)
{
threadInit();
threadAddImage(this);
, 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);
, imgData(NULL)
, filename(file)
, imgBuffer(NULL)
, imgBufferSize(0) {
threadInit();
threadAddImage(this);
}
GuiImageAsync::~GuiImageAsync()
{
threadRemoveImage(this);
while(pInUse == this)
os_usleep(1000);
GuiImageAsync::~GuiImageAsync() {
threadRemoveImage(this);
while(pInUse == this)
OSSleepTicks(OSMicrosecondsToTicks(1000));
if (imgData)
if (imgData)
delete imgData;
//threadExit();
}
void GuiImageAsync::threadAddImage(GuiImageAsync *Image)
{
void GuiImageAsync::threadAddImage(GuiImageAsync *Image) {
pMutex->lock();
imageQueue.push_back(Image);
imageQueue.push_back(Image);
pMutex->unlock();
pThread->resumeThread();
pThread->resumeThread();
}
void GuiImageAsync::threadRemoveImage(GuiImageAsync *image)
{
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;
}
}
for(uint32_t i = 0; i < imageQueue.size(); ++i) {
if(imageQueue[i] == image) {
imageQueue.erase(imageQueue.begin() + i);
break;
}
}
pMutex->unlock();
}
void GuiImageAsync::clearQueue()
{
void GuiImageAsync::clearQueue() {
pMutex->lock();
imageQueue.clear();
imageQueue.clear();
pMutex->unlock();
}
void GuiImageAsync::guiImageAsyncThread(CThread *thread, void *arg)
{
while(!bExitRequested)
{
void GuiImageAsync::guiImageAsyncThread(CThread *thread, void *arg) {
while(!bExitRequested) {
if(imageQueue.empty() && !bExitRequested)
pThread->suspendThread();
if(!imageQueue.empty() && !bExitRequested)
{
if(!imageQueue.empty() && !bExitRequested) {
pMutex->lock();
pInUse = imageQueue.front();
imageQueue.erase(imageQueue.begin());
pInUse = imageQueue.front();
imageQueue.erase(imageQueue.begin());
pMutex->unlock();
if (!pInUse)
continue;
if (!pInUse)
continue;
if(pInUse->imgBuffer && pInUse->imgBufferSize)
{
if(pInUse->imgBuffer && pInUse->imgBufferSize) {
pInUse->imgData = new GuiImageData(pInUse->imgBuffer, pInUse->imgBufferSize);
}
else
{
u8 *buffer = NULL;
u32 bufferSize = 0;
} else {
uint8_t *buffer = NULL;
uint32_t bufferSize = 0;
s32 iResult = FSUtils::LoadFileToMem(pInUse->filename.c_str(), &buffer, &bufferSize);
if(iResult > 0)
{
pInUse->imgData = new GuiImageData(buffer, bufferSize, GX2_TEX_CLAMP_MIRROR);
int32_t iResult = FSUtils::LoadFileToMem(pInUse->filename.c_str(), &buffer, &bufferSize);
if(iResult > 0) {
pInUse->imgData = new GuiImageData(buffer, bufferSize, GX2_TEX_CLAMP_MODE_MIRROR);
//! free original image buffer which is converted to texture now and not needed anymore
free(buffer);
}
}
if(pInUse->imgData)
{
if(pInUse->imgData->getTexture())
{
if(pInUse->imgData) {
if(pInUse->imgData->getTexture()) {
pInUse->width = pInUse->imgData->getWidth();
pInUse->height = pInUse->imgData->getHeight();
pInUse->imageData = pInUse->imgData;
}
else
{
} else {
delete pInUse->imgData;
pInUse->imgData = NULL;
}
}
pInUse->imageLoaded(pInUse);
pInUse = NULL;
}
}
pInUse = NULL;
}
}
}
void GuiImageAsync::threadInit()
{
if (pThread == 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();
pThread = CThread::create(GuiImageAsync::guiImageAsyncThread, NULL, CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 10);
pThread->resumeThread();
}
++threadRefCounter;
}
void GuiImageAsync::threadExit()
{
if(threadRefCounter){
void GuiImageAsync::threadExit() {
if(threadRefCounter) {
--threadRefCounter;
}
if(/*(threadRefCounter == 0) &&*/ (pThread != NULL))
{
bExitRequested = true;
if(/*(threadRefCounter == 0) &&*/ (pThread != NULL)) {
bExitRequested = true;
delete pThread;
delete pMutex;
pThread = NULL;
pMutex = NULL;
}
}
}

View File

@ -1,62 +0,0 @@
/****************************************************************************
* 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_*/

View File

@ -16,52 +16,47 @@
****************************************************************************/
#include <malloc.h>
#include <string.h>
#include "GuiImageData.h"
#include <stdint.h>
#include <gui/GuiImageData.h>
#include <system/memory.h>
/**
* Constructor for the GuiImageData class.
*/
GuiImageData::GuiImageData()
{
GuiImageData::GuiImageData() {
texture = NULL;
sampler = NULL;
memoryType = eMemTypeMEM2;
memoryType = eMemTypeMEM2;
}
/**
* Constructor for the GuiImageData class.
*/
GuiImageData::GuiImageData(const u8 * img, s32 imgSize, s32 textureClamp, s32 textureFormat)
{
GuiImageData::GuiImageData(const uint8_t * img, int32_t imgSize, GX2TexClampMode textureClamp, GX2SurfaceFormat textureFormat) {
texture = NULL;
sampler = NULL;
loadImage(img, imgSize, textureClamp, textureFormat);
loadImage(img, imgSize, textureClamp, textureFormat);
}
/**
* Destructor for the GuiImageData class.
*/
GuiImageData::~GuiImageData()
{
GuiImageData::~GuiImageData() {
releaseData();
}
void GuiImageData::releaseData(void)
{
void GuiImageData::releaseData(void) {
if(texture) {
if(texture->surface.image_data)
{
switch(memoryType)
{
if(texture->surface.image) {
switch(memoryType) {
default:
case eMemTypeMEM2:
free(texture->surface.image_data);
free(texture->surface.image);
break;
case eMemTypeMEM1:
MEM1_free(texture->surface.image_data);
MEM1_free(texture->surface.image);
break;
case eMemTypeMEMBucket:
MEMBucket_free(texture->surface.image_data);
MEMBucket_free(texture->surface.image);
break;
}
}
@ -74,50 +69,43 @@ void GuiImageData::releaseData(void)
}
}
void GuiImageData::loadImage(const u8 *img, s32 imgSize, s32 textureClamp, s32 textureFormat)
{
if(!img || (imgSize < 8))
return;
void GuiImageData::loadImage(const uint8_t *img, int32_t imgSize, GX2TexClampMode textureClamp, GX2SurfaceFormat textureFormat) {
if(!img || (imgSize < 8))
return;
releaseData();
gdImagePtr gdImg = 0;
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 (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, (uint8_t*) img);
} else if (img[0] == 'B' && img[1] == 'M') {
// IMAGE_BMP
//gdImg = gdImageCreateFromBmpPtr(imgSize, (uint8_t*) img);
} else if (img[0] == 0x89 && img[1] == 'P' && img[2] == 'N' && img[3] == 'G') {
// IMAGE_PNG
gdImg = gdImageCreateFromPngPtr(imgSize, (uint8_t*) 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, (uint8_t*) img);
}
if(gdImg == 0)
return;
if(gdImg == 0)
return;
u32 width = (gdImageSX(gdImg));
u32 height = (gdImageSY(gdImg));
uint32_t width = (gdImageSX(gdImg));
uint32_t height = (gdImageSY(gdImg));
//! Initialize texture
texture = new GX2Texture;
GX2InitTexture(texture, width, height, 1, 0, textureFormat, GX2_SURFACE_DIM_2D, GX2_TILE_MODE_LINEAR_ALIGNED);
GX2InitTexture(texture, width, height, 1, 0, textureFormat, GX2_SURFACE_DIM_TEXTURE_2D, GX2_TILE_MODE_LINEAR_ALIGNED);
//! if this fails something went horribly wrong
if(texture->surface.image_size == 0) {
if(texture->surface.imageSize == 0) {
delete texture;
texture = NULL;
gdImageDestroy(gdImg);
@ -125,63 +113,59 @@ void GuiImageData::loadImage(const u8 *img, s32 imgSize, s32 textureClamp, s32 t
}
//! allocate memory for the surface
memoryType = eMemTypeMEM2;
texture->surface.image_data = memalign(texture->surface.align, texture->surface.image_size);
memoryType = eMemTypeMEM2;
texture->surface.image = memalign(texture->surface.alignment, texture->surface.imageSize);
//! try MEM1 on failure
if(!texture->surface.image_data) {
if(!texture->surface.image) {
memoryType = eMemTypeMEM1;
texture->surface.image_data = MEM1_alloc(texture->surface.image_size, texture->surface.align);
texture->surface.image = MEM1_alloc(texture->surface.imageSize, texture->surface.alignment);
}
//! try MEM bucket on failure
if(!texture->surface.image_data) {
if(!texture->surface.image) {
memoryType = eMemTypeMEMBucket;
texture->surface.image_data = MEMBucket_alloc(texture->surface.image_size, texture->surface.align);
texture->surface.image = MEMBucket_alloc(texture->surface.imageSize, texture->surface.alignment);
}
//! check if memory is available for image
if(!texture->surface.image_data) {
if(!texture->surface.image) {
gdImageDestroy(gdImg);
delete texture;
texture = NULL;
return;
}
//! set mip map data pointer
texture->surface.mip_data = NULL;
texture->surface.mipmaps = NULL;
//! convert image to texture
switch(textureFormat)
{
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);
case GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8:
gdImageToUnormR8G8B8A8(gdImg, (uint32_t*)texture->surface.image, 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);
case GX2_SURFACE_FORMAT_UNORM_R5_G6_B5:
gdImageToUnormR5G6B5(gdImg, (uint16_t*)texture->surface.image, texture->surface.width, texture->surface.height, texture->surface.pitch);
break;
}
//! free memory of image as its not needed anymore
gdImageDestroy(gdImg);
//! 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);
//! invalidate the memory
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, texture->surface.image, texture->surface.imageSize);
//! initialize the sampler
sampler = new GX2Sampler;
GX2InitSampler(sampler, textureClamp, GX2_TEX_XY_FILTER_BILINEAR);
GX2InitSampler(sampler, textureClamp, GX2_TEX_XY_FILTER_MODE_LINEAR);
}
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);
void GuiImageData::gdImageToUnormR8G8B8A8(gdImagePtr gdImg, uint32_t *imgBuffer, uint32_t width, uint32_t height, uint32_t pitch) {
for(uint32_t y = 0; y < height; ++y) {
for(uint32_t x = 0; x < width; ++x) {
uint32_t pixel = gdImageGetPixel(gdImg, x, y);
u8 a = 254 - 2*((u8)gdImageAlpha(gdImg, pixel));
if(a == 254) a++;
uint8_t a = 254 - 2*((uint8_t)gdImageAlpha(gdImg, pixel));
if(a == 254) a++;
u8 r = gdImageRed(gdImg, pixel);
u8 g = gdImageGreen(gdImg, pixel);
u8 b = gdImageBlue(gdImg, pixel);
uint8_t r = gdImageRed(gdImg, pixel);
uint8_t g = gdImageGreen(gdImg, pixel);
uint8_t b = gdImageBlue(gdImg, pixel);
imgBuffer[y * pitch + x] = (r << 24) | (g << 16) | (b << 8) | (a);
}
@ -189,17 +173,14 @@ void GuiImageData::gdImageToUnormR8G8B8A8(gdImagePtr gdImg, u32 *imgBuffer, u32
}
//! 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);
void GuiImageData::gdImageToUnormR5G6B5(gdImagePtr gdImg, uint16_t *imgBuffer, uint32_t width, uint32_t height, uint32_t pitch) {
for(uint32_t y = 0; y < height; ++y) {
for(uint32_t x = 0; x < width; ++x) {
uint32_t pixel = gdImageGetPixel(gdImg, x, y);
u8 r = gdImageRed(gdImg, pixel);
u8 g = gdImageGreen(gdImg, pixel);
u8 b = gdImageBlue(gdImg, pixel);
uint8_t r = gdImageRed(gdImg, pixel);
uint8_t g = gdImageGreen(gdImg, pixel);
uint8_t b = gdImageBlue(gdImg, pixel);
imgBuffer[y * pitch + x] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
}

View File

@ -14,38 +14,34 @@
* 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"
#include <gui/GuiParticleImage.h>
#include <video/CVideo.h>
#include <video/shaders/ColorShader.h>
#define CIRCLE_VERTEX_COUNT 36
static inline f32 getRandZeroToOneF32()
{
static inline float getRandZeroToOneF32() {
return (rand() % 10000) * 0.0001f;
}
static inline f32 getRandMinusOneToOneF32()
{
static inline float getRandMinusOneToOneF32() {
return getRandZeroToOneF32() * 2.0f - 1.0f;
}
GuiParticleImage::GuiParticleImage(s32 w, s32 h, u32 particleCount, f32 minRadius, f32 maxRadius, f32 minSpeed, f32 maxSpeed)
: GuiImage(NULL)
{
GuiParticleImage::GuiParticleImage(int32_t w, int32_t h, uint32_t particleCount, float minRadius, float maxRadius, float minSpeed, float maxSpeed)
: GuiImage(NULL) {
width = w;
height = h;
imgType = IMAGE_COLOR;
this->minRadius = minRadius;
this->maxRadius = maxRadius;
this->minSpeed = minSpeed;
this->maxSpeed = maxSpeed;
imgType = IMAGE_COLOR;
this->minRadius = minRadius;
this->maxRadius = maxRadius;
this->minSpeed = minSpeed;
this->maxSpeed = maxSpeed;
posVertexs = (f32 *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ColorShader::cuVertexAttrSize * CIRCLE_VERTEX_COUNT);
colorVertexs = (u8 *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ColorShader::cuColorAttrSize * CIRCLE_VERTEX_COUNT);
posVertexs = (float *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ColorShader::cuVertexAttrSize * CIRCLE_VERTEX_COUNT);
colorVertexs = (uint8_t *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ColorShader::cuColorAttrSize * CIRCLE_VERTEX_COUNT);
for(u32 i = 0; i < CIRCLE_VERTEX_COUNT; i++)
{
for(uint32_t 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;
@ -55,13 +51,12 @@ GuiParticleImage::GuiParticleImage(s32 w, s32 h, u32 particleCount, f32 minRadiu
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);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, posVertexs, ColorShader::cuVertexAttrSize * CIRCLE_VERTEX_COUNT);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, colorVertexs, ColorShader::cuColorAttrSize * CIRCLE_VERTEX_COUNT);
particles.resize(particleCount);
for(u32 i = 0; i < particleCount; i++)
{
for(uint32_t 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;
@ -72,20 +67,18 @@ GuiParticleImage::GuiParticleImage(s32 w, s32 h, u32 particleCount, f32 minRadiu
}
}
GuiParticleImage::~GuiParticleImage()
{
GuiParticleImage::~GuiParticleImage() {
free(posVertexs);
free(colorVertexs);
}
void GuiParticleImage::draw(CVideo *pVideo)
{
if(!this->isVisible())
return;
void GuiParticleImage::draw(CVideo *pVideo) {
if(!this->isVisible())
return;
f32 currScaleX = getScaleX();
f32 currScaleY = getScaleY();
float currScaleX = getScaleX();
float currScaleY = getScaleY();
positionOffsets[2] = getDepth() * pVideo->getDepthScaleFactor() * 2.0f;
@ -94,10 +87,8 @@ void GuiParticleImage::draw(CVideo *pVideo)
//! 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))
{
for(uint32_t 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);
@ -105,8 +96,7 @@ void GuiParticleImage::draw(CVideo *pVideo)
particles[i].speed = (getRandZeroToOneF32() * (maxSpeed - minSpeed)) + minSpeed;
particles[i].direction = getRandMinusOneToOneF32();
}
if(particles[i].position.x < (-getWidth() * 0.5f - 50.0f))
{
if(particles[i].position.x < (-getWidth() * 0.5f - 50.0f)) {
particles[i].position.x = -particles[i].position.x;
}
@ -127,6 +117,6 @@ void GuiParticleImage::draw(CVideo *pVideo)
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);
ColorShader::instance()->draw(GX2_PRIMITIVE_MODE_TRIANGLE_FAN, CIRCLE_VERTEX_COUNT);
}
}

View File

@ -21,195 +21,167 @@
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include "GuiScrollbar.h"
#include "resources/Resources.h"
#include <gui/GuiScrollbar.h>
#include <resources/Resources.h>
GuiScrollbar::GuiScrollbar(s32 h)
GuiScrollbar::GuiScrollbar(int32_t 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;
SetScrollSpeed(15);
ScrollState = 0;
, wpadTouchTrigger(GuiTrigger::CHANNEL_2 | GuiTrigger::CHANNEL_3 | GuiTrigger::CHANNEL_4 | GuiTrigger::CHANNEL_5, GuiTrigger::BUTTON_A) {
SelItem = 0;
SelInd = 0;
PageSize = 0;
EntrieCount = 0;
SetScrollSpeed(15);
ScrollState = 0;
listChanged.connect(this, &GuiScrollbar::setScrollboxPosition);
listChanged.connect(this, &GuiScrollbar::setScrollboxPosition);
height = h;
height = h;
arrowUpBtn = new GuiButton(50, 50);
arrowUpBtn->setParent(this);
arrowUpBtn->setAlignment(ALIGN_CENTER | ALIGN_TOP);
arrowUpBtn->setPosition(0, 0);
arrowUpBtn->setTrigger(&touchTrigger, 0);
arrowUpBtn->setTrigger(&wpadTouchTrigger, 1);
arrowUpBtn->setEffectGrow();
arrowUpBtn->clicked.connect(this, &GuiScrollbar::OnUpButtonClick);
arrowUpBtn = new GuiButton(50, 50);
arrowUpBtn->setParent(this);
arrowUpBtn->setAlignment(ALIGN_CENTER | ALIGN_TOP);
arrowUpBtn->setPosition(0, 0);
arrowUpBtn->setTrigger(&touchTrigger, 0);
arrowUpBtn->setTrigger(&wpadTouchTrigger, 1);
arrowUpBtn->setEffectGrow();
arrowUpBtn->clicked.connect(this, &GuiScrollbar::OnUpButtonClick);
arrowDownBtn = new GuiButton(50, 50);
arrowDownBtn->setParent(this);
arrowDownBtn->setAlignment(ALIGN_CENTER | ALIGN_BOTTOM);
arrowDownBtn->setPosition(0, 0);
arrowDownBtn->setTrigger(&touchTrigger, 0);
arrowDownBtn->setTrigger(&wpadTouchTrigger, 1);
arrowDownBtn->setEffectGrow();
arrowDownBtn->clicked.connect(this, &GuiScrollbar::OnDownButtonClick);
arrowDownBtn = new GuiButton(50, 50);
arrowDownBtn->setParent(this);
arrowDownBtn->setAlignment(ALIGN_CENTER | ALIGN_BOTTOM);
arrowDownBtn->setPosition(0, 0);
arrowDownBtn->setTrigger(&touchTrigger, 0);
arrowDownBtn->setTrigger(&wpadTouchTrigger, 1);
arrowDownBtn->setEffectGrow();
arrowDownBtn->clicked.connect(this, &GuiScrollbar::OnDownButtonClick);
scrollbarBoxBtn = new GuiButton(50, height);
scrollbarBoxBtn->setParent(this);
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, &GuiScrollbar::OnBoxButtonHold);
scrollbarBoxBtn = new GuiButton(50, height);
scrollbarBoxBtn->setParent(this);
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, &GuiScrollbar::OnBoxButtonHold);
}
GuiScrollbar::~GuiScrollbar()
{
delete arrowUpBtn;
delete arrowDownBtn;
delete scrollbarBoxBtn;
GuiScrollbar::~GuiScrollbar() {
delete arrowUpBtn;
delete arrowDownBtn;
delete scrollbarBoxBtn;
}
void GuiScrollbar::ScrollOneUp()
{
if(SelItem == 0 && SelInd > 0)
{
void GuiScrollbar::ScrollOneUp() {
if(SelItem == 0 && SelInd > 0) {
// move list up by 1
--SelInd;
}
else if(SelInd+SelItem > 0)
{
} else if(SelInd+SelItem > 0) {
--SelItem;
}
}
void GuiScrollbar::ScrollOneDown()
{
if(SelInd+SelItem + 1 < EntrieCount)
{
if(SelItem == PageSize-1)
{
void GuiScrollbar::ScrollOneDown() {
if(SelInd+SelItem + 1 < EntrieCount) {
if(SelItem == PageSize-1) {
// move list down by 1
SelInd++;
}
else
{
} else {
SelItem++;
}
}
}
void GuiScrollbar::OnUpButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger)
{
if(ScrollState < ScrollSpeed)
return;
void GuiScrollbar::OnUpButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
if(ScrollState < ScrollSpeed)
return;
ScrollOneUp();
ScrollOneUp();
ScrollState = 0;
listChanged(SelItem, SelInd);
ScrollState = 0;
listChanged(SelItem, SelInd);
}
void GuiScrollbar::OnDownButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger)
{
if(ScrollState < ScrollSpeed)
return;
void GuiScrollbar::OnDownButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
if(ScrollState < ScrollSpeed)
return;
ScrollOneDown();
ScrollOneDown();
ScrollState = 0;
listChanged(SelItem, SelInd);
ScrollState = 0;
listChanged(SelItem, SelInd);
}
void GuiScrollbar::OnBoxButtonHold(GuiButton *button, const GuiController *controller, GuiTrigger *trigger)
{
if(EntrieCount == 0){
void GuiScrollbar::OnBoxButtonHold(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
if(EntrieCount == 0) {
return;
}
if(!controller->data.validPointer){
return;
if(!controller->data.validPointer) {
return;
}
s32 y = controller->data.y - this->getCenterY();
int32_t y = controller->data.y - this->getCenterY();
s32 positionWiimote = LIMIT(y - MinHeight, 0, MaxHeight - MinHeight);
int32_t positionWiimote = LIMIT(y - MinHeight, 0, MaxHeight - MinHeight);
s32 newSelected = (EntrieCount - 1) - (s32) ((float) positionWiimote / (float) (MaxHeight-MinHeight) * (float) (EntrieCount-1));
int32_t newSelected = (EntrieCount - 1) - (int32_t) ((float) positionWiimote / (float) (MaxHeight-MinHeight) * (float) (EntrieCount-1));
s32 diff = newSelected-SelInd-SelItem;
int32_t diff = newSelected-SelInd-SelItem;
if(newSelected <= 0)
{
if(newSelected <= 0) {
SelItem = 0;
SelInd = 0;
}
else if(newSelected >= EntrieCount-1)
{
} 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, (s32)0);
}
else if(EntrieCount-newSelected < PageSize && SelInd == EntrieCount-PageSize && diff > 0)
{
} else if(newSelected < PageSize && SelInd == 0 && diff < 0) {
SelItem = std::max(SelItem+diff, (int32_t)0);
} else if(EntrieCount-newSelected < PageSize && SelInd == EntrieCount-PageSize && diff > 0) {
SelItem = std::min(SelItem+diff, PageSize-1);
}
else
{
} else {
SelInd = LIMIT(SelInd+diff, 0, ((EntrieCount-PageSize < 0) ? 0 : EntrieCount-PageSize));
}
ScrollState = 0;
listChanged(SelItem, SelInd);
ScrollState = 0;
listChanged(SelItem, SelInd);
}
void GuiScrollbar::SetPageSize(s32 size)
{
if(PageSize == size)
return;
void GuiScrollbar::SetPageSize(int32_t size) {
if(PageSize == size)
return;
PageSize = size;
listChanged(SelItem, SelInd);
PageSize = size;
listChanged(SelItem, SelInd);
}
void GuiScrollbar::SetSelectedItem(s32 pos)
{
if(SelItem == pos)
return;
void GuiScrollbar::SetSelectedItem(int32_t pos) {
if(SelItem == pos)
return;
SelItem = LIMIT(pos, 0, EntrieCount-1);
listChanged(SelItem, SelInd);
SelItem = LIMIT(pos, 0, EntrieCount-1);
listChanged(SelItem, SelInd);
}
void GuiScrollbar::SetSelectedIndex(s32 pos)
{
if(SelInd == pos)
return;
void GuiScrollbar::SetSelectedIndex(int32_t pos) {
if(SelInd == pos)
return;
SelInd = pos;
listChanged(SelItem, SelInd);
SelInd = pos;
listChanged(SelItem, SelInd);
}
void GuiScrollbar::SetEntrieCount(s32 cnt)
{
if(EntrieCount == cnt)
return;
void GuiScrollbar::SetEntrieCount(int32_t cnt) {
if(EntrieCount == cnt)
return;
EntrieCount = cnt;
listChanged(SelItem, SelInd);
EntrieCount = cnt;
listChanged(SelItem, SelInd);
}
void GuiScrollbar::setScrollboxPosition(s32 SelItem, s32 SelInd)
{
s32 position = MaxHeight-(MaxHeight-MinHeight)*(SelInd+SelItem)/(EntrieCount-1);
void GuiScrollbar::setScrollboxPosition(int32_t SelItem, int32_t SelInd) {
int32_t position = MaxHeight-(MaxHeight-MinHeight)*(SelInd+SelItem)/(EntrieCount-1);
if(position < MinHeight || (SelInd+SelItem >= EntrieCount-1))
position = MinHeight;
@ -219,25 +191,25 @@ void GuiScrollbar::setScrollboxPosition(s32 SelItem, s32 SelInd)
scrollbarBoxBtn->setPosition(0, position);
}
void GuiScrollbar::draw(CVideo * video)
{
if(scrollbarLineImage){ scrollbarLineImage->draw(video); }
arrowUpBtn->draw(video);
arrowDownBtn->draw(video);
scrollbarBoxBtn->draw(video);
void GuiScrollbar::draw(CVideo * video) {
if(scrollbarLineImage) {
scrollbarLineImage->draw(video);
}
arrowUpBtn->draw(video);
arrowDownBtn->draw(video);
scrollbarBoxBtn->draw(video);
updateEffects();
updateEffects();
}
void GuiScrollbar::update(GuiController * t)
{
if(this->isStateSet(STATE_DISABLED))
return;
void GuiScrollbar::update(GuiController * t) {
if(this->isStateSet(STATE_DISABLED))
return;
arrowUpBtn->update(t);
arrowDownBtn->update(t);
scrollbarBoxBtn->update(t);
arrowUpBtn->update(t);
arrowDownBtn->update(t);
scrollbarBoxBtn->update(t);
++ScrollState;
++ScrollState;
}

View File

@ -1,129 +0,0 @@
/***************************************************************************
* 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 GUI_SCROLLBAR_HPP_
#define GUI_SCROLLBAR_HPP_
#include "gui/GuiElement.h"
#include "gui/GuiButton.h"
class GuiScrollbar : public GuiElement, public sigslot::has_slots<>
{
public:
GuiScrollbar(s32 height);
virtual ~GuiScrollbar();
void ScrollOneUp();
void ScrollOneDown();
s32 GetSelectedItem() { return SelItem; }
s32 GetSelectedIndex() { return SelInd; }
void draw(CVideo * video);
void update(GuiController * t);
//! Signals
sigslot::signal2<s32, s32> listChanged;
//! Slots
void SetScrollSpeed(s32 speed){ScrollSpeed = speed;};
void SetPageSize(s32 size);
void SetRowSize(s32 size);
void SetSelectedItem(s32 pos);
void SetSelectedIndex(s32 pos);
void SetEntrieCount(s32 cnt);
void setSoundClick(GuiSound * snd){
clickSound = snd;
arrowUpBtn->setSoundClick(snd);
arrowDownBtn->setSoundClick(snd);
}
void setImageScrollbarLine(GuiImage * img){
if(img){
scrollbarLineImage = img;
scrollbarLineImage->setParent(this);
scrollbarLineImage->setParent(this);
scrollbarLineImage->setAlignment(ALIGN_CENTER | ALIGN_MIDDLE);
scrollbarLineImage->setPosition(0, 0);
}
}
void setImageArrowDown(GuiImage * img){
if(img){
arrowDownImage = img;
arrowDownBtn->setSize(img->getWidth(), img->getHeight());
arrowDownBtn->setImage(img);
}
}
void setImageArrowUp(GuiImage * img){
if(img){
arrowUpImage = img;
arrowUpBtn->setSize(img->getWidth(), img->getHeight());
arrowUpBtn->setImage(img);
}
}
void setImageScrollbarBox(GuiImage * img){
if(img){
scrollbarBoxImage = img;
scrollbarBoxBtn->setSize(img->getWidth(), height);
scrollbarBoxBtn->setImage(img);
width = img->getWidth();
MaxHeight = height * 0.5f - (img ? (img->getHeight() * 0.5f) : 0) - (arrowUpImage ? arrowUpImage->getHeight() : 0);
MinHeight = -height * 0.5f + (img ? (img->getHeight() * 0.5f) : 0) + (arrowDownImage ? arrowDownImage->getHeight() : 0);
}
}
protected:
void setScrollboxPosition(s32 SelItem, s32 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;
s32 MinHeight;
s32 MaxHeight;
s32 SelItem;
s32 SelInd;
s32 PageSize;
s32 EntrieCount;
s32 pressedChan;
GuiButton * arrowUpBtn;
GuiButton * arrowDownBtn;
GuiButton * scrollbarBoxBtn;
GuiSound * clickSound = NULL;
GuiImage * scrollbarLineImage = NULL;
GuiImage * arrowDownImage = NULL;
GuiImage * arrowUpImage = NULL;
GuiImage * scrollbarBoxImage = NULL;
GuiTrigger touchTrigger;
GuiTrigger wpadTouchTrigger;
};
#endif

View File

@ -19,28 +19,27 @@
#include <utils/StringTools.h>
#include <utils/logger.h>
#include "GuiSelectBox.h"
#include "GuiImage.h"
#include "GuiTrigger.h"
#include "GuiImageData.h"
#include <gui/GuiSelectBox.h>
#include <gui/GuiImage.h>
#include <gui/GuiTrigger.h>
#include <gui/GuiImageData.h>
/**
* Constructor for the GuiCheckBox class.
*/
GuiSelectBox::GuiSelectBox(GuiImage * background,std::string caption,f32 width,f32 height,GuiFrame *parent)
: GuiFrame(width,height,parent)
,selected(0)
,captionText(caption)
,topValueButton(0,0)
,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(0,0)
{
GuiSelectBox::GuiSelectBox(GuiImage * background,std::string caption,float width,float height,GuiFrame *parent)
: GuiFrame(width,height,parent)
,selected(0)
,captionText(caption)
,topValueButton(0,0)
,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(0,0) {
setImageTopBackground(background);
showValues = false;
bChanged = false;
@ -71,23 +70,23 @@ GuiSelectBox::GuiSelectBox(GuiImage * background,std::string caption,f32 width,f
bChanged = true;
}
void GuiSelectBox::setSize(f32 width,f32 height){
void GuiSelectBox::setSize(float width,float height) {
GuiFrame::setSize(width,height);
topValueButton.setSize(width,height);
}
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::OnValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
for(uint32_t 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()){
void GuiSelectBox::SelectValue(uint32_t 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());
@ -101,40 +100,32 @@ void GuiSelectBox::SelectValue(u32 value){
}
}
void GuiSelectBox::OnTopValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger)
{
void GuiSelectBox::OnTopValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
ShowHideValues(!showValues);
}
void GuiSelectBox::ShowHideValues(bool showhide)
{
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)
{
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)
{
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){
} else if(trigger == &buttonBTrigger) {
if(button == &DPADButtons) {
ShowHideValues(false);
}else{
}
}else if(trigger == &buttonUpTrigger){
} else {
}
} else if(trigger == &buttonUpTrigger) {
if(selected > 0 ) selected--;
bSelectedChanged = true;
}
else if(trigger == &buttonDownTrigger){
} else if(trigger == &buttonDownTrigger) {
selected++;
if(selected >= valueButtons.size()) selected = valueButtons.size() - 1;
bSelectedChanged = true;
@ -142,9 +133,8 @@ void GuiSelectBox::OnDPADClick(GuiButton *button, const GuiController *controlle
}
}
void GuiSelectBox::Init(std::map<std::string,std::string> values, s32 valueID)
{
if((u32)valueID >= values.size()){
void GuiSelectBox::Init(std::map<std::string,std::string> values, int32_t valueID) {
if((uint32_t)valueID >= values.size()) {
valueID = 0;
}
@ -153,17 +143,17 @@ void GuiSelectBox::Init(std::map<std::string,std::string> values, s32 valueID)
DeleteValueData();
if(valueImageData == NULL || valueSelectedImageData == NULL || valueHighlightedImageData == NULL){
if(valueImageData == NULL || valueSelectedImageData == NULL || valueHighlightedImageData == NULL) {
return;
}
valueButtons.resize(values.size());
s32 i = 0;
f32 imgScale = 1.0f;
int32_t i = 0;
float imgScale = 1.0f;
std::map<std::string, std::string>::iterator itr;
for(itr = values.begin(); itr != values.end(); itr++) {
if(i == valueID){
if(i == valueID) {
topValueText.setText(itr->first.c_str());
}
@ -192,12 +182,12 @@ void GuiSelectBox::Init(std::map<std::string,std::string> values, s32 valueID)
buttonToValue[valueButtons[i].valueButton] = itr->second;
f32 topHeight = 0;
if(topBackgroundImg != NULL){
float topHeight = 0;
if(topBackgroundImg != NULL) {
topHeight = topBackgroundImg->getHeight();
}
s32 ypos = (((valueButtons[i].valueButtonImg->getHeight()*getScale()) * (i))+ (topHeight-5)*getScale())*-1.0f;
int32_t ypos = (((valueButtons[i].valueButtonImg->getHeight()*getScale()) * (i))+ (topHeight-5)*getScale())*-1.0f;
valueButtons[i].valueButton->setPosition(0, ypos);
valuesFrame.append(valueButtons[i].valueButton);
@ -209,10 +199,8 @@ void GuiSelectBox::Init(std::map<std::string,std::string> values, s32 valueID)
bChanged = true;
}
void GuiSelectBox::DeleteValueData()
{
for(u32 i = 0; i < valueButtons.size(); ++i)
{
void GuiSelectBox::DeleteValueData() {
for(uint32_t i = 0; i < valueButtons.size(); ++i) {
valuesFrame.remove(valueButtons[i].valueButton);
delete valueButtons[i].valueButtonImg;
delete valueButtons[i].valueButtonCheckedImg;
@ -227,7 +215,7 @@ void GuiSelectBox::DeleteValueData()
/**
* Destructor for the GuiButton class.
*/
GuiSelectBox::~GuiSelectBox(){
GuiSelectBox::~GuiSelectBox() {
DeleteValueData();
bChanged = false;
selected = 0;
@ -235,61 +223,58 @@ GuiSelectBox::~GuiSelectBox(){
}
void GuiSelectBox::setState(s32 s, s32 c)
{
GuiElement::setState(s, c);
void GuiSelectBox::setState(int32_t s, int32_t c) {
GuiElement::setState(s, c);
}
void GuiSelectBox::OnValueCloseEffectFinish(GuiElement *element)
{
void GuiSelectBox::OnValueCloseEffectFinish(GuiElement *element) {
valuesFrame.effectFinished.disconnect(this);
}
f32 GuiSelectBox::getTopValueHeight() {
if(topBackgroundImg == NULL){
float GuiSelectBox::getTopValueHeight() {
if(topBackgroundImg == NULL) {
return 0.0f;
}
return topBackgroundImg->getHeight();
}
f32 GuiSelectBox::getTopValueWidth() {
if(topBackgroundImg == NULL){
float GuiSelectBox::getTopValueWidth() {
if(topBackgroundImg == NULL) {
return 0.0f;
}
return topBackgroundImg->getWidth();
}
f32 GuiSelectBox::getHeight(){
float GuiSelectBox::getHeight() {
return getTopValueHeight();
}
f32 GuiSelectBox::getWidth(){
float GuiSelectBox::getWidth() {
return getTopValueWidth();
}
void GuiSelectBox::OnValueOpenEffectFinish(GuiElement *element)
{
void GuiSelectBox::OnValueOpenEffectFinish(GuiElement *element) {
valuesFrame.effectFinished.disconnect(this);
opened = true;
}
void GuiSelectBox::update(GuiController * c){
if(bChanged){
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){
if(showValues) {
for(uint32_t 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);
} 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{
} else {
opened = false;
valuesFrame.setState(STATE_HIDDEN);
DPADButtons.setState(STATE_DISABLE_INPUT);
@ -299,12 +284,12 @@ void GuiSelectBox::update(GuiController * c){
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);
if(bSelectedChanged) {
for(uint32_t i = 0; i < valueButtons.size(); ++i) {
if(i == selected) {
valueButtons[i].valueButton->setState(STATE_SELECTED);
} else {
valueButtons[i].valueButton->clearState(STATE_SELECTED);
}
}
}

View File

@ -1,131 +0,0 @@
/****************************************************************************
* 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(GuiImage * background, std::string caption,f32 width = 0.0f, f32 height = 0.0f,GuiFrame *parent = 0);
//!Destructor
virtual ~GuiSelectBox();
sigslot::signal2<GuiSelectBox *, std::string> valueChanged;
sigslot::signal2<GuiSelectBox *, bool> showhide;
void setImageTopBackground(GuiImage * img){
topBackgroundImg = img;
topValueButton.setImage(img);
}
void setImageTopHighlighted(GuiImage * img){
topHighlightedImg = img;
topValueButton.setIconOver(img);
}
void setImageValueBackground(GuiImageData * img){
valueImageData = img;
}
void setImageValueHighlighted(GuiImageData * img){
valueHighlightedImageData = img;
}
void setImageValueSelected(GuiImageData * img){
valueSelectedImageData = img;
}
void setSoundClick(GuiSound * snd){
buttonClickSound = snd;
topValueButton.setSoundClick(snd);
}
void OnTopValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger);
void Init(std::map<std::string,std::string> values, s32 valueID);
void setState(s32 s, s32 c = -1);
virtual void setSize(f32 width, f32 height);
virtual f32 getTopValueHeight();
virtual f32 getTopValueWidth();
virtual f32 getHeight();
virtual f32 getWidth();
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;
GuiImage* topBackgroundImg = NULL;
GuiImage* topHighlightedImg = NULL;
GuiButton topValueButton;
GuiImageData * valueImageData = NULL;
GuiImageData * valueSelectedImageData = NULL;
GuiImageData * valueHighlightedImageData = NULL;
GuiText topValueText;
GuiTrigger touchTrigger;
GuiTrigger wpadTouchTrigger;
GuiTrigger buttonATrigger;
GuiTrigger buttonBTrigger;
GuiTrigger buttonLeftTrigger;
GuiTrigger buttonRightTrigger;
GuiTrigger buttonUpTrigger;
GuiTrigger buttonDownTrigger;
GuiButton DPADButtons;
GuiSound* buttonClickSound;
typedef struct
{
GuiImage *valueButtonImg;
GuiImage *valueButtonCheckedImg;
GuiImage *valueButtonHighlightedImg;
GuiButton *valueButton;
GuiText *valueButtonText;
} SelectBoxValueButton;
std::map<GuiButton * ,std::string> buttonToValue;
std::vector<SelectBoxValueButton> valueButtons;
};
#endif

View File

@ -14,49 +14,39 @@
* 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>
#include <gui/GuiSound.h>
#include <sounds/SoundHandler.hpp>
GuiSound::GuiSound(const char * filepath)
{
voice = -1;
Load(filepath);
GuiSound::GuiSound(const char * filepath) {
voice = -1;
Load(filepath);
}
GuiSound::GuiSound(const u8 * snd, s32 length)
{
voice = -1;
Load(snd, length);
GuiSound::GuiSound(const uint8_t * snd, int32_t length) {
voice = -1;
Load(snd, length);
}
GuiSound::~GuiSound()
{
if(voice >= 0)
{
GuiSound::~GuiSound() {
if(voice >= 0) {
SoundHandler::instance()->RemoveDecoder(voice);
}
}
bool GuiSound::Load(const char * filepath)
{
if(voice >= 0)
{
bool GuiSound::Load(const char * filepath) {
if(voice >= 0) {
SoundHandler::instance()->RemoveDecoder(voice);
voice = -1;
}
//! find next free decoder
for(s32 i = 0; i < MAX_DECODERS; i++)
{
for(int32_t i = 0; i < MAX_DECODERS; i++) {
SoundDecoder * decoder = SoundHandler::instance()->getDecoder(i);
if(decoder == NULL)
{
if(decoder == NULL) {
SoundHandler::instance()->AddDecoder(i, filepath);
decoder = SoundHandler::instance()->getDecoder(i);
if(decoder)
{
if(decoder) {
voice = i;
SoundHandler::instance()->ThreadSignal();
}
@ -64,17 +54,15 @@ bool GuiSound::Load(const char * filepath)
}
}
if(voice < 0){
if(voice < 0) {
return false;
}
return true;
return true;
}
bool GuiSound::Load(const u8 * snd, s32 len)
{
if(voice >= 0)
{
bool GuiSound::Load(const uint8_t * snd, int32_t len) {
if(voice >= 0) {
SoundHandler::instance()->RemoveDecoder(voice);
voice = -1;
}
@ -83,15 +71,12 @@ bool GuiSound::Load(const u8 * snd, s32 len)
return false;
//! find next free decoder
for(s32 i = 0; i < MAX_DECODERS; i++)
{
for(int32_t i = 0; i < MAX_DECODERS; i++) {
SoundDecoder * decoder = SoundHandler::instance()->getDecoder(i);
if(decoder == NULL)
{
if(decoder == NULL) {
SoundHandler::instance()->AddDecoder(i, snd, len);
decoder = SoundHandler::instance()->getDecoder(i);
if(decoder)
{
if(decoder) {
voice = i;
SoundHandler::instance()->ThreadSignal();
}
@ -99,15 +84,14 @@ bool GuiSound::Load(const u8 * snd, s32 len)
}
}
if(voice < 0){
if(voice < 0) {
return false;
}
return true;
return true;
}
void GuiSound::Play()
{
void GuiSound::Play() {
Stop();
Voice * v = SoundHandler::instance()->getVoice(voice);
@ -117,21 +101,18 @@ void GuiSound::Play()
}
void GuiSound::Stop()
{
void GuiSound::Stop() {
Voice * v = SoundHandler::instance()->getVoice(voice);
if(v)
{
if(v) {
if((v->getState() != Voice::STATE_STOP) && (v->getState() != Voice::STATE_STOPPED))
v->setState(Voice::STATE_STOP);
while(v->getState() != Voice::STATE_STOPPED)
os_usleep(1000);
OSSleepTicks(OSMicrosecondsToTicks(1000));
}
SoundDecoder * decoder = SoundHandler::instance()->getDecoder(voice);
if(decoder)
{
if(decoder) {
decoder->Lock();
decoder->Rewind();
decoder->ClearBuffer();
@ -140,8 +121,7 @@ void GuiSound::Stop()
}
}
void GuiSound::Pause()
{
void GuiSound::Pause() {
if(!IsPlaying())
return;
@ -150,8 +130,7 @@ void GuiSound::Pause()
v->setState(Voice::STATE_STOP);
}
void GuiSound::Resume()
{
void GuiSound::Resume() {
if(IsPlaying())
return;
@ -160,35 +139,31 @@ void GuiSound::Resume()
v->setState(Voice::STATE_START);
}
bool GuiSound::IsPlaying()
{
bool GuiSound::IsPlaying() {
Voice * v = SoundHandler::instance()->getVoice(voice);
if(v){
if(v) {
return v->getState() == Voice::STATE_PLAYING;
}
return false;
return false;
}
void GuiSound::SetVolume(u32 vol)
{
void GuiSound::SetVolume(uint32_t vol) {
if(vol > 100)
vol = 100;
u32 volumeConv = ( (0x8000 * vol) / 100 ) << 16;
uint32_t volumeConv = ( (0x8000 * vol) / 100 ) << 16;
Voice * v = SoundHandler::instance()->getVoice(voice);
if(v)
v->setVolume(volumeConv);
}
void GuiSound::SetLoop(bool l)
{
void GuiSound::SetLoop(bool l) {
SoundDecoder * decoder = SoundHandler::instance()->getDecoder(voice);
if(decoder)
decoder->SetLoop(l);
}
void GuiSound::Rewind()
{
void GuiSound::Rewind() {
Stop();
}

View File

@ -1,60 +0,0 @@
/****************************************************************************
* 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 <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, s32 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

View File

@ -14,57 +14,63 @@
* 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"
#include <gui/GuiSwitch.h>
#include <gui/GuiImage.h>
#include <gui/GuiImageData.h>
#include <utils/logger.h>
/**
* Constructor for the GuiSwitch class.
*/
GuiSwitch::GuiSwitch(GuiImage * background,bool checked,f32 w, f32 h)
: GuiToggle(checked,w,h){
GuiSwitch::GuiSwitch(GuiImage * background,bool checked,float w, float h)
: GuiToggle(checked,w,h) {
setImageBackground(background);
}
/**
* Destructor for the GuiSwitch class.
*/
GuiSwitch::~GuiSwitch(){
GuiSwitch::~GuiSwitch() {
}
void GuiSwitch::setImageBackground(GuiImage* img){
backgroundImg = img;
if(img){ img->setParent(this); }
setImage(img);
void GuiSwitch::setImageBackground(GuiImage* img) {
backgroundImg = img;
if(img) {
img->setParent(this);
}
setImage(img);
}
void GuiSwitch::setImageOn(GuiImage* img){
onImg = img;
if(img){
void GuiSwitch::setImageOn(GuiImage* img) {
onImg = img;
if(img) {
img->setParent(this);
img->setAlignment(ALIGN_RIGHT);
}
}
void GuiSwitch::setImageOff(GuiImage* img){
offImg = img;
if(img){
img->setParent(this);
img->setAlignment(ALIGN_LEFT);
}
}
void GuiSwitch::setImageHighlighted(GuiImage* img){
highlightedImg = img;
setIconOver(img);
}
void GuiSwitch::draw(CVideo *v){
GuiToggle::draw(v);
if(getValue()){
if(onImg != NULL){ onImg->draw(v); }
}else{
if(offImg != NULL){ offImg->draw(v); }
}
}
void GuiSwitch::setImageOff(GuiImage* img) {
offImg = img;
if(img) {
img->setParent(this);
img->setAlignment(ALIGN_LEFT);
}
}
void GuiSwitch::setImageHighlighted(GuiImage* img) {
highlightedImg = img;
setIconOver(img);
}
void GuiSwitch::draw(CVideo *v) {
GuiToggle::draw(v);
if(getValue()) {
if(onImg != NULL) {
onImg->draw(v);
}
} else {
if(offImg != NULL) {
offImg->draw(v);
}
}
}

View File

@ -14,16 +14,18 @@
* 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"
#include <gui/GuiText.h>
#include <gui/FreeTypeGX.h>
#include <video/CVideo.h>
FreeTypeGX * GuiText::presentFont = NULL;
s32 GuiText::presetSize = 28;
int32_t GuiText::presetSize = 28;
float GuiText::presetInternalRenderingScale = 2.0f; //Lets render the font at the doubled size. This make it even smoother!
s32 GuiText::presetMaxWidth = 0xFFFF;
s32 GuiText::presetAlignment = ALIGN_CENTER | ALIGN_MIDDLE;
GX2ColorF32 GuiText::presetColor = (GX2ColorF32){ 1.0f, 1.0f, 1.0f, 1.0f };
int32_t GuiText::presetMaxWidth = 0xFFFF;
int32_t 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
@ -33,583 +35,525 @@ GX2ColorF32 GuiText::presetColor = (GX2ColorF32){ 1.0f, 1.0f, 1.0f, 1.0f };
* 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() {
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, s32 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;
GuiText::GuiText(const char * t, int32_t 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;
if(t) {
text = FreeTypeGX::charToWideChar(t);
if(!text)
return;
textWidth = font->getWidth(text, currentSize);
}
textWidth = font->getWidth(text, currentSize);
}
}
GuiText::GuiText(const wchar_t * t, s32 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;
GuiText::GuiText(const wchar_t * t, int32_t 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;
if(t) {
text = new (std::nothrow) wchar_t[wcslen(t)+1];
if(!text)
return;
wcscpy(text, t);
wcscpy(text, t);
textWidth = font->getWidth(text, currentSize);
}
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;
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;
if(t) {
text = FreeTypeGX::charToWideChar(t);
if(!text)
return;
textWidth = font->getWidth(text, currentSize);
}
textWidth = font->getWidth(text, currentSize);
}
}
/**
* Destructor for the GuiText class.
*/
GuiText::~GuiText()
{
if(text)
delete [] text;
text = NULL;
GuiText::~GuiText() {
if(text)
delete [] text;
text = NULL;
clearDynamicText();
clearDynamicText();
}
void GuiText::setText(const char * t)
{
if(text)
delete [] text;
text = NULL;
void GuiText::setText(const char * t) {
if(text)
delete [] text;
text = NULL;
clearDynamicText();
clearDynamicText();
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
if(t)
{
text = FreeTypeGX::charToWideChar(t);
if(!text)
return;
if(t) {
text = FreeTypeGX::charToWideChar(t);
if(!text)
return;
textWidth = font->getWidth(text, currentSize);
}
textWidth = font->getWidth(text, currentSize);
}
}
void GuiText::setTextf(const char *format, ...)
{
if(!format)
{
setText((char *) NULL);
return;
void GuiText::setTextf(const char *format, ...) {
if(!format) {
setText((char *) NULL);
return;
}
s32 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);
int32_t 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;
if(tmp)
delete [] tmp;
}
void GuiText::setText(const wchar_t * t)
{
if(text)
delete [] text;
text = NULL;
void GuiText::setText(const wchar_t * t) {
if(text)
delete [] text;
text = NULL;
clearDynamicText();
clearDynamicText();
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
if(t)
{
text = new (std::nothrow) wchar_t[wcslen(t)+1];
if(!text)
return;
if(t) {
text = new (std::nothrow) wchar_t[wcslen(t)+1];
if(!text)
return;
wcscpy(text, t);
wcscpy(text, t);
textWidth = font->getWidth(text, currentSize);
}
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::clearDynamicText() {
for(uint32_t i = 0; i < textDyn.size(); i++) {
if(textDyn[i])
delete [] textDyn[i];
}
textDyn.clear();
textDynWidth.clear();
}
void GuiText::setPresets(s32 sz, const glm::vec4 & c, s32 w, s32 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::setPresets(int32_t sz, const glm::vec4 & c, int32_t w, int32_t a) {
presetSize = sz;
presetColor = (GX2ColorF32) {
(float)c.r / 255.0f, (float)c.g / 255.0f, (float)c.b / 255.0f, (float)c.a / 255.0f
};
presetMaxWidth = w;
presetAlignment = a;
}
void GuiText::setPresetFont(FreeTypeGX *f)
{
presentFont = f;
void GuiText::setPresetFont(FreeTypeGX *f) {
presentFont = f;
}
void GuiText::setFontSize(s32 s)
{
size = s;
void GuiText::setFontSize(int32_t s) {
size = s;
}
void GuiText::setMaxWidth(s32 width, s32 w)
{
maxWidth = width;
wrapMode = w;
void GuiText::setMaxWidth(int32_t width, int32_t w) {
maxWidth = width;
wrapMode = w;
if(w == SCROLL_HORIZONTAL)
{
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollDelay = TEXT_SCROLL_DELAY;
}
if(w == SCROLL_HORIZONTAL) {
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollDelay = TEXT_SCROLL_DELAY;
}
clearDynamicText();
clearDynamicText();
}
void GuiText::setColor(const glm::vec4 & c)
{
color = c;
alpha = c[3];
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];
void GuiText::setBlurGlowColor(float blur, const glm::vec4 & c) {
blurGlowColor = c;
blurGlowIntensity = blur;
blurAlpha = c[3];
}
s32 GuiText::getTextWidth(s32 ind)
{
if(ind < 0 || ind >= (s32) textDyn.size())
return this->getTextWidth();
int32_t GuiText::getTextWidth(int32_t ind) {
if(ind < 0 || ind >= (int32_t) textDyn.size())
return this->getTextWidth();
return font->getWidth(textDyn[ind], currentSize);
return font->getWidth(textDyn[ind], currentSize);
}
const wchar_t * GuiText::getDynText(s32 ind)
{
if(ind < 0 || ind >= (s32) textDyn.size())
return text;
const wchar_t * GuiText::getDynText(int32_t ind) {
if(ind < 0 || ind >= (int32_t) textDyn.size())
return text;
return textDyn[ind];
return textDyn[ind];
}
/**
* Change font
*/
bool GuiText::setFont(FreeTypeGX *f)
{
if(!f)
return false;
bool GuiText::setFont(FreeTypeGX *f) {
if(!f)
return false;
font = f;
textWidth = font->getWidth(text, currentSize);
return true;
font = f;
textWidth = font->getWidth(text, currentSize);
return true;
}
std::string GuiText::toUTF8(void) const
{
if(!text)
return std::string();
std::string GuiText::toUTF8(void) const {
if(!text)
return std::string();
char *pUtf8 = FreeTypeGX::wideCharToUTF8(text);
if(!pUtf8)
return std::string();
return std::string();
std::string strOutput(pUtf8);
delete [] pUtf8;
return strOutput;
return strOutput;
}
void GuiText::makeDottedText()
{
s32 pos = textDyn.size();
textDyn.resize(pos + 1);
void GuiText::makeDottedText() {
int32_t pos = textDyn.size();
textDyn.resize(pos + 1);
s32 i = 0, currentWidth = 0;
textDyn[pos] = new (std::nothrow) wchar_t[maxWidth];
if(!textDyn[pos]) {
textDyn.resize(pos);
return;
}
int32_t 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;
}
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];
textDyn[pos][i] = text[i];
i++;
}
textDyn[pos][i] = 0;
i++;
}
textDyn[pos][i] = 0;
}
void GuiText::scrollText(u32 frameCount)
{
if (textDyn.size() == 0)
{
s32 pos = textDyn.size();
s32 i = 0, currentWidth = 0;
textDyn.resize(pos + 1);
void GuiText::scrollText(uint32_t frameCount) {
if (textDyn.size() == 0) {
int32_t pos = textDyn.size();
int32_t i = 0, currentWidth = 0;
textDyn.resize(pos + 1);
textDyn[pos] = new (std::nothrow) wchar_t[maxWidth];
if(!textDyn[pos]) {
textDyn.resize(pos);
return;
}
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];
while (text[i] && currentWidth < maxWidth) {
textDyn[pos][i] = text[i];
currentWidth += font->getCharWidth(text[i], currentSize, i > 0 ? text[i - 1] : 0);
currentWidth += font->getCharWidth(text[i], currentSize, i > 0 ? text[i - 1] : 0);
++i;
}
textDyn[pos][i] = 0;
++i;
}
textDyn[pos][i] = 0;
return;
}
return;
}
if (frameCount % textScrollDelay != 0)
{
return;
}
if (frameCount % textScrollDelay != 0) {
return;
}
if (textScrollInitialDelay)
{
--textScrollInitialDelay;
return;
}
if (textScrollInitialDelay) {
--textScrollInitialDelay;
return;
}
s32 stringlen = wcslen(text);
int32_t stringlen = wcslen(text);
++textScrollPos;
if (textScrollPos > stringlen)
{
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
}
++textScrollPos;
if (textScrollPos > stringlen) {
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
}
s32 ch = textScrollPos;
s32 pos = textDyn.size() - 1;
int32_t ch = textScrollPos;
int32_t pos = textDyn.size() - 1;
if (!textDyn[pos])
textDyn[pos] = new (std::nothrow) wchar_t[maxWidth];
if (!textDyn[pos])
textDyn[pos] = new (std::nothrow) wchar_t[maxWidth];
if(!textDyn[pos]) {
textDyn.resize(pos);
return;
}
if(!textDyn[pos]) {
textDyn.resize(pos);
return;
}
s32 i = 0, currentWidth = 0;
int32_t 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;
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;
}
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;
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;
void GuiText::wrapText() {
if (textDyn.size() > 0) return;
s32 i = 0;
s32 ch = 0;
s32 linenum = 0;
s32 lastSpace = -1;
s32 lastSpaceIndex = -1;
s32 currentWidth = 0;
int32_t i = 0;
int32_t ch = 0;
int32_t linenum = 0;
int32_t lastSpace = -1;
int32_t lastSpaceIndex = -1;
int32_t currentWidth = 0;
while (text[ch] && linenum < linestodraw)
{
if (linenum >= (s32) 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;
while (text[ch] && linenum < linestodraw) {
if (linenum >= (int32_t) textDyn.size()) {
textDyn.resize(linenum + 1);
textDyn[linenum] = new (std::nothrow) wchar_t[maxWidth];
if(!textDyn[linenum]) {
textDyn.resize(linenum);
break;
}
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)
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;
}
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;
}
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;
void GuiText::draw(CVideo *pVideo) {
if(!text)
return;
if(!isVisible())
return;
if(!isVisible())
return;
color[3] = getAlpha();
blurGlowColor[3] = blurAlpha * getAlpha();
float finalRenderingScale = 2.0f * internalRenderingScale;
s32 newSize = size * getScale() * finalRenderingScale;
s32 normal_size = size * getScale();
int32_t newSize = size * getScale() * finalRenderingScale;
int32_t normal_size = size * getScale();
if(newSize != currentSize)
{
currentSize = normal_size;
if(newSize != currentSize) {
currentSize = normal_size;
if(text)
textWidth = font->getWidth(text, normal_size);
}
if(text)
textWidth = font->getWidth(text, normal_size);
}
f32 x_pos = getCenterX() * finalRenderingScale;
f32 y_pos = getCenterY() * finalRenderingScale;
float x_pos = getCenterX() * finalRenderingScale;
float y_pos = getCenterY() * finalRenderingScale;
if(maxWidth > 0 && maxWidth <= textWidth)
{
if(wrapMode == DOTTED) // text dotted
{
if(textDyn.size() == 0)
makeDottedText();
if(maxWidth > 0 && maxWidth <= textWidth) {
if(wrapMode == DOTTED) { // text dotted
if(textDyn.size() == 0)
makeDottedText();
if(textDynWidth.size() != textDyn.size())
{
if(textDynWidth.size() != textDyn.size()) {
textDynWidth.resize(textDyn.size());
for(u32 i = 0; i < textDynWidth.size(); i++)
for(uint32_t 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);
}
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());
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);
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)
{
s32 lineheight = newSize + 6;
s32 yoffset = 0;
s32 voffset = 0;
} else if(wrapMode == WRAP) {
int32_t lineheight = newSize + 6;
int32_t yoffset = 0;
int32_t voffset = 0;
if(textDyn.size() == 0)
wrapText();
if(textDyn.size() == 0)
wrapText();
if(textDynWidth.size() != textDyn.size())
{
if(textDynWidth.size() != textDyn.size()) {
textDynWidth.resize(textDyn.size());
for(u32 i = 0; i < textDynWidth.size(); i++)
for(uint32_t i = 0; i < textDynWidth.size(); i++)
textDynWidth[i] = font->getWidth(textDyn[i], newSize);
}
if(alignment & ALIGN_MIDDLE)
voffset = (lineheight * (textDyn.size()-1)) >> 1;
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);
for(uint32_t 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);
}
}
}
} 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);
}
}

View File

@ -14,14 +14,13 @@
* 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"
#include <gui/GuiToggle.h>
/**
* Constructor for the GuiToggle class.
*/
GuiToggle::GuiToggle(bool checked,f32 width,f32 height)
: GuiButton(width,height)
{
GuiToggle::GuiToggle(bool checked,float width,float height)
: GuiButton(width,height) {
bChanged = false;
selected = checked;
clicked.connect(this,&GuiToggle::OnToggleClick);
@ -30,23 +29,22 @@ GuiToggle::GuiToggle(bool checked,f32 width,f32 height)
/**
* Destructor for the GuiButton class.
*/
GuiToggle::~GuiToggle()
{
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)){
if(selected){
void GuiToggle::OnToggleClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
if(!isStateSet(STATE_DISABLED | STATE_HIDDEN | STATE_DISABLE_INPUT)) {
if(selected) {
setUnchecked();
}else{
} else {
setChecked();
}
}
}
void GuiToggle::update(GuiController * c){
void GuiToggle::update(GuiController * c) {
GuiButton::update(c);
}

View File

@ -14,9 +14,9 @@
* 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"
#include <gui/GuiElement.h>
#include <gui/GuiController.h>
#include <gui/GuiTrigger.h>
/**
* Constructor for the GuiTrigger class.
@ -27,25 +27,22 @@ GuiTrigger::GuiTrigger()
, bClickEverywhere(false)
, bHoldEverywhere(false)
, bSelectionClickEverywhere(false)
, bLastTouched(false)
{
, bLastTouched(false) {
}
GuiTrigger::GuiTrigger(u32 ch, u32 btn, bool clickEverywhere, bool holdEverywhere, bool selectionClickEverywhere)
GuiTrigger::GuiTrigger(uint32_t ch, uint32_t btn, bool clickEverywhere, bool holdEverywhere, bool selectionClickEverywhere)
: chan(ch)
, btns(btn)
, bClickEverywhere(clickEverywhere)
, bHoldEverywhere(holdEverywhere)
, bSelectionClickEverywhere(selectionClickEverywhere)
, bLastTouched(false)
{
, bLastTouched(false) {
}
/**
* Destructor for the GuiTrigger class.
*/
GuiTrigger::~GuiTrigger()
{
GuiTrigger::~GuiTrigger() {
}
/**
@ -53,103 +50,87 @@ GuiTrigger::~GuiTrigger()
* - Element is selected
* - Trigger button is pressed
*/
void GuiTrigger::setTrigger(u32 ch, u32 btn)
{
chan = ch;
btns = btn;
void GuiTrigger::setTrigger(uint32_t ch, uint32_t btn) {
chan = ch;
btns = btn;
}
bool GuiTrigger::left(const GuiController *controller) const
{
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;
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
{
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;
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
{
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;
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
{
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;
if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_DOWN | STICK_L_DOWN)) {
return true;
}
return false;
}
s32 GuiTrigger::clicked(const GuiController *controller) const
{
int32_t GuiTrigger::clicked(const GuiController *controller) const {
if((controller->chan & chan) == 0) {
return CLICKED_NONE;
}
s32 bResult = CLICKED_NONE;
int32_t bResult = CLICKED_NONE;
if(controller->data.touched && controller->data.validPointer && (btns & VPAD_TOUCH) && !controller->lastData.touched)
{
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;
if(controller->data.buttons_d & btns) {
bResult = CLICKED_BUTTON;
}
return bResult;
}
bool GuiTrigger::held(const GuiController *controller) const
{
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)
{
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;
}
if(controller->data.buttons_h & btns) {
bResult = true;
}
return bResult;
return bResult;
}
bool GuiTrigger::released(const GuiController *controller) const
{
bool GuiTrigger::released(const GuiController *controller) const {
if((controller->chan & chan) == 0) {
return false;
}
@ -159,16 +140,14 @@ bool GuiTrigger::released(const GuiController *controller) const
bool bResult = false;
if(!controller->data.touched && (btns & VPAD_TOUCH) && controller->lastData.touched && controller->lastData.validPointer)
{
if(!controller->data.touched && (btns & VPAD_TOUCH) && controller->lastData.touched && controller->lastData.validPointer) {
bResult = true;
}
if(controller->data.buttons_r & btns)
{
bResult = true;
}
if(controller->data.buttons_r & btns) {
bResult = true;
}
return bResult;
return bResult;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,121 +1,107 @@
#include <malloc.h>
#include <string.h>
#include "Resources.h"
#include "filelist.h"
#include <resources/Resources.h>
#include <resources/filelist.h>
#include <system/AsyncDeleter.h>
#include <fs/FSUtils.h>
#include "gui/GuiImageAsync.h"
#include "gui/GuiSound.h"
#include <gui/GuiImageAsync.h>
#include <gui/GuiSound.h>
Resources * Resources::instance = NULL;
void Resources::Clear(){
void Resources::Clear() {
ResourceFile * ResourceList = getResourceList();
if(ResourceList == NULL) return;
for(s32 i = 0; ResourceList[i].filename != NULL; ++i)
{
if(ResourceList[i].CustomFile)
{
free(ResourceList[i].CustomFile);
ResourceList[i].CustomFile = NULL;
}
for(int32_t i = 0; ResourceList[i].filename != NULL; ++i) {
if(ResourceList[i].CustomFile) {
free(ResourceList[i].CustomFile);
ResourceList[i].CustomFile = NULL;
}
if(ResourceList[i].CustomFileSize != 0)
ResourceList[i].CustomFileSize = 0;
}
if(ResourceList[i].CustomFileSize != 0)
ResourceList[i].CustomFileSize = 0;
}
if(instance)
if(instance)
delete instance;
instance = NULL;
}
bool Resources::LoadFiles(const char * path)
{
if(!path)
return false;
bool Resources::LoadFiles(const char * path) {
if(!path)
return false;
bool result = false;
Clear();
bool result = false;
Clear();
ResourceFile * ResourceList = getResourceList();
if(ResourceList == NULL) return false;
ResourceFile * ResourceList = getResourceList();
if(ResourceList == NULL) return false;
for(s32 i = 0; ResourceList[i].filename != NULL; ++i)
{
for(int32_t i = 0; ResourceList[i].filename != NULL; ++i) {
std::string fullpath(path);
fullpath += "/";
fullpath += ResourceList[i].filename;
u8 * buffer = NULL;
u32 filesize = 0;
uint8_t * buffer = NULL;
uint32_t filesize = 0;
FSUtils::LoadFileToMem(fullpath.c_str(), &buffer, &filesize);
ResourceList[i].CustomFile = buffer;
ResourceList[i].CustomFileSize = (u32) filesize;
ResourceList[i].CustomFileSize = (uint32_t) filesize;
result |= (buffer != 0);
}
}
return result;
return result;
}
const u8 * Resources::GetFile(const char * filename)
{
const uint8_t * Resources::GetFile(const char * filename) {
ResourceFile * ResourceList = getResourceList();
if(ResourceList == NULL) return NULL;
for(s32 i = 0; ResourceList[i].filename != NULL; ++i)
{
if(strcasecmp(filename, ResourceList[i].filename) == 0)
{
return (ResourceList[i].CustomFile ? ResourceList[i].CustomFile : ResourceList[i].DefaultFile);
}
}
for(int32_t i = 0; ResourceList[i].filename != NULL; ++i) {
if(strcasecmp(filename, ResourceList[i].filename) == 0) {
return (ResourceList[i].CustomFile ? ResourceList[i].CustomFile : ResourceList[i].DefaultFile);
}
}
return NULL;
return NULL;
}
u32 Resources::GetFileSize(const char * filename)
{
uint32_t Resources::GetFileSize(const char * filename) {
ResourceFile * ResourceList = getResourceList();
if(ResourceList == NULL) return 0;
for(s32 i = 0; ResourceList[i].filename != NULL; ++i)
{
if(strcasecmp(filename, ResourceList[i].filename) == 0)
{
return (ResourceList[i].CustomFile ? ResourceList[i].CustomFileSize : ResourceList[i].DefaultFileSize);
}
}
return 0;
for(int32_t i = 0; ResourceList[i].filename != NULL; ++i) {
if(strcasecmp(filename, ResourceList[i].filename) == 0) {
return (ResourceList[i].CustomFile ? ResourceList[i].CustomFileSize : ResourceList[i].DefaultFileSize);
}
}
return 0;
}
GuiImageData * Resources::GetImageData(const char * filename)
{
GuiImageData * Resources::GetImageData(const char * filename) {
if(!instance)
instance = new Resources;
ResourceFile * ResourceList = getResourceList();
if(ResourceList == NULL) return NULL;
std::map<std::string, std::pair<u32, GuiImageData *> >::iterator itr = instance->imageDataMap.find(std::string(filename));
if(itr != instance->imageDataMap.end())
{
std::map<std::string, std::pair<uint32_t, GuiImageData *> >::iterator itr = instance->imageDataMap.find(std::string(filename));
if(itr != instance->imageDataMap.end()) {
itr->second.first++;
return itr->second.second;
}
for(s32 i = 0; ResourceList[i].filename != NULL; ++i)
{
if(strcasecmp(filename, ResourceList[i].filename) == 0)
{
const u8 * buff = ResourceList[i].CustomFile ? ResourceList[i].CustomFile : ResourceList[i].DefaultFile;
const u32 size = ResourceList[i].CustomFile ? ResourceList[i].CustomFileSize : ResourceList[i].DefaultFileSize;
for(int32_t i = 0; ResourceList[i].filename != NULL; ++i) {
if(strcasecmp(filename, ResourceList[i].filename) == 0) {
const uint8_t * buff = ResourceList[i].CustomFile ? ResourceList[i].CustomFile : ResourceList[i].DefaultFile;
const uint32_t size = ResourceList[i].CustomFile ? ResourceList[i].CustomFileSize : ResourceList[i].DefaultFileSize;
if(buff == NULL)
if(buff == NULL)
return NULL;
GuiImageData * image = new GuiImageData(buff, size);
@ -123,24 +109,20 @@ GuiImageData * Resources::GetImageData(const char * filename)
instance->imageDataMap[std::string(filename)].second = image;
return image;
}
}
}
}
return NULL;
return NULL;
}
void Resources::RemoveImageData(GuiImageData * image)
{
std::map<std::string, std::pair<u32, GuiImageData *> >::iterator itr;
void Resources::RemoveImageData(GuiImageData * image) {
std::map<std::string, std::pair<uint32_t, GuiImageData *> >::iterator itr;
for(itr = instance->imageDataMap.begin(); itr != instance->imageDataMap.end(); itr++)
{
if(itr->second.second == image)
{
for(itr = instance->imageDataMap.begin(); itr != instance->imageDataMap.end(); itr++) {
if(itr->second.second == image) {
itr->second.first--;
if(itr->second.first == 0)
{
if(itr->second.first == 0) {
AsyncDeleter::pushForDelete( itr->second.second );
instance->imageDataMap.erase(itr);
}
@ -149,14 +131,12 @@ void Resources::RemoveImageData(GuiImageData * image)
}
}
GuiSound * Resources::GetSound(const char * filename)
{
GuiSound * Resources::GetSound(const char * filename) {
if(!instance)
instance = new Resources;
std::map<std::string, std::pair<u32, GuiSound *> >::iterator itr = instance->soundDataMap.find(std::string(filename));
if(itr != instance->soundDataMap.end())
{
std::map<std::string, std::pair<uint32_t, GuiSound *> >::iterator itr = instance->soundDataMap.find(std::string(filename));
if(itr != instance->soundDataMap.end()) {
itr->second.first++;
return itr->second.second;
}
@ -164,14 +144,12 @@ GuiSound * Resources::GetSound(const char * filename)
ResourceFile * ResourceList = getResourceList();
if(ResourceList == NULL) return NULL;
for(s32 i = 0; ResourceList[i].filename != NULL; ++i)
{
if(strcasecmp(filename, ResourceList[i].filename) == 0)
{
const u8 * buff = ResourceList[i].CustomFile ? ResourceList[i].CustomFile : ResourceList[i].DefaultFile;
const u32 size = ResourceList[i].CustomFile ? ResourceList[i].CustomFileSize : ResourceList[i].DefaultFileSize;
for(int32_t i = 0; ResourceList[i].filename != NULL; ++i) {
if(strcasecmp(filename, ResourceList[i].filename) == 0) {
const uint8_t * buff = ResourceList[i].CustomFile ? ResourceList[i].CustomFile : ResourceList[i].DefaultFile;
const uint32_t size = ResourceList[i].CustomFile ? ResourceList[i].CustomFileSize : ResourceList[i].DefaultFileSize;
if(buff == NULL)
if(buff == NULL)
return NULL;
GuiSound * sound = new GuiSound(buff, size);
@ -179,24 +157,20 @@ GuiSound * Resources::GetSound(const char * filename)
instance->soundDataMap[std::string(filename)].second = sound;
return sound;
}
}
}
}
return NULL;
return NULL;
}
void Resources::RemoveSound(GuiSound * sound)
{
std::map<std::string, std::pair<u32, GuiSound *> >::iterator itr;
void Resources::RemoveSound(GuiSound * sound) {
std::map<std::string, std::pair<uint32_t, GuiSound *> >::iterator itr;
for(itr = instance->soundDataMap.begin(); itr != instance->soundDataMap.end(); itr++)
{
if(itr->second.second == sound)
{
for(itr = instance->soundDataMap.begin(); itr != instance->soundDataMap.end(); itr++) {
if(itr->second.second == sound) {
itr->second.first--;
if(itr->second.first == 0)
{
if(itr->second.first == 0) {
AsyncDeleter::pushForDelete( itr->second.second );
instance->soundDataMap.erase(itr);
}

View File

@ -1,16 +0,0 @@
#ifndef _FILELIST_H_
#define _FILELIST_H_
#include <dynamic_libs/os_types.h>
typedef struct _ResourceFile
{
const char *filename;
const u8 *DefaultFile;
const u32 &DefaultFileSize;
u8 *CustomFile;
u32 CustomFileSize;
} ResourceFile;
ResourceFile * getResourceList();
#endif

View File

@ -24,119 +24,105 @@
* for WiiXplorer 2010
***************************************************************************/
#include <malloc.h>
#include "utils/utils.h"
#include "BufferCircle.hpp"
#include <utils/utils.h>
#include <sounds/BufferCircle.hpp>
BufferCircle::BufferCircle()
{
which = 0;
BufferBlockSize = 0;
BufferCircle::BufferCircle() {
which = 0;
BufferBlockSize = 0;
}
BufferCircle::~BufferCircle()
{
FreeBuffer();
SoundBuffer.clear();
BufferSize.clear();
BufferReady.clear();
BufferCircle::~BufferCircle() {
FreeBuffer();
SoundBuffer.clear();
BufferSize.clear();
BufferReady.clear();
}
void BufferCircle::SetBufferBlockSize(s32 size)
{
if(size < 0)
return;
void BufferCircle::SetBufferBlockSize(int32_t size) {
if(size < 0)
return;
BufferBlockSize = size;
BufferBlockSize = size;
for(s32 i = 0; i < Size(); i++)
{
if(SoundBuffer[i] != NULL)
free(SoundBuffer[i]);
for(int32_t 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;
}
SoundBuffer[i] = (uint8_t *) memalign(32, ALIGN32(BufferBlockSize));
BufferSize[i] = 0;
BufferReady[i] = false;
}
}
void BufferCircle::Resize(s32 size)
{
while(size < Size())
RemoveBuffer(Size()-1);
void BufferCircle::Resize(int32_t size) {
while(size < Size())
RemoveBuffer(Size()-1);
s32 oldSize = Size();
int32_t oldSize = Size();
SoundBuffer.resize(size);
BufferSize.resize(size);
BufferReady.resize(size);
SoundBuffer.resize(size);
BufferSize.resize(size);
BufferReady.resize(size);
for(s32 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;
}
for(int32_t i = oldSize; i < Size(); i++) {
if(BufferBlockSize > 0)
SoundBuffer[i] = (uint8_t *) memalign(32, ALIGN32(BufferBlockSize));
else
SoundBuffer[i] = NULL;
BufferSize[i] = 0;
BufferReady[i] = false;
}
}
void BufferCircle::RemoveBuffer(s32 pos)
{
if(!Valid(pos))
return;
void BufferCircle::RemoveBuffer(int32_t pos) {
if(!Valid(pos))
return;
if(SoundBuffer[pos] != NULL)
free(SoundBuffer[pos]);
if(SoundBuffer[pos] != NULL)
free(SoundBuffer[pos]);
SoundBuffer.erase(SoundBuffer.begin()+pos);
BufferSize.erase(BufferSize.begin()+pos);
BufferReady.erase(BufferReady.begin()+pos);
SoundBuffer.erase(SoundBuffer.begin()+pos);
BufferSize.erase(BufferSize.begin()+pos);
BufferReady.erase(BufferReady.begin()+pos);
}
void BufferCircle::ClearBuffer()
{
for(s32 i = 0; i < Size(); i++)
{
BufferSize[i] = 0;
BufferReady[i] = false;
}
which = 0;
void BufferCircle::ClearBuffer() {
for(int32_t i = 0; i < Size(); i++) {
BufferSize[i] = 0;
BufferReady[i] = false;
}
which = 0;
}
void BufferCircle::FreeBuffer()
{
for(s32 i = 0; i < Size(); i++)
{
if(SoundBuffer[i] != NULL)
free(SoundBuffer[i]);
void BufferCircle::FreeBuffer() {
for(int32_t i = 0; i < Size(); i++) {
if(SoundBuffer[i] != NULL)
free(SoundBuffer[i]);
SoundBuffer[i] = NULL;
BufferSize[i] = 0;
BufferReady[i] = false;
}
SoundBuffer[i] = NULL;
BufferSize[i] = 0;
BufferReady[i] = false;
}
}
void BufferCircle::LoadNext()
{
BufferReady[which] = false;
BufferSize[which] = 0;
void BufferCircle::LoadNext() {
BufferReady[which] = false;
BufferSize[which] = 0;
which = Next();
which = Next();
}
void BufferCircle::SetBufferReady(s32 pos, bool state)
{
if(!Valid(pos))
return;
void BufferCircle::SetBufferReady(int32_t pos, bool state) {
if(!Valid(pos))
return;
BufferReady[pos] = state;
BufferReady[pos] = state;
}
void BufferCircle::SetBufferSize(s32 pos, s32 size)
{
if(!Valid(pos))
return;
void BufferCircle::SetBufferSize(int32_t pos, int32_t size) {
if(!Valid(pos))
return;
BufferSize[pos] = size;
BufferSize[pos] = size;
}

View File

@ -1,86 +0,0 @@
/***************************************************************************
* 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 <dynamic_libs/os_types.h>
class BufferCircle
{
public:
//!> Constructor
BufferCircle();
//!> Destructor
~BufferCircle();
//!> Set circle size
void Resize(s32 size);
//!> Get the circle size
s32 Size() { return SoundBuffer.size(); };
//!> Set/resize the buffer size
void SetBufferBlockSize(s32 size);
//!> Remove a buffer
void RemoveBuffer(s32 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(s32 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(s32 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(s32 pos) { if(!Valid(pos)) return false; else return BufferReady[pos]; };
//!> Set a buffer at a position to a ready state
void SetBufferReady(s32 pos, bool st);
//!> Set the buffersize at a position
void SetBufferSize(s32 pos, s32 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 ((s32)which-1 < 0) ? Size()-1 : which-1; }
protected:
//!> Check if the position is a valid position in the vector
bool Valid(s32 pos) { return !(pos < 0 || pos >= Size()); };
u16 which;
u32 BufferBlockSize;
std::vector<u8 *> SoundBuffer;
std::vector<u32> BufferSize;
std::vector<bool> BufferReady;
};
#endif

View File

@ -29,8 +29,9 @@
#include <unistd.h>
#include <malloc.h>
#include <math.h>
#include <dynamic_libs/os_functions.h>
#include "Mp3Decoder.hpp"
#include <coreinit/time.h>
#include <coreinit/thread.h>
#include <sounds/Mp3Decoder.hpp>
Mp3Decoder::Mp3Decoder(const char * filepath)
: SoundDecoder(filepath)
@ -48,7 +49,7 @@ Mp3Decoder::Mp3Decoder(const char * filepath)
OpenFile();
}
Mp3Decoder::Mp3Decoder(const u8 * snd, s32 len)
Mp3Decoder::Mp3Decoder(const uint8_t * snd, int32_t len)
: SoundDecoder(snd, len)
{
SoundType = SOUND_MP3;
@ -68,7 +69,7 @@ Mp3Decoder::~Mp3Decoder()
{
ExitRequested = true;
while(Decoding)
os_usleep(100);
OSSleepTicks(OSMicrosecondsToTicks(100));
mad_synth_finish(&Synth);
mad_frame_finish(&Frame);
@ -82,7 +83,7 @@ Mp3Decoder::~Mp3Decoder()
void Mp3Decoder::OpenFile()
{
GuardPtr = NULL;
ReadBuffer = (u8 *) memalign(32, SoundBlockSize*SoundBlocks);
ReadBuffer = (uint8_t *) memalign(32, SoundBlockSize*SoundBlocks);
if(!ReadBuffer)
{
if(file_fd)
@ -91,8 +92,8 @@ void Mp3Decoder::OpenFile()
return;
}
u8 dummybuff[4096];
s32 ret = Read(dummybuff, 4096, 0);
uint8_t dummybuff[4096];
int32_t ret = Read(dummybuff, 4096, 0);
if(ret <= 0)
{
if(file_fd)
@ -101,12 +102,12 @@ void Mp3Decoder::OpenFile()
return;
}
SampleRate = (u32) Frame.header.samplerate;
SampleRate = (uint32_t) Frame.header.samplerate;
Format = ((MAD_NCHANNELS(&Frame.header) == 2) ? (FORMAT_PCM_16_BIT | CHANNELS_STEREO) : (FORMAT_PCM_16_BIT | CHANNELS_MONO));
Rewind();
}
s32 Mp3Decoder::Rewind()
int32_t Mp3Decoder::Rewind()
{
mad_synth_finish(&Synth);
mad_frame_finish(&Frame);
@ -124,7 +125,7 @@ s32 Mp3Decoder::Rewind()
return SoundDecoder::Rewind();
}
static inline s16 FixedToShort(mad_fixed_t Fixed)
static inline int16_t FixedToShort(mad_fixed_t Fixed)
{
/* Clipping */
if(Fixed>=MAD_F_ONE)
@ -133,10 +134,10 @@ static inline s16 FixedToShort(mad_fixed_t Fixed)
return(-SHRT_MAX);
Fixed=Fixed>>(MAD_F_FRACBITS-15);
return((s16)Fixed);
return((int16_t)Fixed);
}
s32 Mp3Decoder::Read(u8 * buffer, s32 buffer_size, s32 pos)
int32_t Mp3Decoder::Read(uint8_t * buffer, int32_t buffer_size, int32_t pos)
{
if(!file_fd)
return -1;
@ -146,8 +147,8 @@ s32 Mp3Decoder::Read(u8 * buffer, s32 buffer_size, s32 pos)
else
buffer_size &= ~0x0001;
u8 * write_pos = buffer;
u8 * write_end = buffer+buffer_size;
uint8_t * write_pos = buffer;
uint8_t * write_end = buffer+buffer_size;
while(1)
{
@ -156,12 +157,12 @@ s32 Mp3Decoder::Read(u8 * buffer, s32 buffer_size, s32 pos)
if(write_pos >= write_end)
return write_pos-buffer;
*((s16 *) write_pos) = FixedToShort(Synth.pcm.samples[0][SynthPos]);
*((int16_t *) 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]);
*((int16_t *) write_pos) = FixedToShort(Synth.pcm.samples[1][SynthPos]);
write_pos += 2;
}
SynthPos++;
@ -169,9 +170,9 @@ s32 Mp3Decoder::Read(u8 * buffer, s32 buffer_size, s32 pos)
if(Stream.buffer == NULL || Stream.error == MAD_ERROR_BUFLEN)
{
u8 * ReadStart = ReadBuffer;
s32 ReadSize = SoundBlockSize*SoundBlocks;
s32 Remaining = 0;
uint8_t * ReadStart = ReadBuffer;
int32_t ReadSize = SoundBlockSize*SoundBlocks;
int32_t Remaining = 0;
if(Stream.next_frame != NULL)
{

View File

@ -25,114 +25,103 @@
***************************************************************************/
#include <unistd.h>
#include <malloc.h>
#include <dynamic_libs/os_functions.h>
#include "OggDecoder.hpp"
#include <coreinit/time.h>
#include <coreinit/thread.h>
#include <sounds/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_read(void * punt, int bytes, int blocks, int *f) {
return ((CFile *) f)->read((uint8_t *) 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_seek(int *f, ogg_int64_t offset, int mode) {
return ((CFile *) f)->seek((uint64_t) offset, mode);
}
static int ogg_close(int *f)
{
((CFile *) f)->close();
return 0;
static int ogg_close(int *f) {
((CFile *) f)->close();
return 0;
}
static long ogg_tell(int *f)
{
return (long) ((CFile *) f)->tell();
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
(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;
: SoundDecoder(filepath) {
SoundType = SOUND_OGG;
if(!file_fd)
return;
if(!file_fd)
return;
OpenFile();
OpenFile();
}
OggDecoder::OggDecoder(const u8 * snd, s32 len)
: SoundDecoder(snd, len)
{
SoundType = SOUND_OGG;
OggDecoder::OggDecoder(const uint8_t * snd, int32_t len)
: SoundDecoder(snd, len) {
SoundType = SOUND_OGG;
if(!file_fd)
return;
if(!file_fd)
return;
OpenFile();
OpenFile();
}
OggDecoder::~OggDecoder()
{
ExitRequested = true;
while(Decoding)
os_usleep(100);
OggDecoder::~OggDecoder() {
ExitRequested = true;
while(Decoding)
OSSleepTicks(OSMicrosecondsToTicks(100));
if(file_fd)
ov_clear(&ogg_file);
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;
}
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;
}
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;
Format = ((ogg_info->channels == 2) ? (FORMAT_PCM_16_BIT | CHANNELS_STEREO) : (FORMAT_PCM_16_BIT | CHANNELS_MONO));
SampleRate = ogg_info->rate;
}
s32 OggDecoder::Rewind()
{
if(!file_fd)
return -1;
int32_t OggDecoder::Rewind() {
if(!file_fd)
return -1;
s32 ret = ov_time_seek(&ogg_file, 0);
CurPos = 0;
EndOfFile = false;
int32_t ret = ov_time_seek(&ogg_file, 0);
CurPos = 0;
EndOfFile = false;
return ret;
return ret;
}
s32 OggDecoder::Read(u8 * buffer, s32 buffer_size, s32 pos)
{
if(!file_fd)
return -1;
int32_t OggDecoder::Read(uint8_t * buffer, int32_t buffer_size, int32_t pos) {
if(!file_fd)
return -1;
s32 bitstream = 0;
int32_t bitstream = 0;
s32 read = (s32) ov_read(&ogg_file, (char *) buffer, (int) buffer_size, (int *)&bitstream);
int32_t read = (int32_t) ov_read(&ogg_file, (char *) buffer, (int) buffer_size, (int *)&bitstream);
if(read > 0)
CurPos += read;
if(read > 0)
CurPos += read;
return read;
return read;
}

View File

@ -18,208 +18,187 @@
#include <malloc.h>
#include <string.h>
#include <unistd.h>
#include <dynamic_libs/os_functions.h>
#include "SoundDecoder.hpp"
#include <coreinit/time.h>
#include <coreinit/thread.h>
#include <coreinit/cache.h>
#include <sounds/SoundDecoder.hpp>
static const u32 FixedPointShift = 15;
static const u32 FixedPointScale = 1 << FixedPointShift;
static const uint32_t FixedPointShift = 15;
static const uint32_t FixedPointScale = 1 << FixedPointShift;
SoundDecoder::SoundDecoder()
{
file_fd = NULL;
Init();
SoundDecoder::SoundDecoder() {
file_fd = NULL;
Init();
}
SoundDecoder::SoundDecoder(const std::string & filepath)
{
file_fd = new CFile(filepath, CFile::ReadOnly);
Init();
SoundDecoder::SoundDecoder(const std::string & filepath) {
file_fd = new CFile(filepath, CFile::ReadOnly);
Init();
}
SoundDecoder::SoundDecoder(const u8 * buffer, s32 size)
{
file_fd = new CFile(buffer, size);
Init();
SoundDecoder::SoundDecoder(const uint8_t * buffer, int32_t size) {
file_fd = new CFile(buffer, size);
Init();
}
SoundDecoder::~SoundDecoder()
{
ExitRequested = true;
while(Decoding)
os_usleep(1000);
SoundDecoder::~SoundDecoder() {
ExitRequested = true;
while(Decoding)
OSSleepTicks(OSMicrosecondsToTicks(1000));
//! lock unlock once to make sure it's really not decoding
Lock();
Unlock();
//! lock unlock once to make sure it's really not decoding
Lock();
Unlock();
if(file_fd)
delete file_fd;
file_fd = NULL;
if(file_fd)
delete file_fd;
file_fd = NULL;
if(ResampleBuffer)
free(ResampleBuffer);
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;
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;
}
s32 SoundDecoder::Rewind()
{
CurPos = 0;
EndOfFile = false;
file_fd->rewind();
int32_t SoundDecoder::Rewind() {
CurPos = 0;
EndOfFile = false;
file_fd->rewind();
return 0;
return 0;
}
s32 SoundDecoder::Read(u8 * buffer, s32 buffer_size, s32 pos)
{
s32 ret = file_fd->read(buffer, buffer_size);
CurPos += ret;
int32_t SoundDecoder::Read(uint8_t * buffer, int32_t buffer_size, int32_t pos) {
int32_t ret = file_fd->read(buffer, buffer_size);
CurPos += ret;
return 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::EnableUpsample(void) {
if( (ResampleBuffer == NULL)
&& IsStereo() && Is16Bit()
&& SampleRate != 32000
&& SampleRate != 48000) {
ResampleBuffer = (uint8_t*)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)
{
s32 timer = 0;
void SoundDecoder::Upsample(int16_t *src, int16_t *dst, uint32_t nr_src_samples, uint32_t nr_dst_samples) {
int32_t 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];
}
for(uint32_t 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;
timer += ResampleRatio;
if(timer >= (s32)FixedPointScale) {
n += 2;
timer -= FixedPointScale;
}
}
if(timer >= (int32_t)FixedPointScale) {
n += 2;
timer -= FixedPointScale;
}
}
}
void SoundDecoder::Decode()
{
if(!file_fd || ExitRequested || EndOfFile)
return;
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;
}
// check if we are not at the pre-last buffer (last buffer is playing)
uint16_t whichPlaying = SoundBuffer.Which();
if( ((whichPlaying == 0) && (whichLoad == SoundBuffer.Size()-2))
|| ((whichPlaying == 1) && (whichLoad == SoundBuffer.Size()-1))
|| (whichLoad == (whichPlaying-2))) {
return;
}
Decoding = true;
Decoding = true;
s32 done = 0;
u8 * write_buf = SoundBuffer.GetBuffer(whichLoad);
if(!write_buf)
{
ExitRequested = true;
Decoding = false;
return;
}
int32_t done = 0;
uint8_t * write_buf = SoundBuffer.GetBuffer(whichLoad);
if(!write_buf) {
ExitRequested = true;
Decoding = false;
return;
}
if(ResampleTo48kHz && !ResampleBuffer)
EnableUpsample();
if(ResampleTo48kHz && !ResampleBuffer)
EnableUpsample();
while(done < SoundBlockSize)
{
s32 ret = Read(&write_buf[done], SoundBlockSize-done, Tell());
while(done < SoundBlockSize) {
int32_t ret = Read(&write_buf[done], SoundBlockSize-done, Tell());
if(ret <= 0)
{
if(Loop)
{
Rewind();
continue;
}
else
{
EndOfFile = true;
break;
}
}
if(ret <= 0) {
if(Loop) {
Rewind();
continue;
} else {
EndOfFile = true;
break;
}
}
done += ret;
}
done += ret;
}
if(done > 0)
{
// check if we need to resample
if(ResampleBuffer && ResampleRatio)
{
memcpy(ResampleBuffer, write_buf, done);
if(done > 0) {
// check if we need to resample
if(ResampleBuffer && ResampleRatio) {
memcpy(ResampleBuffer, write_buf, done);
s32 src_samples = done >> 1;
s32 dest_samples = ( src_samples * FixedPointScale ) / ResampleRatio;
dest_samples &= ~0x01;
Upsample((s16*)ResampleBuffer, (s16*)write_buf, src_samples, dest_samples);
done = dest_samples << 1;
}
int32_t src_samples = done >> 1;
int32_t dest_samples = ( src_samples * FixedPointScale ) / ResampleRatio;
dest_samples &= ~0x01;
Upsample((int16_t*)ResampleBuffer, (int16_t*)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;
//! TODO: remove this later and add STEREO support with two voices, for now we convert to MONO
if(IsStereo()) {
int16_t* monoBuf = (int16_t*)write_buf;
done = done >> 1;
for(s32 i = 0; i < done; i++)
for(int32_t 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;
}
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();
// check if next in queue needs to be filled as well and do so
if(!SoundBuffer.IsBufferReady(whichLoad))
Decode();
Decoding = false;
Decoding = false;
}

View File

@ -1,105 +0,0 @@
/***************************************************************************
* 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, s32 size);
virtual ~SoundDecoder();
virtual void Lock() { mutex.lock(); }
virtual void Unlock() { mutex.unlock(); }
virtual s32 Read(u8 * buffer, s32 buffer_size, s32 pos);
virtual s32 Tell() { return CurPos; }
virtual s32 Seek(s32 pos) { CurPos = pos; return file_fd->seek(CurPos, SEEK_SET); }
virtual s32 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;
s32 SoundBlockSize;
s32 CurPos;
bool ResampleTo48kHz;
bool Loop;
bool EndOfFile;
bool Decoding;
bool ExitRequested;
u16 Format;
u16 SampleRate;
u8 *ResampleBuffer;
u32 ResampleRatio;
CMutex mutex;
};
#endif

View File

@ -25,24 +25,21 @@
***************************************************************************/
#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"
#include <fs/CFile.hpp>
#include <sounds/SoundHandler.hpp>
#include <sounds/WavDecoder.hpp>
#include <sounds/Mp3Decoder.hpp>
#include <sounds/OggDecoder.hpp>
#include <sndcore2/core.h>
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;
: CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 0, 0x8000) {
Decoding = false;
ExitRequested = false;
for(uint32_t i = 0; i < MAX_DECODERS; ++i) {
DecoderList[i] = NULL;
voiceList[i] = NULL;
}
@ -50,302 +47,263 @@ SoundHandler::SoundHandler()
//! wait for initialization
while(!isThreadSuspended())
os_usleep(1000);
OSSleepTicks(OSMicrosecondsToTicks(1000));
}
SoundHandler::~SoundHandler()
{
ExitRequested = true;
ThreadSignal();
SoundHandler::~SoundHandler() {
ExitRequested = true;
ThreadSignal();
ClearDecoderList();
ClearDecoderList();
}
void SoundHandler::AddDecoder(s32 voice, const char * filepath)
{
if(voice < 0 || voice >= MAX_DECODERS)
return;
void SoundHandler::AddDecoder(int32_t voice, const char * filepath) {
if(voice < 0 || voice >= MAX_DECODERS)
return;
if(DecoderList[voice] != NULL)
RemoveDecoder(voice);
if(DecoderList[voice] != NULL)
RemoveDecoder(voice);
DecoderList[voice] = GetSoundDecoder(filepath);
DecoderList[voice] = GetSoundDecoder(filepath);
}
void SoundHandler::AddDecoder(s32 voice, const u8 * snd, s32 len)
{
if(voice < 0 || voice >= MAX_DECODERS)
return;
void SoundHandler::AddDecoder(int32_t voice, const uint8_t * snd, int32_t len) {
if(voice < 0 || voice >= MAX_DECODERS)
return;
if(DecoderList[voice] != NULL)
RemoveDecoder(voice);
if(DecoderList[voice] != NULL)
RemoveDecoder(voice);
DecoderList[voice] = GetSoundDecoder(snd, len);
DecoderList[voice] = GetSoundDecoder(snd, len);
}
void SoundHandler::RemoveDecoder(s32 voice)
{
if(voice < 0 || voice >= MAX_DECODERS)
return;
void SoundHandler::RemoveDecoder(int32_t voice) {
if(voice < 0 || voice >= MAX_DECODERS)
return;
if(DecoderList[voice] != NULL)
{
if(voiceList[voice] && voiceList[voice]->getState() != Voice::STATE_STOPPED)
{
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)
os_usleep(1000);
OSSleepTicks(OSMicrosecondsToTicks(1000));
}
SoundDecoder *decoder = DecoderList[voice];
decoder->Lock();
DecoderList[voice] = NULL;
decoder->Unlock();
delete decoder;
delete decoder;
}
}
void SoundHandler::ClearDecoderList()
{
for(u32 i = 0; i < MAX_DECODERS; ++i)
RemoveDecoder(i);
void SoundHandler::ClearDecoderList() {
for(uint32_t 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'),
};
static inline bool CheckMP3Signature(const uint8_t * 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;
}
if(buffer[0] == MP3_Magic[0][0] && buffer[1] == MP3_Magic[0][1] &&
buffer[2] == MP3_Magic[0][2]) {
return true;
}
for(s32 i = 1; i < 13; i++)
{
if(buffer[0] == MP3_Magic[i][0] && buffer[1] == MP3_Magic[i][1])
return true;
}
for(int32_t i = 1; i < 13; i++) {
if(buffer[0] == MP3_Magic[i][0] && buffer[1] == MP3_Magic[i][1])
return true;
}
return false;
return false;
}
SoundDecoder * SoundHandler::GetSoundDecoder(const char * filepath)
{
u32 magic;
CFile f(filepath, CFile::ReadOnly);
if(f.size() == 0)
return NULL;
SoundDecoder * SoundHandler::GetSoundDecoder(const char * filepath) {
uint32_t 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());
do {
f.read((uint8_t *) &magic, 1);
} while(((uint8_t *) &magic)[0] == 0 && f.tell() < f.size());
if(f.tell() == f.size())
return NULL;
if(f.tell() == f.size())
return NULL;
f.seek(f.tell()-1, SEEK_SET);
f.read((u8 *) &magic, 4);
f.close();
f.seek(f.tell()-1, SEEK_SET);
f.read((uint8_t *) &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);
}
if(magic == 0x4f676753) { // 'OggS'
return new OggDecoder(filepath);
} else if(magic == 0x52494646) { // 'RIFF'
return new WavDecoder(filepath);
} else if(CheckMP3Signature((uint8_t *) &magic) == true) {
return new Mp3Decoder(filepath);
}
return new SoundDecoder(filepath);
return new SoundDecoder(filepath);
}
SoundDecoder * SoundHandler::GetSoundDecoder(const u8 * sound, s32 length)
{
const u8 * check = sound;
s32 counter = 0;
SoundDecoder * SoundHandler::GetSoundDecoder(const uint8_t * sound, int32_t length) {
const uint8_t * check = sound;
int32_t counter = 0;
while(check[0] == 0 && counter < length)
{
check++;
counter++;
}
while(check[0] == 0 && counter < length) {
check++;
counter++;
}
if(counter >= length)
return NULL;
if(counter >= length)
return NULL;
u32 * magic = (u32 *) check;
uint32_t * magic = (uint32_t *) 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);
}
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);
return new SoundDecoder(sound, length);
}
void SoundHandler::executeThread()
{
// v2 sound lib can not properly end transition audio on old firmwares
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 };
AXInitParams params;
memset(&params, 0, sizeof(params));
params.renderer = AX_INIT_RENDERER_48KHZ;
if(AXInitWithParams != 0)
AXInitWithParams(params);
else
AXInit();
// TODO: handle support for 3.1.0 with dynamic libs instead of static linking it
//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)
{
s32 priority = (MAX_DECODERS - i) * Voice::PRIO_MAX / MAX_DECODERS;
for(uint32_t i = 0; i < MAX_DECODERS; ++i) {
int32_t priority = (MAX_DECODERS - i) * Voice::PRIO_MAX / MAX_DECODERS;
voiceList[i] = new Voice(priority); // allocate voice 0 with highest priority
}
AXRegisterFrameCallback((void*)&axFrameCallback);
AXRegisterAppFrameCallback(SoundHandler::axFrameCallback);
u16 i = 0;
while (!ExitRequested)
{
suspendThread();
uint16_t i = 0;
while (!ExitRequested) {
suspendThread();
for(i = 0; i < MAX_DECODERS; ++i)
{
if(DecoderList[i] == NULL)
continue;
for(i = 0; i < MAX_DECODERS; ++i) {
if(DecoderList[i] == NULL)
continue;
Decoding = true;
if(DecoderList[i])
Decoding = true;
if(DecoderList[i])
DecoderList[i]->Lock();
if(DecoderList[i])
if(DecoderList[i])
DecoderList[i]->Decode();
if(DecoderList[i])
if(DecoderList[i])
DecoderList[i]->Unlock();
}
Decoding = false;
}
}
Decoding = false;
}
for(u32 i = 0; i < MAX_DECODERS; ++i)
for(uint32_t i = 0; i < MAX_DECODERS; ++i)
voiceList[i]->stop();
AXRegisterFrameCallback(NULL);
AXRegisterAppFrameCallback(NULL);
AXQuit();
for(u32 i = 0; i < MAX_DECODERS; ++i)
{
for(uint32_t i = 0; i < MAX_DECODERS; ++i) {
delete voiceList[i];
voiceList[i] = NULL;
}
}
void SoundHandler::axFrameCallback(void)
{
for (u32 i = 0; i < MAX_DECODERS; i++)
{
void SoundHandler::axFrameCallback(void) {
for (uint32_t i = 0; i < MAX_DECODERS; i++) {
Voice *voice = handlerInstance->getVoice(i);
switch (voice->getState())
{
default:
case Voice::STATE_STOPPED:
break;
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();
case Voice::STATE_START: {
SoundDecoder * decoder = handlerInstance->getDecoder(i);
decoder->Lock();
if(decoder->IsBufferReady()) {
const uint8_t *buffer = decoder->GetBuffer();
const uint32_t bufferSize = decoder->GetBufferSize();
decoder->LoadNext();
const uint8_t *nextBuffer = NULL;
uint32_t nextBufferSize = 0;
if(decoder->IsBufferReady()) {
nextBuffer = decoder->GetBuffer();
nextBufferSize = 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;
voice->play(buffer, bufferSize, nextBuffer, nextBufferSize, decoder->GetFormat() & 0xff, decoder->GetSampleRate());
handlerInstance->ThreadSignal();
voice->setState(Voice::STATE_PLAYING);
}
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();
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();
} else {
voice->setState(Voice::STATE_STOPPED);
break;
}
break;
case Voice::STATE_STOP:
if(voice->getInternState() != 0)
voice->stop();
voice->setState(Voice::STATE_STOPPED);
break;
}
}
}

View File

@ -1,170 +0,0 @@
/****************************************************************************
* 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 _AXSOUND_H_
#define _AXSOUND_H_
#include <dynamic_libs/os_functions.h>
#include <dynamic_libs/ax_functions.h>
class Voice
{
public:
enum VoicePriorities
{
PRIO_MIN = 1,
PRIO_MAX = 31
};
enum VoiceStates
{
STATE_STOPPED,
STATE_START,
STATE_PLAYING,
STATE_STOP,
};
Voice(s32 prio)
: state(STATE_STOPPED)
{
lastLoopCounter = 0;
nextBufferSize = 0;
voice = AXAcquireVoice(prio, 0, 0);
if(voice)
{
AXVoiceBegin(voice);
AXSetVoiceType(voice, 0);
setVolume(0x80000000);
u32 mix[24];
memset(mix, 0, sizeof(mix));
mix[0] = 0x80000000;
mix[4] = 0x80000000;
AXSetVoiceDeviceMix(voice, 0, 0, mix);
AXSetVoiceDeviceMix(voice, 1, 0, mix);
AXVoiceEnd(voice);
}
}
~Voice()
{
if(voice)
{
AXFreeVoice(voice);
}
}
void play(const u8 *buffer, u32 bufferSize, const u8 *nextBuffer, u32 nextBufSize, u16 format, u32 sampleRate)
{
if(!voice)
return;
memset(&voiceBuffer, 0, sizeof(voiceBuffer));
voiceBuffer.samples = buffer;
voiceBuffer.format = format;
voiceBuffer.loop = (nextBuffer == NULL) ? 0 : 1;
voiceBuffer.cur_pos = 0;
voiceBuffer.end_pos = bufferSize >> 1;
voiceBuffer.loop_offset = ((nextBuffer - buffer) >> 1);
nextBufferSize = nextBufSize;
u32 samplesPerSec = (AXGetInputSamplesPerSec != 0) ? AXGetInputSamplesPerSec() : 32000;
ratioBits[0] = (u32)(0x00010000 * ((f32)sampleRate / (f32)samplesPerSec));
ratioBits[1] = 0;
ratioBits[2] = 0;
ratioBits[3] = 0;
AXSetVoiceOffsets(voice, &voiceBuffer);
AXSetVoiceSrc(voice, ratioBits);
AXSetVoiceSrcType(voice, 1);
AXSetVoiceState(voice, 1);
}
void stop()
{
if(voice)
AXSetVoiceState(voice, 0);
}
void setVolume(u32 vol)
{
if(voice)
AXSetVoiceVe(voice, &vol);
}
void setNextBuffer(const u8 *buffer, u32 bufferSize)
{
voiceBuffer.loop_offset = ((buffer - voiceBuffer.samples) >> 1);
nextBufferSize = bufferSize;
AXSetVoiceLoopOffset(voice, voiceBuffer.loop_offset);
}
bool isBufferSwitched()
{
u32 loopCounter = AXGetVoiceLoopCount(voice);
if(lastLoopCounter != loopCounter)
{
lastLoopCounter = loopCounter;
AXSetVoiceEndOffset(voice, voiceBuffer.loop_offset + (nextBufferSize >> 1));
return true;
}
return false;
}
u32 getInternState() const {
if(voice)
return ((u32 *)voice)[1];
return 0;
}
u32 getState() const {
return state;
}
void setState(u32 s) {
state = s;
}
void * getVoice() const {
return voice;
}
private:
void *voice;
u32 ratioBits[4];
typedef struct _ax_buffer_t {
u16 format;
u16 loop;
u32 loop_offset;
u32 end_pos;
u32 cur_pos;
const unsigned char *samples;
} ax_buffer_t;
ax_buffer_t voiceBuffer;
u32 state;
u32 nextBufferSize;
u32 lastLoopCounter;
};
#endif // _AXSOUND_H_

View File

@ -24,131 +24,116 @@
* for WiiXplorer 2010
***************************************************************************/
#include <string.h>
#include "WavDecoder.hpp"
#include "utils/utils.h"
#include <utils/utils.h>
#include <sounds/WavDecoder.hpp>
WavDecoder::WavDecoder(const char * filepath)
: SoundDecoder(filepath)
{
SoundType = SOUND_WAV;
SampleRate = 48000;
Format = CHANNELS_STEREO | FORMAT_PCM_16_BIT;
: SoundDecoder(filepath) {
SoundType = SOUND_WAV;
SampleRate = 48000;
Format = CHANNELS_STEREO | FORMAT_PCM_16_BIT;
if(!file_fd)
return;
if(!file_fd)
return;
OpenFile();
OpenFile();
}
WavDecoder::WavDecoder(const u8 * snd, s32 len)
: SoundDecoder(snd, len)
{
SoundType = SOUND_WAV;
SampleRate = 48000;
Format = CHANNELS_STEREO | FORMAT_PCM_16_BIT;
WavDecoder::WavDecoder(const uint8_t * snd, int32_t len)
: SoundDecoder(snd, len) {
SoundType = SOUND_WAV;
SampleRate = 48000;
Format = CHANNELS_STEREO | FORMAT_PCM_16_BIT;
if(!file_fd)
return;
if(!file_fd)
return;
OpenFile();
OpenFile();
}
WavDecoder::~WavDecoder()
{
WavDecoder::~WavDecoder() {
}
void WavDecoder::OpenFile()
{
SWaveHdr Header;
SWaveFmtChunk FmtChunk;
memset(&Header, 0, sizeof(SWaveHdr));
memset(&FmtChunk, 0, sizeof(SWaveFmtChunk));
void WavDecoder::OpenFile() {
SWaveHdr Header;
SWaveFmtChunk FmtChunk;
memset(&Header, 0, sizeof(SWaveHdr));
memset(&FmtChunk, 0, sizeof(SWaveFmtChunk));
file_fd->read((u8 *) &Header, sizeof(SWaveHdr));
file_fd->read((u8 *) &FmtChunk, sizeof(SWaveFmtChunk));
file_fd->read((uint8_t *) &Header, sizeof(SWaveHdr));
file_fd->read((uint8_t *) &FmtChunk, sizeof(SWaveFmtChunk));
if (Header.magicRIFF != 0x52494646) // 'RIFF'
{
CloseFile();
return;
}
else if(Header.magicWAVE != 0x57415645) // 'WAVE'
{
CloseFile();
return;
}
else if(FmtChunk.magicFMT != 0x666d7420) // 'fmt '
{
CloseFile();
return;
}
if (Header.magicRIFF != 0x52494646) { // 'RIFF'
CloseFile();
return;
} else if(Header.magicWAVE != 0x57415645) { // 'WAVE'
CloseFile();
return;
} else if(FmtChunk.magicFMT != 0x666d7420) { // 'fmt '
CloseFile();
return;
}
DataOffset = sizeof(SWaveHdr)+le32(FmtChunk.size)+8;
file_fd->seek(DataOffset, SEEK_SET);
SWaveChunk DataChunk;
file_fd->read((u8 *) &DataChunk, sizeof(SWaveChunk));
DataOffset = sizeof(SWaveHdr)+le32(FmtChunk.size)+8;
file_fd->seek(DataOffset, SEEK_SET);
SWaveChunk DataChunk;
file_fd->read((uint8_t *) &DataChunk, sizeof(SWaveChunk));
while(DataChunk.magicDATA != 0x64617461) // 'data'
{
DataOffset += 8+le32(DataChunk.size);
file_fd->seek(DataOffset, SEEK_SET);
s32 ret = file_fd->read((u8 *) &DataChunk, sizeof(SWaveChunk));
if(ret <= 0)
{
CloseFile();
return;
}
}
while(DataChunk.magicDATA != 0x64617461) { // 'data'
DataOffset += 8+le32(DataChunk.size);
file_fd->seek(DataOffset, SEEK_SET);
int32_t ret = file_fd->read((uint8_t *) &DataChunk, sizeof(SWaveChunk));
if(ret <= 0) {
CloseFile();
return;
}
}
DataOffset += 8;
DataSize = le32(DataChunk.size);
Is16Bit = (le16(FmtChunk.bps) == 16);
SampleRate = le32(FmtChunk.freq);
DataOffset += 8;
DataSize = le32(DataChunk.size);
Is16Bit = (le16(FmtChunk.bps) == 16);
SampleRate = le32(FmtChunk.freq);
if (le16(FmtChunk.channels) == 1 && le16(FmtChunk.bps) == 8 && le16(FmtChunk.alignment) <= 1)
Format = CHANNELS_MONO | FORMAT_PCM_8_BIT;
else if (le16(FmtChunk.channels) == 1 && le16(FmtChunk.bps) == 16 && le16(FmtChunk.alignment) <= 2)
Format = CHANNELS_MONO | FORMAT_PCM_16_BIT;
else if (le16(FmtChunk.channels) == 2 && le16(FmtChunk.bps) == 8 && le16(FmtChunk.alignment) <= 2)
Format = CHANNELS_STEREO | FORMAT_PCM_8_BIT;
else if (le16(FmtChunk.channels) == 2 && le16(FmtChunk.bps) == 16 && le16(FmtChunk.alignment) <= 4)
Format = CHANNELS_STEREO | FORMAT_PCM_16_BIT;
if (le16(FmtChunk.channels) == 1 && le16(FmtChunk.bps) == 8 && le16(FmtChunk.alignment) <= 1)
Format = CHANNELS_MONO | FORMAT_PCM_8_BIT;
else if (le16(FmtChunk.channels) == 1 && le16(FmtChunk.bps) == 16 && le16(FmtChunk.alignment) <= 2)
Format = CHANNELS_MONO | FORMAT_PCM_16_BIT;
else if (le16(FmtChunk.channels) == 2 && le16(FmtChunk.bps) == 8 && le16(FmtChunk.alignment) <= 2)
Format = CHANNELS_STEREO | FORMAT_PCM_8_BIT;
else if (le16(FmtChunk.channels) == 2 && le16(FmtChunk.bps) == 16 && le16(FmtChunk.alignment) <= 4)
Format = CHANNELS_STEREO | FORMAT_PCM_16_BIT;
}
void WavDecoder::CloseFile()
{
if(file_fd)
delete file_fd;
void WavDecoder::CloseFile() {
if(file_fd)
delete file_fd;
file_fd = NULL;
file_fd = NULL;
}
s32 WavDecoder::Read(u8 * buffer, s32 buffer_size, s32 pos)
{
if(!file_fd)
return -1;
int32_t WavDecoder::Read(uint8_t * buffer, int32_t buffer_size, int32_t pos) {
if(!file_fd)
return -1;
if(CurPos >= (s32) DataSize)
return 0;
if(CurPos >= (int32_t) DataSize)
return 0;
file_fd->seek(DataOffset+CurPos, SEEK_SET);
file_fd->seek(DataOffset+CurPos, SEEK_SET);
if(buffer_size > (s32) DataSize-CurPos)
buffer_size = DataSize-CurPos;
if(buffer_size > (int32_t) DataSize-CurPos)
buffer_size = DataSize-CurPos;
s32 read = file_fd->read(buffer, buffer_size);
if(read > 0)
{
if (Is16Bit)
{
read &= ~0x0001;
int32_t read = file_fd->read(buffer, buffer_size);
if(read > 0) {
if (Is16Bit) {
read &= ~0x0001;
for (u32 i = 0; i < (u32) (read / sizeof (u16)); ++i)
((u16 *) buffer)[i] = le16(((u16 *) buffer)[i]);
}
CurPos += read;
}
for (uint32_t i = 0; i < (uint32_t) (read / sizeof (uint16_t)); ++i)
((uint16_t *) buffer)[i] = le16(((uint16_t *) buffer)[i]);
}
CurPos += read;
}
return read;
return read;
}

View File

@ -16,17 +16,14 @@
****************************************************************************/
#include <malloc.h>
#include <string.h>
#include "CVideo.h"
#include <video/CVideo.h>
#include <system/memory.h>
#include "shaders/Texture2DShader.h"
#include "shaders/ColorShader.h"
#include "shaders/Shader3D.h"
#include "shaders/ShaderFractalColor.h"
#include "shaders/FXAAShader.h"
#include <dynamic_libs/os_functions.h>
CVideo::CVideo(s32 forceTvScanMode, s32 forceDrcScanMode)
{
#include <video/shaders/Texture2DShader.h>
#include <video/shaders/ColorShader.h>
#include <video/shaders/Shader3D.h>
#include <video/shaders/ShaderFractalColor.h>
#include <video/shaders/FXAAShader.h>
CVideo::CVideo(int32_t forceTvScanMode, int32_t forceDrcScanMode) {
tvEnabled = false;
drcEnabled = false;
@ -34,134 +31,128 @@ CVideo::CVideo(s32 forceTvScanMode, s32 forceDrcScanMode)
gx2CommandBuffer = MEM2_alloc(GX2_COMMAND_BUFFER_SIZE, 0x40);
//! initialize GX2 command buffer
u32 gx2_init_attributes[9];
gx2_init_attributes[0] = GX2_INIT_ATTRIB_CB_BASE;
gx2_init_attributes[1] = (u32)gx2CommandBuffer;
gx2_init_attributes[2] = GX2_INIT_ATTRIB_CB_SIZE;
uint32_t gx2_init_attributes[9];
gx2_init_attributes[0] = GX2_INIT_CMD_BUF_BASE;
gx2_init_attributes[1] = (uint32_t)gx2CommandBuffer;
gx2_init_attributes[2] = GX2_INIT_CMD_BUF_POOL_SIZE;
gx2_init_attributes[3] = GX2_COMMAND_BUFFER_SIZE;
gx2_init_attributes[4] = GX2_INIT_ATTRIB_ARGC;
gx2_init_attributes[4] = GX2_INIT_ARGC;
gx2_init_attributes[5] = 0;
gx2_init_attributes[6] = GX2_INIT_ATTRIB_ARGV;
gx2_init_attributes[6] = GX2_INIT_ARGV;
gx2_init_attributes[7] = 0;
gx2_init_attributes[8] = GX2_INIT_ATTRIB_NULL;
gx2_init_attributes[8] = GX2_INIT_END;
GX2Init(gx2_init_attributes);
//! GX2 resources are not used in this application but if needed, the allocator is setup
GX2RSetAllocator(&CVideo::GX2RAlloc, &CVideo::GX2RFree);
uint32_t scanBufferSize = 0;
uint32_t scaleNeeded = 0;
u32 scanBufferSize = 0;
s32 scaleNeeded = 0;
int32_t tvScanMode = ((forceTvScanMode >= 0) ? forceTvScanMode : (int32_t)GX2GetSystemTVScanMode());
int32_t drcScanMode = ((forceDrcScanMode >= 0) ? forceDrcScanMode : (int32_t)GX2GetSystemDRCScanMode());
s32 tvScanMode = (forceTvScanMode >= 0) ? forceTvScanMode : GX2GetSystemTVScanMode();
s32 drcScanMode = (forceDrcScanMode >= 0) ? forceDrcScanMode : GX2GetSystemDRCScanMode();
int32_t tvRenderMode;
uint32_t tvWidth = 0;
uint32_t tvHeight = 0;
s32 tvRenderMode;
u32 tvWidth = 0;
u32 tvHeight = 0;
switch(tvScanMode)
{
switch(tvScanMode) {
case GX2_TV_SCAN_MODE_480I:
case GX2_TV_SCAN_MODE_480P:
tvWidth = 854;
tvHeight = 480;
tvRenderMode = GX2_TV_RENDER_480_WIDE;
tvRenderMode = GX2_TV_RENDER_MODE_WIDE_480P;
break;
case GX2_TV_SCAN_MODE_1080I:
case GX2_TV_SCAN_MODE_1080P:
tvWidth = 1920;
tvHeight = 1080;
tvRenderMode = GX2_TV_RENDER_1080;
tvRenderMode = GX2_TV_RENDER_MODE_WIDE_1080P;
break;
case GX2_TV_SCAN_MODE_720P:
default:
tvWidth = 1280;
tvHeight = 720;
tvRenderMode = GX2_TV_RENDER_720;
tvRenderMode = GX2_TV_RENDER_MODE_WIDE_720P;
break;
}
s32 tvAAMode = GX2_AA_MODE_1X;
s32 drcAAMode = GX2_AA_MODE_4X;
int32_t tvAAMode = GX2_AA_MODE1X;
int32_t drcAAMode = GX2_AA_MODE4X;
//! calculate the scale factor for later texture resize
widthScaleFactor = 1.0f / (f32)tvWidth;
heightScaleFactor = 1.0f / (f32)tvHeight;
widthScaleFactor = 1.0f / (float)tvWidth;
heightScaleFactor = 1.0f / (float)tvHeight;
depthScaleFactor = widthScaleFactor;
//! calculate the size needed for the TV scan buffer and allocate the buffer from bucket memory
GX2CalcTVSize(tvRenderMode, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GX2_BUFFERING_DOUBLE, &scanBufferSize, &scaleNeeded);
GX2CalcTVSize((GX2TVRenderMode)tvRenderMode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE, &scanBufferSize, &scaleNeeded);
tvScanBuffer = MEMBucket_alloc(scanBufferSize, GX2_SCAN_BUFFER_ALIGNMENT);
GX2Invalidate(GX2_INVALIDATE_CPU, tvScanBuffer, scanBufferSize);
GX2SetTVBuffer(tvScanBuffer, scanBufferSize, tvRenderMode, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GX2_BUFFERING_DOUBLE);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, tvScanBuffer, scanBufferSize);
GX2SetTVBuffer(tvScanBuffer, scanBufferSize, (GX2TVRenderMode)tvRenderMode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE);
//! calculate the size needed for the DRC scan buffer and allocate the buffer from bucket memory
GX2CalcDRCSize(drcScanMode, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GX2_BUFFERING_DOUBLE, &scanBufferSize, &scaleNeeded);
GX2CalcDRCSize((GX2DrcRenderMode)drcScanMode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE, &scanBufferSize, &scaleNeeded);
drcScanBuffer = MEMBucket_alloc(scanBufferSize, GX2_SCAN_BUFFER_ALIGNMENT);
GX2Invalidate(GX2_INVALIDATE_CPU, drcScanBuffer, scanBufferSize);
GX2SetDRCBuffer(drcScanBuffer, scanBufferSize, drcScanMode, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GX2_BUFFERING_DOUBLE);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, drcScanBuffer, scanBufferSize);
GX2SetDRCBuffer(drcScanBuffer, scanBufferSize, (GX2DrcRenderMode)drcScanMode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE);
//! Setup color buffer for TV rendering
GX2InitColorBuffer(&tvColorBuffer, GX2_SURFACE_DIM_2D, tvWidth, tvHeight, 1, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, tvAAMode);
tvColorBuffer.surface.image_data = MEM1_alloc(tvColorBuffer.surface.image_size, tvColorBuffer.surface.align);
GX2Invalidate(GX2_INVALIDATE_CPU, tvColorBuffer.surface.image_data, tvColorBuffer.surface.image_size);
GX2InitColorBuffer(&tvColorBuffer, GX2_SURFACE_DIM_TEXTURE_2D, tvWidth, tvHeight, 1, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, (GX2AAMode)tvAAMode);
tvColorBuffer.surface.image = MEM1_alloc(tvColorBuffer.surface.imageSize, tvColorBuffer.surface.alignment);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, tvColorBuffer.surface.image, tvColorBuffer.surface.imageSize);
//! due to AA we can only use 16 bit depth buffer in MEM1 otherwise we would have to switch to mem2 for depth buffer
//! this should be ok for our purpose i guess
//! Setup TV depth buffer (can be the same for both if rendered one after another)
u32 size, align;
GX2InitDepthBuffer(&tvDepthBuffer, GX2_SURFACE_DIM_2D, tvColorBuffer.surface.width, tvColorBuffer.surface.height, 1, GX2_SURFACE_FORMAT_TCD_R32_FLOAT, tvAAMode);
tvDepthBuffer.surface.image_data = MEM1_alloc(tvDepthBuffer.surface.image_size, tvDepthBuffer.surface.align);
GX2Invalidate(GX2_INVALIDATE_CPU, tvDepthBuffer.surface.image_data, tvDepthBuffer.surface.image_size);
uint32_t size, align;
GX2InitDepthBuffer(&tvDepthBuffer, GX2_SURFACE_DIM_TEXTURE_2D, tvColorBuffer.surface.width, tvColorBuffer.surface.height, 1, GX2_SURFACE_FORMAT_FLOAT_R32, (GX2AAMode)tvAAMode);
tvDepthBuffer.surface.image = MEM1_alloc(tvDepthBuffer.surface.imageSize, tvDepthBuffer.surface.alignment);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, tvDepthBuffer.surface.image, tvDepthBuffer.surface.imageSize);
//! Setup TV HiZ buffer
GX2CalcDepthBufferHiZInfo(&tvDepthBuffer, &size, &align);
tvDepthBuffer.hiZ_data = MEM1_alloc(size, align);
GX2Invalidate(GX2_INVALIDATE_CPU, tvDepthBuffer.hiZ_data, size);
tvDepthBuffer.hiZPtr = MEM1_alloc(size, align);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, tvDepthBuffer.hiZPtr, size);
GX2InitDepthBufferHiZEnable(&tvDepthBuffer, GX2_ENABLE);
//! Setup color buffer for DRC rendering
GX2InitColorBuffer(&drcColorBuffer, GX2_SURFACE_DIM_2D, 854, 480, 1, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, drcAAMode);
drcColorBuffer.surface.image_data = MEM1_alloc(drcColorBuffer.surface.image_size, drcColorBuffer.surface.align);
GX2Invalidate(GX2_INVALIDATE_CPU, drcColorBuffer.surface.image_data, drcColorBuffer.surface.image_size);
GX2InitColorBuffer(&drcColorBuffer, GX2_SURFACE_DIM_TEXTURE_2D, 854, 480, 1, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, (GX2AAMode)drcAAMode);
drcColorBuffer.surface.image = MEM1_alloc(drcColorBuffer.surface.imageSize, drcColorBuffer.surface.alignment);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, drcColorBuffer.surface.image, drcColorBuffer.surface.imageSize);
//! Setup DRC depth buffer (can be the same for both if rendered one after another)
GX2InitDepthBuffer(&drcDepthBuffer, GX2_SURFACE_DIM_2D, drcColorBuffer.surface.width, drcColorBuffer.surface.height, 1, GX2_SURFACE_FORMAT_TCD_R32_FLOAT, drcAAMode);
drcDepthBuffer.surface.image_data = MEM1_alloc(drcDepthBuffer.surface.image_size, drcDepthBuffer.surface.align);
GX2Invalidate(GX2_INVALIDATE_CPU, drcDepthBuffer.surface.image_data, drcDepthBuffer.surface.image_size);
GX2InitDepthBuffer(&drcDepthBuffer, GX2_SURFACE_DIM_TEXTURE_2D, drcColorBuffer.surface.width, drcColorBuffer.surface.height, 1, GX2_SURFACE_FORMAT_FLOAT_R32, (GX2AAMode)drcAAMode);
drcDepthBuffer.surface.image = MEM1_alloc(drcDepthBuffer.surface.imageSize, drcDepthBuffer.surface.alignment);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, drcDepthBuffer.surface.image, drcDepthBuffer.surface.imageSize);
//! Setup DRC HiZ buffer
GX2CalcDepthBufferHiZInfo(&drcDepthBuffer, &size, &align);
drcDepthBuffer.hiZ_data = MEM1_alloc(size, align);
GX2Invalidate(GX2_INVALIDATE_CPU, drcDepthBuffer.hiZ_data, size);
drcDepthBuffer.hiZPtr = MEM1_alloc(size, align);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, drcDepthBuffer.hiZPtr, size);
GX2InitDepthBufferHiZEnable(&drcDepthBuffer, GX2_ENABLE);
//! allocate auxilary buffer last as there might not be enough MEM1 left for other stuff after that
if (tvColorBuffer.surface.aa)
{
u32 auxSize, auxAlign;
if (tvColorBuffer.surface.aa) {
uint32_t auxSize, auxAlign;
GX2CalcColorBufferAuxInfo(&tvColorBuffer, &auxSize, &auxAlign);
tvColorBuffer.aux_data = MEM1_alloc(auxSize, auxAlign);
if(!tvColorBuffer.aux_data)
tvColorBuffer.aux_data = MEM2_alloc(auxSize, auxAlign);
tvColorBuffer.aaBuffer = MEM1_alloc(auxSize, auxAlign);
if(!tvColorBuffer.aaBuffer)
tvColorBuffer.aaBuffer = MEM2_alloc(auxSize, auxAlign);
tvColorBuffer.aux_size = auxSize;
memset(tvColorBuffer.aux_data, GX2_AUX_BUFFER_CLEAR_VALUE, auxSize);
GX2Invalidate(GX2_INVALIDATE_CPU, tvColorBuffer.aux_data, auxSize);
tvColorBuffer.aaSize = auxSize;
memset(tvColorBuffer.aaBuffer, GX2_AA_BUFFER_CLEAR_VALUE, auxSize);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, tvColorBuffer.aaBuffer, auxSize);
}
if (drcColorBuffer.surface.aa)
{
u32 auxSize, auxAlign;
if (drcColorBuffer.surface.aa) {
uint32_t auxSize, auxAlign;
GX2CalcColorBufferAuxInfo(&drcColorBuffer, &auxSize, &auxAlign);
drcColorBuffer.aux_data = MEM1_alloc(auxSize, auxAlign);
if(!drcColorBuffer.aux_data)
drcColorBuffer.aux_data = MEM2_alloc(auxSize, auxAlign);
drcColorBuffer.aux_size = auxSize;
memset(drcColorBuffer.aux_data, GX2_AUX_BUFFER_CLEAR_VALUE, auxSize);
GX2Invalidate(GX2_INVALIDATE_CPU, drcColorBuffer.aux_data, auxSize );
drcColorBuffer.aaBuffer = MEM1_alloc(auxSize, auxAlign);
if(!drcColorBuffer.aaBuffer)
drcColorBuffer.aaBuffer = MEM2_alloc(auxSize, auxAlign);
drcColorBuffer.aaSize = auxSize;
memset(drcColorBuffer.aaBuffer, GX2_AA_BUFFER_CLEAR_VALUE, auxSize);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, drcColorBuffer.aaBuffer, auxSize);
}
//! allocate memory and setup context state TV
@ -192,23 +183,22 @@ CVideo::CVideo(s32 forceTvScanMode, s32 forceDrcScanMode)
//GX2SetDRCGamma(0.8f);
//! initialize perspective matrix
const float cam_X_rot = 25.0f;
const float cam_X_rot = 25.0f;
projectionMtx = glm::perspective(45.0f, 1.0f, 0.1f, 100.0f);
projectionMtx = glm::perspective(45.0f, 1.0f, 0.1f, 100.0f);
viewMtx = glm::mat4(1.0f);
viewMtx = glm::translate(viewMtx, glm::vec3(0.0f, 0.0f, -2.5f));
viewMtx = glm::rotate(viewMtx, DegToRad(cam_X_rot), glm::vec3(1.0f, 0.0f, 0.0f));
viewMtx = glm::mat4(1.0f);
viewMtx = glm::translate(viewMtx, glm::vec3(0.0f, 0.0f, -2.5f));
viewMtx = glm::rotate(viewMtx, DegToRad(cam_X_rot), glm::vec3(1.0f, 0.0f, 0.0f));
GX2InitSampler(&aaSampler, GX2_TEX_CLAMP_CLAMP, GX2_TEX_XY_FILTER_BILINEAR);
GX2InitTexture(&tvAaTexture, tvColorBuffer.surface.width, tvColorBuffer.surface.height, 1, 0, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GX2_SURFACE_DIM_2D, GX2_TILE_MODE_DEFAULT);
tvAaTexture.surface.image_data = tvColorBuffer.surface.image_data;
tvAaTexture.surface.image_size = tvColorBuffer.surface.image_size;
tvAaTexture.surface.mip_data = tvColorBuffer.surface.mip_data;
GX2InitSampler(&aaSampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR);
GX2InitTexture(&tvAaTexture, tvColorBuffer.surface.width, tvColorBuffer.surface.height, 1, 0, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_SURFACE_DIM_TEXTURE_2D, GX2_TILE_MODE_DEFAULT);
tvAaTexture.surface.image = tvColorBuffer.surface.image;
tvAaTexture.surface.imageSize = tvColorBuffer.surface.imageSize;
tvAaTexture.surface.mipmaps = tvColorBuffer.surface.mipmaps;
}
CVideo::~CVideo()
{
CVideo::~CVideo() {
//! flush buffers
GX2Flush();
GX2DrawDone();
@ -220,71 +210,47 @@ CVideo::~CVideo()
MEMBucket_free(tvScanBuffer);
MEMBucket_free(drcScanBuffer);
//! free color buffers
MEM1_free(tvColorBuffer.surface.image_data);
MEM1_free(drcColorBuffer.surface.image_data);
MEM1_free(tvColorBuffer.surface.image);
MEM1_free(drcColorBuffer.surface.image);
//! free depth buffers
MEM1_free(tvDepthBuffer.surface.image_data);
MEM1_free(tvDepthBuffer.hiZ_data);
MEM1_free(drcDepthBuffer.surface.image_data);
MEM1_free(drcDepthBuffer.hiZ_data);
MEM1_free(tvDepthBuffer.surface.image);
MEM1_free(tvDepthBuffer.hiZPtr);
MEM1_free(drcDepthBuffer.surface.image);
MEM1_free(drcDepthBuffer.hiZPtr);
//! free context buffers
MEM2_free(tvContextState);
MEM2_free(drcContextState);
//! free aux buffer
if(tvColorBuffer.aux_data)
{
if(((u32)tvColorBuffer.aux_data & 0xF0000000) == 0xF0000000)
MEM1_free(tvColorBuffer.aux_data);
if(tvColorBuffer.aaBuffer) {
if(((uint32_t)tvColorBuffer.aaBuffer & 0xF0000000) == 0xF0000000)
MEM1_free(tvColorBuffer.aaBuffer);
else
MEM2_free(tvColorBuffer.aux_data);
MEM2_free(tvColorBuffer.aaBuffer);
}
if(drcColorBuffer.aux_data)
{
if(((u32)drcColorBuffer.aux_data & 0xF0000000) == 0xF0000000)
MEM1_free(drcColorBuffer.aux_data);
if(drcColorBuffer.aaBuffer) {
if(((uint32_t)drcColorBuffer.aaBuffer & 0xF0000000) == 0xF0000000)
MEM1_free(drcColorBuffer.aaBuffer);
else
MEM2_free(drcColorBuffer.aux_data);
MEM2_free(drcColorBuffer.aaBuffer);
}
//! destroy shaders
ColorShader::destroyInstance();
FXAAShader::destroyInstance();
Shader3D::destroyInstance();
ShaderFractalColor::destroyInstance();
Texture2DShader::destroyInstance();
}
void CVideo::renderFXAA(const GX2Texture * texture, const GX2Sampler *sampler)
{
void CVideo::renderFXAA(const GX2Texture * texture, const GX2Sampler *sampler) {
resolution[0] = texture->surface.width;
resolution[1] = texture->surface.height;
GX2Invalidate(GX2_INVALIDATE_COLOR_BUFFER | GX2_INVALIDATE_TEXTURE, texture->surface.image_data, texture->surface.image_size);
GX2Invalidate((GX2InvalidateMode)(GX2_INVALIDATE_MODE_COLOR_BUFFER | GX2_INVALIDATE_MODE_TEXTURE), texture->surface.image, texture->surface.imageSize);
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_ALWAYS);
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_FUNC_ALWAYS);
FXAAShader::instance()->setShaders();
FXAAShader::instance()->setAttributeBuffer();
FXAAShader::instance()->setResolution(resolution);
FXAAShader::instance()->setTextureAndSampler(texture, sampler);
FXAAShader::instance()->draw();
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL);
}
void* CVideo::GX2RAlloc(u32 flags, u32 size, u32 align)
{
//! min. alignment
if (align < 4)
align = 4;
if ((flags & 0x2040E) && !(flags & 0x40000))
return MEM1_alloc(size, align);
else
return MEM2_alloc(size, align);
}
void CVideo::GX2RFree(u32 flags, void* p)
{
if ((flags & 0x2040E) && !(flags & 0x40000))
MEM1_free(p);
else
MEM2_free(p);
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_FUNC_LEQUAL);
}

View File

@ -18,58 +18,54 @@
#include <stdlib.h>
#include <string.h>
#include <dynamic_libs/gx2_functions.h>
#include "video/shaders/ColorShader.h"
#include "video/shaders/FXAAShader.h"
#include "video/shaders/Shader3D.h"
#include "video/shaders/ShaderFractalColor.h"
#include "video/shaders/Texture2DShader.h"
#include "CursorDrawer.h"
#include <video/shaders/ColorShader.h>
#include <video/shaders/FXAAShader.h>
#include <video/shaders/Shader3D.h>
#include <video/shaders/ShaderFractalColor.h>
#include <video/shaders/Texture2DShader.h>
#include <video/CursorDrawer.h>
CursorDrawer *CursorDrawer::instance = NULL;
CursorDrawer::CursorDrawer()
{
CursorDrawer::CursorDrawer() {
init_colorVtxs();
}
CursorDrawer::~CursorDrawer()
{
CursorDrawer::~CursorDrawer() {
//! destroy shaders
ColorShader::destroyInstance();
FXAAShader::destroyInstance();
Shader3D::destroyInstance();
ShaderFractalColor::destroyInstance();
Texture2DShader::destroyInstance();
if(this->colorVtxs){
if(this->colorVtxs) {
free(this->colorVtxs);
this->colorVtxs = NULL;
}
}
void CursorDrawer::init_colorVtxs(){
if(!this->colorVtxs){
this->colorVtxs = (u8*)memalign(0x40, sizeof(u8) * 16);
void CursorDrawer::init_colorVtxs() {
if(!this->colorVtxs) {
this->colorVtxs = (uint8_t*)memalign(0x40, sizeof(uint8_t) * 16);
if(this->colorVtxs == NULL) return;
}
memset(this->colorVtxs,0xFF,16*sizeof(u8));
memset(this->colorVtxs,0xFF,16*sizeof(uint8_t));
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, this->colorVtxs, 16 * sizeof(u8));
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, this->colorVtxs, 16 * sizeof(uint8_t));
}
// Could be improved. It be more generic.
void CursorDrawer::draw_Cursor(f32 x,f32 y)
{
if(this->colorVtxs == NULL){
void CursorDrawer::draw_Cursor(float x,float y) {
if(this->colorVtxs == NULL) {
init_colorVtxs();
return;
}
f32 widthScaleFactor = 1.0f / (f32)1280;
f32 heightScaleFactor = 1.0f / (f32)720;
float widthScaleFactor = 1.0f / (float)1280;
float heightScaleFactor = 1.0f / (float)720;
s32 width = 20;
int32_t width = 20;
glm::vec3 positionOffsets = glm::vec3(0.0f);
@ -84,5 +80,5 @@ void CursorDrawer::draw_Cursor(f32 x,f32 y)
ColorShader::instance()->setOffset(positionOffsets);
ColorShader::instance()->setScale(scale);
ColorShader::instance()->setColorIntensity(glm::vec4(1.0f));
ColorShader::instance()->draw(GX2_PRIMITIVE_QUADS, 4);
ColorShader::instance()->draw(GX2_PRIMITIVE_MODE_QUADS, 4);
}

View File

@ -16,10 +16,9 @@
****************************************************************************/
#include <malloc.h>
#include <string.h>
#include "ColorShader.h"
#include <video/shaders/ColorShader.h>
static const u32 cpVertexShaderProgram[] =
{
static const uint32_t cpVertexShaderProgram[] = {
0x00000000,0x00008009,0x20000000,0x000078a0,
0x3c200000,0x88060094,0x00c00000,0x88062014,
0x00000000,0x00000000,0x00000000,0x00000000,
@ -55,7 +54,7 @@ static const u32 cpVertexShaderProgram[] =
0xfbbdb2ab,0x768ac733
};
static const u32 cpVertexShaderRegs[] = {
static const uint32_t cpVertexShaderRegs[] = {
0x00000103,0x00000000,0x00000000,0x00000001,
0xffffff00,0xffffffff,0xffffffff,0xffffffff,
0xffffffff,0xffffffff,0xffffffff,0xffffffff,
@ -71,8 +70,7 @@ static const u32 cpVertexShaderRegs[] = {
0x000000ff,0x00000000,0x0000000e,0x00000010
};
static const u32 cpPixelShaderProgram[] =
{
static const uint32_t cpPixelShaderProgram[] = {
0x20000000,0x00000ca0,0x00000000,0x88062094,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
@ -93,7 +91,7 @@ static const u32 cpPixelShaderProgram[] =
0x00082001,0x90000040,0x000ca081,0x90000060,
0xbb7dd898,0x9746c59c,0xc69b00e7,0x03c36218
};
static const u32 cpPixelShaderRegs[] = {
static const uint32_t cpPixelShaderRegs[] = {
0x00000001,0x00000002,0x14000001,0x00000000,
0x00000001,0x00000100,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
@ -110,13 +108,14 @@ static const u32 cpPixelShaderRegs[] = {
ColorShader * ColorShader::shaderInstance = NULL;
ColorShader::ColorShader()
: vertexShader(cuAttributeCount)
{
: vertexShader(cuAttributeCount) {
//! create pixel shader
pixelShader.setProgram(cpPixelShaderProgram, sizeof(cpPixelShaderProgram), cpPixelShaderRegs, sizeof(cpPixelShaderRegs));
colorIntensityLocation = 0;
pixelShader.addUniformVar((GX2UniformVar){ "unf_color_intensity", GX2_VAR_TYPE_VEC4, 1, colorIntensityLocation, 0xffffffff });
pixelShader.addUniformVar((GX2UniformVar) {
"unf_color_intensity", GX2_SHADER_VAR_TYPE_FLOAT4, 1, colorIntensityLocation, -1
});
//! create vertex shader
vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));
@ -124,40 +123,55 @@ ColorShader::ColorShader()
angleLocation = 0;
offsetLocation = 4;
scaleLocation = 8;
vertexShader.addUniformVar((GX2UniformVar){ "unf_angle", GX2_VAR_TYPE_FLOAT, 1, angleLocation, 0xffffffff });
vertexShader.addUniformVar((GX2UniformVar){ "unf_offset", GX2_VAR_TYPE_VEC3, 1, offsetLocation, 0xffffffff });
vertexShader.addUniformVar((GX2UniformVar){ "unf_scale", GX2_VAR_TYPE_VEC3, 1, scaleLocation, 0xffffffff });
vertexShader.addUniformVar((GX2UniformVar) {
"unf_angle", GX2_SHADER_VAR_TYPE_FLOAT, 1, angleLocation, -1
});
vertexShader.addUniformVar((GX2UniformVar) {
"unf_offset", GX2_SHADER_VAR_TYPE_FLOAT3, 1, offsetLocation, -1
});
vertexShader.addUniformVar((GX2UniformVar) {
"unf_scale", GX2_SHADER_VAR_TYPE_FLOAT3, 1, scaleLocation, -1
});
colorLocation = 1;
positionLocation = 0;
vertexShader.addAttribVar((GX2AttribVar){ "attr_color", GX2_VAR_TYPE_VEC4, 0, colorLocation });
vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation });
vertexShader.addAttribVar((GX2AttribVar) {
"attr_color", GX2_SHADER_VAR_TYPE_FLOAT4, 0, colorLocation
});
vertexShader.addAttribVar((GX2AttribVar) {
"attr_position", GX2_SHADER_VAR_TYPE_FLOAT3, 0, positionLocation
});
//! setup attribute streams
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT);
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), colorLocation, 1, 0, GX2_ATTRIB_FORMAT_8_8_8_8_UNORM);
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32);
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), colorLocation, 1, 0, GX2_ATTRIB_FORMAT_UNORM_8_8_8_8);
//! create fetch shader
fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());
//! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
positionVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, cuPositionVtxsSize);
if(positionVtxs)
{
positionVtxs = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, cuPositionVtxsSize);
if(positionVtxs) {
//! position vertex structure
s32 i = 0;
positionVtxs[i++] = -1.0f; positionVtxs[i++] = -1.0f; positionVtxs[i++] = 0.0f;
positionVtxs[i++] = 1.0f; positionVtxs[i++] = -1.0f; positionVtxs[i++] = 0.0f;
positionVtxs[i++] = 1.0f; positionVtxs[i++] = 1.0f; positionVtxs[i++] = 0.0f;
positionVtxs[i++] = -1.0f; positionVtxs[i++] = 1.0f; positionVtxs[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, positionVtxs, cuPositionVtxsSize);
int32_t i = 0;
positionVtxs[i++] = -1.0f;
positionVtxs[i++] = -1.0f;
positionVtxs[i++] = 0.0f;
positionVtxs[i++] = 1.0f;
positionVtxs[i++] = -1.0f;
positionVtxs[i++] = 0.0f;
positionVtxs[i++] = 1.0f;
positionVtxs[i++] = 1.0f;
positionVtxs[i++] = 0.0f;
positionVtxs[i++] = -1.0f;
positionVtxs[i++] = 1.0f;
positionVtxs[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, positionVtxs, cuPositionVtxsSize);
}
}
ColorShader::~ColorShader()
{
if(positionVtxs)
{
ColorShader::~ColorShader() {
if(positionVtxs) {
free(positionVtxs);
positionVtxs = NULL;
}

View File

@ -16,10 +16,9 @@
****************************************************************************/
#include <malloc.h>
#include <string.h>
#include "FXAAShader.h"
#include <video/shaders/FXAAShader.h>
static const u32 cpVertexShaderProgram[] =
{
static const uint32_t cpVertexShaderProgram[] = {
0x00000000,0x00008009,0x20000000,0x000004a0,
0x3ca00000,0x88060094,0x00400000,0xff0f2094,
0x00000000,0x00000000,0x00000000,0x00000000,
@ -40,7 +39,7 @@ static const u32 cpVertexShaderProgram[] =
0xc1a229f5,0xd0eddc33,0x426618fd,0x8509cfe7
};
static const u32 cpVertexShaderRegs[] = {
static const uint32_t cpVertexShaderRegs[] = {
0x00000102,0x00000000,0x00000000,0x00000001,
0xffffffff,0xffffffff,0xffffffff,0xffffffff,
0xffffffff,0xffffffff,0xffffffff,0xffffffff,
@ -56,8 +55,7 @@ static const u32 cpVertexShaderRegs[] = {
0x000000ff,0x00000000,0x0000000e,0x00000010
};
static const u32 cpPixelShaderProgram[] =
{
static const uint32_t cpPixelShaderProgram[] = {
0x20000000,0x00003ca0,0xa0000000,0x000c8080,
0x30000000,0x000010a1,0xa8000000,0x0010c080,
0x75000000,0x000088a0,0x00800100,0x88062094,
@ -149,7 +147,7 @@ static const u32 cpPixelShaderProgram[] =
0x10000100,0x01101df0,0x00008010,0xecdfea0d,
0xfe2e963a,0x0269a9a3,0x38f88096,0x400cf48b
};
static const u32 cpPixelShaderRegs[] = {
static const uint32_t cpPixelShaderRegs[] = {
0x00000007,0x00000002,0x04000101,0x00000000,
0x00000001,0x00000100,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
@ -166,61 +164,77 @@ static const u32 cpPixelShaderRegs[] = {
FXAAShader * FXAAShader::shaderInstance = NULL;
FXAAShader::FXAAShader()
: vertexShader(cuAttributeCount)
{
: vertexShader(cuAttributeCount) {
//! create pixel shader
pixelShader.setProgram(cpPixelShaderProgram, sizeof(cpPixelShaderProgram), cpPixelShaderRegs, sizeof(cpPixelShaderRegs));
resolutionLocation = 0;
pixelShader.addUniformVar((GX2UniformVar){ "unf_resolution", GX2_VAR_TYPE_VEC2, 1, resolutionLocation, 0xffffffff });
pixelShader.addUniformVar((GX2UniformVar) {
"unf_resolution", GX2_SHADER_VAR_TYPE_FLOAT2, 1, resolutionLocation, -1
});
samplerLocation = 0;
pixelShader.addSamplerVar((GX2SamplerVar){ "sampl_texture", GX2_SAMPLER_TYPE_2D, samplerLocation });
pixelShader.addSamplerVar((GX2SamplerVar) {
"sampl_texture", GX2_SAMPLER_VAR_TYPE_SAMPLER_2D, samplerLocation
});
//! create vertex shader
vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));
positionLocation = 0;
texCoordLocation = 1;
vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation });
vertexShader.addAttribVar((GX2AttribVar){ "attr_texture_coord", GX2_VAR_TYPE_VEC2, 0, texCoordLocation });
vertexShader.addAttribVar((GX2AttribVar) {
"attr_position", GX2_SHADER_VAR_TYPE_FLOAT3, 0, positionLocation
});
vertexShader.addAttribVar((GX2AttribVar) {
"attr_texture_coord", GX2_SHADER_VAR_TYPE_FLOAT2, 0, texCoordLocation
});
//! setup attribute streams
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT);
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_32_32_FLOAT);
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32);
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
//! create fetch shader
fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());
//! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);
posVtxs = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
texCoords = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);
//! position vertex structure and texture coordinate vertex structure
s32 i = 0;
posVtxs[i++] = -1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
posVtxs[i++] = -1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, posVtxs, ciPositionVtxsSize);
int32_t i = 0;
posVtxs[i++] = -1.0f;
posVtxs[i++] = -1.0f;
posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = -1.0f;
posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = 0.0f;
posVtxs[i++] = -1.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, posVtxs, ciPositionVtxsSize);
i = 0;
texCoords[i++] = 0.0f; texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f; texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f; texCoords[i++] = 0.0f;
texCoords[i++] = 0.0f; texCoords[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, texCoords, ciTexCoordsVtxsSize);
texCoords[i++] = 0.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 0.0f;
texCoords[i++] = 0.0f;
texCoords[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, texCoords, ciTexCoordsVtxsSize);
}
FXAAShader::~FXAAShader()
{
if(posVtxs)
{
FXAAShader::~FXAAShader() {
if(posVtxs) {
free(posVtxs);
posVtxs = NULL;
}
if(texCoords)
{
if(texCoords) {
free(texCoords);
texCoords = NULL;
}

View File

@ -1,150 +0,0 @@
/****************************************************************************
* 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 PIXEL_SHADER_H
#define PIXEL_SHADER_H
#include "Shader.h"
class PixelShader : public Shader
{
public:
PixelShader()
: pixelShader((GX2PixelShader*) memalign(0x40, sizeof(GX2PixelShader)))
{
if(pixelShader)
{
memset(pixelShader, 0, sizeof(GX2PixelShader));
pixelShader->shader_mode = GX2_SHADER_MODE_UNIFORM_REGISTER;
}
}
virtual ~PixelShader()
{
if(pixelShader)
{
if(pixelShader->shader_data)
free(pixelShader->shader_data);
for(u32 i = 0; i < pixelShader->uniform_blocks_count; i++)
free((void*)pixelShader->uniform_block[i].name);
if(pixelShader->uniform_block)
free((void*)pixelShader->uniform_block);
for(u32 i = 0; i < pixelShader->uniform_vars_count; i++)
free((void*)pixelShader->uniform_var[i].name);
if(pixelShader->uniform_var)
free((void*)pixelShader->uniform_var);
if(pixelShader->initial_value)
free((void*)pixelShader->initial_value);
for(u32 i = 0; i < pixelShader->sampler_vars_count; i++)
free((void*)pixelShader->sampler_var[i].name);
if(pixelShader->sampler_var)
free((void*)pixelShader->sampler_var);
if(pixelShader->loops_data)
free((void*)pixelShader->loops_data);
free(pixelShader);
}
}
void setProgram(const u32 * program, const u32 & programSize, const u32 * regs, const u32 & regsSize)
{
if(!pixelShader)
return;
//! this must be moved into an area where the graphic engine has access to and must be aligned to 0x100
pixelShader->shader_size = programSize;
pixelShader->shader_data = memalign(GX2_SHADER_ALIGNMENT, pixelShader->shader_size);
if(pixelShader->shader_data)
{
memcpy(pixelShader->shader_data, program, pixelShader->shader_size);
GX2Invalidate(GX2_INVALIDATE_CPU_SHADER, pixelShader->shader_data, pixelShader->shader_size);
}
memcpy(pixelShader->regs, regs, regsSize);
}
void addUniformVar(const GX2UniformVar & var)
{
if(!pixelShader)
return;
u32 idx = pixelShader->uniform_vars_count;
GX2UniformVar* newVar = (GX2UniformVar*) malloc((pixelShader->uniform_vars_count + 1) * sizeof(GX2UniformVar));
if(newVar)
{
if(pixelShader->uniform_var)
{
memcpy(newVar, pixelShader->uniform_var, pixelShader->uniform_vars_count * sizeof(GX2UniformVar));
free(pixelShader->uniform_var);
}
pixelShader->uniform_var = newVar;
memcpy(pixelShader->uniform_var + idx, &var, sizeof(GX2UniformVar));
pixelShader->uniform_var[idx].name = (char*) malloc(strlen(var.name) + 1);
strcpy((char*)pixelShader->uniform_var[idx].name, var.name);
pixelShader->uniform_vars_count++;
}
}
void addSamplerVar(const GX2SamplerVar & var)
{
if(!pixelShader)
return;
u32 idx = pixelShader->sampler_vars_count;
GX2SamplerVar* newVar = (GX2SamplerVar*) malloc((pixelShader->sampler_vars_count + 1) * sizeof(GX2SamplerVar));
if(newVar)
{
if(pixelShader->sampler_var)
{
memcpy(newVar, pixelShader->sampler_var, pixelShader->sampler_vars_count * sizeof(GX2SamplerVar));
free(pixelShader->sampler_var);
}
pixelShader->sampler_var = newVar;
memcpy(pixelShader->sampler_var + idx, &var, sizeof(GX2SamplerVar));
pixelShader->sampler_var[idx].name = (char*) malloc(strlen(var.name) + 1);
strcpy((char*)pixelShader->sampler_var[idx].name, var.name);
pixelShader->sampler_vars_count++;
}
}
GX2PixelShader * getPixelShader() const {
return pixelShader;
}
void setShader(void) const {
GX2SetPixelShader(pixelShader);
}
static inline void setUniformReg(u32 location, u32 size, const void * reg) {
GX2SetPixelUniformReg(location, size, reg);
}
protected:
GX2PixelShader *pixelShader;
};
#endif // PIXEL_SHADER_H

View File

@ -1,74 +0,0 @@
/****************************************************************************
* 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 SHADER_H_
#define SHADER_H_
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include <dynamic_libs/gx2_functions.h>
#include <utils/utils.h>
class Shader
{
protected:
Shader() {}
virtual ~Shader() {}
public:
static const u16 cuVertexAttrSize = sizeof(f32) * 3;
static const u16 cuTexCoordAttrSize = sizeof(f32) * 2;
static const u16 cuColorAttrSize = sizeof(u8) * 4;
static void setLineWidth(const f32 & width) {
GX2SetLineWidth(width);
}
static void draw(s32 primitive = GX2_PRIMITIVE_QUADS, u32 vtxCount = 4)
{
switch(primitive)
{
default:
case GX2_PRIMITIVE_QUADS:
{
GX2DrawEx(GX2_PRIMITIVE_QUADS, vtxCount, 0, 1);
break;
}
case GX2_PRIMITIVE_TRIANGLES:
{
GX2DrawEx(GX2_PRIMITIVE_TRIANGLES, vtxCount, 0, 1);
break;
}
case GX2_PRIMITIVE_TRIANGLE_FAN:
{
GX2DrawEx(GX2_PRIMITIVE_TRIANGLE_FAN, vtxCount, 0, 1);
break;
}
case GX2_PRIMITIVE_LINES:
{
GX2DrawEx(GX2_PRIMITIVE_LINES, vtxCount, 0, 1);
break;
}
case GX2_PRIMITIVE_LINE_STRIP:
{
GX2DrawEx(GX2_PRIMITIVE_LINE_STRIP, vtxCount, 0, 1);
break;
}
//! TODO: add other primitives later
};
}
};
#endif // SHADER_H_

View File

@ -16,10 +16,9 @@
****************************************************************************/
#include <malloc.h>
#include <string.h>
#include "Shader3D.h"
#include <video/shaders/Shader3D.h>
static const u32 cpVertexShaderProgram[] =
{
static const uint32_t cpVertexShaderProgram[] = {
0x00000000,0x00008009,0x20000000,0x0000e4a1,
0x00c00100,0x88048093,0x01c00300,0x98060014,
0x9a000000,0x000058a0,0x3c200200,0x88062094,
@ -112,7 +111,7 @@ static const u32 cpVertexShaderProgram[] =
0x7642ed30,0x7408600d
};
static const u32 cpVertexShaderRegs[] = {
static const uint32_t cpVertexShaderRegs[] = {
0x00000108,0x00000000,0x00000002,0x00000001,
0xffff0001,0xffffffff,0xffffffff,0xffffffff,
0xffffffff,0xffffffff,0xffffffff,0xffffffff,
@ -128,8 +127,7 @@ static const u32 cpVertexShaderRegs[] = {
0x000000ff,0x00000000,0x0000000e,0x00000010
};
static const u32 cPixelShaderProgram[] =
{
static const uint32_t cPixelShaderProgram[] = {
0x20000000,0x000008a4,0x03000000,0x01004085,
0x23000000,0x000044a8,0x35000000,0x000000a4,
0x06000000,0x01004085,0x36000000,0x00002ca8,
@ -173,7 +171,7 @@ static const u32 cPixelShaderProgram[] =
0x10000100,0x01100df0,0x00008010,0xecdfea0d,
0x99720984,0x041cab0d,0xa28a9ccd,0x95d199a5
};
static const u32 cPixelShaderRegs[] = {
static const uint32_t cPixelShaderRegs[] = {
0x00000102,0x00000002,0x14000002,0x00000000,
0x00000002,0x00000100,0x00000101,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
@ -190,73 +188,96 @@ static const u32 cPixelShaderRegs[] = {
Shader3D * Shader3D::shaderInstance = NULL;
Shader3D::Shader3D()
: vertexShader(cuAttributeCount)
{
: vertexShader(cuAttributeCount) {
//! create pixel shader
pixelShader.setProgram(cPixelShaderProgram, sizeof(cPixelShaderProgram), cPixelShaderRegs, sizeof(cPixelShaderRegs));
colorIntensityLocation = 0;
fadeDistanceLocation = 4;
fadeOutLocation = 8;
pixelShader.addUniformVar((GX2UniformVar){ "unf_color_intensity", GX2_VAR_TYPE_VEC4, 1, colorIntensityLocation, 0xffffffff });
pixelShader.addUniformVar((GX2UniformVar){ "unf_fade_distance", GX2_VAR_TYPE_FLOAT, 1, fadeDistanceLocation, 0xffffffff });
pixelShader.addUniformVar((GX2UniformVar){ "unf_fade_out_alpha", GX2_VAR_TYPE_VEC4, 1, fadeOutLocation, 0xffffffff });
pixelShader.addUniformVar((GX2UniformVar) {
"unf_color_intensity", GX2_SHADER_VAR_TYPE_FLOAT4, 1, colorIntensityLocation, -1
});
pixelShader.addUniformVar((GX2UniformVar) {
"unf_fade_distance", GX2_SHADER_VAR_TYPE_FLOAT, 1, fadeDistanceLocation, -1
});
pixelShader.addUniformVar((GX2UniformVar) {
"unf_fade_out_alpha", GX2_SHADER_VAR_TYPE_FLOAT4, 1, fadeOutLocation, -1
});
samplerLocation = 0;
pixelShader.addSamplerVar((GX2SamplerVar){ "sampl_texture", GX2_SAMPLER_TYPE_2D, samplerLocation });
//! create vertex shader
vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));
pixelShader.addSamplerVar((GX2SamplerVar) {
"sampl_texture", GX2_SAMPLER_VAR_TYPE_SAMPLER_2D, samplerLocation
});
modelMatrixLocation = 0;
projectionMatrixLocation = 16;
viewMatrixLocation = 32;
vertexShader.addUniformVar((GX2UniformVar){ "modelMatrix", GX2_VAR_TYPE_MAT4, 1, modelMatrixLocation, 0xffffffff });
vertexShader.addUniformVar((GX2UniformVar){ "viewMatrix", GX2_VAR_TYPE_MAT4, 1, projectionMatrixLocation, 0xffffffff });
vertexShader.addUniformVar((GX2UniformVar){ "projectionMatrix", GX2_VAR_TYPE_MAT4, 1, viewMatrixLocation, 0xffffffff });
vertexShader.addUniformVar((GX2UniformVar) {
"modelMatrix", GX2_SHADER_VAR_TYPE_MATRIX4X4, 1, modelMatrixLocation, -1
});
vertexShader.addUniformVar((GX2UniformVar) {
"viewMatrix", GX2_SHADER_VAR_TYPE_MATRIX4X4, 1, projectionMatrixLocation, -1
});
vertexShader.addUniformVar((GX2UniformVar) {
"projectionMatrix", GX2_SHADER_VAR_TYPE_MATRIX4X4, 1, viewMatrixLocation, -1
});
positionLocation = 0;
texCoordLocation = 1;
vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation });
vertexShader.addAttribVar((GX2AttribVar){ "attr_texture_coord", GX2_VAR_TYPE_VEC2, 0, texCoordLocation });
vertexShader.addAttribVar((GX2AttribVar) {
"attr_position", GX2_SHADER_VAR_TYPE_FLOAT4, 0, positionLocation
});
vertexShader.addAttribVar((GX2AttribVar) {
"attr_texture_coord", GX2_SHADER_VAR_TYPE_FLOAT2, 0, texCoordLocation
});
//! setup attribute streams
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT);
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_32_32_FLOAT);
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32);
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
//! create fetch shader
fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());
//! initialize default quad texture vertexes as those are very commonly used
//! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);
posVtxs = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
texCoords = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);
//! position vertex structure and texture coordinate vertex structure
s32 i = 0;
posVtxs[i++] = -1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
posVtxs[i++] = -1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, posVtxs, ciPositionVtxsSize);
int32_t i = 0;
posVtxs[i++] = -1.0f;
posVtxs[i++] = -1.0f;
posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = -1.0f;
posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = 0.0f;
posVtxs[i++] = -1.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, posVtxs, ciPositionVtxsSize);
i = 0;
texCoords[i++] = 0.0f; texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f; texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f; texCoords[i++] = 0.0f;
texCoords[i++] = 0.0f; texCoords[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, texCoords, ciTexCoordsVtxsSize);
texCoords[i++] = 0.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 0.0f;
texCoords[i++] = 0.0f;
texCoords[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, texCoords, ciTexCoordsVtxsSize);
}
Shader3D::~Shader3D()
{
if(posVtxs)
{
Shader3D::~Shader3D() {
if(posVtxs) {
free(posVtxs);
posVtxs = NULL;
}
if(texCoords)
{
if(texCoords) {
free(texCoords);
texCoords = NULL;
}

View File

@ -16,10 +16,9 @@
****************************************************************************/
#include <malloc.h>
#include <string.h>
#include "ShaderFractalColor.h"
#include <video/shaders/ShaderFractalColor.h>
static const u32 cpVertexShaderProgram[] =
{
static const uint32_t cpVertexShaderProgram[] = {
0x00000000,0x00008009,0x20000000,0x0000eca1,
0x00c00000,0x88068093,0x01400200,0x9a048013,
0x9c000000,0x000044a0,0x3c200000,0x88060094,
@ -110,7 +109,7 @@ static const u32 cpVertexShaderProgram[] =
0x8aa480ad,0x2bfc5ca6,0xb5e05b5b,0xd48dc71c
};
static const u32 cpVertexShaderRegs[] = {
static const uint32_t cpVertexShaderRegs[] = {
0x00000108,0x00000000,0x00000004,0x00000001,
0xff000201,0xffffffff,0xffffffff,0xffffffff,
0xffffffff,0xffffffff,0xffffffff,0xffffffff,
@ -126,8 +125,7 @@ static const u32 cpVertexShaderRegs[] = {
0x000000ff,0x00000000,0x0000000e,0x00000010
};
static const u32 cpPixelShaderProgram[] =
{
static const uint32_t cpPixelShaderProgram[] = {
0x20000000,0x000008a4,0x04000000,0x01004085,
0x23000000,0x0000eca1,0x9f000000,0x0000e0a8,
0xd8000000,0x000000a4,0x07000000,0x01004085,
@ -266,7 +264,7 @@ static const u32 cpPixelShaderProgram[] =
0x01cc1f80,0x90000060,0xc21e82a7,0x62ccc547,
0x1708607c,0x73ea57a6
};
static const u32 cpPixelShaderRegs[] = {
static const uint32_t cpPixelShaderRegs[] = {
0x00000106,0x00000002,0x14000003,0x00000000,
0x00000003,0x00000100,0x00000101,0x00000102,
0x00000000,0x00000000,0x00000000,0x00000000,
@ -283,8 +281,7 @@ static const u32 cpPixelShaderRegs[] = {
ShaderFractalColor * ShaderFractalColor::shaderInstance = NULL;
ShaderFractalColor::ShaderFractalColor()
: vertexShader(cuAttributeCount)
{
: vertexShader(cuAttributeCount) {
//! create pixel shader
pixelShader.setProgram(cpPixelShaderProgram, sizeof(cpPixelShaderProgram), cpPixelShaderRegs, sizeof(cpPixelShaderRegs));
@ -292,78 +289,105 @@ ShaderFractalColor::ShaderFractalColor()
colorIntensityLocation = 4;
fadeOutLocation = 8;
fractalLocation = 12;
pixelShader.addUniformVar((GX2UniformVar){ "unf_blur_border", GX2_VAR_TYPE_FLOAT, 1, blurLocation, 0xffffffff });
pixelShader.addUniformVar((GX2UniformVar){ "unf_color_intensity", GX2_VAR_TYPE_VEC4, 1, colorIntensityLocation, 0xffffffff });
pixelShader.addUniformVar((GX2UniformVar){ "unf_fade_out_alpha", GX2_VAR_TYPE_VEC4, 1, fadeOutLocation, 0xffffffff });
pixelShader.addUniformVar((GX2UniformVar){ "unf_fract_alpha", GX2_VAR_TYPE_INT, 1, fractalLocation, 0xffffffff });
pixelShader.addUniformVar((GX2UniformVar) {
"unf_blur_border", GX2_SHADER_VAR_TYPE_FLOAT, 1, blurLocation, -1
});
pixelShader.addUniformVar((GX2UniformVar) {
"unf_color_intensity", GX2_SHADER_VAR_TYPE_FLOAT4, 1, colorIntensityLocation, -1
});
pixelShader.addUniformVar((GX2UniformVar) {
"unf_fade_out_alpha", GX2_SHADER_VAR_TYPE_FLOAT4, 1, fadeOutLocation, -1
});
pixelShader.addUniformVar((GX2UniformVar) {
"unf_fract_alpha", GX2_SHADER_VAR_TYPE_INT, 1, fractalLocation, -1
});
//! create vertex shader
vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));
modelMatrixLocation = 0;
projectionMatrixLocation = 16;
viewMatrixLocation = 32;
vertexShader.addUniformVar((GX2UniformVar){ "modelMatrix", GX2_VAR_TYPE_MAT4, 1, modelMatrixLocation, 0xffffffff });
vertexShader.addUniformVar((GX2UniformVar){ "projectionMatrix", GX2_VAR_TYPE_MAT4, 1, projectionMatrixLocation, 0xffffffff });
vertexShader.addUniformVar((GX2UniformVar){ "viewMatrix", GX2_VAR_TYPE_MAT4, 1, viewMatrixLocation, 0xffffffff });
vertexShader.addUniformVar((GX2UniformVar) {
"modelMatrix", GX2_SHADER_VAR_TYPE_MATRIX4X4, 1, modelMatrixLocation, -1
});
vertexShader.addUniformVar((GX2UniformVar) {
"projectionMatrix", GX2_SHADER_VAR_TYPE_MATRIX4X4, 1, projectionMatrixLocation, -1
});
vertexShader.addUniformVar((GX2UniformVar) {
"viewMatrix", GX2_SHADER_VAR_TYPE_MATRIX4X4, 1, viewMatrixLocation, -1
});
positionLocation = 0;
colorLocation = 1;
texCoordLocation = 2;
vertexShader.addAttribVar((GX2AttribVar){ "attr_colors", GX2_VAR_TYPE_VEC4, 0, colorLocation });
vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation });
vertexShader.addAttribVar((GX2AttribVar){ "attr_texture_coord", GX2_VAR_TYPE_VEC2, 0, texCoordLocation });
vertexShader.addAttribVar((GX2AttribVar) {
"attr_colors", GX2_SHADER_VAR_TYPE_FLOAT4, 0, colorLocation
});
vertexShader.addAttribVar((GX2AttribVar) {
"attr_position", GX2_SHADER_VAR_TYPE_FLOAT3, 0, positionLocation
});
vertexShader.addAttribVar((GX2AttribVar) {
"attr_texture_coord", GX2_SHADER_VAR_TYPE_FLOAT2, 0, texCoordLocation
});
//! setup attribute streams
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT);
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_32_32_FLOAT);
GX2InitAttribStream(vertexShader.getAttributeBuffer(2), colorLocation, 2, 0, GX2_ATTRIB_FORMAT_8_8_8_8_UNORM);
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32);
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
GX2InitAttribStream(vertexShader.getAttributeBuffer(2), colorLocation, 2, 0, GX2_ATTRIB_FORMAT_UNORM_8_8_8_8);
//! create fetch shader
fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());
//! initialize default quad texture vertexes as those are very commonly used
//! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);
colorVtxs = (u8*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciColorVtxsSize);
posVtxs = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
texCoords = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);
colorVtxs = (uint8_t*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciColorVtxsSize);
//! position vertex structure and texture coordinate vertex structure
s32 i = 0;
posVtxs[i++] = -1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
posVtxs[i++] = -1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, posVtxs, ciPositionVtxsSize);
int32_t i = 0;
posVtxs[i++] = -1.0f;
posVtxs[i++] = -1.0f;
posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = -1.0f;
posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = 0.0f;
posVtxs[i++] = -1.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, posVtxs, ciPositionVtxsSize);
i = 0;
texCoords[i++] = 0.0f; texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f; texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f; texCoords[i++] = 0.0f;
texCoords[i++] = 0.0f; texCoords[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, texCoords, ciTexCoordsVtxsSize);
texCoords[i++] = 0.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 0.0f;
texCoords[i++] = 0.0f;
texCoords[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, texCoords, ciTexCoordsVtxsSize);
for(i = 0; i < (s32)ciColorVtxsSize; i++)
for(i = 0; i < (int32_t)ciColorVtxsSize; i++)
colorVtxs[i] = 0xff;
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, colorVtxs, ciColorVtxsSize);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, colorVtxs, ciColorVtxsSize);
}
ShaderFractalColor::~ShaderFractalColor()
{
if(posVtxs)
{
ShaderFractalColor::~ShaderFractalColor() {
if(posVtxs) {
free(posVtxs);
posVtxs = NULL;
}
if(texCoords)
{
if(texCoords) {
free(texCoords);
texCoords = NULL;
}
if(colorVtxs)
{
if(colorVtxs) {
free(colorVtxs);
colorVtxs = NULL;
}

View File

@ -16,10 +16,9 @@
****************************************************************************/
#include <malloc.h>
#include <string.h>
#include "Texture2DShader.h"
#include <video/shaders/Texture2DShader.h>
static const u32 cpVertexShaderProgram[] =
{
static const uint32_t cpVertexShaderProgram[] = {
0x00000000,0x00008009,0x20000000,0x000080a0,
0x3c200100,0x88060094,0x00400000,0x88042014,
0x00000000,0x00000000,0x00000000,0x00000000,
@ -56,7 +55,7 @@ static const u32 cpVertexShaderProgram[] =
0x7c0e2df2,0x81173cfa
};
static const u32 cpVertexShaderRegs[] = {
static const uint32_t cpVertexShaderRegs[] = {
0x00000103,0x00000000,0x00000000,0x00000001,
0xffffff00,0xffffffff,0xffffffff,0xffffffff,
0xffffffff,0xffffffff,0xffffffff,0xffffffff,
@ -72,8 +71,7 @@ static const u32 cpVertexShaderRegs[] = {
0x000000ff,0x00000000,0x0000000e,0x00000010
};
static const u32 cPixelShaderProgram[] =
{
static const uint32_t cPixelShaderProgram[] = {
0x20000000,0x00000ca4,0x0b000000,0x00000085,
0x24000000,0x000050a0,0xb0000000,0x000cc080,
0x39000000,0x00005ca0,0xb8000000,0x000cc080,
@ -180,7 +178,7 @@ static const u32 cPixelShaderProgram[] =
0x10000000,0x00100df0,0x00008010,0xecdfea0d,
0xc8581837,0x22740275,0x281eddcc,0xfa8b9b65
};
static const u32 cPixelShaderRegs[] = {
static const uint32_t cPixelShaderRegs[] = {
0x00000109,0x00000002,0x14000001,0x00000000,
0x00000001,0x00000100,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
@ -197,18 +195,23 @@ static const u32 cPixelShaderRegs[] = {
Texture2DShader * Texture2DShader::shaderInstance = NULL;
Texture2DShader::Texture2DShader()
: vertexShader(cuAttributeCount)
{
: vertexShader(cuAttributeCount) {
//! create pixel shader
pixelShader.setProgram(cPixelShaderProgram, sizeof(cPixelShaderProgram), cPixelShaderRegs, sizeof(cPixelShaderRegs));
blurLocation = 0;
colorIntensityLocation = 4;
pixelShader.addUniformVar((GX2UniformVar){ "unf_blur_texture_direction", GX2_VAR_TYPE_VEC3, 1, blurLocation, 0xffffffff });
pixelShader.addUniformVar((GX2UniformVar){ "unf_color_intensity", GX2_VAR_TYPE_VEC4, 1, colorIntensityLocation, 0xffffffff });
pixelShader.addUniformVar((GX2UniformVar) {
"unf_blur_texture_direction", GX2_SHADER_VAR_TYPE_FLOAT3, 1, blurLocation, -1
});
pixelShader.addUniformVar((GX2UniformVar) {
"unf_color_intensity", GX2_SHADER_VAR_TYPE_FLOAT4, 1, colorIntensityLocation, -1
});
samplerLocation = 0;
pixelShader.addSamplerVar((GX2SamplerVar){ "sampl_texture", GX2_SAMPLER_TYPE_2D, samplerLocation });
pixelShader.addSamplerVar((GX2SamplerVar) {
"sampl_texture", GX2_SAMPLER_VAR_TYPE_SAMPLER_2D, samplerLocation
});
//! create vertex shader
vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));
@ -216,52 +219,71 @@ Texture2DShader::Texture2DShader()
angleLocation = 0;
offsetLocation = 4;
scaleLocation = 8;
vertexShader.addUniformVar((GX2UniformVar){ "unf_angle", GX2_VAR_TYPE_FLOAT, 1, angleLocation, 0xffffffff });
vertexShader.addUniformVar((GX2UniformVar){ "unf_offset", GX2_VAR_TYPE_VEC3, 1, offsetLocation, 0xffffffff });
vertexShader.addUniformVar((GX2UniformVar){ "unf_scale", GX2_VAR_TYPE_VEC3, 1, scaleLocation, 0xffffffff });
vertexShader.addUniformVar((GX2UniformVar) {
"unf_angle", GX2_SHADER_VAR_TYPE_FLOAT, 1, angleLocation, -1
});
vertexShader.addUniformVar((GX2UniformVar) {
"unf_offset", GX2_SHADER_VAR_TYPE_FLOAT3, 1, offsetLocation, -1
});
vertexShader.addUniformVar((GX2UniformVar) {
"unf_scale", GX2_SHADER_VAR_TYPE_FLOAT3, 1, scaleLocation, -1
});
positionLocation = 0;
texCoordLocation = 1;
vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation });
vertexShader.addAttribVar((GX2AttribVar){ "attr_texture_coord", GX2_VAR_TYPE_VEC2, 0, texCoordLocation });
vertexShader.addAttribVar((GX2AttribVar) {
"attr_position", GX2_SHADER_VAR_TYPE_FLOAT3, 0, positionLocation
});
vertexShader.addAttribVar((GX2AttribVar) {
"attr_texture_coord", GX2_SHADER_VAR_TYPE_FLOAT2, 0, texCoordLocation
});
//! setup attribute streams
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT);
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_32_32_FLOAT);
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32);
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
//! create fetch shader
fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());
//! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);
posVtxs = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
texCoords = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);
//! defaults for normal square
//! position vertex structure and texture coordinate vertex structure
s32 i = 0;
posVtxs[i++] = -1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
posVtxs[i++] = -1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, posVtxs, ciPositionVtxsSize);
int32_t i = 0;
posVtxs[i++] = -1.0f;
posVtxs[i++] = -1.0f;
posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = -1.0f;
posVtxs[i++] = 0.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = 0.0f;
posVtxs[i++] = -1.0f;
posVtxs[i++] = 1.0f;
posVtxs[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, posVtxs, ciPositionVtxsSize);
i = 0;
texCoords[i++] = 0.0f; texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f; texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f; texCoords[i++] = 0.0f;
texCoords[i++] = 0.0f; texCoords[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, texCoords, ciTexCoordsVtxsSize);
texCoords[i++] = 0.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 1.0f;
texCoords[i++] = 0.0f;
texCoords[i++] = 0.0f;
texCoords[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, texCoords, ciTexCoordsVtxsSize);
}
Texture2DShader::~Texture2DShader()
{
if(posVtxs)
{
Texture2DShader::~Texture2DShader() {
if(posVtxs) {
free(posVtxs);
posVtxs = NULL;
}
if(texCoords)
{
if(texCoords) {
free(texCoords);
texCoords = NULL;
}

Some files were not shown because too many files have changed in this diff Show More