Merge branch 'wut'

# Conflicts:
#	.travis.yml
#	README.md
This commit is contained in:
orboditilt 2019-08-14 23:28:23 +02:00
commit 9a3811194d
105 changed files with 8593 additions and 8761 deletions

6
.gitignore vendored
View File

@ -1,2 +1,6 @@
build/*
release/* release/*
libgui.cbp libgui.cbp
lib/
*.bz2
libgui.layout

171
Makefile
View File

@ -1,70 +1,64 @@
DO_LOGGING := 0 #-------------------------------------------------------------------------------
#---------------------------------------------------------------------------------
.SUFFIXES: .SUFFIXES:
#--------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC) ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
endif endif
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) TOPDIR ?= $(CURDIR)
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
PREFIX := powerpc-eabi- include $(DEVKITPRO)/wut/share/wut_rules
export AS := $(PREFIX)as export VER_MAJOR := 1
export CC := $(PREFIX)gcc export VER_MINOR := 0
export CXX := $(PREFIX)g++ export VER_PATCH := 0
export AR := $(PREFIX)ar
export OBJCOPY := $(PREFIX)objcopy
include $(DEVKITPPC)/base_rules VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_PATCH)
#--------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed # BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code # 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 data files
# DATA is a list of directories containing binary files # INCLUDES is a list of directories containing header files
# LIBDIR is where the built library will be placed #-------------------------------------------------------------------------------
# all directories are relative to this makefile TARGET := $(notdir $(CURDIR))
#--------------------------------------------------------------------------------- BUILD := build
BUILD ?= release
SOURCES := source \ SOURCES := source \
source/gui \ source/gui \
source/resources \
source/sounds \ source/sounds \
source/video \ source/video \
source/video/shaders source/video/shaders \
DATA := data
INCLUDES := source \ INCLUDES := source \
include include \
DATA :=
LIB := lib
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
CFLAGS = -g -Os -Wall -D__wiiu__ -D_GNU_SOURCE $(MACHDEP) $(INCLUDE) CFLAGS := -Wall -Werror -save-temps \
CXXFLAGS = $(CFLAGS) -ffunction-sections -fdata-sections \
$(MACHDEP) \
$(BUILD_CFLAGS)
ifeq ($(DO_LOGGING), 1) CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__
CFLAGS += -D__LOGGING__
CXXFLAGS += -D__LOGGING__
endif
ASFLAGS := -mregnames CXXFLAGS := $(CFLAGS) -std=gnu++17
export WIIUBIN := $(LIB)/libgui.a ASFLAGS := $(MACHDEP)
#--------------------------------------------------------------------------------- LDFLAGS = $(ARCH) -Wl,--gc-sections
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lutils -ldynamiclibs -lfreetype -lgd -lpng -ljpeg -lz -lmad -lvorbisidec LIBS :=
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing
# include and lib # include and lib
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBDIRS := LIBDIRS := $(PORTLIBS) $(WUT_ROOT)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional # no real need to edit anything past this point unless you need to add additional
@ -73,58 +67,74 @@ LIBDIRS :=
ifneq ($(BUILD),$(notdir $(CURDIR))) ifneq ($(BUILD),$(notdir $(CURDIR)))
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
export TOPDIR ?= $(CURDIR)/.. export TOPDIR := $(CURDIR)
export DEPSDIR := $(CURDIR)/$(BUILD)
export INCLUDEDIR := $(PORTLIBS)/include/libgui
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) $(foreach dir,$(DATA),$(CURDIR)/$(dir))
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) DEFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.def)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES := $(addsuffix .o,$(BINFILES)) \ export OFILES_BIN := $(addsuffix .o,$(BINFILES))
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) $(sFILES:.s=.o) export OFILES_SRC := $(DEFFILES:.def=.o) $(SFILES:.s=.o) $(CFILES:.c=.o) $(CPPFILES:.cpp=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \ $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) -I$(LIBOGC_INC) \ -I. -I$(PORTLIBS_PATH)/ppc/include/freetype2
-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: all dist-bin dist-src dist install clean
.PHONY: $(BUILD) clean
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
$(BUILD): all: lib/libgui.a
dist-bin: all
@tar --exclude=*~ -cjf libgui-$(VERSION).tar.bz2 include lib
dist-src:
@tar --exclude=*~ -cjf libgui-src-$(VERSION).tar.bz2 include source Makefile
dist: dist-src dist-bin
install: dist-bin
mkdir -p $(DESTDIR)$(DEVKITPRO)/wut
bzip2 -cd libgui-$(VERSION).tar.bz2 | tar -xf - -C $(DESTDIR)$(DEVKITPRO)/wut
lib:
@[ -d $@ ] || mkdir -p $@ @[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
release:
@[ -d $@ ] || mkdir -p $@
lib/libgui.a :$(SOURCES) $(INCLUDES) | lib release
@$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
BUILD_CFLAGS="-DNDEBUG=1 -O2 -s" \
DEPSDIR=$(CURDIR)/release \
--no-print-directory -C release \
-f $(CURDIR)/Makefile
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
clean: clean:
@echo clean ... @echo clean ...
@rm -fr debug release $(LIB) include @rm -rf release lib
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 else
@ -134,18 +144,19 @@ DEPENDS := $(OFILES:.o=.d)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# main targets # main targets
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
$(WIIUBIN) : $(OFILES) $(LIB) $(OUTPUT) : $(OFILES)
@rm -f "$(WIIUBIN)"
@$(AR) rcs "$(WIIUBIN)" $(OFILES) $(OFILES_SRC) : $(HFILES)
@echo built ... $(notdir $@)
#---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
$(LIB):
mkdir $(LIB)
-include $(DEPENDS) -include $(DEPENDS)
#--------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------
endif endif
#--------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------

View File

@ -1,36 +1,26 @@
# libgui # 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 ## Usage
Following steps are required for initialization: Following steps are required for initialization:
```C ```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 memoryInitialize(); // Initialize memory management
//DO GUI STUFF HERE! //DO GUI STUFF HERE!
memoryRelease(); memoryRelease();
unmount_sd_fat("sd");
``` ```
Link the application with: Link the application with:
```Makefile ```Makefile
-lgui -lutils -ldynamiclibs -lfreetype -lgd -lpng -ljpeg -lz -lmad -lvorbisidec -logg -lbz2 -lgui -lfreetype -lgd -lpng -ljpeg -lz -lmad -lvorbisidec -logg -lbz2
``` ```
You also need to add the include path to your Makefile. Example: You also need to add the freetype2 nclude path to your Makefile. Example:
```Makefile ```Makefile
export INCLUDE := [...] -I$(PORTLIBS)/include/freetype2 \ -I$(PORTLIBS_PATH)/ppc/include/freetype2
-I$(PORTLIBS)/include/libgui \
-I$(PORTLIBS)/include
``` ```
TODO: provide more information TODO: provide more information
@ -38,20 +28,9 @@ TODO: provide more information
## Dependencies ## Dependencies
To be able to use libgui, you need to install the following dependencies: 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) - [wut](https://github.com/devkitPro/wut/)
- [libutils](https://github.com/Maschell/libutils) for common functions.
- [dynamic_libs](https://github.com/Maschell/dynamic_libs/tree/lib) for access to the functions.
- Install the required portlibs via `(dkp-)pacman -Syu ppc-zlib ppc-libmad ppc-libogg ppc-libgd ppc-freetype ppc-libjpeg-turbo ppc-libpng ppc-libvorbisidec ppc-glm ppc-bzip2` - Install the required portlibs via `(dkp-)pacman -Syu ppc-zlib ppc-libmad ppc-libogg ppc-libgd ppc-freetype ppc-libjpeg-turbo ppc-libpng ppc-libvorbisidec ppc-glm ppc-bzip2`
# Use the prebuilt files from a Docker image.
The image `wiiulegacy/libgui` on [Docker Hub](https://hub.docker.com/r/wiiulegacy/libgui/) provides a prebuilt library in the `/artifacts` directory. Copy it into your DevkitPPC portlibs folder.
Example:
```
COPY --from=wiiulegacy/libgui:0.1 /artifacts $DEVKITPRO/portlibs
```
# Credits # Credits
- Orignally based on https://github.com/dborth/libwiigui - Orignally based on https://github.com/dborth/libwiigui
- Wii U port / modification / new functions / sound / much more by dimok. - Wii U port / modification / new functions / sound / much more by dimok.

View File

@ -34,17 +34,20 @@
#include <wchar.h> #include <wchar.h>
#include <map> #include <map>
#include <gui/gx2_ext.h>
#include <gx2/sampler.h>
#include <gx2/texture.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <dynamic_libs/gx2_functions.h>
/*! \struct ftgxCharData_ /*! \struct ftgxCharData_
* *
* Font face character glyph relevant data structure. * Font face character glyph relevant data structure.
*/ */
typedef struct ftgxCharData_ typedef struct ftgxCharData_ {
{
int16_t renderOffsetX; /**< Texture X axis bearing offset. */ int16_t renderOffsetX; /**< Texture X axis bearing offset. */
uint16_t glyphAdvanceX; /**< Character glyph X coordinate advance in pixels. */ uint16_t glyphAdvanceX; /**< Character glyph X coordinate advance in pixels. */
uint16_t glyphAdvanceY; /**< Character glyph Y 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. * Offset structure which hold both a maximum and minimum value.
*/ */
typedef struct ftgxDataOffset_ typedef struct ftgxDataOffset_ {
{
int16_t ascender; /**< Maximum data offset. */ int16_t ascender; /**< Maximum data offset. */
int16_t descender; /**< Minimum data offset. */ int16_t descender; /**< Minimum data offset. */
int16_t max; /**< Maximum data offset. */ int16_t max; /**< Maximum data offset. */
@ -93,7 +95,9 @@ typedef struct ftgxDataOffset_ ftgxDataOffset;
#define FTGX_STYLE_MASK 0xf000 #define FTGX_STYLE_MASK 0xf000
/**< Constant color value used only to sanitize Doxygen documentation. */ /**< 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 //! 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 * 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. * GX texture functions resulting in high throughput of string rendering.
*/ */
class FreeTypeGX class FreeTypeGX {
{ private:
private: FT_Library ftLibrary; /**< FreeType FT_Library instance. */
FT_Library ftLibrary; /**< FreeType FT_Library instance. */ FT_Face ftFace; /**< FreeType reusable FT_Face typographic object. */
FT_Face ftFace; /**< FreeType reusable FT_Face typographic object. */ int16_t ftPointSize; /**< Current set size of the rendered font. */
int16_t ftPointSize; /**< Current set size of the rendered font. */ bool ftKerningEnabled; /**< Flag indicating the availability of font kerning data. */
bool ftKerningEnabled; /**< Flag indicating the availability of font kerning data. */ uint8_t vertexIndex; /**< Vertex format descriptor index. */
uint8_t vertexIndex; /**< Vertex format descriptor index. */ GX2Sampler ftSampler;
GX2Sampler ftSampler;
typedef struct _ftGX2Data typedef struct _ftGX2Data {
{ ftgxDataOffset ftgxAlign;
ftgxDataOffset ftgxAlign; std::map<wchar_t, ftgxCharData> ftgxCharMap;
std::map<wchar_t, ftgxCharData> ftgxCharMap; } ftGX2Data;
} 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 getStyleOffsetWidth(uint16_t width, uint16_t format);
int16_t getStyleOffsetHeight(int16_t format, uint16_t pixelSize); int16_t getStyleOffsetHeight(int16_t format, uint16_t pixelSize);
void unloadFont(); void unloadFont();
ftgxCharData *cacheGlyphData(wchar_t charCode, int16_t pixelSize); ftgxCharData *cacheGlyphData(wchar_t charCode, int16_t pixelSize);
uint16_t cacheGlyphDataComplete(int16_t pixelSize); uint16_t cacheGlyphDataComplete(int16_t pixelSize);
void loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData); 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: public:
FreeTypeGX(const uint8_t* fontBuffer, FT_Long bufferSize, bool lastFace = false); FreeTypeGX(const uint8_t* fontBuffer, FT_Long bufferSize, bool lastFace = false);
~FreeTypeGX(); ~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 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 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 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 getCharWidth(const wchar_t wChar, int16_t pixelSize, const wchar_t prevChar = 0x0000);
uint16_t getHeight(const wchar_t *text, int16_t pixelSize); uint16_t getHeight(const wchar_t *text, int16_t pixelSize);
void getOffset(const wchar_t *text, int16_t pixelSize, uint16_t widthLimit = 0); void getOffset(const wchar_t *text, int16_t pixelSize, uint16_t widthLimit = 0);
static wchar_t* charToWideChar(const char* p); static wchar_t* charToWideChar(const char* p);
static char* wideCharToUTF8(const wchar_t* strChar); static char* wideCharToUTF8(const wchar_t* strChar);
}; };
#endif /* FREETYPEGX_H_ */ #endif /* FREETYPEGX_H_ */

View File

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

View File

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

43
include/gui/Gui.h Normal file
View File

@ -0,0 +1,43 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef __GUI_H
#define __GUI_H
#include <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_ #ifndef GUI_CHECKBOX_H_
#define GUI_CHECKBOX_H_ #define GUI_CHECKBOX_H_
#include "GuiToggle.h" #include <gui/GuiToggle.h>
#include "GuiImage.h" #include <gui/GuiImage.h>
#include "GuiImageData.h" #include <gui/GuiImageData.h>
//!A simple CheckBox //!A simple CheckBox
class GuiCheckBox : public GuiToggle{ class GuiCheckBox : public GuiToggle {
public: public:
//!Constructor //!Constructor
//!\param checked Checked //!\param checked Checked
GuiCheckBox(GuiImage * background, bool checked, f32 width = 0.0f,f32 height= 0.0f); GuiCheckBox(GuiImage * background, bool checked, float width = 0.0f,float height= 0.0f);
//!Destructor //!Destructor
virtual ~GuiCheckBox(); 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: protected:
GuiImage * backgroundImg = NULL; GuiImage * backgroundImg = NULL;
GuiImage * selectedImg = NULL; GuiImage * selectedImg = NULL;
GuiImage * highlightedImg = NULL; GuiImage * highlightedImg = NULL;
void update(GuiController * c); void update(GuiController * c);
}; };
#endif #endif

View File

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

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

@ -0,0 +1,541 @@
/****************************************************************************
* 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 <gui/system/AsyncDeleter.h>
#include <gui/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_ #ifndef GUI_IMAGE_H_
#define GUI_IMAGE_H_ #define GUI_IMAGE_H_
#include "video/shaders/Shader.h" #include <gui/video/shaders/Shader.h>
#include "GuiElement.h" #include <gui/GuiElement.h>
#include "GuiImageData.h" #include <gui/GuiImageData.h>
#include <gui/gx2_ext.h>
//!Display, manage, and manipulate images in the GUI //!Display, manage, and manipulate images in the GUI
class GuiImage : public GuiElement class GuiImage : public GuiElement {
{
public: public:
enum ImageTypes enum ImageTypes {
{
IMAGE_TEXTURE, IMAGE_TEXTURE,
IMAGE_COLOR IMAGE_COLOR
}; };
@ -39,72 +38,76 @@ public:
//!\param w Image width //!\param w Image width
//!\param h Image height //!\param h Image height
//!\param c Array with 4 x image color (BL, BR, TL, TR) //!\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(int32_t w, int32_t h, const GX2Color & c, int32_t 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, uint32_t colorCount = 1, int32_t imgType = IMAGE_COLOR);
//!Destructor //!Destructor
virtual ~GuiImage(); virtual ~GuiImage();
//!Sets the number of times to draw the image horizontally //!Sets the number of times to draw the image horizontally
//!\param t Number of times to draw the image //!\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 //!Sets the number of times to draw the image vertically
//!\param t Number of times to draw the image //!\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 //!Constantly called to draw the image
void draw(CVideo *pVideo); void draw(CVideo *pVideo);
//!Gets the image data //!Gets the image data
//!\return pointer to 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 //!Sets up a new image using the GuiImageData object specified
//!\param img Pointer to GuiImageData object //!\param img Pointer to GuiImageData object
void setImageData(GuiImageData * img); void setImageData(GuiImageData * img);
//!Gets the pixel color at the specified coordinates of the image //!Gets the pixel color at the specified coordinates of the image
//!\param x X coordinate //!\param x X coordinate
//!\param y Y 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 //!Sets the pixel color at the specified coordinates of the image
//!\param x X coordinate //!\param x X coordinate
//!\param y Y coordinate //!\param y Y coordinate
//!\param color Pixel color //!\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 //!Change ImageColor
void setImageColor(const GX2Color & c, s32 idx = -1); void setImageColor(const GX2Color & c, int32_t idx = -1);
//!Change ImageColor //!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) { if(dir < 2) {
blurDirection[dir] = value; blurDirection[dir] = value;
} }
} }
void setColorIntensity(const glm::vec4 & col) void setColorIntensity(const glm::vec4 & col) {
{
colorIntensity = col; colorIntensity = col;
} }
protected: 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 GuiImageData * imageData; //!< Poiner to image data. May be shared with GuiImageData data
s32 tileHorizontal; //!< Number of times to draw (tile) the image horizontally int32_t tileHorizontal; //!< Number of times to draw (tile) the image horizontally
s32 tileVertical; //!< Number of times to draw (tile) the image vertically int32_t tileVertical; //!< Number of times to draw (tile) the image vertically
//! Internally used variables for rendering //! Internally used variables for rendering
u8 *colorVtxs; uint8_t *colorVtxs;
u32 colorCount; uint32_t colorCount;
bool colorVtxsDirty; bool colorVtxsDirty;
glm::vec3 positionOffsets; glm::vec3 positionOffsets;
glm::vec3 scaleFactor; glm::vec3 scaleFactor;
glm::vec4 colorIntensity; glm::vec4 colorIntensity;
f32 imageAngle; float imageAngle;
glm::vec3 blurDirection; glm::vec3 blurDirection;
const f32 * posVtxs; const float * posVtxs;
const f32 * texCoords; const float * texCoords;
u32 vtxCount; uint32_t vtxCount;
s32 primitive; int32_t primitive;
}; };
#endif #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 <gui/system/CThread.h>
#include <gui/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_ #ifndef GUI_IMAGEDATA_H_
#define GUI_IMAGEDATA_H_ #define GUI_IMAGEDATA_H_
#include <gd.h> #include <gd.h>
#include <dynamic_libs/gx2_functions.h> #include <gui/system/AsyncDeleter.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: public:
//!Constructor //!Constructor
GuiImageData(); GuiImageData();
//!\param img Image data //!\param img Image data
//!\param imgSize The image size //!\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 //!Destructor
virtual ~GuiImageData(); virtual ~GuiImageData();
//!Load image from buffer //!Load image from buffer
//!\param img Image data //!\param img Image data
//!\param imgSize The image size //!\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 //! getter functions
const GX2Texture * getTexture() const { return texture; }; const GX2Texture * getTexture() const {
const GX2Sampler * getSampler() const { return sampler; }; return texture;
};
const GX2Sampler * getSampler() const {
return sampler;
};
//!Gets the image width //!Gets the image width
//!\return 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 //!Gets the image height
//!\return 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 //! release memory of the image data
void releaseData(void); void releaseData(void);
private: private:
void gdImageToUnormR8G8B8A8(gdImagePtr gdImg, u32 *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, u16 *imgBuffer, u32 width, u32 height, u32 pitch); void gdImageToUnormR5G6B5(gdImagePtr gdImg, uint16_t *imgBuffer, uint32_t width, uint32_t height, uint32_t pitch);
GX2Texture *texture; GX2Texture *texture;
GX2Sampler *sampler; GX2Sampler *sampler;
enum eMemoryTypes enum eMemoryTypes {
{
eMemTypeMEM2, eMemTypeMEM2,
eMemTypeMEM1, eMemTypeMEM1,
eMemTypeMEMBucket eMemTypeMEMBucket
}; };
u8 memoryType; uint8_t memoryType;
}; };
#endif #endif

View File

@ -17,31 +17,29 @@
#ifndef _GUI_PARTICLE_IMAGE_H_ #ifndef _GUI_PARTICLE_IMAGE_H_
#define _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: 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(); virtual ~GuiParticleImage();
void draw(CVideo *pVideo); void draw(CVideo *pVideo);
private: private:
f32 *posVertexs; float *posVertexs;
u8 *colorVertexs; uint8_t *colorVertexs;
f32 minRadius; float minRadius;
f32 maxRadius; float maxRadius;
f32 minSpeed; float minSpeed;
f32 maxSpeed; float maxSpeed;
typedef struct typedef struct {
{
glm::vec3 position; glm::vec3 position;
glm::vec4 colors; glm::vec4 colors;
f32 radius; float radius;
f32 speed; float speed;
f32 direction; float direction;
} Particle; } Particle;
std::vector<Particle> particles; 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 <gui/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_ #ifndef GUI_SWTICH_H_
#define GUI_SWTICH_H_ #define GUI_SWTICH_H_
#include "GuiToggle.h" #include <gui/GuiToggle.h>
#include "GuiImage.h" #include <gui/GuiImage.h>
#include "GuiImageData.h" #include <gui/GuiImageData.h>
//!A simple switch //!A simple switch
class GuiSwitch : public GuiToggle{ class GuiSwitch : public GuiToggle {
public: public:
//!Constructor //!Constructor
//!\param checked Checked //!\param checked Checked
GuiSwitch(GuiImage * background, bool checked, f32 w = 0.0f, f32 h = 0.0f); GuiSwitch(GuiImage * background, bool checked, float w = 0.0f, float h = 0.0f);
//!Destructor //!Destructor
virtual ~GuiSwitch(); 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); void setImageHighlighted(GuiImage* img);
protected: protected:
GuiImage * backgroundImg = NULL; GuiImage * backgroundImg = NULL;
GuiImage * onImg = NULL; GuiImage * onImg = NULL;
GuiImage * offImg = NULL; GuiImage * offImg = NULL;
GuiImage * highlightedImg = NULL; GuiImage * highlightedImg = NULL;
void draw(CVideo * v); void draw(CVideo * v);
}; };
#endif #endif

View File

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

View File

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

View File

@ -17,14 +17,10 @@
#ifndef GUI_TRIGGER_H_ #ifndef GUI_TRIGGER_H_
#define 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. //!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: public:
enum eClicked{ enum eClicked {
CLICKED_NONE = 0x00, CLICKED_NONE = 0x00,
CLICKED_TOUCH = 0x01, CLICKED_TOUCH = 0x01,
CLICKED_BUTTON = 0x02, CLICKED_BUTTON = 0x02,
@ -73,30 +69,42 @@ public:
//!Constructor //!Constructor
GuiTrigger(); GuiTrigger();
//!Constructor //!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 //!Destructor
virtual ~GuiTrigger(); virtual ~GuiTrigger();
//!Sets a simple trigger. Requires: element is selected, and trigger button is pressed //!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 setClickEverywhere(bool b) {
void setHoldOnly(bool b) { bHoldEverywhere = b; } bClickEverywhere = b;
void setSelectionClickEverywhere(bool b) { bSelectionClickEverywhere = b; } }
void setHoldOnly(bool b) {
bHoldEverywhere = b;
}
void setSelectionClickEverywhere(bool b) {
bSelectionClickEverywhere = b;
}
bool isClickEverywhere() const { return bClickEverywhere; } bool isClickEverywhere() const {
bool isHoldEverywhere() const { return bHoldEverywhere; } return bClickEverywhere;
bool isSelectionClickEverywhere() const { return bSelectionClickEverywhere; } }
bool isHoldEverywhere() const {
return bHoldEverywhere;
}
bool isSelectionClickEverywhere() const {
return bSelectionClickEverywhere;
}
bool left(const GuiController *controller) const; bool left(const GuiController *controller) const;
bool right(const GuiController *controller) const; bool right(const GuiController *controller) const;
bool up(const GuiController *controller) const; bool up(const GuiController *controller) const;
bool down(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 held(const GuiController *controller) const;
bool released(const GuiController *controller) const; bool released(const GuiController *controller) const;
private: private:
u32 chan; uint32_t chan;
u32 btns; uint32_t btns;
bool bClickEverywhere; bool bClickEverywhere;
bool bHoldEverywhere; bool bHoldEverywhere;
bool bSelectionClickEverywhere; bool bSelectionClickEverywhere;

View File

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

View File

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

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

@ -0,0 +1,161 @@
#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_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
typedef struct _GX2Color {
uint8_t r, g, b, a;
} GX2Color;
typedef struct _GX2ColorF32 {
float r, g, b, a;
} GX2ColorF32;
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
};
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

2377
include/gui/sigslot.h Normal file

File diff suppressed because it is too large Load Diff

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

View File

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

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

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

View File

@ -0,0 +1,76 @@
/****************************************************************************
* 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 _ASYNC_DELETER_H
#define _ASYNC_DELETER_H
#include <queue>
#include "CThread.h"
#include "CMutex.h"
class AsyncDeleter : public CThread {
public:
static void destroyInstance() {
if(deleterInstance != NULL) {
delete deleterInstance;
deleterInstance = NULL;
}
}
class Element {
public:
Element() {}
virtual ~Element() {}
};
static void pushForDelete(AsyncDeleter::Element *e) {
if(!deleterInstance) {
deleterInstance = new AsyncDeleter();
}
deleterInstance->deleteElements.push(e);
}
static BOOL deleteListEmpty() {
if(!deleterInstance) {
return true;
}
return deleterInstance->deleteElements.empty();
}
static BOOL realListEmpty() {
if(!deleterInstance) {
return true;
}
return deleterInstance->realDeleteElements.empty();
}
static void triggerDeleteProcess(void);
private:
AsyncDeleter();
virtual ~AsyncDeleter();
static AsyncDeleter *deleterInstance;
void executeThread(void);
BOOL exitApplication;
std::queue<AsyncDeleter::Element *> deleteElements;
std::queue<AsyncDeleter::Element *> realDeleteElements;
CMutex deleteMutex;
};
#endif // _ASYNC_DELETER_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 _CMUTEX_H_
#define _CMUTEX_H_
#include <malloc.h>
#include <coreinit/mutex.h>
class CMutex
{
public:
CMutex() {
pMutex = (OSMutex*) malloc(sizeof(OSMutex));
if(!pMutex)
return;
OSInitMutex(pMutex);
}
virtual ~CMutex() {
if(pMutex)
free(pMutex);
}
void lock(void) {
if(pMutex)
OSLockMutex(pMutex);
}
void unlock(void) {
if(pMutex)
OSUnlockMutex(pMutex);
}
BOOL tryLock(void) {
if(!pMutex)
return false;
return (OSTryLockMutex(pMutex) != 0);
}
private:
OSMutex *pMutex;
};
class CMutexLock
{
public:
CMutexLock() {
mutex.lock();
}
virtual ~CMutexLock() {
mutex.unlock();
}
private:
CMutex mutex;
};
#endif // _CMUTEX_H_

View File

@ -0,0 +1,133 @@
/****************************************************************************
* 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 CTHREAD_H_
#define CTHREAD_H_
#include <malloc.h>
#include <unistd.h>
#include <coreinit/systeminfo.h>
#include <coreinit/thread.h>
class CThread {
public:
typedef void (* Callback)(CThread *thread, void *arg);
//! constructor
CThread(int32_t iAttr, int32_t iPriority = 16, int32_t iStackSize = 0x8000, CThread::Callback callback = NULL, void *callbackArg = NULL)
: pThread(NULL)
, pThreadStack(NULL)
, pCallback(callback)
, pCallbackArg(callbackArg) {
//! save attribute assignment
iAttributes = iAttr;
//! allocate the thread
pThread = (OSThread*)memalign(8, sizeof(OSThread));
//! allocate the stack
pThreadStack = (uint8_t *) memalign(0x20, iStackSize);
//! create the thread
if(pThread && pThreadStack)
OSCreateThread(pThread, &CThread::threadCallback, 1, (char*)this, pThreadStack+iStackSize, iStackSize, iPriority, iAttributes);
}
//! destructor
virtual ~CThread() {
shutdownThread();
}
static CThread *create(CThread::Callback callback, void *callbackArg, int32_t iAttr = eAttributeNone, int32_t iPriority = 16, int32_t iStackSize = 0x8000) {
return ( new CThread(iAttr, iPriority, iStackSize, callback, callbackArg) );
}
//! Get thread ID
virtual void* getThread() const {
return pThread;
}
//! Thread entry function
virtual void executeThread(void) {
if(pCallback)
pCallback(this, pCallbackArg);
}
//! Suspend thread
virtual void suspendThread(void) {
if(isThreadSuspended()) return;
if(pThread) OSSuspendThread(pThread);
}
//! Resume thread
virtual void resumeThread(void) {
if(!isThreadSuspended()) return;
if(pThread) OSResumeThread(pThread);
}
//! Set thread priority
virtual void setThreadPriority(int prio) {
if(pThread) OSSetThreadPriority(pThread, prio);
}
//! Check if thread is suspended
virtual BOOL isThreadSuspended(void) const {
if(pThread) return OSIsThreadSuspended(pThread);
return false;
}
//! Check if thread is terminated
virtual BOOL isThreadTerminated(void) const {
if(pThread) return OSIsThreadTerminated(pThread);
return false;
}
//! Check if thread is running
virtual BOOL isThreadRunning(void) const {
return !isThreadSuspended() && !isThreadRunning();
}
//! Shutdown thread
virtual void shutdownThread(void) {
//! wait for thread to finish
if(pThread && !(iAttributes & eAttributeDetach)) {
if(isThreadSuspended())
resumeThread();
OSJoinThread(pThread, NULL);
}
//! free the thread stack buffer
if(pThreadStack)
free(pThreadStack);
if(pThread)
free(pThread);
pThread = NULL;
pThreadStack = NULL;
}
//! Thread attributes
enum eCThreadAttributes {
eAttributeNone = 0x07,
eAttributeAffCore0 = 0x01,
eAttributeAffCore1 = 0x02,
eAttributeAffCore2 = 0x04,
eAttributeDetach = 0x08,
eAttributePinnedAff = 0x10
};
private:
static int threadCallback(int argc, const char **argv) {
//! After call to start() continue with the internal function
((CThread *) argv)->executeThread();
return 0;
}
int iAttributes;
OSThread *pThread;
uint8_t *pThreadStack;
Callback pCallback;
void *pCallbackArg;
};
#endif

View File

@ -17,13 +17,22 @@
#ifndef __CVIDEO_H_ #ifndef __CVIDEO_H_
#define __CVIDEO_H_ #define __CVIDEO_H_
#include <dynamic_libs/gx2_functions.h> #include <gx2/sampler.h>
#include "shaders/Shader.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 <gui/video/shaders/Shader.h>
{
class CVideo {
public: public:
CVideo(s32 forceTvScanMode = -1, s32 forceDrcScanMode = -1); CVideo(int32_t forceTvScanMode = -1, int32_t forceDrcScanMode = -1);
virtual ~CVideo(); virtual ~CVideo();
void prepareTvRendering(void) { void prepareTvRendering(void) {
@ -42,38 +51,34 @@ public:
void prepareRendering(void) { void prepareRendering(void) {
GX2ClearColor(currColorBuffer, 0.0f, 0.0f, 0.0f, 1.0f); 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); GX2SetContextState(currContextState);
GX2SetViewport(0.0f, 0.0f, currColorBuffer->surface.width, currColorBuffer->surface.height, 0.0f, 1.0f); GX2SetViewport(0.0f, 0.0f, currColorBuffer->surface.width, currColorBuffer->surface.height, 0.0f, 1.0f);
GX2SetScissor(0, 0, currColorBuffer->surface.width, currColorBuffer->surface.height); 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); 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); GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_DISABLE, GX2_ENABLE);
} }
void setStencilRender(bool bEnable) void setStencilRender(bool bEnable) {
{ if(bEnable) {
if(bEnable)
{
GX2SetStencilMask(0xff, 0xff, 0x01, 0xff, 0xff, 0x01); 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, 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_ALWAYS, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP, GX2_STENCIL_REPLACE); GX2_COMPARE_FUNC_ALWAYS, GX2_STENCIL_FUNCTION_KEEP, GX2_STENCIL_FUNCTION_KEEP, GX2_STENCIL_FUNCTION_REPLACE);
} } else {
else
{
GX2SetStencilMask(0xff, 0xff, 0xff, 0xff, 0xff, 0xff); 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, 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_NEVER, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP); GX2_COMPARE_FUNC_NEVER, GX2_STENCIL_FUNCTION_KEEP, GX2_STENCIL_FUNCTION_KEEP, GX2_STENCIL_FUNCTION_KEEP);
} }
} }
void drcDrawDone(void) { void drcDrawDone(void) {
//! on DRC we do a hardware AA because FXAA does not look good //! on DRC we do a hardware AA because FXAA does not look good
//renderFXAA(&drcAaTexture, &aaSampler); //renderFXAA(&drcAaTexture, &aaSampler);
GX2CopyColorBufferToScanBuffer(&drcColorBuffer, GX2_SCAN_TARGET_DRC_FIRST); GX2CopyColorBufferToScanBuffer(&drcColorBuffer, GX2_SCAN_TARGET_DRC);
} }
void tvDrawDone(void) { void tvDrawDone(void) {
@ -89,35 +94,33 @@ public:
} }
void tvEnable(bool bEnable) { void tvEnable(bool bEnable) {
if(tvEnabled != bEnable) if(tvEnabled != bEnable) {
{
GX2SetTVEnable(bEnable ? GX2_ENABLE : GX2_DISABLE); GX2SetTVEnable(bEnable ? GX2_ENABLE : GX2_DISABLE);
tvEnabled = bEnable; tvEnabled = bEnable;
} }
} }
void drcEnable(bool bEnable) { void drcEnable(bool bEnable) {
if(drcEnabled != bEnable) if(drcEnabled != bEnable) {
{
GX2SetDRCEnable(bEnable ? GX2_ENABLE : GX2_DISABLE); GX2SetDRCEnable(bEnable ? GX2_ENABLE : GX2_DISABLE);
drcEnabled = bEnable; drcEnabled = bEnable;
} }
} }
u32 getFrameCount(void) const { uint32_t getFrameCount(void) const {
return frameCount; return frameCount;
} }
u32 getTvWidth(void) const { uint32_t getTvWidth(void) const {
return tvColorBuffer.surface.width; return tvColorBuffer.surface.width;
} }
u32 getTvHeight(void) const { uint32_t getTvHeight(void) const {
return tvColorBuffer.surface.height; return tvColorBuffer.surface.height;
} }
u32 getDrcWidth(void) const { uint32_t getDrcWidth(void) const {
return drcColorBuffer.surface.width; return drcColorBuffer.surface.width;
} }
u32 getDrcHeight(void) const { uint32_t getDrcHeight(void) const {
return drcColorBuffer.surface.height; return drcColorBuffer.surface.height;
} }
@ -128,18 +131,17 @@ public:
return viewMtx; return viewMtx;
} }
f32 getWidthScaleFactor(void) const { float getWidthScaleFactor(void) const {
return widthScaleFactor; return widthScaleFactor;
} }
f32 getHeightScaleFactor(void) const { float getHeightScaleFactor(void) const {
return heightScaleFactor; return heightScaleFactor;
} }
f32 getDepthScaleFactor(void) const { float getDepthScaleFactor(void) const {
return depthScaleFactor; 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 //! normalize positions
posX = 2.0f * posX * getWidthScaleFactor(); posX = 2.0f * posX * getWidthScaleFactor();
posY = 2.0f * posY * getHeightScaleFactor(); posY = 2.0f * posY * getHeightScaleFactor();
@ -161,8 +163,8 @@ public:
rayDirection = glm::normalize(rayDirectionWorld); rayDirection = glm::normalize(rayDirectionWorld);
} }
private: private:
static void *GX2RAlloc(u32 flags, u32 size, u32 align); static void *GX2RAlloc(uint32_t flags, uint32_t size, uint32_t align);
static void GX2RFree(u32 flags, void* p); static void GX2RFree(uint32_t flags, void* p);
void renderFXAA(const GX2Texture * texture, const GX2Sampler *sampler); void renderFXAA(const GX2Texture * texture, const GX2Sampler *sampler);
@ -171,10 +173,10 @@ private:
void *tvScanBuffer; void *tvScanBuffer;
void *drcScanBuffer; void *drcScanBuffer;
u32 frameCount; uint32_t frameCount;
f32 widthScaleFactor; float widthScaleFactor;
f32 heightScaleFactor; float heightScaleFactor;
f32 depthScaleFactor; float depthScaleFactor;
bool tvEnabled; bool tvEnabled;
bool drcEnabled; bool drcEnabled;

View File

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

View File

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

View File

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

View File

@ -17,22 +17,19 @@
#ifndef FETCH_SHADER_H #ifndef FETCH_SHADER_H
#define FETCH_SHADER_H #define FETCH_SHADER_H
#include "Shader.h" #include <gui/video/shaders/Shader.h>
class FetchShader : public Shader class FetchShader : public Shader {
{
public: 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) : fetchShader(NULL)
, fetchShaderProgramm(NULL) , fetchShaderProgramm(NULL) {
{ uint32_t shaderSize = GX2CalcFetchShaderSizeEx(attrCount, type, tess);
u32 shaderSize = GX2CalcFetchShaderSizeEx(attrCount, type, tess); fetchShaderProgramm = (uint8_t*)memalign(GX2_SHADER_PROGRAM_ALIGNMENT, shaderSize);
fetchShaderProgramm = memalign(GX2_SHADER_ALIGNMENT, shaderSize); if(fetchShaderProgramm) {
if(fetchShaderProgramm)
{
fetchShader = new GX2FetchShader; fetchShader = new GX2FetchShader;
GX2InitFetchShaderEx(fetchShader, fetchShaderProgramm, attrCount, attributes, type, tess); GX2InitFetchShaderEx(fetchShader, fetchShaderProgramm, attrCount, attributes, type, tess);
GX2Invalidate(GX2_INVALIDATE_CPU_SHADER, fetchShaderProgramm, shaderSize); GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, fetchShaderProgramm, shaderSize);
} }
} }
virtual ~FetchShader() { virtual ~FetchShader() {
@ -52,7 +49,7 @@ public:
protected: protected:
GX2FetchShader *fetchShader; GX2FetchShader *fetchShader;
void *fetchShaderProgramm; uint8_t *fetchShaderProgramm;
}; };
#endif // FETCH_SHADER_H #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 <gui/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_PROGRAM_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,70 @@
/****************************************************************************
* 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 <gx2/shaders.h>
#include <gx2/mem.h>
#include <gx2/enum.h>
#include <gx2/registers.h>
#include <gx2/draw.h>
#include <malloc.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_ #ifndef SHADER_3D_H_
#define SHADER_3D_H_ #define SHADER_3D_H_
#include "VertexShader.h" #include <gui/video/shaders/VertexShader.h>
#include "PixelShader.h" #include <gui/video/shaders/PixelShader.h>
#include "FetchShader.h" #include <gui/video/shaders/FetchShader.h>
class Shader3D : public Shader class Shader3D : public Shader {
{
private: private:
Shader3D(); Shader3D();
virtual ~Shader3D(); virtual ~Shader3D();
@ -30,26 +29,26 @@ private:
static Shader3D * shaderInstance; static Shader3D * shaderInstance;
static const unsigned char cuAttributeCount = 2; static const unsigned char cuAttributeCount = 2;
static const u32 ciPositionVtxsSize = 4 * cuVertexAttrSize; static const uint32_t ciPositionVtxsSize = 4 * cuVertexAttrSize;
static const u32 ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize; static const uint32_t ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
FetchShader *fetchShader; FetchShader *fetchShader;
VertexShader vertexShader; VertexShader vertexShader;
PixelShader pixelShader; PixelShader pixelShader;
f32 *posVtxs; float *posVtxs;
f32 *texCoords; float *texCoords;
u32 modelMatrixLocation; uint32_t modelMatrixLocation;
u32 viewMatrixLocation; uint32_t viewMatrixLocation;
u32 projectionMatrixLocation; uint32_t projectionMatrixLocation;
u32 positionLocation; uint32_t positionLocation;
u32 texCoordLocation; uint32_t texCoordLocation;
u32 colorIntensityLocation; uint32_t colorIntensityLocation;
u32 fadeDistanceLocation; uint32_t fadeDistanceLocation;
u32 fadeOutLocation; uint32_t fadeOutLocation;
u32 samplerLocation; uint32_t samplerLocation;
public: public:
static Shader3D *instance() { static Shader3D *instance() {
if(!shaderInstance) { if(!shaderInstance) {
@ -64,55 +63,45 @@ public:
} }
} }
void setShaders(void) const void setShaders(void) const {
{
fetchShader->setShader(); fetchShader->setShader();
vertexShader.setShader(); vertexShader.setShader();
pixelShader.setShader(); pixelShader.setShader();
} }
void setAttributeBuffer(const u32 & vtxCount = 0, const f32 * posVtxs_in = NULL, const f32 * texCoords_in = NULL) const void setAttributeBuffer(const uint32_t & vtxCount = 0, const float * posVtxs_in = NULL, const float * texCoords_in = NULL) const {
{ if(posVtxs_in && texCoords_in && vtxCount) {
if(posVtxs_in && texCoords_in && vtxCount)
{
VertexShader::setAttributeBuffer(0, vtxCount * cuVertexAttrSize, cuVertexAttrSize, posVtxs_in); VertexShader::setAttributeBuffer(0, vtxCount * cuVertexAttrSize, cuVertexAttrSize, posVtxs_in);
VertexShader::setAttributeBuffer(1, vtxCount * cuTexCoordAttrSize, cuTexCoordAttrSize, texCoords_in); VertexShader::setAttributeBuffer(1, vtxCount * cuTexCoordAttrSize, cuTexCoordAttrSize, texCoords_in);
} } else {
else {
//! use default quad vertex and texture coordinates if nothing is passed //! use default quad vertex and texture coordinates if nothing is passed
VertexShader::setAttributeBuffer(0, ciPositionVtxsSize, cuVertexAttrSize, posVtxs); VertexShader::setAttributeBuffer(0, ciPositionVtxsSize, cuVertexAttrSize, posVtxs);
VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords); 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]); 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]); 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]); 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]); PixelShader::setUniformReg(colorIntensityLocation, 4, &vec[0]);
} }
void setAlphaFadeOut(const glm::vec4 & vec) void setAlphaFadeOut(const glm::vec4 & vec) {
{
PixelShader::setUniformReg(fadeOutLocation, 4, &vec[0]); PixelShader::setUniformReg(fadeOutLocation, 4, &vec[0]);
} }
void setDistanceFadeOut(const float & value) void setDistanceFadeOut(const float & value) {
{
PixelShader::setUniformReg(fadeDistanceLocation, 4, &value); PixelShader::setUniformReg(fadeDistanceLocation, 4, &value);
} }
void setTextureAndSampler(const GX2Texture *texture, const GX2Sampler *sampler) const { void setTextureAndSampler(const GX2Texture *texture, const GX2Sampler *sampler) const {
GX2SetPixelTexture(texture, samplerLocation); GX2SetPixelTexture((GX2Texture*)texture, samplerLocation);
GX2SetPixelSampler(sampler, samplerLocation); GX2SetPixelSampler((GX2Sampler*)sampler, samplerLocation);
} }
}; };

View File

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

View File

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

61
source/fs/CFile.hpp Normal file
View File

@ -0,0 +1,61 @@
#ifndef CFILE_HPP_
#define CFILE_HPP_
#include <stdio.h>
#include <string>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <wut_types.h>
class CFile {
public:
enum eOpenTypes {
ReadOnly,
WriteOnly,
ReadWrite,
Append
};
CFile();
CFile(const std::string & filepath, eOpenTypes mode);
CFile(const uint8_t * memory, int32_t memsize);
virtual ~CFile();
int32_t open(const std::string & filepath, eOpenTypes mode);
int32_t open(const uint8_t * memory, int32_t memsize);
BOOL isOpen() const {
if(iFd >= 0)
return true;
if(mem_file)
return true;
return false;
}
void close();
int32_t read(uint8_t * ptr, size_t size);
int32_t write(const uint8_t * ptr, size_t size);
int32_t fwrite(const char *format, ...);
int32_t seek(long int offset, int32_t origin);
uint64_t tell() {
return pos;
};
uint64_t size() {
return filesize;
};
void rewind() {
this->seek(0, SEEK_SET);
};
protected:
int32_t iFd;
const uint8_t * mem_file;
uint64_t filesize;
uint64_t pos;
};
#endif

103
source/fs/DirList.h Normal file
View File

@ -0,0 +1,103 @@
/****************************************************************************
* Copyright (C) 2010
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* DirList Class
* for WiiXplorer 2010
***************************************************************************/
#ifndef ___DIRLIST_H_
#define ___DIRLIST_H_
#include <vector>
#include <string>
#include <wut_types.h>
typedef struct {
char * FilePath;
BOOL isDir;
} DirEntry;
class DirList {
public:
//!Constructor
DirList(void);
//!\param path Path from where to load the filelist of all files
//!\param filter A fileext that needs to be filtered
//!\param flags search/filter flags from the enum
DirList(const std::string & path, const char *filter = NULL, uint32_t flags = Files | Dirs, uint32_t maxDepth = 0xffffffff);
//!Destructor
virtual ~DirList();
//! Load all the files from a directory
BOOL LoadPath(const std::string & path, const char *filter = NULL, uint32_t flags = Files | Dirs, uint32_t maxDepth = 0xffffffff);
//! Get a filename of the list
//!\param list index
const char * GetFilename(int32_t index) const;
//! Get the a filepath of the list
//!\param list index
const char *GetFilepath(int32_t index) const {
if (!valid(index)) return "";
else return FileInfo[index].FilePath;
}
//! Get the a filesize of the list
//!\param list index
uint64_t GetFilesize(int32_t index) const;
//! Is index a dir or a file
//!\param list index
BOOL IsDir(int32_t index) const {
if(!valid(index)) return false;
return FileInfo[index].isDir;
};
//! Get the filecount of the whole list
int32_t GetFilecount() const {
return FileInfo.size();
};
//! Sort list by filepath
void SortList();
//! Custom sort command for custom sort functions definitions
void SortList(BOOL (*SortFunc)(const DirEntry &a, const DirEntry &b));
//! Get the index of the specified filename
int32_t GetFileIndex(const char *filename) const;
//! Enum for search/filter flags
enum {
Files = 0x01,
Dirs = 0x02,
CheckSubfolders = 0x08,
};
protected:
// Internal parser
BOOL InternalLoadPath(std::string &path);
//!Add a list entrie
void AddEntrie(const std::string &filepath, const char * filename, BOOL isDir);
//! Clear the list
void ClearList();
//! Check if valid pos is requested
inline BOOL valid(uint32_t pos) const {
return (pos < FileInfo.size());
};
uint32_t Flags;
uint32_t Depth;
const char *Filter;
std::vector<DirEntry> FileInfo;
};
#endif

16
source/fs/FSUtils.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef __FS_UTILS_H_
#define __FS_UTILS_H_
#include <wut_types.h>
class FSUtils {
public:
static int32_t LoadFileToMem(const char *filepath, uint8_t **inbuffer, uint32_t *size);
//! todo: C++ class
static int32_t CreateSubfolder(const char * fullpath);
static int32_t CheckFile(const char * filepath);
static BOOL saveBufferToFile(const char * path, void * buffer, uint32_t size);
};
#endif // __FS_UTILS_H_

View File

@ -20,9 +20,9 @@
* along with FreeTypeGX. If not, see <http://www.gnu.org/licenses/>. * along with FreeTypeGX. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "FreeTypeGX.h" #include <gui/FreeTypeGX.h>
#include "video/CVideo.h" #include <gui/video/CVideo.h>
#include "video/shaders/Texture2DShader.h" #include <gui/video/shaders/Texture2DShader.h>
using namespace std; using namespace std;
@ -31,33 +31,30 @@ using namespace std;
/** /**
* Default constructor for the FreeTypeGX class for WiiXplorer. * Default constructor for the FreeTypeGX class for WiiXplorer.
*/ */
FreeTypeGX::FreeTypeGX(const uint8_t* fontBuffer, FT_Long bufferSize, bool lastFace) FreeTypeGX::FreeTypeGX(const uint8_t* fontBuffer, FT_Long bufferSize, bool lastFace) {
{ int32_t faceIndex = 0;
int32_t faceIndex = 0; ftPointSize = 0;
ftPointSize = 0; GX2InitSampler(&ftSampler, GX2_TEX_CLAMP_MODE_CLAMP_BORDER, GX2_TEX_XY_FILTER_MODE_LINEAR);
GX2InitSampler(&ftSampler, GX2_TEX_CLAMP_CLAMP_BORDER, GX2_TEX_XY_FILTER_BILINEAR);
FT_Init_FreeType(&ftLibrary); FT_Init_FreeType(&ftLibrary);
if(lastFace) if(lastFace) {
{ FT_New_Memory_Face(ftLibrary, (FT_Byte *)fontBuffer, bufferSize, -1, &ftFace);
FT_New_Memory_Face(ftLibrary, (FT_Byte *)fontBuffer, bufferSize, -1, &ftFace); faceIndex = ftFace->num_faces - 1; // Use the last face
faceIndex = ftFace->num_faces - 1; // Use the last face FT_Done_Face(ftFace);
FT_Done_Face(ftFace); ftFace = NULL;
ftFace = NULL; }
} FT_New_Memory_Face(ftLibrary, (FT_Byte *) fontBuffer, bufferSize, faceIndex, &ftFace);
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. * Default destructor for the FreeTypeGX class.
*/ */
FreeTypeGX::~FreeTypeGX() FreeTypeGX::~FreeTypeGX() {
{ unloadFont();
unloadFont(); FT_Done_Face(ftFace);
FT_Done_Face(ftFace); FT_Done_FreeType(ftLibrary);
FT_Done_FreeType(ftLibrary);
} }
/** /**
@ -70,48 +67,44 @@ FreeTypeGX::~FreeTypeGX()
* @return Wide character representation of supplied character string. * @return Wide character representation of supplied character string.
*/ */
wchar_t* FreeTypeGX::charToWideChar(const char* strChar) wchar_t* FreeTypeGX::charToWideChar(const char* strChar) {
{ if (!strChar) return NULL;
if (!strChar) return NULL;
wchar_t *strWChar = new (std::nothrow) wchar_t[strlen(strChar) + 1]; wchar_t *strWChar = new (std::nothrow) wchar_t[strlen(strChar) + 1];
if (!strWChar) return NULL; if (!strWChar) return NULL;
int32_t bt = mbstowcs(strWChar, strChar, strlen(strChar)); int32_t bt = mbstowcs(strWChar, strChar, strlen(strChar));
if (bt > 0) if (bt > 0) {
{ strWChar[bt] = 0;
strWChar[bt] = 0; return strWChar;
return strWChar; }
}
wchar_t *tempDest = strWChar; wchar_t *tempDest = strWChar;
while ((*tempDest++ = *strChar++)) while ((*tempDest++ = *strChar++))
; ;
return strWChar; return strWChar;
} }
char *FreeTypeGX::wideCharToUTF8(const wchar_t* strChar) char *FreeTypeGX::wideCharToUTF8(const wchar_t* strChar) {
{
if(!strChar) { if(!strChar) {
return NULL; return NULL;
} }
size_t len = 0; size_t len = 0;
wchar_t wc; wchar_t wc;
for (size_t i = 0; strChar[i]; ++i) for (size_t i = 0; strChar[i]; ++i) {
{ wc = strChar[i];
wc = strChar[i]; if (wc < 0x80)
if (wc < 0x80) ++len;
++len; else if (wc < 0x800)
else if (wc < 0x800) len += 2;
len += 2; else if (wc < 0x10000)
else if (wc < 0x10000) len += 3;
len += 3; else
else len += 4;
len += 4; }
}
char *pOut = new (std::nothrow) char[len]; char *pOut = new (std::nothrow) char[len];
if(!pOut) if(!pOut)
@ -119,31 +112,25 @@ char *FreeTypeGX::wideCharToUTF8(const wchar_t* strChar)
size_t n = 0; size_t n = 0;
for (size_t i = 0; strChar[i]; ++i) for (size_t i = 0; strChar[i]; ++i) {
{ wc = strChar[i];
wc = strChar[i]; if (wc < 0x80)
if (wc < 0x80) pOut[n++] = (char)wc;
pOut[n++] = (char)wc; else if (wc < 0x800) {
else if (wc < 0x800) pOut[n++] = (char)((wc >> 6) | 0xC0);
{ pOut[n++] = (char)((wc & 0x3F) | 0x80);
pOut[n++] = (char)((wc >> 6) | 0xC0); } else if (wc < 0x10000) {
pOut[n++] = (char)((wc & 0x3F) | 0x80); pOut[n++] = (char)((wc >> 12) | 0xE0);
} pOut[n++] = (char)(((wc >> 6) & 0x3F) | 0x80);
else if (wc < 0x10000) pOut[n++] = (char)((wc & 0x3F) | 0x80);
{ } else {
pOut[n++] = (char)((wc >> 12) | 0xE0); pOut[n++] = (char)(((wc >> 18) & 0x07) | 0xF0);
pOut[n++] = (char)(((wc >> 6) & 0x3F) | 0x80); pOut[n++] = (char)(((wc >> 12) & 0x3F) | 0x80);
pOut[n++] = (char)((wc & 0x3F) | 0x80); pOut[n++] = (char)(((wc >> 6) & 0x3F) | 0x80);
} pOut[n++] = (char)((wc & 0x3F) | 0x80);
else }
{ }
pOut[n++] = (char)(((wc >> 18) & 0x07) | 0xF0); return pOut;
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. * This routine clears all members of the font map structure and frees all allocated memory back to the system.
*/ */
void FreeTypeGX::unloadFont() void FreeTypeGX::unloadFont() {
{ map<int16_t, ftGX2Data >::iterator itr;
map<int16_t, ftGX2Data >::iterator itr; map<wchar_t, ftgxCharData>::iterator itr2;
map<wchar_t, ftgxCharData>::iterator itr2;
for (itr = fontData.begin(); itr != fontData.end(); itr++) for (itr = fontData.begin(); itr != fontData.end(); itr++) {
{ for (itr2 = itr->second.ftgxCharMap.begin(); itr2 != itr->second.ftgxCharMap.end(); itr2++) {
for (itr2 = itr->second.ftgxCharMap.begin(); itr2 != itr->second.ftgxCharMap.end(); itr2++) if(itr2->second.texture) {
{ if(itr2->second.texture->surface.image)
if(itr2->second.texture) free(itr2->second.texture->surface.image);
{
if(itr2->second.texture->surface.image_data)
free(itr2->second.texture->surface.image_data);
delete itr2->second.texture; delete itr2->second.texture;
itr2->second.texture = NULL; itr2->second.texture = NULL;
} }
} }
} }
fontData.clear(); fontData.clear();
} }
/** /**
@ -183,24 +166,20 @@ void FreeTypeGX::unloadFont()
* @param charCode The requested glyph's character code. * @param charCode The requested glyph's character code.
* @return A pointer to the allocated font structure. * @return A pointer to the allocated font structure.
*/ */
ftgxCharData * FreeTypeGX::cacheGlyphData(wchar_t charCode, int16_t pixelSize) ftgxCharData * FreeTypeGX::cacheGlyphData(wchar_t charCode, int16_t pixelSize) {
{ map<int16_t, ftGX2Data>::iterator itr = fontData.find(pixelSize);
map<int16_t, ftGX2Data>::iterator itr = fontData.find(pixelSize); if (itr != fontData.end()) {
if (itr != fontData.end()) map<wchar_t, ftgxCharData>::iterator itr2 = itr->second.ftgxCharMap.find(charCode);
{ if (itr2 != itr->second.ftgxCharMap.end()) {
map<wchar_t, ftgxCharData>::iterator itr2 = itr->second.ftgxCharMap.find(charCode); return &itr2->second;
if (itr2 != itr->second.ftgxCharMap.end()) }
{ }
return &itr2->second;
}
}
//!Cache ascender and decender as well //!Cache ascender and decender as well
ftGX2Data *ftData = &fontData[pixelSize]; ftGX2Data *ftData = &fontData[pixelSize];
FT_UInt gIndex; FT_UInt gIndex;
uint16_t textureWidth = 0, textureHeight = 0; uint16_t textureWidth = 0, textureHeight = 0;
if (ftPointSize != pixelSize) if (ftPointSize != pixelSize) {
{
ftPointSize = pixelSize; ftPointSize = pixelSize;
FT_Set_Pixel_Sizes(ftFace, 0, ftPointSize); FT_Set_Pixel_Sizes(ftFace, 0, ftPointSize);
ftData->ftgxAlign.ascender = (int16_t) ftFace->size->metrics.ascender >> 6; 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; ftData->ftgxAlign.min = 0;
} }
gIndex = FT_Get_Char_Index(ftFace, (FT_ULong) charCode); 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 (gIndex != 0 && FT_Load_Glyph(ftFace, gIndex, FT_LOAD_DEFAULT | FT_LOAD_RENDER) == 0) {
{ if (ftFace->glyph->format == FT_GLYPH_FORMAT_BITMAP) {
if (ftFace->glyph->format == FT_GLYPH_FORMAT_BITMAP) FT_Bitmap *glyphBitmap = &ftFace->glyph->bitmap;
{
FT_Bitmap *glyphBitmap = &ftFace->glyph->bitmap;
textureWidth = ALIGN4(glyphBitmap->width); textureWidth = ALIGN4(glyphBitmap->width);
textureHeight = ALIGN4(glyphBitmap->rows); textureHeight = ALIGN4(glyphBitmap->rows);
if(textureWidth == 0) if(textureWidth == 0)
textureWidth = 4; textureWidth = 4;
if(textureHeight == 0) if(textureHeight == 0)
textureHeight = 4; textureHeight = 4;
ftgxCharData *charData = &ftData->ftgxCharMap[charCode]; ftgxCharData *charData = &ftData->ftgxCharMap[charCode];
charData->renderOffsetX = (int16_t) ftFace->glyph->bitmap_left; charData->renderOffsetX = (int16_t) ftFace->glyph->bitmap_left;
charData->glyphAdvanceX = (uint16_t) (ftFace->glyph->advance.x >> 6); charData->glyphAdvanceX = (uint16_t) (ftFace->glyph->advance.x >> 6);
charData->glyphAdvanceY = (uint16_t) (ftFace->glyph->advance.y >> 6); charData->glyphAdvanceY = (uint16_t) (ftFace->glyph->advance.y >> 6);
charData->glyphIndex = (uint32_t) gIndex; charData->glyphIndex = (uint32_t) gIndex;
charData->renderOffsetY = (int16_t) ftFace->glyph->bitmap_top; charData->renderOffsetY = (int16_t) ftFace->glyph->bitmap_top;
charData->renderOffsetMax = (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->renderOffsetMin = (int16_t) glyphBitmap->rows - ftFace->glyph->bitmap_top;
//! Initialize texture //! Initialize texture
charData->texture = new GX2Texture; 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 charData;
} }
} }
return NULL; 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. * 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. * 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) uint16_t FreeTypeGX::cacheGlyphDataComplete(int16_t pixelSize) {
{ uint32_t i = 0;
uint32_t i = 0; FT_UInt gIndex;
FT_UInt gIndex;
FT_ULong charCode = FT_Get_First_Char(ftFace, &gIndex); FT_ULong charCode = FT_Get_First_Char(ftFace, &gIndex);
while (gIndex != 0) while (gIndex != 0) {
{ if (cacheGlyphData(charCode, pixelSize) != NULL) ++i;
if (cacheGlyphData(charCode, pixelSize) != NULL) ++i; charCode = FT_Get_Next_Char(ftFace, charCode, &gIndex);
charCode = FT_Get_Next_Char(ftFace, charCode, &gIndex); }
} return (uint16_t) (i);
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. * @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) void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData) {
{ charData->texture->surface.image = (uint8_t *) memalign(charData->texture->surface.alignment, charData->texture->surface.imageSize);
charData->texture->surface.image_data = (uint8_t *) memalign(charData->texture->surface.align, charData->texture->surface.image_size); if(!charData->texture->surface.image)
if(!charData->texture->surface.image_data)
return; 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; uint8_t *src = (uint8_t *)bmp->buffer;
uint16_t *dst = (uint16_t *)charData->texture->surface.image_data; uint16_t *dst = (uint16_t *)charData->texture->surface.image;
int32_t x, y; uint32_t x, y;
for(y = 0; y < bmp->rows; y++) for(y = 0; y < bmp->rows; y++) {
{ for(x = 0; x < bmp->width; x++) {
for(x = 0; x < bmp->width; x++) uint8_t intensity = src[y * bmp->width + x] >> 3;
{
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; 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 width Current pixel width of the string.
* @param format Positional format of the string. * @param format Positional format of the string.
*/ */
int16_t FreeTypeGX::getStyleOffsetWidth(uint16_t width, uint16_t format) int16_t FreeTypeGX::getStyleOffsetWidth(uint16_t width, uint16_t format) {
{ if (format & FTGX_JUSTIFY_LEFT)
if (format & FTGX_JUSTIFY_LEFT) return 0;
return 0; else if (format & FTGX_JUSTIFY_CENTER)
else if (format & FTGX_JUSTIFY_CENTER) return -(width >> 1);
return -(width >> 1); else if (format & FTGX_JUSTIFY_RIGHT) return -width;
else if (format & FTGX_JUSTIFY_RIGHT) return -width; return 0;
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 offset Current pixel offset data of the string.
* @param format Positional format of the string. * @param format Positional format of the string.
*/ */
int16_t FreeTypeGX::getStyleOffsetHeight(int16_t format, uint16_t pixelSize) int16_t FreeTypeGX::getStyleOffsetHeight(int16_t format, uint16_t pixelSize) {
{ std::map<int16_t, ftGX2Data>::iterator itr = fontData.find(pixelSize);
std::map<int16_t, ftGX2Data>::iterator itr = fontData.find(pixelSize); if (itr == fontData.end()) return 0;
if (itr == fontData.end()) return 0;
switch (format & FTGX_ALIGN_MASK) switch (format & FTGX_ALIGN_MASK) {
{ case FTGX_ALIGN_TOP:
case FTGX_ALIGN_TOP: return itr->second.ftgxAlign.descender;
return itr->second.ftgxAlign.descender;
case FTGX_ALIGN_MIDDLE: case FTGX_ALIGN_MIDDLE:
default: default:
return (itr->second.ftgxAlign.ascender + itr->second.ftgxAlign.descender + 1) >> 1; return (itr->second.ftgxAlign.ascender + itr->second.ftgxAlign.descender + 1) >> 1;
case FTGX_ALIGN_BOTTOM: case FTGX_ALIGN_BOTTOM:
return itr->second.ftgxAlign.ascender; return itr->second.ftgxAlign.ascender;
case FTGX_ALIGN_BASELINE: case FTGX_ALIGN_BASELINE:
return 0; return 0;
case FTGX_ALIGN_GLYPH_TOP: case FTGX_ALIGN_GLYPH_TOP:
return itr->second.ftgxAlign.max; return itr->second.ftgxAlign.max;
case FTGX_ALIGN_GLYPH_MIDDLE: case FTGX_ALIGN_GLYPH_MIDDLE:
return (itr->second.ftgxAlign.max + itr->second.ftgxAlign.min + 1) >> 1; return (itr->second.ftgxAlign.max + itr->second.ftgxAlign.min + 1) >> 1;
case FTGX_ALIGN_GLYPH_BOTTOM: case FTGX_ALIGN_GLYPH_BOTTOM:
return itr->second.ftgxAlign.min; return itr->second.ftgxAlign.min;
} }
return 0; return 0;
} }
/** /**
@ -369,47 +338,41 @@ int16_t FreeTypeGX::getStyleOffsetHeight(int16_t format, uint16_t pixelSize)
* @return The number of characters printed. * @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) 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)
if (!text)
return 0; return 0;
uint16_t fullTextWidth = (textWidth > 0) ? textWidth : getWidth(text, pixelSize); uint16_t fullTextWidth = (textWidth > 0) ? textWidth : getWidth(text, pixelSize);
uint16_t x_pos = x, printed = 0; uint16_t x_pos = x, printed = 0;
uint16_t x_offset = 0, y_offset = 0; uint16_t x_offset = 0, y_offset = 0;
FT_Vector pairDelta; FT_Vector pairDelta;
if (textStyle & FTGX_JUSTIFY_MASK) if (textStyle & FTGX_JUSTIFY_MASK) {
{ x_offset = getStyleOffsetWidth(fullTextWidth, textStyle);
x_offset = getStyleOffsetWidth(fullTextWidth, textStyle); }
} if (textStyle & FTGX_ALIGN_MASK) {
if (textStyle & FTGX_ALIGN_MASK) y_offset = getStyleOffsetHeight(textStyle, pixelSize);
{ }
y_offset = getStyleOffsetHeight(textStyle, pixelSize);
}
int32_t i = 0; int32_t i = 0;
while (text[i]) while (text[i]) {
{ ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
if (glyphData != NULL) if (glyphData != NULL) {
{ if (ftKerningEnabled && i > 0) {
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);
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; x_pos += glyphData->glyphAdvanceX;
++printed; ++printed;
} }
++i; ++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. * @param text NULL terminated string to calculate.
* @return The width of the text string in pixels. * @return The width of the text string in pixels.
*/ */
uint16_t FreeTypeGX::getWidth(const wchar_t *text, int16_t pixelSize) uint16_t FreeTypeGX::getWidth(const wchar_t *text, int16_t pixelSize) {
{ if (!text) return 0;
if (!text) return 0;
uint16_t strWidth = 0; uint16_t strWidth = 0;
FT_Vector pairDelta; FT_Vector pairDelta;
int32_t i = 0; int32_t i = 0;
while (text[i]) while (text[i]) {
{ ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
if (glyphData != NULL) if (glyphData != NULL) {
{ if (ftKerningEnabled && (i > 0)) {
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;
FT_Get_Kerning(ftFace, fontData[pixelSize].ftgxCharMap[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta); }
strWidth += pairDelta.x >> 6;
}
strWidth += glyphData->glyphAdvanceX; strWidth += glyphData->glyphAdvanceX;
} }
++i; ++i;
} }
return strWidth; return strWidth;
} }
/** /**
* Single char width * Single char width
*/ */
uint16_t FreeTypeGX::getCharWidth(const wchar_t wChar, int16_t pixelSize, const wchar_t prevChar) uint16_t FreeTypeGX::getCharWidth(const wchar_t wChar, int16_t pixelSize, const wchar_t prevChar) {
{ uint16_t strWidth = 0;
uint16_t strWidth = 0; ftgxCharData * glyphData = cacheGlyphData(wChar, pixelSize);
ftgxCharData * glyphData = cacheGlyphData(wChar, pixelSize);
if (glyphData != NULL) if (glyphData != NULL) {
{ if (ftKerningEnabled && prevChar != 0x0000) {
if (ftKerningEnabled && prevChar != 0x0000) FT_Vector pairDelta;
{ FT_Get_Kerning(ftFace, fontData[pixelSize].ftgxCharMap[prevChar].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
FT_Vector pairDelta; strWidth += pairDelta.x >> 6;
FT_Get_Kerning(ftFace, fontData[pixelSize].ftgxCharMap[prevChar].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta); }
strWidth += pairDelta.x >> 6; strWidth += glyphData->glyphAdvanceX;
} }
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. * @param text NULL terminated string to calculate.
* @return The height of the text string in pixels. * @return The height of the text string in pixels.
*/ */
uint16_t FreeTypeGX::getHeight(const wchar_t *text, int16_t pixelSize) uint16_t FreeTypeGX::getHeight(const wchar_t *text, int16_t pixelSize) {
{ getOffset(text, pixelSize);
getOffset(text, pixelSize); return fontData[pixelSize].ftgxAlign.max - fontData[pixelSize].ftgxAlign.min;
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 * @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) void FreeTypeGX::getOffset(const wchar_t *text, int16_t pixelSize, uint16_t widthLimit) {
{ if (fontData.find(pixelSize) != fontData.end())
if (fontData.find(pixelSize) != fontData.end())
return; return;
int16_t strMax = 0, strMin = 9999; int16_t strMax = 0, strMin = 9999;
uint16_t currWidth = 0; uint16_t currWidth = 0;
int32_t i = 0; int32_t i = 0;
while (text[i]) while (text[i]) {
{ if (widthLimit > 0 && currWidth >= widthLimit) break;
if (widthLimit > 0 && currWidth >= widthLimit) break;
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize); ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
if (glyphData != NULL) if (glyphData != NULL) {
{ strMax = glyphData->renderOffsetMax > strMax ? glyphData->renderOffsetMax : strMax;
strMax = glyphData->renderOffsetMax > strMax ? glyphData->renderOffsetMax : strMax; strMin = glyphData->renderOffsetMin < strMin ? glyphData->renderOffsetMin : strMin;
strMin = glyphData->renderOffsetMin < strMin ? glyphData->renderOffsetMin : strMin; currWidth += glyphData->glyphAdvanceX;
currWidth += glyphData->glyphAdvanceX; }
}
++i; ++i;
} }
if (ftPointSize != pixelSize) if (ftPointSize != pixelSize) {
{ ftPointSize = pixelSize;
ftPointSize = pixelSize; FT_Set_Pixel_Sizes(ftFace, 0, ftPointSize);
FT_Set_Pixel_Sizes(ftFace, 0, ftPointSize); }
}
fontData[pixelSize].ftgxAlign.ascender = ftFace->size->metrics.ascender >> 6; fontData[pixelSize].ftgxAlign.ascender = ftFace->size->metrics.ascender >> 6;
fontData[pixelSize].ftgxAlign.descender = ftFace->size->metrics.descender >> 6; fontData[pixelSize].ftgxAlign.descender = ftFace->size->metrics.descender >> 6;
fontData[pixelSize].ftgxAlign.max = strMax; fontData[pixelSize].ftgxAlign.max = strMax;
fontData[pixelSize].ftgxAlign.min = strMin; 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 screenY The screen Y coordinate at which to output the rendered texture.
* @param color Color to apply to the 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) 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 f32 imageAngle = 0.0f; static const float blurScale = (2.0f/ (internalRenderingScale));
static const f32 blurScale = (2.0f/ (internalRenderingScale));
f32 offsetLeft = blurScale * ((f32)x + 0.5f * (f32)texture->surface.width) * (f32)pVideo->getWidthScaleFactor(); float offsetLeft = blurScale * ((float)x + 0.5f * (float)texture->surface.width) * (float)pVideo->getWidthScaleFactor();
f32 offsetTop = blurScale * ((f32)y - 0.5f * (f32)texture->surface.height) * (f32)pVideo->getHeightScaleFactor(); float offsetTop = blurScale * ((float)y - 0.5f * (float)texture->surface.height) * (float)pVideo->getHeightScaleFactor();
f32 widthScale = blurScale * (f32)texture->surface.width * pVideo->getWidthScaleFactor(); float widthScale = blurScale * (float)texture->surface.width * pVideo->getWidthScaleFactor();
f32 heightScale = blurScale * (f32)texture->surface.height * pVideo->getHeightScaleFactor(); 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 scaleFactor( widthScale, heightScale, 1.0f );
glm::vec3 blurDirection; glm::vec3 blurDirection;
@ -572,8 +522,7 @@ void FreeTypeGX::copyTextureToFramebuffer(CVideo *pVideo, GX2Texture *texture, i
Texture2DShader::instance()->setScale(scaleFactor); Texture2DShader::instance()->setScale(scaleFactor);
Texture2DShader::instance()->setTextureAndSampler(texture, &ftSampler); Texture2DShader::instance()->setTextureAndSampler(texture, &ftSampler);
if(blurIntensity > 0.0f) if(blurIntensity > 0.0f) {
{
//! glow blur color //! glow blur color
Texture2DShader::instance()->setColorIntensity(blurColor); Texture2DShader::instance()->setColorIntensity(blurColor);

View File

@ -1,30 +1,27 @@
#include "GameBgImage.h" #include <gui/GameBgImage.h>
#include "video/CVideo.h" #include <gui/video/CVideo.h>
#include "video/shaders/Shader3D.h" #include <gui/video/shaders/Shader3D.h>
GameBgImage::GameBgImage(const std::string & filename, GuiImageData *preloadImage) GameBgImage::GameBgImage(const std::string & filename, GuiImageData *preloadImage)
: GuiImageAsync(filename, preloadImage) : GuiImageAsync(filename, preloadImage) {
{
identity = glm::mat4(1.0f); identity = glm::mat4(1.0f);
alphaFadeOut = glm::vec4(1.0f, 0.075f, 5.305f, 2.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()) if(!getImageData() || !getImageData()->getTexture())
return; return;
//! first setup 2D GUI positions //! first setup 2D GUI positions
f32 currPosX = getCenterX(); float currPosX = getCenterX();
f32 currPosY = getCenterY(); float currPosY = getCenterY();
f32 currPosZ = getDepth(); float currPosZ = getDepth();
f32 currScaleX = getScaleX() * (f32)getWidth() * pVideo->getWidthScaleFactor(); float currScaleX = getScaleX() * (float)getWidth() * pVideo->getWidthScaleFactor();
f32 currScaleY = getScaleY() * (f32)getHeight() * pVideo->getHeightScaleFactor(); float currScaleY = getScaleY() * (float)getHeight() * pVideo->getHeightScaleFactor();
f32 currScaleZ = getScaleZ() * (f32)getWidth() * pVideo->getDepthScaleFactor(); float currScaleZ = getScaleZ() * (float)getWidth() * pVideo->getDepthScaleFactor();
glm::mat4 m_modelView = glm::translate(identity, glm::vec3(currPosX,currPosY, currPosZ)); glm::mat4 m_modelView = glm::translate(identity, glm::vec3(currPosX,currPosY, currPosZ));
m_modelView = glm::scale(m_modelView, glm::vec3(currScaleX, currScaleY, currScaleZ)); m_modelView = glm::scale(m_modelView, glm::vec3(currScaleX, currScaleY, currScaleZ));

View File

@ -1,13 +1,13 @@
#include "GridBackground.h" #include <gui/GridBackground.h>
#include "video/CVideo.h" #include <gui/video/CVideo.h>
#include "video/shaders/Shader3D.h" #include <gui/video/shaders/Shader3D.h>
#include "utils/utils.h"
static const float bgRepeat = 1000.0f; static const float bgRepeat = 1000.0f;
static const float bgTexRotate = 39.0f; static const float bgTexRotate = 39.0f;
GridBackground::GridBackground(GuiImageData *img) GridBackground::GridBackground(GuiImageData *img)
: GuiImage(img) : GuiImage(img) {
{
colorIntensity = glm::vec4(1.0f, 1.0f, 1.0f, 0.9f); colorIntensity = glm::vec4(1.0f, 1.0f, 1.0f, 0.9f);
alphaFadeOut = glm::vec4(0.0f); alphaFadeOut = glm::vec4(0.0f);
distanceFadeOut = 0.15f; distanceFadeOut = 0.15f;
@ -15,26 +15,36 @@ GridBackground::GridBackground(GuiImageData *img)
vtxCount = 4; vtxCount = 4;
//! texture and vertex coordinates //! texture and vertex coordinates
f32 *m_posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, vtxCount * Shader3D::cuVertexAttrSize); float *m_posVtxs = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, vtxCount * Shader3D::cuVertexAttrSize);
f32 *m_texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, vtxCount * Shader3D::cuTexCoordAttrSize); float *m_texCoords = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, vtxCount * Shader3D::cuTexCoordAttrSize);
if(m_posVtxs) if(m_posVtxs) {
{ int32_t i = 0;
s32 i = 0; m_posVtxs[i++] = -1.0f;
m_posVtxs[i++] = -1.0f; m_posVtxs[i++] = 0.0f; m_posVtxs[i++] = 1.0f; m_posVtxs[i++] = 0.0f;
m_posVtxs[i++] = 1.0f; m_posVtxs[i++] = 0.0f; m_posVtxs[i++] = 1.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++] = -1.0f; m_posVtxs[i++] = 0.0f; m_posVtxs[i++] = -1.0f; m_posVtxs[i++] = 0.0f;
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, m_posVtxs, vtxCount * Shader3D::cuVertexAttrSize); 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]; glm::vec2 texCoordVec[4];
texCoordVec[0][0] = -0.5f * bgRepeat; texCoordVec[0][1] = 0.5f * bgRepeat; texCoordVec[0][0] = -0.5f * bgRepeat;
texCoordVec[1][0] = 0.5f * bgRepeat; texCoordVec[1][1] = 0.5f * bgRepeat; texCoordVec[0][1] = 0.5f * bgRepeat;
texCoordVec[2][0] = 0.5f * bgRepeat; texCoordVec[2][1] = -0.5f * bgRepeat; texCoordVec[1][0] = 0.5f * bgRepeat;
texCoordVec[3][0] = -0.5f * bgRepeat; texCoordVec[3][1] = -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 cosRot = cosf(DegToRad(bgTexRotate));
const float sinRot = sinf(DegToRad(bgTexRotate)); const float sinRot = sinf(DegToRad(bgTexRotate));
@ -44,13 +54,13 @@ GridBackground::GridBackground(GuiImageData *img)
sinRot, cosRot sinRot, cosRot
}); });
for(s32 i = 0; i < 4; i++) { for(int32_t i = 0; i < 4; i++) {
texCoordVec[i] = texRotateMtx * texCoordVec[i]; texCoordVec[i] = texRotateMtx * texCoordVec[i];
m_texCoords[i*2 + 0] = texCoordVec[i][0]; m_texCoords[i*2 + 0] = texCoordVec[i][0];
m_texCoords[i*2 + 1] = texCoordVec[i][1]; 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 //! assign to internal variables which are const but oh well
@ -58,30 +68,26 @@ GridBackground::GridBackground(GuiImageData *img)
texCoords = m_texCoords; texCoords = m_texCoords;
} }
GridBackground::~GridBackground() GridBackground::~GridBackground() {
{
//! remove image so it can not be drawn anymore from this point on //! remove image so it can not be drawn anymore from this point on
imageData = NULL; imageData = NULL;
//! main image vertexes //! main image vertexes
if(posVtxs) if(posVtxs) {
{
free((void*)posVtxs); free((void*)posVtxs);
posVtxs = NULL; posVtxs = NULL;
} }
if(texCoords) if(texCoords) {
{
free((void*)texCoords); free((void*)texCoords);
texCoords = NULL; 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 //! first setup 2D GUI positions
f32 currScaleX = bgRepeat * scaleX * (f32)getWidth() * pVideo->getWidthScaleFactor(); float currScaleX = bgRepeat * scaleX * (float)getWidth() * pVideo->getWidthScaleFactor();
f32 currScaleY = 1.0f; float currScaleY = 1.0f;
f32 currScaleZ = bgRepeat * scaleZ * (f32)getHeight() * pVideo->getDepthScaleFactor(); float currScaleZ = bgRepeat * scaleZ * (float)getHeight() * pVideo->getDepthScaleFactor();
m_modelView = glm::scale(modelView, glm::vec3(currScaleX, currScaleY, currScaleZ)); m_modelView = glm::scale(modelView, glm::vec3(currScaleX, currScaleY, currScaleZ));
@ -96,5 +102,5 @@ void GridBackground::draw(CVideo *pVideo, const glm::mat4 & modelView)
Shader3D::instance()->setAlphaFadeOut(alphaFadeOut); Shader3D::instance()->setAlphaFadeOut(alphaFadeOut);
Shader3D::instance()->setColorIntensity(colorIntensity); Shader3D::instance()->setColorIntensity(colorIntensity);
Shader3D::instance()->setAttributeBuffer(vtxCount, posVtxs, texCoords); 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "GuiButton.h" #include <gui/GuiButton.h>
#include "GuiTrigger.h" #include <gui/GuiTrigger.h>
#include "GuiController.h" #include <gui/GuiController.h>
/** /**
* Constructor for the GuiButton class. * Constructor for the GuiButton class.
*/ */
GuiButton::GuiButton(f32 w, f32 h) GuiButton::GuiButton(float w, float h) {
{
width = w; width = w;
height = h; height = h;
image = NULL; image = NULL;
imageOver = NULL; imageOver = NULL;
imageHold = NULL; imageHold = NULL;
imageClick = NULL; imageClick = NULL;
icon = NULL; icon = NULL;
iconOver = NULL; iconOver = NULL;
for(s32 i = 0; i < 4; i++) for(int32_t i = 0; i < 4; i++) {
{ label[i] = NULL;
label[i] = NULL; labelOver[i] = NULL;
labelOver[i] = NULL; labelHold[i] = NULL;
labelHold[i] = NULL; labelClick[i] = NULL;
labelClick[i] = NULL; }
} for(int32_t i = 0; i < iMaxGuiTriggers; i++) {
for(s32 i = 0; i < iMaxGuiTriggers; i++) trigger[i] = NULL;
{ }
trigger[i] = NULL;
}
soundOver = NULL; soundOver = NULL;
soundHold = NULL; soundHold = NULL;
soundClick = NULL; soundClick = NULL;
clickedTrigger = NULL; clickedTrigger = NULL;
heldTrigger = NULL; heldTrigger = NULL;
selectable = true; selectable = true;
holdable = false; holdable = false;
clickable = true; clickable = true;
} }
/** /**
* Destructor for the GuiButton class. * Destructor for the GuiButton class.
*/ */
GuiButton::~GuiButton() GuiButton::~GuiButton() {
{
} }
void GuiButton::setImage(GuiImage* img) void GuiButton::setImage(GuiImage* img) {
{ image = img;
image = img; if(img) img->setParent(this);
if(img) img->setParent(this);
} }
void GuiButton::setImageOver(GuiImage* img) void GuiButton::setImageOver(GuiImage* img) {
{ imageOver = img;
imageOver = img; if(img) img->setParent(this);
if(img) img->setParent(this);
} }
void GuiButton::setImageHold(GuiImage* img) void GuiButton::setImageHold(GuiImage* img) {
{ imageHold = img;
imageHold = img; if(img) img->setParent(this);
if(img) img->setParent(this);
} }
void GuiButton::setImageClick(GuiImage* img) void GuiButton::setImageClick(GuiImage* img) {
{ imageClick = img;
imageClick = img; if(img) img->setParent(this);
if(img) img->setParent(this);
} }
void GuiButton::setIcon(GuiImage* img) void GuiButton::setIcon(GuiImage* img) {
{ icon = img;
icon = img; if(img) img->setParent(this);
if(img) img->setParent(this);
} }
void GuiButton::setIconOver(GuiImage* img) void GuiButton::setIconOver(GuiImage* img) {
{ iconOver = img;
iconOver = img; if(img) img->setParent(this);
if(img) img->setParent(this);
} }
void GuiButton::setLabel(GuiText* txt, s32 n) void GuiButton::setLabel(GuiText* txt, int32_t n) {
{ label[n] = txt;
label[n] = txt; if(txt) txt->setParent(this);
if(txt) txt->setParent(this);
} }
void GuiButton::setLabelOver(GuiText* txt, s32 n) void GuiButton::setLabelOver(GuiText* txt, int32_t n) {
{ labelOver[n] = txt;
labelOver[n] = txt; if(txt) txt->setParent(this);
if(txt) txt->setParent(this);
} }
void GuiButton::setLabelHold(GuiText* txt, s32 n) void GuiButton::setLabelHold(GuiText* txt, int32_t n) {
{ labelHold[n] = txt;
labelHold[n] = txt; if(txt) txt->setParent(this);
if(txt) txt->setParent(this);
} }
void GuiButton::setLabelClick(GuiText* txt, s32 n) void GuiButton::setLabelClick(GuiText* txt, int32_t n) {
{ labelClick[n] = txt;
labelClick[n] = txt; if(txt) txt->setParent(this);
if(txt) txt->setParent(this);
} }
void GuiButton::setSoundOver(GuiSound * snd) void GuiButton::setSoundOver(GuiSound * snd) {
{ soundOver = snd;
soundOver = snd;
} }
void GuiButton::setSoundHold(GuiSound * snd) void GuiButton::setSoundHold(GuiSound * snd) {
{ soundHold = snd;
soundHold = snd;
} }
void GuiButton::setSoundClick(GuiSound * snd) void GuiButton::setSoundClick(GuiSound * snd) {
{ soundClick = snd;
soundClick = snd;
} }
void GuiButton::setTrigger(GuiTrigger * t, s32 idx) void GuiButton::setTrigger(GuiTrigger * t, int32_t idx) {
{ if(idx >= 0 && idx < iMaxGuiTriggers) {
if(idx >= 0 && idx < iMaxGuiTriggers)
{
trigger[idx] = t; trigger[idx] = t;
} } else {
else for(int32_t i = 0; i < iMaxGuiTriggers; i++) {
{ if(!trigger[i]) {
for(s32 i = 0; i < iMaxGuiTriggers; i++)
{
if(!trigger[i])
{
trigger[i] = t; trigger[i] = t;
break; break;
} }
@ -146,9 +123,8 @@ void GuiButton::setTrigger(GuiTrigger * t, s32 idx)
} }
} }
void GuiButton::resetState(void) void GuiButton::resetState(void) {
{ clickedTrigger = NULL;
clickedTrigger = NULL;
heldTrigger = NULL; heldTrigger = NULL;
GuiElement::resetState(); GuiElement::resetState();
} }
@ -156,113 +132,98 @@ void GuiButton::resetState(void)
/** /**
* Draw the button on screen * Draw the button on screen
*/ */
void GuiButton::draw(CVideo *v) void GuiButton::draw(CVideo *v) {
{ if(!this->isVisible())
if(!this->isVisible()) return;
return;
// draw image // draw image
if((isDrawOverOnlyWhenSelected() && (isStateSet(STATE_SELECTED) && imageOver)) || if((isDrawOverOnlyWhenSelected() && (isStateSet(STATE_SELECTED) && imageOver)) ||
(!isDrawOverOnlyWhenSelected() && (isStateSet(STATE_OVER | STATE_SELECTED | STATE_CLICKED | STATE_HELD) && imageOver))) (!isDrawOverOnlyWhenSelected() && (isStateSet(STATE_OVER | STATE_SELECTED | STATE_CLICKED | STATE_HELD) && imageOver)))
imageOver->draw(v); imageOver->draw(v);
else if(image) else if(image)
image->draw(v); image->draw(v);
if((isDrawOverOnlyWhenSelected() && (isStateSet(STATE_SELECTED) && iconOver)) || if((isDrawOverOnlyWhenSelected() && (isStateSet(STATE_SELECTED) && iconOver)) ||
(!isDrawOverOnlyWhenSelected() && (isStateSet(STATE_OVER | STATE_SELECTED | STATE_CLICKED | STATE_HELD) && iconOver))) (!isDrawOverOnlyWhenSelected() && (isStateSet(STATE_OVER | STATE_SELECTED | STATE_CLICKED | STATE_HELD) && iconOver)))
iconOver->draw(v); iconOver->draw(v);
else if(icon) else if(icon)
icon->draw(v); icon->draw(v);
// draw text // draw text
for(s32 i = 0; i < 4; i++) for(int32_t i = 0; i < 4; i++) {
{ if(isStateSet(STATE_OVER | STATE_SELECTED | STATE_CLICKED | STATE_HELD) && labelOver[i])
if(isStateSet(STATE_OVER | STATE_SELECTED | STATE_CLICKED | STATE_HELD) && labelOver[i]) labelOver[i]->draw(v);
labelOver[i]->draw(v); else if(label[i])
else if(label[i]) label[i]->draw(v);
label[i]->draw(v); }
}
} }
void GuiButton::update(GuiController * c) void GuiButton::update(GuiController * c) {
{ if(!c || isStateSet(STATE_DISABLED|STATE_HIDDEN|STATE_DISABLE_INPUT, c->chan))
if(!c || isStateSet(STATE_DISABLED|STATE_HIDDEN|STATE_DISABLE_INPUT, c->chan)) return;
return; else if(parentElement && (parentElement->isStateSet(STATE_DISABLED|STATE_HIDDEN|STATE_DISABLE_INPUT, c->chan)))
else if(parentElement && (parentElement->isStateSet(STATE_DISABLED|STATE_HIDDEN|STATE_DISABLE_INPUT, c->chan))) return;
return;
if(selectable) if(selectable) {
{ if(c->data.validPointer && this->isInside(c->data.x, c->data.y)) {
if(c->data.validPointer && this->isInside(c->data.x, c->data.y)) if(!isStateSet(STATE_OVER, c->chan)) {
{ setState(STATE_OVER, c->chan);
if(!isStateSet(STATE_OVER, c->chan))
{
setState(STATE_OVER, c->chan);
//if(this->isRumbleActive()) //if(this->isRumbleActive())
// this->rumble(t->chan); // this->rumble(t->chan);
if(soundOver) if(soundOver)
soundOver->Play(); soundOver->Play();
if(effectsOver && !effects) if(effectsOver && !effects) {
{ // initiate effects
// initiate effects effects = effectsOver;
effects = effectsOver; effectAmount = effectAmountOver;
effectAmount = effectAmountOver; effectTarget = effectTargetOver;
effectTarget = effectTargetOver; }
}
pointedOn(this, c); pointedOn(this, c);
} }
} } else if(isStateSet(STATE_OVER, c->chan)) {
else if(isStateSet(STATE_OVER, c->chan))
{
this->clearState(STATE_OVER, c->chan); this->clearState(STATE_OVER, c->chan);
pointedOff(this, c); pointedOff(this, c);
if(effectTarget == effectTargetOver && effectAmount == effectAmountOver) if(effectTarget == effectTargetOver && effectAmount == effectAmountOver) {
{ // initiate effects (in reverse)
// initiate effects (in reverse) effects = effectsOver;
effects = effectsOver; effectAmount = -effectAmountOver;
effectAmount = -effectAmountOver; effectTarget = 100;
effectTarget = 100; }
}
} }
} }
for(s32 i = 0; i < iMaxGuiTriggers; i++) for(int32_t i = 0; i < iMaxGuiTriggers; i++) {
{
if(!trigger[i]) if(!trigger[i])
continue; continue;
// button triggers // 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) 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) if(soundClick)
soundClick->Play(); soundClick->Play();
clickedTrigger = trigger[i]; clickedTrigger = trigger[i];
if(!isStateSet(STATE_CLICKED, c->chan)){ if(!isStateSet(STATE_CLICKED, c->chan)) {
if(isClicked == GuiTrigger::CLICKED_TOUCH){ if(isClicked == GuiTrigger::CLICKED_TOUCH) {
setState(STATE_CLICKED_TOUCH, c->chan); setState(STATE_CLICKED_TOUCH, c->chan);
}else{ } else {
setState(STATE_CLICKED, c->chan); setState(STATE_CLICKED, c->chan);
} }
} }
clicked(this, c, trigger[i]); 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))) {
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))) {
{
if((isStateSet(STATE_CLICKED_TOUCH, c->chan) && this->isInside(c->data.x, c->data.y)) || (isStateSet(STATE_CLICKED, c->chan))){
clickedTrigger = NULL; clickedTrigger = NULL;
clearState(STATE_CLICKED, c->chan); clearState(STATE_CLICKED, c->chan);
released(this, c, trigger[i]); released(this, c, trigger[i]);
@ -270,25 +231,20 @@ void GuiButton::update(GuiController * c)
} }
} }
if(holdable) if(holdable) {
{
bool isHeld = trigger[i]->held(c); bool isHeld = trigger[i]->held(c);
if( (!heldTrigger || heldTrigger == trigger[i]) && isHeld 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]; heldTrigger = trigger[i];
if(!isStateSet(STATE_HELD, c->chan)) if(!isStateSet(STATE_HELD, c->chan))
setState(STATE_HELD, c->chan); setState(STATE_HELD, c->chan);
held(this, c, trigger[i]); 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 //! click is removed at this point and converted to held
if(clickedTrigger == trigger[i]) if(clickedTrigger == trigger[i]) {
{
clickedTrigger = NULL; clickedTrigger = NULL;
clearState(STATE_CLICKED, c->chan); 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "GuiCheckBox.h" #include <gui/GuiCheckBox.h>
#include "GuiImage.h" #include <gui/GuiImage.h>
#include "GuiImageData.h" #include <gui/GuiImageData.h>
/** /**
* Constructor for the GuiCheckBox class. * Constructor for the GuiCheckBox class.
*/ */
GuiCheckBox::GuiCheckBox(GuiImage * background, bool checked, f32 width,f32 height) GuiCheckBox::GuiCheckBox(GuiImage * background, bool checked, float width,float height)
: GuiToggle(checked,width,height){ : GuiToggle(checked,width,height) {
setImageBackground(background); setImageBackground(background);
} }
/** /**
* Destructor for the GuiCheckBox class. * Destructor for the GuiCheckBox class.
*/ */
GuiCheckBox::~GuiCheckBox(){ GuiCheckBox::~GuiCheckBox() {
} }
void GuiCheckBox::setImageBackground(GuiImage* img){ void GuiCheckBox::setImageBackground(GuiImage* img) {
backgroundImg = img; backgroundImg = img;
if(img){ img->setParent(this); } if(img) {
img->setParent(this);
}
} }
void GuiCheckBox::setImageSelected(GuiImage* img){ void GuiCheckBox::setImageSelected(GuiImage* img) {
selectedImg = img; selectedImg = img;
if(img){ img->setParent(this); } if(img) {
img->setParent(this);
}
} }
void GuiCheckBox::setImageHighlighted(GuiImage* img){ void GuiCheckBox::setImageHighlighted(GuiImage* img) {
highlightedImg = img; highlightedImg = img;
if(img){ img->setParent(this); } if(img) {
setIconOver(img); img->setParent(this);
}
setIconOver(img);
} }
void GuiCheckBox::update(GuiController * c){ void GuiCheckBox::update(GuiController * c) {
if(bChanged){ if(bChanged) {
if(selected){ if(selected) {
GuiButton::setImage(selectedImg); GuiButton::setImage(selectedImg);
}else{ } else {
GuiButton::setImage(backgroundImg); GuiButton::setImage(backgroundImg);
} }
bChanged = false; bChanged = false;
} }
GuiToggle::update(c); GuiToggle::update(c);
} }

View File

@ -15,44 +15,37 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "GuiDragListener.h" #include <gui/GuiDragListener.h>
#include "GuiController.h" #include <gui/GuiController.h>
#include <utils/logger.h>
/** /**
* Constructor for the GuiDragListener class. * Constructor for the GuiDragListener class.
*/ */
GuiDragListener::GuiDragListener(f32 w,f32 h){ GuiDragListener::GuiDragListener(float w,float h) {
width = w; width = w;
height = h; height = h;
for(s32 i = 0; i < iMaxGuiTriggers; i++) for(int32_t i = 0; i < iMaxGuiTriggers; i++) {
{ trigger[i] = NULL;
trigger[i] = NULL; }
}
} }
/** /**
* Destructor for the GuiDragListener class. * 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); GuiElement::setState(i,c);
} }
void GuiDragListener::setTrigger(GuiTrigger * t, s32 idx){ void GuiDragListener::setTrigger(GuiTrigger * t, int32_t idx) {
if(idx >= 0 && idx < iMaxGuiTriggers) if(idx >= 0 && idx < iMaxGuiTriggers) {
{
trigger[idx] = t; trigger[idx] = t;
} } else {
else for(int32_t i = 0; i < iMaxGuiTriggers; i++) {
{ if(!trigger[i]) {
for(s32 i = 0; i < iMaxGuiTriggers; i++)
{
if(!trigger[i])
{
trigger[i] = t; trigger[i] = t;
break; break;
} }
@ -60,23 +53,23 @@ void GuiDragListener::setTrigger(GuiTrigger * t, s32 idx){
} }
} }
void GuiDragListener::update(GuiController * c){ void GuiDragListener::update(GuiController * c) {
if(!c || isStateSet(STATE_DISABLED|STATE_HIDDEN|STATE_DISABLE_INPUT, c->chan)) if(!c || isStateSet(STATE_DISABLED|STATE_HIDDEN|STATE_DISABLE_INPUT, c->chan))
return; return;
else if(parentElement && (parentElement->isStateSet(STATE_DISABLED|STATE_HIDDEN|STATE_DISABLE_INPUT, c->chan))) else if(parentElement && (parentElement->isStateSet(STATE_DISABLED|STATE_HIDDEN|STATE_DISABLE_INPUT, c->chan)))
return; return;
for(s32 i = 0; i < iMaxGuiTriggers; i++){ for(int32_t i = 0; i < iMaxGuiTriggers; i++) {
if(!trigger[i]){ if(!trigger[i]) {
continue; continue;
} }
bool isHeld = trigger[i]->held(c); bool isHeld = trigger[i]->held(c);
if(isHeld && this->isInside(c->data.x, c->data.y)){ if(isHeld && this->isInside(c->data.x, c->data.y)) {
s32 dx = c->data.x - c->lastData.x; int32_t dx = c->data.x - c->lastData.x;
s32 dy = c->data.y - c->lastData.y; int32_t dy = c->data.y - c->lastData.y;
if(dx == 0 && dy == 0) continue; 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "GuiElement.h" #include <gui/GuiElement.h>
//! TODO remove this! //! TODO remove this!
static s32 screenwidth = 1280; static int32_t screenwidth = 1280;
static s32 screenheight = 720; static int32_t screenheight = 720;
/** /**
* Constructor for the Object class. * Constructor for the Object class.
*/ */
GuiElement::GuiElement() GuiElement::GuiElement() {
{ xoffset = 0.0f;
xoffset = 0.0f; yoffset = 0.0f;
yoffset = 0.0f; zoffset = 0.0f;
zoffset = 0.0f; width = 0.0f;
width = 0.0f; height = 0.0f;
height = 0.0f; alpha = 1.0f;
alpha = 1.0f; scaleX = 1.0f;
scaleX = 1.0f; scaleY = 1.0f;
scaleY = 1.0f; scaleZ = 1.0f;
scaleZ = 1.0f; for(int32_t i = 0; i < 4; i++)
for(s32 i = 0; i < 4; i++)
state[i] = STATE_DEFAULT; state[i] = STATE_DEFAULT;
stateChan = -1; stateChan = -1;
parentElement = NULL; parentElement = NULL;
rumble = true; rumble = true;
selectable = false; selectable = false;
clickable = false; clickable = false;
holdable = false; holdable = false;
drawOverOnlyWhenSelected = false; drawOverOnlyWhenSelected = false;
visible = true; visible = true;
yoffsetDyn = 0; yoffsetDyn = 0;
xoffsetDyn = 0; xoffsetDyn = 0;
alphaDyn = -1; alphaDyn = -1;
scaleDyn = 1; scaleDyn = 1;
effects = EFFECT_NONE; effects = EFFECT_NONE;
effectAmount = 0; effectAmount = 0;
effectTarget = 0; effectTarget = 0;
effectsOver = EFFECT_NONE; effectsOver = EFFECT_NONE;
effectAmountOver = 0; effectAmountOver = 0;
effectTargetOver = 0; effectTargetOver = 0;
angle = 0.0f; angle = 0.0f;
// default alignment - align to top left // default alignment - align to top left
alignment = (ALIGN_CENTER | ALIGN_MIDDLE); alignment = (ALIGN_CENTER | ALIGN_MIDDLE);
} }
/** /**
@ -65,34 +64,29 @@ GuiElement::GuiElement()
* @see SetLeft() * @see SetLeft()
* @return Left position in pixel. * @return Left position in pixel.
*/ */
f32 GuiElement::getLeft() float GuiElement::getLeft() {
{ float pWidth = 0;
f32 pWidth = 0; float pLeft = 0;
f32 pLeft = 0; float pScaleX = 1.0f;
f32 pScaleX = 1.0f;
if(parentElement) if(parentElement) {
{ pWidth = parentElement->getWidth();
pWidth = parentElement->getWidth(); pLeft = parentElement->getLeft();
pLeft = parentElement->getLeft(); pScaleX = parentElement->getScaleX();
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 //! TODO: the conversion from int to float and back to int is bad for performance, change that
if(alignment & ALIGN_CENTER) if(alignment & ALIGN_CENTER) {
{ x = pLeft + pWidth * 0.5f * pScaleX - width * 0.5f * getScaleX();
x = pLeft + pWidth * 0.5f * pScaleX - width * 0.5f * getScaleX(); } else if(alignment & ALIGN_RIGHT) {
} x = pLeft + pWidth * pScaleX - width * 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() * @see SetTop()
* @return Top position in pixel. * @return Top position in pixel.
*/ */
f32 GuiElement::getTop() float GuiElement::getTop() {
{ float pHeight = 0;
f32 pHeight = 0; float pTop = 0;
f32 pTop = 0; float pScaleY = 1.0f;
f32 pScaleY = 1.0f;
if(parentElement) if(parentElement) {
{ pHeight = parentElement->getHeight();
pHeight = parentElement->getHeight(); pTop = parentElement->getTop();
pTop = parentElement->getTop(); pScaleY = parentElement->getScaleY();
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 //! TODO: the conversion from int to float and back to int is bad for performance, change that
if(alignment & ALIGN_MIDDLE) if(alignment & ALIGN_MIDDLE) {
{ y = pTop + pHeight * 0.5f * pScaleY - getHeight() * 0.5f * getScaleY();
y = pTop + pHeight * 0.5f * pScaleY - getHeight() * 0.5f * getScaleY(); } else if(alignment & ALIGN_BOTTOM) {
} y = pTop + pHeight * pScaleY - getHeight() * 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) void GuiElement::setEffect(int32_t eff, int32_t amount, int32_t target) {
{ if(eff & EFFECT_SLIDE_IN) {
if(eff & EFFECT_SLIDE_IN) // these calculations overcompensate a little
{ if(eff & EFFECT_SLIDE_TOP) {
// these calculations overcompensate a little if(eff & EFFECT_SLIDE_FROM)
if(eff & EFFECT_SLIDE_TOP) yoffsetDyn = (int32_t) -getHeight()*scaleY;
{ else
if(eff & EFFECT_SLIDE_FROM) yoffsetDyn = -screenheight;
yoffsetDyn = (s32) -getHeight()*scaleY; } else if(eff & EFFECT_SLIDE_LEFT) {
else if(eff & EFFECT_SLIDE_FROM)
yoffsetDyn = -screenheight; xoffsetDyn = (int32_t) -getWidth()*scaleX;
} else
else if(eff & EFFECT_SLIDE_LEFT) xoffsetDyn = -screenwidth;
{ } else if(eff & EFFECT_SLIDE_BOTTOM) {
if(eff & EFFECT_SLIDE_FROM) if(eff & EFFECT_SLIDE_FROM)
xoffsetDyn = (s32) -getWidth()*scaleX; yoffsetDyn = (int32_t) getHeight()*scaleY;
else else
xoffsetDyn = -screenwidth; yoffsetDyn = screenheight;
} } else if(eff & EFFECT_SLIDE_RIGHT) {
else if(eff & EFFECT_SLIDE_BOTTOM) if(eff & EFFECT_SLIDE_FROM)
{ xoffsetDyn = (int32_t) getWidth()*scaleX;
if(eff & EFFECT_SLIDE_FROM) else
yoffsetDyn = (s32) getHeight()*scaleY; xoffsetDyn = screenwidth;
else }
yoffsetDyn = screenheight; }
} if((eff & EFFECT_FADE) && amount > 0) {
else if(eff & EFFECT_SLIDE_RIGHT) alphaDyn = 0;
{ } else if((eff & EFFECT_FADE) && amount < 0) {
if(eff & EFFECT_SLIDE_FROM) alphaDyn = alpha;
xoffsetDyn = (s32) getWidth()*scaleX; }
else effects |= eff;
xoffsetDyn = screenwidth; effectAmount = amount;
} effectTarget = target;
}
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 //!Sets an effect to be enabled on wiimote cursor over
//!\param e Effect to enable //!\param e Effect to enable
//!\param a Amount of the effect (usage varies on effect) //!\param a Amount of the effect (usage varies on effect)
//!\param t Target 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) void GuiElement::setEffectOnOver(int32_t e, int32_t a, int32_t t) {
{ effectsOver |= e;
effectsOver |= e; effectAmountOver = a;
effectAmountOver = a; effectTargetOver = t;
effectTargetOver = t;
} }
void GuiElement::resetEffects() void GuiElement::resetEffects() {
{ yoffsetDyn = 0;
yoffsetDyn = 0; xoffsetDyn = 0;
xoffsetDyn = 0; alphaDyn = -1;
alphaDyn = -1; scaleDyn = 1;
scaleDyn = 1; effects = EFFECT_NONE;
effects = EFFECT_NONE; effectAmount = 0;
effectAmount = 0; effectTarget = 0;
effectTarget = 0; effectsOver = EFFECT_NONE;
effectsOver = EFFECT_NONE; effectAmountOver = 0;
effectAmountOver = 0; effectTargetOver = 0;
effectTargetOver = 0;
} }
void GuiElement::updateEffects() void GuiElement::updateEffects() {
{ if(!this->isVisible() && parentElement)
if(!this->isVisible() && parentElement) return;
return;
if(effects & (EFFECT_SLIDE_IN | EFFECT_SLIDE_OUT | EFFECT_SLIDE_FROM)) if(effects & (EFFECT_SLIDE_IN | EFFECT_SLIDE_OUT | EFFECT_SLIDE_FROM)) {
{ if(effects & EFFECT_SLIDE_IN) {
if(effects & EFFECT_SLIDE_IN) if(effects & EFFECT_SLIDE_LEFT) {
{ xoffsetDyn += effectAmount;
if(effects & EFFECT_SLIDE_LEFT)
{
xoffsetDyn += effectAmount;
if(xoffsetDyn >= 0) if(xoffsetDyn >= 0) {
{ xoffsetDyn = 0;
xoffsetDyn = 0; effects = 0;
effects = 0;
effectFinished(this); effectFinished(this);
} }
} } else if(effects & EFFECT_SLIDE_RIGHT) {
else if(effects & EFFECT_SLIDE_RIGHT) xoffsetDyn -= effectAmount;
{
xoffsetDyn -= effectAmount;
if(xoffsetDyn <= 0) if(xoffsetDyn <= 0) {
{ xoffsetDyn = 0;
xoffsetDyn = 0; effects = 0;
effects = 0;
effectFinished(this); effectFinished(this);
} }
} } else if(effects & EFFECT_SLIDE_TOP) {
else if(effects & EFFECT_SLIDE_TOP) yoffsetDyn += effectAmount;
{
yoffsetDyn += effectAmount;
if(yoffsetDyn >= 0) if(yoffsetDyn >= 0) {
{ yoffsetDyn = 0;
yoffsetDyn = 0; effects = 0;
effects = 0;
effectFinished(this); effectFinished(this);
} }
} } else if(effects & EFFECT_SLIDE_BOTTOM) {
else if(effects & EFFECT_SLIDE_BOTTOM) yoffsetDyn -= effectAmount;
{
yoffsetDyn -= effectAmount;
if(yoffsetDyn <= 0) if(yoffsetDyn <= 0) {
{ yoffsetDyn = 0;
yoffsetDyn = 0; effects = 0;
effects = 0;
effectFinished(this); effectFinished(this);
} }
} }
} } else {
else if(effects & EFFECT_SLIDE_LEFT) {
{ xoffsetDyn -= effectAmount;
if(effects & EFFECT_SLIDE_LEFT)
{
xoffsetDyn -= effectAmount;
if(xoffsetDyn <= -screenwidth) { if(xoffsetDyn <= -screenwidth) {
effects = 0; // shut off effect effects = 0; // shut off effect
effectFinished(this); effectFinished(this);
} } else if((effects & EFFECT_SLIDE_FROM) && xoffsetDyn <= -getWidth()) {
else if((effects & EFFECT_SLIDE_FROM) && xoffsetDyn <= -getWidth()) { effects = 0; // shut off effect
effects = 0; // shut off effect
effectFinished(this); effectFinished(this);
} }
} } else if(effects & EFFECT_SLIDE_RIGHT) {
else if(effects & EFFECT_SLIDE_RIGHT) xoffsetDyn += effectAmount;
{
xoffsetDyn += effectAmount;
if(xoffsetDyn >= screenwidth) { if(xoffsetDyn >= screenwidth) {
effects = 0; // shut off effect effects = 0; // shut off effect
effectFinished(this); effectFinished(this);
} } else if((effects & EFFECT_SLIDE_FROM) && xoffsetDyn >= getWidth()*scaleX) {
else if((effects & EFFECT_SLIDE_FROM) && xoffsetDyn >= getWidth()*scaleX) { effects = 0; // shut off effect
effects = 0; // shut off effect
effectFinished(this); effectFinished(this);
} }
} } else if(effects & EFFECT_SLIDE_TOP) {
else if(effects & EFFECT_SLIDE_TOP) yoffsetDyn -= effectAmount;
{
yoffsetDyn -= effectAmount;
if(yoffsetDyn <= -screenheight) { if(yoffsetDyn <= -screenheight) {
effects = 0; // shut off effect effects = 0; // shut off effect
effectFinished(this); effectFinished(this);
} } else if((effects & EFFECT_SLIDE_FROM) && yoffsetDyn <= -getHeight()) {
else if((effects & EFFECT_SLIDE_FROM) && yoffsetDyn <= -getHeight()) { effects = 0; // shut off effect
effects = 0; // shut off effect
effectFinished(this); effectFinished(this);
} }
} } else if(effects & EFFECT_SLIDE_BOTTOM) {
else if(effects & EFFECT_SLIDE_BOTTOM) yoffsetDyn += effectAmount;
{
yoffsetDyn += effectAmount;
if(yoffsetDyn >= screenheight) { if(yoffsetDyn >= screenheight) {
effects = 0; // shut off effect effects = 0; // shut off effect
effectFinished(this); effectFinished(this);
} } else if((effects & EFFECT_SLIDE_FROM) && yoffsetDyn >= getHeight()) {
else if((effects & EFFECT_SLIDE_FROM) && yoffsetDyn >= getHeight()) { effects = 0; // shut off effect
effects = 0; // shut off effect
effectFinished(this); effectFinished(this);
} }
} }
} }
} } else if(effects & EFFECT_FADE) {
else if(effects & EFFECT_FADE) alphaDyn += effectAmount * (1.0f / 255.0f);
{
alphaDyn += effectAmount * (1.0f / 255.0f);
if(effectAmount < 0 && alphaDyn <= 0) if(effectAmount < 0 && alphaDyn <= 0) {
{ alphaDyn = 0;
alphaDyn = 0; effects = 0; // shut off effect
effects = 0; // shut off effect effectFinished(this);
effectFinished(this); } else if(effectAmount > 0 && alphaDyn >= alpha) {
} alphaDyn = alpha;
else if(effectAmount > 0 && alphaDyn >= alpha) effects = 0; // shut off effect
{ effectFinished(this);
alphaDyn = alpha; }
effects = 0; // shut off effect } else if(effects & EFFECT_SCALE) {
effectFinished(this); scaleDyn += effectAmount * 0.01f;
}
}
else if(effects & EFFECT_SCALE)
{
scaleDyn += effectAmount * 0.01f;
if((effectAmount < 0 && scaleDyn <= (effectTarget * 0.01f)) if((effectAmount < 0 && scaleDyn <= (effectTarget * 0.01f))
|| (effectAmount > 0 && scaleDyn >= (effectTarget * 0.01f))) || (effectAmount > 0 && scaleDyn >= (effectTarget * 0.01f))) {
{ scaleDyn = effectTarget * 0.01f;
scaleDyn = effectTarget * 0.01f; effects = 0; // shut off effect
effects = 0; // shut off effect effectFinished(this);
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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * 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; parent = p;
width = 0; width = 0;
height = 0; height = 0;
@ -27,8 +26,7 @@ GuiFrame::GuiFrame(GuiFrame *p)
parent->append(this); parent->append(this);
} }
GuiFrame::GuiFrame(f32 w, f32 h, GuiFrame *p) GuiFrame::GuiFrame(float w, float h, GuiFrame *p) {
{
parent = p; parent = p;
width = w; width = w;
height = h; height = h;
@ -38,16 +36,14 @@ GuiFrame::GuiFrame(f32 w, f32 h, GuiFrame *p)
parent->append(this); parent->append(this);
} }
GuiFrame::~GuiFrame() GuiFrame::~GuiFrame() {
{
closing(this); closing(this);
if(parent) if(parent)
parent->remove(this); parent->remove(this);
} }
void GuiFrame::append(GuiElement* e) void GuiFrame::append(GuiElement* e) {
{
if (e == NULL) if (e == NULL)
return; return;
@ -56,8 +52,7 @@ void GuiFrame::append(GuiElement* e)
e->setParent(this); e->setParent(this);
} }
void GuiFrame::insert(GuiElement* e, u32 index) void GuiFrame::insert(GuiElement* e, uint32_t index) {
{
if (e == NULL || (index >= elements.size())) if (e == NULL || (index >= elements.size()))
return; return;
@ -66,96 +61,77 @@ void GuiFrame::insert(GuiElement* e, u32 index)
e->setParent(this); e->setParent(this);
} }
void GuiFrame::remove(GuiElement* e) void GuiFrame::remove(GuiElement* e) {
{
if (e == NULL) if (e == NULL)
return; return;
for (u32 i = 0; i < elements.size(); ++i) for (uint32_t i = 0; i < elements.size(); ++i) {
{ if(e == elements[i]) {
if(e == elements[i])
{
elements.erase(elements.begin()+i); elements.erase(elements.begin()+i);
break; break;
} }
} }
} }
void GuiFrame::removeAll() void GuiFrame::removeAll() {
{
elements.clear(); elements.clear();
} }
void GuiFrame::close() void GuiFrame::close() {
{
//Application::instance()->pushForDelete(this); //Application::instance()->pushForDelete(this);
} }
void GuiFrame::dimBackground(bool d) void GuiFrame::dimBackground(bool d) {
{
dim = d; dim = d;
} }
GuiElement* GuiFrame::getGuiElementAt(u32 index) const GuiElement* GuiFrame::getGuiElementAt(uint32_t index) const {
{
if (index >= elements.size()) if (index >= elements.size())
return NULL; return NULL;
return elements[index]; return elements[index];
} }
u32 GuiFrame::getSize() uint32_t GuiFrame::getSize() {
{
return elements.size(); return elements.size();
} }
void GuiFrame::resetState() void GuiFrame::resetState() {
{
GuiElement::resetState(); GuiElement::resetState();
for (u32 i = 0; i < elements.size(); ++i) for (uint32_t i = 0; i < elements.size(); ++i) {
{
elements[i]->resetState(); elements[i]->resetState();
} }
} }
void GuiFrame::setState(s32 s, s32 c) void GuiFrame::setState(int32_t s, int32_t c) {
{
GuiElement::setState(s, 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); 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); 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); elements[i]->clearState(s, c);
} }
} }
void GuiFrame::setVisible(bool v) void GuiFrame::setVisible(bool v) {
{
visible = v; visible = v;
for (u32 i = 0; i < elements.size(); ++i) for (uint32_t i = 0; i < elements.size(); ++i) {
{
elements[i]->setVisible(v); elements[i]->setVisible(v);
} }
} }
s32 GuiFrame::getSelected() int32_t GuiFrame::getSelected() {
{
// find selected element // find selected element
s32 found = -1; int32_t found = -1;
for (u32 i = 0; i < elements.size(); ++i) for (uint32_t i = 0; i < elements.size(); ++i) {
{ if(elements[i]->isStateSet(STATE_SELECTED | STATE_OVER)) {
if(elements[i]->isStateSet(STATE_SELECTED | STATE_OVER))
{
found = i; found = i;
break; break;
} }
@ -163,68 +139,59 @@ s32 GuiFrame::getSelected()
return found; return found;
} }
void GuiFrame::draw(CVideo * v) void GuiFrame::draw(CVideo * v) {
{
if(!this->isVisible() && parentElement) if(!this->isVisible() && parentElement)
return; return;
if(parentElement && dim == true) if(parentElement && dim == true) {
{
//GXColor dimColor = (GXColor){0, 0, 0, 0x70}; //GXColor dimColor = (GXColor){0, 0, 0, 0x70};
//Menu_DrawRectangle(0, 0, GetZPosition(), screenwidth,screenheight, &dimColor, false, true); //Menu_DrawRectangle(0, 0, GetZPosition(), screenwidth,screenheight, &dimColor, false, true);
} }
//! render appended items next frame but allow stop of render if size is reached //! 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); elements[i]->draw(v);
} }
} }
void GuiFrame::updateEffects() void GuiFrame::updateEffects() {
{
if(!this->isVisible() && parentElement) if(!this->isVisible() && parentElement)
return; return;
GuiElement::updateEffects(); GuiElement::updateEffects();
//! render appended items next frame but allow stop of render if size is reached //! 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(); elements[i]->updateEffects();
} }
} }
void GuiFrame::process() void GuiFrame::process() {
{
if(!this->isVisible() && parentElement) if(!this->isVisible() && parentElement)
return; return;
GuiElement::process(); GuiElement::process();
//! render appended items next frame but allow stop of render if size is reached //! 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(); elements[i]->process();
} }
} }
void GuiFrame::update(GuiController * c) void GuiFrame::update(GuiController * c) {
{
if(isStateSet(STATE_DISABLED) && parentElement) if(isStateSet(STATE_DISABLED) && parentElement)
return; return;
//! update appended items next frame //! 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); 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,48 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "GuiImage.h" #include <gui/GuiImage.h>
#include "video/CVideo.h" #include <gui/video/CVideo.h>
#include "video/shaders/Texture2DShader.h" #include <gui/video/shaders/Texture2DShader.h>
#include "video/shaders/ColorShader.h" #include <gui/video/shaders/ColorShader.h>
#include "utils/utils.h"
static const f32 fPiDiv180 = ((f32)M_PI / 180.0f); static const float fPiDiv180 = ((float)M_PI / 180.0f);
GuiImage::GuiImage(GuiImageData * img) GuiImage::GuiImage(GuiImageData * img) {
{ if(img && img->getTexture()) {
if(img && img->getTexture()) width = img->getWidth();
{ height = img->getHeight();
width = img->getWidth(); }
height = img->getHeight();
}
internalInit(width, height); internalInit(width, height);
imageData = img; imageData = img;
} }
GuiImage::GuiImage(s32 w, s32 h, const GX2Color & c, s32 type) GuiImage::GuiImage(int32_t w, int32_t h, const GX2Color & c, int32_t type) {
{ internalInit(w, h);
internalInit(w, h); imgType = type;
imgType = type; colorCount = ColorShader::cuColorVtxsSize / ColorShader::cuColorAttrSize;
colorCount = ColorShader::cuColorVtxsSize / ColorShader::cuColorAttrSize;
colorVtxs = (u8 *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, colorCount * ColorShader::cuColorAttrSize); colorVtxs = (uint8_t *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, colorCount * ColorShader::cuColorAttrSize);
if(colorVtxs) if(colorVtxs) {
{ for(uint32_t i = 0; i < colorCount; i++)
for(u32 i = 0; i < colorCount; i++)
setImageColor(c, i); setImageColor(c, i);
} }
} }
GuiImage::GuiImage(s32 w, s32 h, const GX2Color *c, u32 color_count, s32 type) GuiImage::GuiImage(int32_t w, int32_t h, const GX2Color *c, uint32_t color_count, int32_t type) {
{ internalInit(w, h);
internalInit(w, h); imgType = type;
imgType = type; colorCount = ColorShader::cuColorVtxsSize / ColorShader::cuColorAttrSize;
colorCount = ColorShader::cuColorVtxsSize / ColorShader::cuColorAttrSize; if(colorCount < color_count)
if(colorCount < color_count)
colorCount = color_count; colorCount = color_count;
colorVtxs = (u8 *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, colorCount * ColorShader::cuColorAttrSize); colorVtxs = (uint8_t *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, colorCount * ColorShader::cuColorAttrSize);
if(colorVtxs) if(colorVtxs) {
{ for(uint32_t i = 0; i < colorCount; i++) {
for(u32 i = 0; i < colorCount; i++)
{
// take the last as reference if not enough colors defined // 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); setImageColor(c[idx], i);
} }
} }
@ -70,29 +64,27 @@ GuiImage::GuiImage(s32 w, s32 h, const GX2Color *c, u32 color_count, s32 type)
/** /**
* Destructor for the GuiImage class. * Destructor for the GuiImage class.
*/ */
GuiImage::~GuiImage() GuiImage::~GuiImage() {
{
if(colorVtxs) { if(colorVtxs) {
free(colorVtxs); free(colorVtxs);
colorVtxs = NULL; colorVtxs = NULL;
} }
} }
void GuiImage::internalInit(s32 w, s32 h) void GuiImage::internalInit(int32_t w, int32_t h) {
{ imageData = NULL;
imageData = NULL; width = w;
width = w; height = h;
height = h; tileHorizontal = -1;
tileHorizontal = -1; tileVertical = -1;
tileVertical = -1; imgType = IMAGE_TEXTURE;
imgType = IMAGE_TEXTURE; colorVtxsDirty = false;
colorVtxsDirty = false; colorVtxs = NULL;
colorVtxs = NULL; colorCount = 0;
colorCount = 0;
posVtxs = NULL; posVtxs = NULL;
texCoords = NULL; texCoords = NULL;
vtxCount = 4; vtxCount = 4;
primitive = GX2_PRIMITIVE_QUADS; primitive = GX2_PRIMITIVE_MODE_QUADS;
imageAngle = 0.0f; imageAngle = 0.0f;
blurDirection = glm::vec3(0.0f); blurDirection = glm::vec3(0.0f);
@ -101,65 +93,58 @@ void GuiImage::internalInit(s32 w, s32 h)
colorIntensity = glm::vec4(1.0f); colorIntensity = glm::vec4(1.0f);
} }
void GuiImage::setImageData(GuiImageData * img) void GuiImage::setImageData(GuiImageData * img) {
{ imageData = img;
imageData = img; width = 0;
width = 0; height = 0;
height = 0; if(img && img->getTexture()) {
if(img && img->getTexture()) width = img->getWidth();
{ height = img->getHeight();
width = img->getWidth(); }
height = img->getHeight(); imgType = IMAGE_TEXTURE;
}
imgType = IMAGE_TEXTURE;
} }
GX2Color GuiImage::getPixel(s32 x, s32 y) GX2Color GuiImage::getPixel(int32_t x, int32_t y) {
{ if(!imageData || this->getWidth() <= 0 || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight())
if(!imageData || this->getWidth() <= 0 || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight()) return (GX2Color) {
return (GX2Color){0, 0, 0, 0}; 0, 0, 0, 0
};
u32 pitch = imageData->getTexture()->surface.pitch; uint32_t pitch = imageData->getTexture()->surface.pitch;
u32 *imagePtr = (u32*)imageData->getTexture()->surface.image_data; 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; GX2Color color;
color.r = (color_u32 >> 24) & 0xFF; color.r = (color_u32 >> 24) & 0xFF;
color.g = (color_u32 >> 16) & 0xFF; color.g = (color_u32 >> 16) & 0xFF;
color.b = (color_u32 >> 8) & 0xFF; color.b = (color_u32 >> 8) & 0xFF;
color.a = (color_u32 >> 0) & 0xFF; color.a = (color_u32 >> 0) & 0xFF;
return color; return color;
} }
void GuiImage::setPixel(s32 x, s32 y, const GX2Color & color) 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())
if(!imageData || this->getWidth() <= 0 || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight()) return;
return;
u32 pitch = imageData->getTexture()->surface.pitch; uint32_t pitch = imageData->getTexture()->surface.pitch;
u32 *imagePtr = (u32*)imageData->getTexture()->surface.image_data; 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); 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) { if(!colorVtxs) {
return; return;
} }
if(idx >= 0 && idx < (s32)colorCount) if(idx >= 0 && idx < (int32_t)colorCount) {
{
colorVtxs[(idx << 2) + 0] = c.r; colorVtxs[(idx << 2) + 0] = c.r;
colorVtxs[(idx << 2) + 1] = c.g; colorVtxs[(idx << 2) + 1] = c.g;
colorVtxs[(idx << 2) + 2] = c.b; colorVtxs[(idx << 2) + 2] = c.b;
colorVtxs[(idx << 2) + 3] = c.a; colorVtxs[(idx << 2) + 3] = c.a;
colorVtxsDirty = true; colorVtxsDirty = true;
} } else if(colorVtxs) {
else if(colorVtxs) for(uint32_t i = 0; i < (ColorShader::cuColorVtxsSize / sizeof(uint8_t)); i += 4) {
{
for(u32 i = 0; i < (ColorShader::cuColorVtxsSize / sizeof(u8)); i += 4)
{
colorVtxs[i + 0] = c.r; colorVtxs[i + 0] = c.r;
colorVtxs[i + 1] = c.g; colorVtxs[i + 1] = c.g;
colorVtxs[i + 2] = c.b; colorVtxs[i + 2] = c.b;
@ -169,27 +154,23 @@ void GuiImage::setImageColor(const GX2Color & c, s32 idx)
} }
} }
void GuiImage::setSize(s32 w, s32 h) void GuiImage::setSize(int32_t w, int32_t h) {
{ width = w;
width = w; height = h;
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; primitive = prim;
vtxCount = vtxcount; vtxCount = vtxcount;
posVtxs = posVtx; posVtxs = posVtx;
texCoords = texCoord; texCoords = texCoord;
if(imgType == IMAGE_COLOR) if(imgType == IMAGE_COLOR) {
{ uint8_t * newColorVtxs = (uint8_t *) memalign(0x40, ColorShader::cuColorAttrSize * vtxCount);
u8 * newColorVtxs = (u8 *) memalign(0x40, ColorShader::cuColorAttrSize * vtxCount);
for(u32 i = 0; i < vtxCount; i++) for(uint32_t i = 0; i < vtxCount; i++) {
{ int32_t newColorIdx = (i << 2);
s32 newColorIdx = (i << 2); int32_t colorIdx = (i < colorCount) ? (newColorIdx) : ((colorCount - 1) << 2);
s32 colorIdx = (i < colorCount) ? (newColorIdx) : ((colorCount - 1) << 2);
newColorVtxs[newColorIdx + 0] = colorVtxs[colorIdx + 0]; newColorVtxs[newColorIdx + 0] = colorVtxs[colorIdx + 0];
newColorVtxs[newColorIdx + 1] = colorVtxs[colorIdx + 1]; newColorVtxs[newColorIdx + 1] = colorVtxs[colorIdx + 1];
@ -204,13 +185,12 @@ void GuiImage::setPrimitiveVertex(s32 prim, const f32 *posVtx, const f32 *texCoo
} }
} }
void GuiImage::draw(CVideo *pVideo) void GuiImage::draw(CVideo *pVideo) {
{ if(!this->isVisible() || tileVertical == 0 || tileHorizontal == 0)
if(!this->isVisible() || tileVertical == 0 || tileHorizontal == 0) return;
return;
f32 currScaleX = getScaleX(); float currScaleX = getScaleX();
f32 currScaleY = getScaleY(); float currScaleY = getScaleY();
positionOffsets[0] = getCenterX() * pVideo->getWidthScaleFactor() * 2.0f; positionOffsets[0] = getCenterX() * pVideo->getWidthScaleFactor() * 2.0f;
positionOffsets[1] = getCenterY() * pVideo->getHeightScaleFactor() * 2.0f; positionOffsets[1] = getCenterY() * pVideo->getHeightScaleFactor() * 2.0f;
@ -228,8 +208,8 @@ void GuiImage::draw(CVideo *pVideo)
// if(image && tileHorizontal > 0 && tileVertical > 0) // if(image && tileHorizontal > 0 && tileVertical > 0)
// { // {
// for(s32 n=0; n<tileVertical; n++) // for(int32_t n=0; n<tileVertical; n++)
// for(s32 i=0; i<tileHorizontal; i++) // for(int32_t i=0; i<tileHorizontal; i++)
// { // {
// if(bUnCut) // if(bUnCut)
// Menu_DrawImg(image, width, height, format, currLeft+width*i, currTop+width*n, currZ, imageangle, currScaleX, currScaleY, currAlpha); // Menu_DrawImg(image, width, height, format, currLeft+width*i, currTop+width*n, currZ, imageangle, currScaleX, currScaleY, currAlpha);
@ -239,9 +219,9 @@ void GuiImage::draw(CVideo *pVideo)
// } // }
// else if(image && tileHorizontal > 0) // 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) // if(bUnCut)
// Menu_DrawImg(image, width, height, format, currLeft+widthTile*i, currTop, currZ, imageangle, currScaleX, currScaleY, currAlpha); // Menu_DrawImg(image, width, height, format, currLeft+widthTile*i, currTop, currZ, imageangle, currScaleX, currScaleY, currAlpha);
// else // else
@ -250,7 +230,7 @@ void GuiImage::draw(CVideo *pVideo)
// } // }
// else if(image && tileVertical > 0) // else if(image && tileVertical > 0)
// { // {
// for(s32 i=0; i<tileVertical; i++) // for(int32_t i=0; i<tileVertical; i++)
// { // {
// if(bUnCut) // if(bUnCut)
// Menu_DrawImg(image, width, height, format, currLeft, currTop+height*i, currZ, imageangle, currScaleX, currScaleY, currAlpha); // Menu_DrawImg(image, width, height, format, currLeft, currTop+height*i, currZ, imageangle, currScaleX, currScaleY, currAlpha);
@ -260,12 +240,11 @@ void GuiImage::draw(CVideo *pVideo)
// } // }
if(colorVtxsDirty && colorVtxs) { if(colorVtxsDirty && colorVtxs) {
//! flush color vertex only on main GX2 thread //! 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; colorVtxsDirty = false;
} }
if(imgType == IMAGE_COLOR && colorVtxs) if(imgType == IMAGE_COLOR && colorVtxs) {
{
ColorShader::instance()->setShaders(); ColorShader::instance()->setShaders();
ColorShader::instance()->setAttributeBuffer(colorVtxs, posVtxs, vtxCount); ColorShader::instance()->setAttributeBuffer(colorVtxs, posVtxs, vtxCount);
ColorShader::instance()->setAngle(imageAngle); ColorShader::instance()->setAngle(imageAngle);
@ -273,9 +252,7 @@ void GuiImage::draw(CVideo *pVideo)
ColorShader::instance()->setScale(scaleFactor); ColorShader::instance()->setScale(scaleFactor);
ColorShader::instance()->setColorIntensity(colorIntensity); ColorShader::instance()->setColorIntensity(colorIntensity);
ColorShader::instance()->draw(primitive, vtxCount); ColorShader::instance()->draw(primitive, vtxCount);
} } else if(imageData) {
else if(imageData)
{
Texture2DShader::instance()->setShaders(); Texture2DShader::instance()->setShaders();
Texture2DShader::instance()->setAttributeBuffer(texCoords, posVtxs, vtxCount); Texture2DShader::instance()->setAttributeBuffer(texCoords, posVtxs, vtxCount);
Texture2DShader::instance()->setAngle(imageAngle); Texture2DShader::instance()->setAngle(imageAngle);
@ -285,5 +262,5 @@ void GuiImage::draw(CVideo *pVideo)
Texture2DShader::instance()->setBlurring(blurDirection); Texture2DShader::instance()->setBlurring(blurDirection);
Texture2DShader::instance()->setTextureAndSampler(imageData->getTexture(), imageData->getSampler()); Texture2DShader::instance()->setTextureAndSampler(imageData->getTexture(), imageData->getSampler());
Texture2DShader::instance()->draw(primitive, vtxCount); Texture2DShader::instance()->draw(primitive, vtxCount);
} }
} }

View File

@ -15,160 +15,137 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include <unistd.h> #include <unistd.h>
#include "GuiImageAsync.h" #include <gui/GuiImageAsync.h>
#include <fs/FSUtils.h> #include "fs/FSUtils.h"
std::vector<GuiImageAsync *> GuiImageAsync::imageQueue; std::vector<GuiImageAsync *> GuiImageAsync::imageQueue;
CThread * GuiImageAsync::pThread = NULL; CThread * GuiImageAsync::pThread = NULL;
CMutex * GuiImageAsync::pMutex = NULL; CMutex * GuiImageAsync::pMutex = NULL;
u32 GuiImageAsync::threadRefCounter = 0; uint32_t GuiImageAsync::threadRefCounter = 0;
bool GuiImageAsync::bExitRequested = false; bool GuiImageAsync::bExitRequested = false;
GuiImageAsync * GuiImageAsync::pInUse = NULL; 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) : GuiImage(preloadImg)
, imgData(NULL) , imgData(NULL)
, imgBuffer(imageBuffer) , imgBuffer(imageBuffer)
, imgBufferSize(imageBufferSize) , imgBufferSize(imageBufferSize) {
{ threadInit();
threadInit(); threadAddImage(this);
threadAddImage(this);
} }
GuiImageAsync::GuiImageAsync(const std::string & file, GuiImageData * preloadImg) GuiImageAsync::GuiImageAsync(const std::string & file, GuiImageData * preloadImg)
: GuiImage(preloadImg) : GuiImage(preloadImg)
, imgData(NULL) , imgData(NULL)
, filename(file) , filename(file)
, imgBuffer(NULL) , imgBuffer(NULL)
, imgBufferSize(0) , imgBufferSize(0) {
{ threadInit();
threadInit(); threadAddImage(this);
threadAddImage(this);
} }
GuiImageAsync::~GuiImageAsync() GuiImageAsync::~GuiImageAsync() {
{ threadRemoveImage(this);
threadRemoveImage(this); while(pInUse == this)
while(pInUse == this) OSSleepTicks(OSMicrosecondsToTicks(1000));
os_usleep(1000);
if (imgData) if (imgData)
delete imgData; delete imgData;
//threadExit(); //threadExit();
} }
void GuiImageAsync::threadAddImage(GuiImageAsync *Image) void GuiImageAsync::threadAddImage(GuiImageAsync *Image) {
{
pMutex->lock(); pMutex->lock();
imageQueue.push_back(Image); imageQueue.push_back(Image);
pMutex->unlock(); pMutex->unlock();
pThread->resumeThread(); pThread->resumeThread();
} }
void GuiImageAsync::threadRemoveImage(GuiImageAsync *image) void GuiImageAsync::threadRemoveImage(GuiImageAsync *image) {
{
pMutex->lock(); pMutex->lock();
for(u32 i = 0; i < imageQueue.size(); ++i) for(uint32_t i = 0; i < imageQueue.size(); ++i) {
{ if(imageQueue[i] == image) {
if(imageQueue[i] == image) imageQueue.erase(imageQueue.begin() + i);
{ break;
imageQueue.erase(imageQueue.begin() + i); }
break; }
}
}
pMutex->unlock(); pMutex->unlock();
} }
void GuiImageAsync::clearQueue() void GuiImageAsync::clearQueue() {
{
pMutex->lock(); pMutex->lock();
imageQueue.clear(); imageQueue.clear();
pMutex->unlock(); pMutex->unlock();
} }
void GuiImageAsync::guiImageAsyncThread(CThread *thread, void *arg) void GuiImageAsync::guiImageAsyncThread(CThread *thread, void *arg) {
{ while(!bExitRequested) {
while(!bExitRequested)
{
if(imageQueue.empty() && !bExitRequested) if(imageQueue.empty() && !bExitRequested)
pThread->suspendThread(); pThread->suspendThread();
if(!imageQueue.empty() && !bExitRequested) if(!imageQueue.empty() && !bExitRequested) {
{
pMutex->lock(); pMutex->lock();
pInUse = imageQueue.front(); pInUse = imageQueue.front();
imageQueue.erase(imageQueue.begin()); imageQueue.erase(imageQueue.begin());
pMutex->unlock(); pMutex->unlock();
if (!pInUse) if (!pInUse)
continue; continue;
if(pInUse->imgBuffer && pInUse->imgBufferSize) if(pInUse->imgBuffer && pInUse->imgBufferSize) {
{
pInUse->imgData = new GuiImageData(pInUse->imgBuffer, pInUse->imgBufferSize); pInUse->imgData = new GuiImageData(pInUse->imgBuffer, pInUse->imgBufferSize);
} } else {
else uint8_t *buffer = NULL;
{ uint32_t bufferSize = 0;
u8 *buffer = NULL;
u32 bufferSize = 0;
s32 iResult = FSUtils::LoadFileToMem(pInUse->filename.c_str(), &buffer, &bufferSize); int32_t iResult = FSUtils::LoadFileToMem(pInUse->filename.c_str(), &buffer, &bufferSize);
if(iResult > 0) if(iResult > 0) {
{ pInUse->imgData = new GuiImageData(buffer, bufferSize, GX2_TEX_CLAMP_MODE_MIRROR);
pInUse->imgData = new GuiImageData(buffer, bufferSize, GX2_TEX_CLAMP_MIRROR);
//! free original image buffer which is converted to texture now and not needed anymore //! free original image buffer which is converted to texture now and not needed anymore
free(buffer); free(buffer);
} }
} }
if(pInUse->imgData) if(pInUse->imgData) {
{ if(pInUse->imgData->getTexture()) {
if(pInUse->imgData->getTexture())
{
pInUse->width = pInUse->imgData->getWidth(); pInUse->width = pInUse->imgData->getWidth();
pInUse->height = pInUse->imgData->getHeight(); pInUse->height = pInUse->imgData->getHeight();
pInUse->imageData = pInUse->imgData; pInUse->imageData = pInUse->imgData;
} } else {
else
{
delete pInUse->imgData; delete pInUse->imgData;
pInUse->imgData = NULL; pInUse->imgData = NULL;
} }
} }
pInUse->imageLoaded(pInUse); pInUse->imageLoaded(pInUse);
pInUse = NULL; pInUse = NULL;
} }
} }
} }
void GuiImageAsync::threadInit() void GuiImageAsync::threadInit() {
{ if (pThread == NULL) {
if (pThread == NULL)
{
bExitRequested = false; bExitRequested = false;
pMutex = new CMutex(); pMutex = new CMutex();
pThread = CThread::create(GuiImageAsync::guiImageAsyncThread, NULL, CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 10); pThread = CThread::create(GuiImageAsync::guiImageAsyncThread, NULL, CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 10);
pThread->resumeThread(); pThread->resumeThread();
} }
++threadRefCounter; ++threadRefCounter;
} }
void GuiImageAsync::threadExit() void GuiImageAsync::threadExit() {
{ if(threadRefCounter) {
if(threadRefCounter){
--threadRefCounter; --threadRefCounter;
} }
if(/*(threadRefCounter == 0) &&*/ (pThread != NULL)) if(/*(threadRefCounter == 0) &&*/ (pThread != NULL)) {
{ bExitRequested = true;
bExitRequested = true;
delete pThread; delete pThread;
delete pMutex; delete pMutex;
pThread = NULL; pThread = NULL;
pMutex = 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 <malloc.h>
#include <string.h> #include <string.h>
#include "GuiImageData.h" #include <stdint.h>
#include <gui/GuiImageData.h>
#include <system/memory.h> #include <system/memory.h>
/** /**
* Constructor for the GuiImageData class. * Constructor for the GuiImageData class.
*/ */
GuiImageData::GuiImageData() GuiImageData::GuiImageData() {
{
texture = NULL; texture = NULL;
sampler = NULL; sampler = NULL;
memoryType = eMemTypeMEM2; memoryType = eMemTypeMEM2;
} }
/** /**
* Constructor for the GuiImageData class. * 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; texture = NULL;
sampler = NULL; sampler = NULL;
loadImage(img, imgSize, textureClamp, textureFormat); loadImage(img, imgSize, textureClamp, textureFormat);
} }
/** /**
* Destructor for the GuiImageData class. * Destructor for the GuiImageData class.
*/ */
GuiImageData::~GuiImageData() GuiImageData::~GuiImageData() {
{
releaseData(); releaseData();
} }
void GuiImageData::releaseData(void) void GuiImageData::releaseData(void) {
{
if(texture) { if(texture) {
if(texture->surface.image_data) if(texture->surface.image) {
{ switch(memoryType) {
switch(memoryType)
{
default: default:
case eMemTypeMEM2: case eMemTypeMEM2:
free(texture->surface.image_data); free(texture->surface.image);
break; break;
case eMemTypeMEM1: case eMemTypeMEM1:
MEM1_free(texture->surface.image_data); MEM1_free(texture->surface.image);
break; break;
case eMemTypeMEMBucket: case eMemTypeMEMBucket:
MEMBucket_free(texture->surface.image_data); MEMBucket_free(texture->surface.image);
break; break;
} }
} }
@ -74,50 +69,43 @@ void GuiImageData::releaseData(void)
} }
} }
void GuiImageData::loadImage(const u8 *img, s32 imgSize, s32 textureClamp, s32 textureFormat) void GuiImageData::loadImage(const uint8_t *img, int32_t imgSize, GX2TexClampMode textureClamp, GX2SurfaceFormat textureFormat) {
{ if(!img || (imgSize < 8))
if(!img || (imgSize < 8)) return;
return;
releaseData(); releaseData();
gdImagePtr gdImg = 0; gdImagePtr gdImg = 0;
if (img[0] == 0xFF && img[1] == 0xD8) if (img[0] == 0xFF && img[1] == 0xD8) {
{ //! not needed for now therefore comment out to safe ELF size
//! not needed for now therefore comment out to safe ELF size //! if needed uncomment, adds 200 kb to the ELF size
//! if needed uncomment, adds 200 kb to the ELF size // IMAGE_JPEG
// IMAGE_JPEG //gdImg = gdImageCreateFromJpegPtr(imgSize, (uint8_t*) img);
gdImg = gdImageCreateFromJpegPtr(imgSize, (u8*) img); } else if (img[0] == 'B' && img[1] == 'M') {
} // IMAGE_BMP
else if (img[0] == 'B' && img[1] == 'M') //gdImg = gdImageCreateFromBmpPtr(imgSize, (uint8_t*) img);
{ } else if (img[0] == 0x89 && img[1] == 'P' && img[2] == 'N' && img[3] == 'G') {
// IMAGE_BMP // IMAGE_PNG
gdImg = gdImageCreateFromBmpPtr(imgSize, (u8*) img); gdImg = gdImageCreateFromPngPtr(imgSize, (uint8_t*) img);
} }
else if (img[0] == 0x89 && img[1] == 'P' && img[2] == 'N' && img[3] == 'G') //!This must be last since it can also intefere with outher formats
{ else if(img[0] == 0x00) {
// IMAGE_PNG // Try loading TGA image
gdImg = gdImageCreateFromPngPtr(imgSize, (u8*) img); //gdImg = gdImageCreateFromTgaPtr(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, (u8*) img);
}
if(gdImg == 0) if(gdImg == 0)
return; return;
u32 width = (gdImageSX(gdImg)); uint32_t width = (gdImageSX(gdImg));
u32 height = (gdImageSY(gdImg)); uint32_t height = (gdImageSY(gdImg));
//! Initialize texture //! Initialize texture
texture = new GX2Texture; 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 this fails something went horribly wrong
if(texture->surface.image_size == 0) { if(texture->surface.imageSize == 0) {
delete texture; delete texture;
texture = NULL; texture = NULL;
gdImageDestroy(gdImg); gdImageDestroy(gdImg);
@ -125,63 +113,59 @@ void GuiImageData::loadImage(const u8 *img, s32 imgSize, s32 textureClamp, s32 t
} }
//! allocate memory for the surface //! allocate memory for the surface
memoryType = eMemTypeMEM2; memoryType = eMemTypeMEM2;
texture->surface.image_data = memalign(texture->surface.align, texture->surface.image_size); texture->surface.image = memalign(texture->surface.alignment, texture->surface.imageSize);
//! try MEM1 on failure //! try MEM1 on failure
if(!texture->surface.image_data) { if(!texture->surface.image) {
memoryType = eMemTypeMEM1; 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 //! try MEM bucket on failure
if(!texture->surface.image_data) { if(!texture->surface.image) {
memoryType = eMemTypeMEMBucket; 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 //! check if memory is available for image
if(!texture->surface.image_data) { if(!texture->surface.image) {
gdImageDestroy(gdImg); gdImageDestroy(gdImg);
delete texture; delete texture;
texture = NULL; texture = NULL;
return; return;
} }
//! set mip map data pointer //! set mip map data pointer
texture->surface.mip_data = NULL; texture->surface.mipmaps = NULL;
//! convert image to texture //! convert image to texture
switch(textureFormat) switch(textureFormat) {
{
default: default:
case GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM: case GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8:
gdImageToUnormR8G8B8A8(gdImg, (u32*)texture->surface.image_data, texture->surface.width, texture->surface.height, texture->surface.pitch); gdImageToUnormR8G8B8A8(gdImg, (uint32_t*)texture->surface.image, texture->surface.width, texture->surface.height, texture->surface.pitch);
break; break;
case GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM: case GX2_SURFACE_FORMAT_UNORM_R5_G6_B5:
gdImageToUnormR5G6B5(gdImg, (u16*)texture->surface.image_data, texture->surface.width, texture->surface.height, texture->surface.pitch); gdImageToUnormR5G6B5(gdImg, (uint16_t*)texture->surface.image, texture->surface.width, texture->surface.height, texture->surface.pitch);
break; break;
} }
//! free memory of image as its not needed anymore //! free memory of image as its not needed anymore
gdImageDestroy(gdImg); gdImageDestroy(gdImg);
//! invalidate the memory //! invalidate the memory
GX2Invalidate(GX2_INVALIDATE_CPU_TEXTURE, texture->surface.image_data, texture->surface.image_size); GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, texture->surface.image, texture->surface.imageSize);
//! initialize the sampler //! initialize the sampler
sampler = new GX2Sampler; 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) 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(u32 y = 0; y < height; ++y) for(uint32_t x = 0; x < width; ++x) {
{ uint32_t pixel = gdImageGetPixel(gdImg, x, y);
for(u32 x = 0; x < width; ++x)
{
u32 pixel = gdImageGetPixel(gdImg, x, y);
u8 a = 254 - 2*((u8)gdImageAlpha(gdImg, pixel)); uint8_t a = 254 - 2*((uint8_t)gdImageAlpha(gdImg, pixel));
if(a == 254) a++; if(a == 254) a++;
u8 r = gdImageRed(gdImg, pixel); uint8_t r = gdImageRed(gdImg, pixel);
u8 g = gdImageGreen(gdImg, pixel); uint8_t g = gdImageGreen(gdImg, pixel);
u8 b = gdImageBlue(gdImg, pixel); uint8_t b = gdImageBlue(gdImg, pixel);
imgBuffer[y * pitch + x] = (r << 24) | (g << 16) | (b << 8) | (a); 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 //! TODO: figure out why this seems to not work correct yet
void GuiImageData::gdImageToUnormR5G6B5(gdImagePtr gdImg, u16 *imgBuffer, u32 width, u32 height, u32 pitch) 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(u32 y = 0; y < height; ++y) for(uint32_t x = 0; x < width; ++x) {
{ uint32_t pixel = gdImageGetPixel(gdImg, x, y);
for(u32 x = 0; x < width; ++x)
{
u32 pixel = gdImageGetPixel(gdImg, x, y);
u8 r = gdImageRed(gdImg, pixel); uint8_t r = gdImageRed(gdImg, pixel);
u8 g = gdImageGreen(gdImg, pixel); uint8_t g = gdImageGreen(gdImg, pixel);
u8 b = gdImageBlue(gdImg, pixel); uint8_t b = gdImageBlue(gdImg, pixel);
imgBuffer[y * pitch + x] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); imgBuffer[y * pitch + x] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
} }

View File

@ -14,38 +14,35 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "GuiParticleImage.h" #include <gui/GuiParticleImage.h>
#include "video/CVideo.h" #include <gui/video/CVideo.h>
#include "video/shaders/ColorShader.h" #include <gui/video/shaders/ColorShader.h>
#include "utils/utils.h"
#define CIRCLE_VERTEX_COUNT 36 #define CIRCLE_VERTEX_COUNT 36
static inline f32 getRandZeroToOneF32() static inline float getRandZeroToOneF32() {
{
return (rand() % 10000) * 0.0001f; return (rand() % 10000) * 0.0001f;
} }
static inline f32 getRandMinusOneToOneF32() static inline float getRandMinusOneToOneF32() {
{
return getRandZeroToOneF32() * 2.0f - 1.0f; return getRandZeroToOneF32() * 2.0f - 1.0f;
} }
GuiParticleImage::GuiParticleImage(s32 w, s32 h, u32 particleCount, f32 minRadius, f32 maxRadius, f32 minSpeed, f32 maxSpeed) GuiParticleImage::GuiParticleImage(int32_t w, int32_t h, uint32_t particleCount, float minRadius, float maxRadius, float minSpeed, float maxSpeed)
: GuiImage(NULL) : GuiImage(NULL) {
{
width = w; width = w;
height = h; height = h;
imgType = IMAGE_COLOR; imgType = IMAGE_COLOR;
this->minRadius = minRadius; this->minRadius = minRadius;
this->maxRadius = maxRadius; this->maxRadius = maxRadius;
this->minSpeed = minSpeed; this->minSpeed = minSpeed;
this->maxSpeed = maxSpeed; this->maxSpeed = maxSpeed;
posVertexs = (f32 *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ColorShader::cuVertexAttrSize * CIRCLE_VERTEX_COUNT); posVertexs = (float *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ColorShader::cuVertexAttrSize * CIRCLE_VERTEX_COUNT);
colorVertexs = (u8 *) memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ColorShader::cuColorAttrSize * 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 + 0] = cosf(DegToRad(i * 360.0f / CIRCLE_VERTEX_COUNT));
posVertexs[i * 3 + 1] = sinf(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; posVertexs[i * 3 + 2] = 0.0f;
@ -55,13 +52,12 @@ GuiParticleImage::GuiParticleImage(s32 w, s32 h, u32 particleCount, f32 minRadiu
colorVertexs[i * 4 + 2] = 0xff; colorVertexs[i * 4 + 2] = 0xff;
colorVertexs[i * 4 + 3] = 0xff; colorVertexs[i * 4 + 3] = 0xff;
} }
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, posVertexs, ColorShader::cuVertexAttrSize * CIRCLE_VERTEX_COUNT); GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_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, colorVertexs, ColorShader::cuColorAttrSize * CIRCLE_VERTEX_COUNT);
particles.resize(particleCount); 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.x = getRandMinusOneToOneF32() * getWidth() * 0.5f;
particles[i].position.y = getRandMinusOneToOneF32() * getHeight() * 0.5f; particles[i].position.y = getRandMinusOneToOneF32() * getHeight() * 0.5f;
particles[i].position.z = 0.0f; particles[i].position.z = 0.0f;
@ -72,20 +68,18 @@ GuiParticleImage::GuiParticleImage(s32 w, s32 h, u32 particleCount, f32 minRadiu
} }
} }
GuiParticleImage::~GuiParticleImage() GuiParticleImage::~GuiParticleImage() {
{
free(posVertexs); free(posVertexs);
free(colorVertexs); free(colorVertexs);
} }
void GuiParticleImage::draw(CVideo *pVideo) void GuiParticleImage::draw(CVideo *pVideo) {
{ if(!this->isVisible())
if(!this->isVisible()) return;
return;
f32 currScaleX = getScaleX(); float currScaleX = getScaleX();
f32 currScaleY = getScaleY(); float currScaleY = getScaleY();
positionOffsets[2] = getDepth() * pVideo->getDepthScaleFactor() * 2.0f; positionOffsets[2] = getDepth() * pVideo->getDepthScaleFactor() * 2.0f;
@ -94,10 +88,8 @@ void GuiParticleImage::draw(CVideo *pVideo)
//! add other colors intensities parameters //! add other colors intensities parameters
colorIntensity[3] = getAlpha(); colorIntensity[3] = getAlpha();
for(u32 i = 0; i < particles.size(); ++i) for(uint32_t i = 0; i < particles.size(); ++i) {
{ if(particles[i].position.y > (getHeight() * 0.5f + 30.0f)) {
if(particles[i].position.y > (getHeight() * 0.5f + 30.0f))
{
particles[i].position.x = getRandMinusOneToOneF32() * getWidth() * 0.5f; particles[i].position.x = getRandMinusOneToOneF32() * getWidth() * 0.5f;
particles[i].position.y = -getHeight() * 0.5f - 30.0f; particles[i].position.y = -getHeight() * 0.5f - 30.0f;
particles[i].colors = glm::vec4(1.0f, 1.0f, 1.0f, (getRandZeroToOneF32() * 0.6f) + 0.05f); particles[i].colors = glm::vec4(1.0f, 1.0f, 1.0f, (getRandZeroToOneF32() * 0.6f) + 0.05f);
@ -105,8 +97,7 @@ void GuiParticleImage::draw(CVideo *pVideo)
particles[i].speed = (getRandZeroToOneF32() * (maxSpeed - minSpeed)) + minSpeed; particles[i].speed = (getRandZeroToOneF32() * (maxSpeed - minSpeed)) + minSpeed;
particles[i].direction = getRandMinusOneToOneF32(); 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; particles[i].position.x = -particles[i].position.x;
} }
@ -127,6 +118,6 @@ void GuiParticleImage::draw(CVideo *pVideo)
ColorShader::instance()->setOffset(positionOffsets); ColorShader::instance()->setOffset(positionOffsets);
ColorShader::instance()->setScale(scaleFactor); ColorShader::instance()->setScale(scaleFactor);
ColorShader::instance()->setColorIntensity(colorIntensity * particles[i].colors); 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,168 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
***************************************************************************/ ***************************************************************************/
#include "GuiScrollbar.h" #include <gui/GuiScrollbar.h>
#include "resources/Resources.h" #include <gui/resources/Resources.h>
#include "utils/utils.h"
GuiScrollbar::GuiScrollbar(s32 h) GuiScrollbar::GuiScrollbar(int32_t h)
: touchTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::VPAD_TOUCH) : touchTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::VPAD_TOUCH)
, wpadTouchTrigger(GuiTrigger::CHANNEL_2 | GuiTrigger::CHANNEL_3 | GuiTrigger::CHANNEL_4 | GuiTrigger::CHANNEL_5, GuiTrigger::BUTTON_A) , wpadTouchTrigger(GuiTrigger::CHANNEL_2 | GuiTrigger::CHANNEL_3 | GuiTrigger::CHANNEL_4 | GuiTrigger::CHANNEL_5, GuiTrigger::BUTTON_A) {
{ SelItem = 0;
SelItem = 0; SelInd = 0;
SelInd = 0; PageSize = 0;
PageSize = 0; EntrieCount = 0;
EntrieCount = 0; SetScrollSpeed(15);
SetScrollSpeed(15); ScrollState = 0;
ScrollState = 0;
listChanged.connect(this, &GuiScrollbar::setScrollboxPosition); listChanged.connect(this, &GuiScrollbar::setScrollboxPosition);
height = h; height = h;
arrowUpBtn = new GuiButton(50, 50); arrowUpBtn = new GuiButton(50, 50);
arrowUpBtn->setParent(this); arrowUpBtn->setParent(this);
arrowUpBtn->setAlignment(ALIGN_CENTER | ALIGN_TOP); arrowUpBtn->setAlignment(ALIGN_CENTER | ALIGN_TOP);
arrowUpBtn->setPosition(0, 0); arrowUpBtn->setPosition(0, 0);
arrowUpBtn->setTrigger(&touchTrigger, 0); arrowUpBtn->setTrigger(&touchTrigger, 0);
arrowUpBtn->setTrigger(&wpadTouchTrigger, 1); arrowUpBtn->setTrigger(&wpadTouchTrigger, 1);
arrowUpBtn->setEffectGrow(); arrowUpBtn->setEffectGrow();
arrowUpBtn->clicked.connect(this, &GuiScrollbar::OnUpButtonClick); arrowUpBtn->clicked.connect(this, &GuiScrollbar::OnUpButtonClick);
arrowDownBtn = new GuiButton(50, 50); arrowDownBtn = new GuiButton(50, 50);
arrowDownBtn->setParent(this); arrowDownBtn->setParent(this);
arrowDownBtn->setAlignment(ALIGN_CENTER | ALIGN_BOTTOM); arrowDownBtn->setAlignment(ALIGN_CENTER | ALIGN_BOTTOM);
arrowDownBtn->setPosition(0, 0); arrowDownBtn->setPosition(0, 0);
arrowDownBtn->setTrigger(&touchTrigger, 0); arrowDownBtn->setTrigger(&touchTrigger, 0);
arrowDownBtn->setTrigger(&wpadTouchTrigger, 1); arrowDownBtn->setTrigger(&wpadTouchTrigger, 1);
arrowDownBtn->setEffectGrow(); arrowDownBtn->setEffectGrow();
arrowDownBtn->clicked.connect(this, &GuiScrollbar::OnDownButtonClick); arrowDownBtn->clicked.connect(this, &GuiScrollbar::OnDownButtonClick);
scrollbarBoxBtn = new GuiButton(50, height); scrollbarBoxBtn = new GuiButton(50, height);
scrollbarBoxBtn->setParent(this); scrollbarBoxBtn->setParent(this);
scrollbarBoxBtn->setAlignment(ALIGN_CENTER | ALIGN_TOP); scrollbarBoxBtn->setAlignment(ALIGN_CENTER | ALIGN_TOP);
scrollbarBoxBtn->setPosition(0, MaxHeight); scrollbarBoxBtn->setPosition(0, MaxHeight);
scrollbarBoxBtn->setHoldable(true); scrollbarBoxBtn->setHoldable(true);
scrollbarBoxBtn->setTrigger(&touchTrigger, 0); scrollbarBoxBtn->setTrigger(&touchTrigger, 0);
scrollbarBoxBtn->setTrigger(&wpadTouchTrigger, 1); scrollbarBoxBtn->setTrigger(&wpadTouchTrigger, 1);
scrollbarBoxBtn->setEffectGrow(); scrollbarBoxBtn->setEffectGrow();
scrollbarBoxBtn->held.connect(this, &GuiScrollbar::OnBoxButtonHold); scrollbarBoxBtn->held.connect(this, &GuiScrollbar::OnBoxButtonHold);
} }
GuiScrollbar::~GuiScrollbar() GuiScrollbar::~GuiScrollbar() {
{ delete arrowUpBtn;
delete arrowUpBtn; delete arrowDownBtn;
delete arrowDownBtn; delete scrollbarBoxBtn;
delete scrollbarBoxBtn;
} }
void GuiScrollbar::ScrollOneUp() void GuiScrollbar::ScrollOneUp() {
{ if(SelItem == 0 && SelInd > 0) {
if(SelItem == 0 && SelInd > 0)
{
// move list up by 1 // move list up by 1
--SelInd; --SelInd;
} } else if(SelInd+SelItem > 0) {
else if(SelInd+SelItem > 0)
{
--SelItem; --SelItem;
} }
} }
void GuiScrollbar::ScrollOneDown() void GuiScrollbar::ScrollOneDown() {
{ if(SelInd+SelItem + 1 < EntrieCount) {
if(SelInd+SelItem + 1 < EntrieCount) if(SelItem == PageSize-1) {
{
if(SelItem == PageSize-1)
{
// move list down by 1 // move list down by 1
SelInd++; SelInd++;
} } else {
else
{
SelItem++; SelItem++;
} }
} }
} }
void GuiScrollbar::OnUpButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) void GuiScrollbar::OnUpButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
{ if(ScrollState < ScrollSpeed)
if(ScrollState < ScrollSpeed) return;
return;
ScrollOneUp(); ScrollOneUp();
ScrollState = 0; ScrollState = 0;
listChanged(SelItem, SelInd); listChanged(SelItem, SelInd);
} }
void GuiScrollbar::OnDownButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) void GuiScrollbar::OnDownButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
{ if(ScrollState < ScrollSpeed)
if(ScrollState < ScrollSpeed) return;
return;
ScrollOneDown(); ScrollOneDown();
ScrollState = 0; ScrollState = 0;
listChanged(SelItem, SelInd); listChanged(SelItem, SelInd);
} }
void GuiScrollbar::OnBoxButtonHold(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) void GuiScrollbar::OnBoxButtonHold(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
{ if(EntrieCount == 0) {
if(EntrieCount == 0){
return; return;
} }
if(!controller->data.validPointer){ if(!controller->data.validPointer) {
return; 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; SelItem = 0;
SelInd = 0; SelInd = 0;
} } else if(newSelected >= EntrieCount-1) {
else if(newSelected >= EntrieCount-1)
{
SelItem = (PageSize-1 < EntrieCount-1) ? PageSize-1 : EntrieCount-1; SelItem = (PageSize-1 < EntrieCount-1) ? PageSize-1 : EntrieCount-1;
SelInd = EntrieCount-PageSize; SelInd = EntrieCount-PageSize;
} } else if(newSelected < PageSize && SelInd == 0 && 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::max(SelItem+diff, (s32)0);
}
else if(EntrieCount-newSelected < PageSize && SelInd == EntrieCount-PageSize && diff > 0)
{
SelItem = std::min(SelItem+diff, PageSize-1); SelItem = std::min(SelItem+diff, PageSize-1);
} } else {
else
{
SelInd = LIMIT(SelInd+diff, 0, ((EntrieCount-PageSize < 0) ? 0 : EntrieCount-PageSize)); SelInd = LIMIT(SelInd+diff, 0, ((EntrieCount-PageSize < 0) ? 0 : EntrieCount-PageSize));
} }
ScrollState = 0; ScrollState = 0;
listChanged(SelItem, SelInd); listChanged(SelItem, SelInd);
} }
void GuiScrollbar::SetPageSize(s32 size) void GuiScrollbar::SetPageSize(int32_t size) {
{ if(PageSize == size)
if(PageSize == size) return;
return;
PageSize = size; PageSize = size;
listChanged(SelItem, SelInd); listChanged(SelItem, SelInd);
} }
void GuiScrollbar::SetSelectedItem(s32 pos) void GuiScrollbar::SetSelectedItem(int32_t pos) {
{ if(SelItem == pos)
if(SelItem == pos) return;
return;
SelItem = LIMIT(pos, 0, EntrieCount-1); SelItem = LIMIT(pos, 0, EntrieCount-1);
listChanged(SelItem, SelInd); listChanged(SelItem, SelInd);
} }
void GuiScrollbar::SetSelectedIndex(s32 pos) void GuiScrollbar::SetSelectedIndex(int32_t pos) {
{ if(SelInd == pos)
if(SelInd == pos) return;
return;
SelInd = pos; SelInd = pos;
listChanged(SelItem, SelInd); listChanged(SelItem, SelInd);
} }
void GuiScrollbar::SetEntrieCount(s32 cnt) void GuiScrollbar::SetEntrieCount(int32_t cnt) {
{ if(EntrieCount == cnt)
if(EntrieCount == cnt) return;
return;
EntrieCount = cnt; EntrieCount = cnt;
listChanged(SelItem, SelInd); listChanged(SelItem, SelInd);
} }
void GuiScrollbar::setScrollboxPosition(s32 SelItem, s32 SelInd) void GuiScrollbar::setScrollboxPosition(int32_t SelItem, int32_t SelInd) {
{ int32_t position = MaxHeight-(MaxHeight-MinHeight)*(SelInd+SelItem)/(EntrieCount-1);
s32 position = MaxHeight-(MaxHeight-MinHeight)*(SelInd+SelItem)/(EntrieCount-1);
if(position < MinHeight || (SelInd+SelItem >= EntrieCount-1)) if(position < MinHeight || (SelInd+SelItem >= EntrieCount-1))
position = MinHeight; position = MinHeight;
@ -219,25 +192,25 @@ void GuiScrollbar::setScrollboxPosition(s32 SelItem, s32 SelInd)
scrollbarBoxBtn->setPosition(0, position); scrollbarBoxBtn->setPosition(0, position);
} }
void GuiScrollbar::draw(CVideo * video) void GuiScrollbar::draw(CVideo * video) {
{ if(scrollbarLineImage) {
if(scrollbarLineImage){ scrollbarLineImage->draw(video); } scrollbarLineImage->draw(video);
arrowUpBtn->draw(video); }
arrowDownBtn->draw(video); arrowUpBtn->draw(video);
scrollbarBoxBtn->draw(video); arrowDownBtn->draw(video);
scrollbarBoxBtn->draw(video);
updateEffects(); updateEffects();
} }
void GuiScrollbar::update(GuiController * t) void GuiScrollbar::update(GuiController * t) {
{ if(this->isStateSet(STATE_DISABLED))
if(this->isStateSet(STATE_DISABLED)) return;
return;
arrowUpBtn->update(t); arrowUpBtn->update(t);
arrowDownBtn->update(t); arrowDownBtn->update(t);
scrollbarBoxBtn->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

@ -16,31 +16,28 @@
****************************************************************************/ ****************************************************************************/
#include <vector> #include <vector>
#include <string> #include <string>
#include <utils/StringTools.h>
#include <utils/logger.h>
#include "GuiSelectBox.h" #include <gui/GuiSelectBox.h>
#include "GuiImage.h" #include <gui/GuiImage.h>
#include "GuiTrigger.h" #include <gui/GuiTrigger.h>
#include "GuiImageData.h" #include <gui/GuiImageData.h>
/** /**
* Constructor for the GuiCheckBox class. * Constructor for the GuiCheckBox class.
*/ */
GuiSelectBox::GuiSelectBox(GuiImage * background,std::string caption,f32 width,f32 height,GuiFrame *parent) GuiSelectBox::GuiSelectBox(GuiImage * background,std::string caption,float width,float height,GuiFrame *parent)
: GuiFrame(width,height,parent) : GuiFrame(width,height,parent)
,selected(0) ,selected(0)
,captionText(caption) ,captionText(caption)
,topValueButton(0,0) ,topValueButton(0,0)
,touchTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::VPAD_TOUCH) ,touchTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::VPAD_TOUCH)
,wpadTouchTrigger(GuiTrigger::CHANNEL_2 | GuiTrigger::CHANNEL_3 | GuiTrigger::CHANNEL_4 | GuiTrigger::CHANNEL_5, GuiTrigger::BUTTON_A) ,wpadTouchTrigger(GuiTrigger::CHANNEL_2 | GuiTrigger::CHANNEL_3 | GuiTrigger::CHANNEL_4 | GuiTrigger::CHANNEL_5, GuiTrigger::BUTTON_A)
,buttonATrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_A, true) ,buttonATrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_A, true)
,buttonBTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_B, true) ,buttonBTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_B, true)
,buttonUpTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_UP | GuiTrigger::STICK_L_UP, 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) ,buttonDownTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_DOWN | GuiTrigger::STICK_L_DOWN, true)
,DPADButtons(0,0) ,DPADButtons(0,0) {
{
setImageTopBackground(background); setImageTopBackground(background);
showValues = false; showValues = false;
bChanged = false; bChanged = false;
@ -71,23 +68,23 @@ GuiSelectBox::GuiSelectBox(GuiImage * background,std::string caption,f32 width,f
bChanged = true; bChanged = true;
} }
void GuiSelectBox::setSize(f32 width,f32 height){ void GuiSelectBox::setSize(float width,float height) {
GuiFrame::setSize(width,height); GuiFrame::setSize(width,height);
topValueButton.setSize(width,height); topValueButton.setSize(width,height);
} }
void GuiSelectBox::OnValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger){ void GuiSelectBox::OnValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
for(u32 i = 0; i < valueButtons.size(); ++i){ for(uint32_t i = 0; i < valueButtons.size(); ++i) {
if(valueButtons[i].valueButton == button){ if(valueButtons[i].valueButton == button) {
selected = i; selected = i;
SelectValue(i); SelectValue(i);
break; break;
}
} }
}
} }
void GuiSelectBox::SelectValue(u32 value){ void GuiSelectBox::SelectValue(uint32_t value) {
if(value < valueButtons.size()){ if(value < valueButtons.size()) {
const wchar_t* w_text = valueButtons[value].valueButtonText->getText(); const wchar_t* w_text = valueButtons[value].valueButtonText->getText();
std::wstring ws(w_text); std::wstring ws(w_text);
std::string text(ws.begin(), ws.end()); std::string text(ws.begin(), ws.end());
@ -101,40 +98,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); ShowHideValues(!showValues);
} }
void GuiSelectBox::ShowHideValues(bool showhide) void GuiSelectBox::ShowHideValues(bool showhide) {
{
showValues = showhide; showValues = showhide;
bChanged = true; bChanged = true;
} }
void GuiSelectBox::OnDPADClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) void GuiSelectBox::OnDPADClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
{ if(opened == true) {
if(opened == true){ if(trigger == &buttonATrigger) {
if(trigger == &buttonATrigger)
{
//! do not auto launch when wiimote is pointing to screen and presses A //! 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; return;
} }
SelectValue(selected); SelectValue(selected);
} } else if(trigger == &buttonBTrigger) {
else if(trigger == &buttonBTrigger) if(button == &DPADButtons) {
{
if(button == &DPADButtons){
ShowHideValues(false); ShowHideValues(false);
}else{ } else {
} }
}else if(trigger == &buttonUpTrigger){ } else if(trigger == &buttonUpTrigger) {
if(selected > 0 ) selected--; if(selected > 0 ) selected--;
bSelectedChanged = true; bSelectedChanged = true;
} } else if(trigger == &buttonDownTrigger) {
else if(trigger == &buttonDownTrigger){
selected++; selected++;
if(selected >= valueButtons.size()) selected = valueButtons.size() - 1; if(selected >= valueButtons.size()) selected = valueButtons.size() - 1;
bSelectedChanged = true; bSelectedChanged = true;
@ -142,9 +131,8 @@ void GuiSelectBox::OnDPADClick(GuiButton *button, const GuiController *controlle
} }
} }
void GuiSelectBox::Init(std::map<std::string,std::string> values, s32 valueID) void GuiSelectBox::Init(std::map<std::string,std::string> values, int32_t valueID) {
{ if((uint32_t)valueID >= values.size()) {
if((u32)valueID >= values.size()){
valueID = 0; valueID = 0;
} }
@ -153,17 +141,17 @@ void GuiSelectBox::Init(std::map<std::string,std::string> values, s32 valueID)
DeleteValueData(); DeleteValueData();
if(valueImageData == NULL || valueSelectedImageData == NULL || valueHighlightedImageData == NULL){ if(valueImageData == NULL || valueSelectedImageData == NULL || valueHighlightedImageData == NULL) {
return; return;
} }
valueButtons.resize(values.size()); valueButtons.resize(values.size());
s32 i = 0; int32_t i = 0;
f32 imgScale = 1.0f; float imgScale = 1.0f;
std::map<std::string, std::string>::iterator itr; std::map<std::string, std::string>::iterator itr;
for(itr = values.begin(); itr != values.end(); itr++) { for(itr = values.begin(); itr != values.end(); itr++) {
if(i == valueID){ if(i == valueID) {
topValueText.setText(itr->first.c_str()); topValueText.setText(itr->first.c_str());
} }
@ -192,12 +180,12 @@ void GuiSelectBox::Init(std::map<std::string,std::string> values, s32 valueID)
buttonToValue[valueButtons[i].valueButton] = itr->second; buttonToValue[valueButtons[i].valueButton] = itr->second;
f32 topHeight = 0; float topHeight = 0;
if(topBackgroundImg != NULL){ if(topBackgroundImg != NULL) {
topHeight = topBackgroundImg->getHeight(); 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); valueButtons[i].valueButton->setPosition(0, ypos);
valuesFrame.append(valueButtons[i].valueButton); valuesFrame.append(valueButtons[i].valueButton);
@ -209,10 +197,8 @@ void GuiSelectBox::Init(std::map<std::string,std::string> values, s32 valueID)
bChanged = true; bChanged = true;
} }
void GuiSelectBox::DeleteValueData() void GuiSelectBox::DeleteValueData() {
{ for(uint32_t i = 0; i < valueButtons.size(); ++i) {
for(u32 i = 0; i < valueButtons.size(); ++i)
{
valuesFrame.remove(valueButtons[i].valueButton); valuesFrame.remove(valueButtons[i].valueButton);
delete valueButtons[i].valueButtonImg; delete valueButtons[i].valueButtonImg;
delete valueButtons[i].valueButtonCheckedImg; delete valueButtons[i].valueButtonCheckedImg;
@ -227,7 +213,7 @@ void GuiSelectBox::DeleteValueData()
/** /**
* Destructor for the GuiButton class. * Destructor for the GuiButton class.
*/ */
GuiSelectBox::~GuiSelectBox(){ GuiSelectBox::~GuiSelectBox() {
DeleteValueData(); DeleteValueData();
bChanged = false; bChanged = false;
selected = 0; selected = 0;
@ -235,61 +221,58 @@ GuiSelectBox::~GuiSelectBox(){
} }
void GuiSelectBox::setState(s32 s, s32 c) void GuiSelectBox::setState(int32_t s, int32_t c) {
{ GuiElement::setState(s, c);
GuiElement::setState(s, c);
} }
void GuiSelectBox::OnValueCloseEffectFinish(GuiElement *element) void GuiSelectBox::OnValueCloseEffectFinish(GuiElement *element) {
{
valuesFrame.effectFinished.disconnect(this); valuesFrame.effectFinished.disconnect(this);
} }
f32 GuiSelectBox::getTopValueHeight() { float GuiSelectBox::getTopValueHeight() {
if(topBackgroundImg == NULL){ if(topBackgroundImg == NULL) {
return 0.0f; return 0.0f;
} }
return topBackgroundImg->getHeight(); return topBackgroundImg->getHeight();
} }
f32 GuiSelectBox::getTopValueWidth() { float GuiSelectBox::getTopValueWidth() {
if(topBackgroundImg == NULL){ if(topBackgroundImg == NULL) {
return 0.0f; return 0.0f;
} }
return topBackgroundImg->getWidth(); return topBackgroundImg->getWidth();
} }
f32 GuiSelectBox::getHeight(){ float GuiSelectBox::getHeight() {
return getTopValueHeight(); return getTopValueHeight();
} }
f32 GuiSelectBox::getWidth(){ float GuiSelectBox::getWidth() {
return getTopValueWidth(); return getTopValueWidth();
} }
void GuiSelectBox::OnValueOpenEffectFinish(GuiElement *element) void GuiSelectBox::OnValueOpenEffectFinish(GuiElement *element) {
{
valuesFrame.effectFinished.disconnect(this); valuesFrame.effectFinished.disconnect(this);
opened = true; opened = true;
} }
void GuiSelectBox::update(GuiController * c){ void GuiSelectBox::update(GuiController * c) {
if(bChanged){ if(bChanged) {
showhide(this,showValues); showhide(this,showValues);
if(showValues){ if(showValues) {
for(u32 i = 0; i < valueButtons.size(); ++i){ //TODO: only set when it really changed for(uint32_t i = 0; i < valueButtons.size(); ++i) { //TODO: only set when it really changed
if(i == selected){ if(i == selected) {
valueButtons[i].valueButton->setImage(valueButtons[i].valueButtonCheckedImg); valueButtons[i].valueButton->setImage(valueButtons[i].valueButtonCheckedImg);
}else{ } else {
valueButtons[i].valueButton->setImage(valueButtons[i].valueButtonImg); valueButtons[i].valueButton->setImage(valueButtons[i].valueButtonImg);
} }
} }
valuesFrame.clearState(STATE_HIDDEN); valuesFrame.clearState(STATE_HIDDEN);
DPADButtons.clearState(STATE_DISABLE_INPUT); DPADButtons.clearState(STATE_DISABLE_INPUT);
valuesFrame.setEffect(EFFECT_FADE, 10, 255); valuesFrame.setEffect(EFFECT_FADE, 10, 255);
valuesFrame.effectFinished.connect(this, &GuiSelectBox::OnValueCloseEffectFinish); valuesFrame.effectFinished.connect(this, &GuiSelectBox::OnValueCloseEffectFinish);
}else{ } else {
opened = false; opened = false;
valuesFrame.setState(STATE_HIDDEN); valuesFrame.setState(STATE_HIDDEN);
DPADButtons.setState(STATE_DISABLE_INPUT); DPADButtons.setState(STATE_DISABLE_INPUT);
@ -299,12 +282,12 @@ void GuiSelectBox::update(GuiController * c){
bChanged = false; bChanged = false;
} }
if(bSelectedChanged){ if(bSelectedChanged) {
for(u32 i = 0; i < valueButtons.size(); ++i){ for(uint32_t i = 0; i < valueButtons.size(); ++i) {
if(i == selected){ if(i == selected) {
valueButtons[i].valueButton->setState(STATE_SELECTED); valueButtons[i].valueButton->setState(STATE_SELECTED);
}else{ } else {
valueButtons[i].valueButton->clearState(STATE_SELECTED); 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,42 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "GuiSound.h" #include <string.h>
#include "sounds/SoundHandler.hpp" #include <string>
#include <dynamic_libs/os_functions.h> #include <stdio.h>
#include <gui/GuiSound.h>
#include <gui/sounds/SoundHandler.hpp>
GuiSound::GuiSound(const char * filepath) GuiSound::GuiSound(const char * filepath) {
{ voice = -1;
voice = -1; Load(filepath);
Load(filepath);
} }
GuiSound::GuiSound(const u8 * snd, s32 length) GuiSound::GuiSound(const uint8_t * snd, int32_t length) {
{ voice = -1;
voice = -1; Load(snd, length);
Load(snd, length);
} }
GuiSound::~GuiSound() GuiSound::~GuiSound() {
{ if(voice >= 0) {
if(voice >= 0)
{
SoundHandler::instance()->RemoveDecoder(voice); SoundHandler::instance()->RemoveDecoder(voice);
} }
} }
bool GuiSound::Load(const char * filepath) bool GuiSound::Load(const char * filepath) {
{ if(voice >= 0) {
if(voice >= 0)
{
SoundHandler::instance()->RemoveDecoder(voice); SoundHandler::instance()->RemoveDecoder(voice);
voice = -1; voice = -1;
} }
//! find next free decoder //! 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); SoundDecoder * decoder = SoundHandler::instance()->getDecoder(i);
if(decoder == NULL) if(decoder == NULL) {
{
SoundHandler::instance()->AddDecoder(i, filepath); SoundHandler::instance()->AddDecoder(i, filepath);
decoder = SoundHandler::instance()->getDecoder(i); decoder = SoundHandler::instance()->getDecoder(i);
if(decoder) if(decoder) {
{
voice = i; voice = i;
SoundHandler::instance()->ThreadSignal(); SoundHandler::instance()->ThreadSignal();
} }
@ -64,17 +57,15 @@ bool GuiSound::Load(const char * filepath)
} }
} }
if(voice < 0){ if(voice < 0) {
return false; return false;
} }
return true; return true;
} }
bool GuiSound::Load(const u8 * snd, s32 len) bool GuiSound::Load(const uint8_t * snd, int32_t len) {
{ if(voice >= 0) {
if(voice >= 0)
{
SoundHandler::instance()->RemoveDecoder(voice); SoundHandler::instance()->RemoveDecoder(voice);
voice = -1; voice = -1;
} }
@ -83,15 +74,12 @@ bool GuiSound::Load(const u8 * snd, s32 len)
return false; return false;
//! find next free decoder //! 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); SoundDecoder * decoder = SoundHandler::instance()->getDecoder(i);
if(decoder == NULL) if(decoder == NULL) {
{
SoundHandler::instance()->AddDecoder(i, snd, len); SoundHandler::instance()->AddDecoder(i, snd, len);
decoder = SoundHandler::instance()->getDecoder(i); decoder = SoundHandler::instance()->getDecoder(i);
if(decoder) if(decoder) {
{
voice = i; voice = i;
SoundHandler::instance()->ThreadSignal(); SoundHandler::instance()->ThreadSignal();
} }
@ -99,15 +87,14 @@ bool GuiSound::Load(const u8 * snd, s32 len)
} }
} }
if(voice < 0){ if(voice < 0) {
return false; return false;
} }
return true; return true;
} }
void GuiSound::Play() void GuiSound::Play() {
{
Stop(); Stop();
Voice * v = SoundHandler::instance()->getVoice(voice); Voice * v = SoundHandler::instance()->getVoice(voice);
@ -117,21 +104,18 @@ void GuiSound::Play()
} }
void GuiSound::Stop() void GuiSound::Stop() {
{
Voice * v = SoundHandler::instance()->getVoice(voice); Voice * v = SoundHandler::instance()->getVoice(voice);
if(v) if(v) {
{
if((v->getState() != Voice::STATE_STOP) && (v->getState() != Voice::STATE_STOPPED)) if((v->getState() != Voice::STATE_STOP) && (v->getState() != Voice::STATE_STOPPED))
v->setState(Voice::STATE_STOP); v->setState(Voice::STATE_STOP);
while(v->getState() != Voice::STATE_STOPPED) while(v->getState() != Voice::STATE_STOPPED)
os_usleep(1000); OSSleepTicks(OSMicrosecondsToTicks(1000));
} }
SoundDecoder * decoder = SoundHandler::instance()->getDecoder(voice); SoundDecoder * decoder = SoundHandler::instance()->getDecoder(voice);
if(decoder) if(decoder) {
{
decoder->Lock(); decoder->Lock();
decoder->Rewind(); decoder->Rewind();
decoder->ClearBuffer(); decoder->ClearBuffer();
@ -140,8 +124,7 @@ void GuiSound::Stop()
} }
} }
void GuiSound::Pause() void GuiSound::Pause() {
{
if(!IsPlaying()) if(!IsPlaying())
return; return;
@ -150,8 +133,7 @@ void GuiSound::Pause()
v->setState(Voice::STATE_STOP); v->setState(Voice::STATE_STOP);
} }
void GuiSound::Resume() void GuiSound::Resume() {
{
if(IsPlaying()) if(IsPlaying())
return; return;
@ -160,35 +142,31 @@ void GuiSound::Resume()
v->setState(Voice::STATE_START); v->setState(Voice::STATE_START);
} }
bool GuiSound::IsPlaying() bool GuiSound::IsPlaying() {
{
Voice * v = SoundHandler::instance()->getVoice(voice); Voice * v = SoundHandler::instance()->getVoice(voice);
if(v){ if(v) {
return v->getState() == Voice::STATE_PLAYING; return v->getState() == Voice::STATE_PLAYING;
} }
return false; return false;
} }
void GuiSound::SetVolume(u32 vol) void GuiSound::SetVolume(uint32_t vol) {
{
if(vol > 100) if(vol > 100)
vol = 100; vol = 100;
u32 volumeConv = ( (0x8000 * vol) / 100 ) << 16; uint32_t volumeConv = ( (0x8000 * vol) / 100 ) << 16;
Voice * v = SoundHandler::instance()->getVoice(voice); Voice * v = SoundHandler::instance()->getVoice(voice);
if(v) if(v)
v->setVolume(volumeConv); v->setVolume(volumeConv);
} }
void GuiSound::SetLoop(bool l) void GuiSound::SetLoop(bool l) {
{
SoundDecoder * decoder = SoundHandler::instance()->getDecoder(voice); SoundDecoder * decoder = SoundHandler::instance()->getDecoder(voice);
if(decoder) if(decoder)
decoder->SetLoop(l); decoder->SetLoop(l);
} }
void GuiSound::Rewind() void GuiSound::Rewind() {
{
Stop(); 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,62 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "GuiSwitch.h" #include <gui/GuiSwitch.h>
#include "GuiImage.h" #include <gui/GuiImage.h>
#include "GuiImageData.h" #include <gui/GuiImageData.h>
#include <utils/logger.h>
/** /**
* Constructor for the GuiSwitch class. * Constructor for the GuiSwitch class.
*/ */
GuiSwitch::GuiSwitch(GuiImage * background,bool checked,f32 w, f32 h) GuiSwitch::GuiSwitch(GuiImage * background,bool checked,float w, float h)
: GuiToggle(checked,w,h){ : GuiToggle(checked,w,h) {
setImageBackground(background); setImageBackground(background);
} }
/** /**
* Destructor for the GuiSwitch class. * Destructor for the GuiSwitch class.
*/ */
GuiSwitch::~GuiSwitch(){ GuiSwitch::~GuiSwitch() {
} }
void GuiSwitch::setImageBackground(GuiImage* img){ void GuiSwitch::setImageBackground(GuiImage* img) {
backgroundImg = img; backgroundImg = img;
if(img){ img->setParent(this); } if(img) {
setImage(img); img->setParent(this);
}
setImage(img);
} }
void GuiSwitch::setImageOn(GuiImage* img){ void GuiSwitch::setImageOn(GuiImage* img) {
onImg = img; onImg = img;
if(img){ if(img) {
img->setParent(this); img->setParent(this);
img->setAlignment(ALIGN_RIGHT); img->setAlignment(ALIGN_RIGHT);
} }
} }
void GuiSwitch::setImageOff(GuiImage* img){ void GuiSwitch::setImageOff(GuiImage* img) {
offImg = img; offImg = img;
if(img){ if(img) {
img->setParent(this); img->setParent(this);
img->setAlignment(ALIGN_LEFT); img->setAlignment(ALIGN_LEFT);
} }
} }
void GuiSwitch::setImageHighlighted(GuiImage* img){ void GuiSwitch::setImageHighlighted(GuiImage* img) {
highlightedImg = img; highlightedImg = img;
setIconOver(img); setIconOver(img);
} }
void GuiSwitch::draw(CVideo *v){ void GuiSwitch::draw(CVideo *v) {
GuiToggle::draw(v); GuiToggle::draw(v);
if(getValue()){ if(getValue()) {
if(onImg != NULL){ onImg->draw(v); } if(onImg != NULL) {
}else{ onImg->draw(v);
if(offImg != NULL){ offImg->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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "GuiText.h" #include <gui/GuiText.h>
#include "FreeTypeGX.h" #include <gui/FreeTypeGX.h>
#include "video/CVideo.h" #include <gui/video/CVideo.h>
FreeTypeGX * GuiText::presentFont = NULL; 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! float GuiText::presetInternalRenderingScale = 2.0f; //Lets render the font at the doubled size. This make it even smoother!
s32 GuiText::presetMaxWidth = 0xFFFF; int32_t GuiText::presetMaxWidth = 0xFFFF;
s32 GuiText::presetAlignment = ALIGN_CENTER | ALIGN_MIDDLE; int32_t GuiText::presetAlignment = ALIGN_CENTER | ALIGN_MIDDLE;
GX2ColorF32 GuiText::presetColor = (GX2ColorF32){ 1.0f, 1.0f, 1.0f, 1.0f }; GX2ColorF32 GuiText::presetColor = (GX2ColorF32) {
1.0f, 1.0f, 1.0f, 1.0f
};
#define TEXT_SCROLL_DELAY 6 #define TEXT_SCROLL_DELAY 6
#define TEXT_SCROLL_INITIAL_DELAY 10 #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. * Constructor for the GuiText class.
*/ */
GuiText::GuiText() GuiText::GuiText() {
{ text = NULL;
text = NULL; size = presetSize;
size = presetSize; currentSize = size;
currentSize = size; color = glm::vec4(presetColor.r, presetColor.g, presetColor.b, presetColor.a);
color = glm::vec4(presetColor.r, presetColor.g, presetColor.b, presetColor.a); alpha = presetColor.a;
alpha = presetColor.a; alignment = presetAlignment;
alignment = presetAlignment; maxWidth = presetMaxWidth;
maxWidth = presetMaxWidth; wrapMode = 0;
wrapMode = 0; textWidth = 0;
textWidth = 0; font = presentFont;
font = presentFont; linestodraw = MAX_LINES_TO_DRAW;
linestodraw = MAX_LINES_TO_DRAW; textScrollPos = 0;
textScrollPos = 0; textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY; textScrollDelay = TEXT_SCROLL_DELAY;
textScrollDelay = TEXT_SCROLL_DELAY; defaultBlur = 4.0f;
defaultBlur = 4.0f; blurGlowIntensity = 0.0f;
blurGlowIntensity = 0.0f; blurAlpha = 0.0f;
blurAlpha = 0.0f; blurGlowColor = glm::vec4(0.0f);
blurGlowColor = glm::vec4(0.0f); internalRenderingScale = presetInternalRenderingScale;
internalRenderingScale = presetInternalRenderingScale;
} }
GuiText::GuiText(const char * t, s32 s, const glm::vec4 & c) GuiText::GuiText(const char * t, int32_t s, const glm::vec4 & c) {
{ text = NULL;
text = NULL; size = s;
size = s; currentSize = size;
currentSize = size; color = c;
color = c; alpha = c[3];
alpha = c[3]; alignment = ALIGN_CENTER | ALIGN_MIDDLE;
alignment = ALIGN_CENTER | ALIGN_MIDDLE; maxWidth = presetMaxWidth;
maxWidth = presetMaxWidth; wrapMode = 0;
wrapMode = 0; textWidth = 0;
textWidth = 0; font = presentFont;
font = presentFont; linestodraw = MAX_LINES_TO_DRAW;
linestodraw = MAX_LINES_TO_DRAW; textScrollPos = 0;
textScrollPos = 0; textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY; textScrollDelay = TEXT_SCROLL_DELAY;
textScrollDelay = TEXT_SCROLL_DELAY; defaultBlur = 4.0f;
defaultBlur = 4.0f; blurGlowIntensity = 0.0f;
blurGlowIntensity = 0.0f; blurAlpha = 0.0f;
blurAlpha = 0.0f; blurGlowColor = glm::vec4(0.0f);
blurGlowColor = glm::vec4(0.0f); internalRenderingScale = presetInternalRenderingScale;
internalRenderingScale = presetInternalRenderingScale;
if(t) if(t) {
{ text = FreeTypeGX::charToWideChar(t);
text = FreeTypeGX::charToWideChar(t); if(!text)
if(!text) return;
return;
textWidth = font->getWidth(text, currentSize); textWidth = font->getWidth(text, currentSize);
} }
} }
GuiText::GuiText(const wchar_t * t, s32 s, const glm::vec4 & c) GuiText::GuiText(const wchar_t * t, int32_t s, const glm::vec4 & c) {
{ text = NULL;
text = NULL; size = s;
size = s; currentSize = size;
currentSize = size; color = c;
color = c; alpha = c[3];
alpha = c[3]; alignment = ALIGN_CENTER | ALIGN_MIDDLE;
alignment = ALIGN_CENTER | ALIGN_MIDDLE; maxWidth = presetMaxWidth;
maxWidth = presetMaxWidth; wrapMode = 0;
wrapMode = 0; textWidth = 0;
textWidth = 0; font = presentFont;
font = presentFont; linestodraw = MAX_LINES_TO_DRAW;
linestodraw = MAX_LINES_TO_DRAW; textScrollPos = 0;
textScrollPos = 0; textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY; textScrollDelay = TEXT_SCROLL_DELAY;
textScrollDelay = TEXT_SCROLL_DELAY; defaultBlur = 4.0f;
defaultBlur = 4.0f; blurGlowIntensity = 0.0f;
blurGlowIntensity = 0.0f; blurAlpha = 0.0f;
blurAlpha = 0.0f; blurGlowColor = glm::vec4(0.0f);
blurGlowColor = glm::vec4(0.0f); internalRenderingScale = presetInternalRenderingScale;
internalRenderingScale = presetInternalRenderingScale;
if(t) if(t) {
{ text = new (std::nothrow) wchar_t[wcslen(t)+1];
text = new (std::nothrow) wchar_t[wcslen(t)+1]; if(!text)
if(!text) return;
return;
wcscpy(text, t); wcscpy(text, t);
textWidth = font->getWidth(text, currentSize); textWidth = font->getWidth(text, currentSize);
} }
} }
/** /**
* Constructor for the GuiText class, uses presets * Constructor for the GuiText class, uses presets
*/ */
GuiText::GuiText(const char * t) GuiText::GuiText(const char * t) {
{ text = NULL;
text = NULL; size = presetSize;
size = presetSize; currentSize = size;
currentSize = size; color = glm::vec4(presetColor.r, presetColor.g, presetColor.b, presetColor.a);
color = glm::vec4(presetColor.r, presetColor.g, presetColor.b, presetColor.a); alpha = presetColor.a;
alpha = presetColor.a; alignment = presetAlignment;
alignment = presetAlignment; maxWidth = presetMaxWidth;
maxWidth = presetMaxWidth; wrapMode = 0;
wrapMode = 0; textWidth = 0;
textWidth = 0; font = presentFont;
font = presentFont; linestodraw = MAX_LINES_TO_DRAW;
linestodraw = MAX_LINES_TO_DRAW; textScrollPos = 0;
textScrollPos = 0; textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY; textScrollDelay = TEXT_SCROLL_DELAY;
textScrollDelay = TEXT_SCROLL_DELAY; defaultBlur = 4.0f;
defaultBlur = 4.0f; blurGlowIntensity = 0.0f;
blurGlowIntensity = 0.0f; blurAlpha = 0.0f;
blurAlpha = 0.0f; blurGlowColor = glm::vec4(0.0f);
blurGlowColor = glm::vec4(0.0f); internalRenderingScale = presetInternalRenderingScale;
internalRenderingScale = presetInternalRenderingScale;
if(t) if(t) {
{ text = FreeTypeGX::charToWideChar(t);
text = FreeTypeGX::charToWideChar(t); if(!text)
if(!text) return;
return;
textWidth = font->getWidth(text, currentSize); textWidth = font->getWidth(text, currentSize);
} }
} }
/** /**
* Destructor for the GuiText class. * Destructor for the GuiText class.
*/ */
GuiText::~GuiText() GuiText::~GuiText() {
{ if(text)
if(text) delete [] text;
delete [] text; text = NULL;
text = NULL;
clearDynamicText(); clearDynamicText();
} }
void GuiText::setText(const char * t) void GuiText::setText(const char * t) {
{ if(text)
if(text) delete [] text;
delete [] text; text = NULL;
text = NULL;
clearDynamicText(); clearDynamicText();
textScrollPos = 0; textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY; textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
if(t) if(t) {
{ text = FreeTypeGX::charToWideChar(t);
text = FreeTypeGX::charToWideChar(t); if(!text)
if(!text) return;
return;
textWidth = font->getWidth(text, currentSize); textWidth = font->getWidth(text, currentSize);
} }
} }
void GuiText::setTextf(const char *format, ...) void GuiText::setTextf(const char *format, ...) {
{ if(!format) {
if(!format) setText((char *) NULL);
{ return;
setText((char *) NULL);
return;
} }
s32 max_len = strlen(format) + 8192; int32_t max_len = strlen(format) + 8192;
char *tmp = new char[max_len]; char *tmp = new char[max_len];
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsnprintf(tmp, max_len, format, va) >= 0) && tmp) if((vsnprintf(tmp, max_len, format, va) >= 0) && tmp) {
{ setText(tmp);
setText(tmp); }
} va_end(va);
va_end(va);
if(tmp) if(tmp)
delete [] tmp; delete [] tmp;
} }
void GuiText::setText(const wchar_t * t) void GuiText::setText(const wchar_t * t) {
{ if(text)
if(text) delete [] text;
delete [] text; text = NULL;
text = NULL;
clearDynamicText(); clearDynamicText();
textScrollPos = 0; textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY; textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
if(t) if(t) {
{ text = new (std::nothrow) wchar_t[wcslen(t)+1];
text = new (std::nothrow) wchar_t[wcslen(t)+1]; if(!text)
if(!text) return;
return;
wcscpy(text, t); wcscpy(text, t);
textWidth = font->getWidth(text, currentSize); textWidth = font->getWidth(text, currentSize);
} }
} }
void GuiText::clearDynamicText() void GuiText::clearDynamicText() {
{ for(uint32_t i = 0; i < textDyn.size(); i++) {
for(u32 i = 0; i < textDyn.size(); i++) if(textDyn[i])
{ delete [] textDyn[i];
if(textDyn[i]) }
delete [] textDyn[i]; textDyn.clear();
} textDynWidth.clear();
textDyn.clear();
textDynWidth.clear();
} }
void GuiText::setPresets(s32 sz, const glm::vec4 & c, s32 w, s32 a) void GuiText::setPresets(int32_t sz, const glm::vec4 & c, int32_t w, int32_t a) {
{ presetSize = sz;
presetSize = sz; presetColor = (GX2ColorF32) {
presetColor = (GX2ColorF32) { (f32)c.r / 255.0f, (f32)c.g / 255.0f, (f32)c.b / 255.0f, (f32)c.a / 255.0f }; (float)c.r / 255.0f, (float)c.g / 255.0f, (float)c.b / 255.0f, (float)c.a / 255.0f
presetMaxWidth = w; };
presetAlignment = a; presetMaxWidth = w;
presetAlignment = a;
} }
void GuiText::setPresetFont(FreeTypeGX *f) void GuiText::setPresetFont(FreeTypeGX *f) {
{ presentFont = f;
presentFont = f;
} }
void GuiText::setFontSize(s32 s) void GuiText::setFontSize(int32_t s) {
{ size = s;
size = s;
} }
void GuiText::setMaxWidth(s32 width, s32 w) void GuiText::setMaxWidth(int32_t width, int32_t w) {
{ maxWidth = width;
maxWidth = width; wrapMode = w;
wrapMode = w;
if(w == SCROLL_HORIZONTAL) if(w == SCROLL_HORIZONTAL) {
{ textScrollPos = 0;
textScrollPos = 0; textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY; textScrollDelay = TEXT_SCROLL_DELAY;
textScrollDelay = TEXT_SCROLL_DELAY; }
}
clearDynamicText(); clearDynamicText();
} }
void GuiText::setColor(const glm::vec4 & c) void GuiText::setColor(const glm::vec4 & c) {
{ color = c;
color = c; alpha = c[3];
alpha = c[3];
} }
void GuiText::setBlurGlowColor(float blur, const glm::vec4 & c) void GuiText::setBlurGlowColor(float blur, const glm::vec4 & c) {
{ blurGlowColor = c;
blurGlowColor = c; blurGlowIntensity = blur;
blurGlowIntensity = blur; blurAlpha = c[3];
blurAlpha = c[3];
} }
s32 GuiText::getTextWidth(s32 ind) int32_t GuiText::getTextWidth(int32_t ind) {
{ if(ind < 0 || ind >= (int32_t) textDyn.size())
if(ind < 0 || ind >= (s32) textDyn.size()) return this->getTextWidth();
return this->getTextWidth();
return font->getWidth(textDyn[ind], currentSize); return font->getWidth(textDyn[ind], currentSize);
} }
const wchar_t * GuiText::getDynText(s32 ind) const wchar_t * GuiText::getDynText(int32_t ind) {
{ if(ind < 0 || ind >= (int32_t) textDyn.size())
if(ind < 0 || ind >= (s32) textDyn.size()) return text;
return text;
return textDyn[ind]; return textDyn[ind];
} }
/** /**
* Change font * Change font
*/ */
bool GuiText::setFont(FreeTypeGX *f) bool GuiText::setFont(FreeTypeGX *f) {
{ if(!f)
if(!f) return false;
return false;
font = f; font = f;
textWidth = font->getWidth(text, currentSize); textWidth = font->getWidth(text, currentSize);
return true; return true;
} }
std::string GuiText::toUTF8(void) const std::string GuiText::toUTF8(void) const {
{ if(!text)
if(!text) return std::string();
return std::string();
char *pUtf8 = FreeTypeGX::wideCharToUTF8(text); char *pUtf8 = FreeTypeGX::wideCharToUTF8(text);
if(!pUtf8) if(!pUtf8)
return std::string(); return std::string();
std::string strOutput(pUtf8); std::string strOutput(pUtf8);
delete [] pUtf8; delete [] pUtf8;
return strOutput; return strOutput;
} }
void GuiText::makeDottedText() void GuiText::makeDottedText() {
{ int32_t pos = textDyn.size();
s32 pos = textDyn.size(); textDyn.resize(pos + 1);
textDyn.resize(pos + 1);
s32 i = 0, currentWidth = 0; int32_t i = 0, currentWidth = 0;
textDyn[pos] = new (std::nothrow) wchar_t[maxWidth]; textDyn[pos] = new (std::nothrow) wchar_t[maxWidth];
if(!textDyn[pos]) { if(!textDyn[pos]) {
textDyn.resize(pos); textDyn.resize(pos);
return; return;
} }
while (text[i]) while (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); if (currentWidth >= maxWidth && i > 2) {
if (currentWidth >= maxWidth && i > 2) textDyn[pos][i - 2] = '.';
{ textDyn[pos][i - 1] = '.';
textDyn[pos][i - 2] = '.'; textDyn[pos][i] = '.';
textDyn[pos][i - 1] = '.'; i++;
textDyn[pos][i] = '.'; break;
i++; }
break;
}
textDyn[pos][i] = text[i]; textDyn[pos][i] = text[i];
i++; i++;
} }
textDyn[pos][i] = 0; textDyn[pos][i] = 0;
} }
void GuiText::scrollText(u32 frameCount) void GuiText::scrollText(uint32_t frameCount) {
{ if (textDyn.size() == 0) {
if (textDyn.size() == 0) int32_t pos = textDyn.size();
{ int32_t i = 0, currentWidth = 0;
s32 pos = textDyn.size(); textDyn.resize(pos + 1);
s32 i = 0, currentWidth = 0;
textDyn.resize(pos + 1);
textDyn[pos] = new (std::nothrow) wchar_t[maxWidth]; textDyn[pos] = new (std::nothrow) wchar_t[maxWidth];
if(!textDyn[pos]) { if(!textDyn[pos]) {
textDyn.resize(pos); textDyn.resize(pos);
return; return;
} }
while (text[i] && currentWidth < maxWidth) while (text[i] && currentWidth < maxWidth) {
{ textDyn[pos][i] = text[i];
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; ++i;
} }
textDyn[pos][i] = 0; textDyn[pos][i] = 0;
return; return;
} }
if (frameCount % textScrollDelay != 0) if (frameCount % textScrollDelay != 0) {
{ return;
return; }
}
if (textScrollInitialDelay) if (textScrollInitialDelay) {
{ --textScrollInitialDelay;
--textScrollInitialDelay; return;
return; }
}
s32 stringlen = wcslen(text); int32_t stringlen = wcslen(text);
++textScrollPos; ++textScrollPos;
if (textScrollPos > stringlen) if (textScrollPos > stringlen) {
{ textScrollPos = 0;
textScrollPos = 0; textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY; }
}
s32 ch = textScrollPos; int32_t ch = textScrollPos;
s32 pos = textDyn.size() - 1; int32_t pos = textDyn.size() - 1;
if (!textDyn[pos]) if (!textDyn[pos])
textDyn[pos] = new (std::nothrow) wchar_t[maxWidth]; textDyn[pos] = new (std::nothrow) wchar_t[maxWidth];
if(!textDyn[pos]) { if(!textDyn[pos]) {
textDyn.resize(pos); textDyn.resize(pos);
return; return;
} }
s32 i = 0, currentWidth = 0; int32_t i = 0, currentWidth = 0;
while (currentWidth < maxWidth) while (currentWidth < maxWidth) {
{ if (ch > stringlen - 1) {
if (ch > stringlen - 1) textDyn[pos][i++] = ' ';
{ currentWidth += font->getCharWidth(L' ', currentSize, ch > 0 ? text[ch - 1] : 0);
textDyn[pos][i++] = ' '; textDyn[pos][i++] = ' ';
currentWidth += font->getCharWidth(L' ', currentSize, ch > 0 ? text[ch - 1] : 0); currentWidth += font->getCharWidth(L' ', currentSize, L' ');
textDyn[pos][i++] = ' '; textDyn[pos][i++] = ' ';
currentWidth += font->getCharWidth(L' ', currentSize, L' '); currentWidth += font->getCharWidth(L' ', currentSize, L' ');
textDyn[pos][i++] = ' '; ch = 0;
currentWidth += font->getCharWidth(L' ', currentSize, L' ');
ch = 0;
if(currentWidth >= maxWidth) if(currentWidth >= maxWidth)
break; break;
} }
textDyn[pos][i] = text[ch]; textDyn[pos][i] = text[ch];
currentWidth += font->getCharWidth(text[ch], currentSize, ch > 0 ? text[ch - 1] : 0); currentWidth += font->getCharWidth(text[ch], currentSize, ch > 0 ? text[ch - 1] : 0);
++ch; ++ch;
++i; ++i;
} }
textDyn[pos][i] = 0; textDyn[pos][i] = 0;
} }
void GuiText::wrapText() void GuiText::wrapText() {
{ if (textDyn.size() > 0) return;
if (textDyn.size() > 0) return;
s32 i = 0; int32_t i = 0;
s32 ch = 0; int32_t ch = 0;
s32 linenum = 0; int32_t linenum = 0;
s32 lastSpace = -1; int32_t lastSpace = -1;
s32 lastSpaceIndex = -1; int32_t lastSpaceIndex = -1;
s32 currentWidth = 0; int32_t currentWidth = 0;
while (text[ch] && linenum < linestodraw) while (text[ch] && linenum < linestodraw) {
{ if (linenum >= (int32_t) textDyn.size()) {
if (linenum >= (s32) textDyn.size()) textDyn.resize(linenum + 1);
{ textDyn[linenum] = new (std::nothrow) wchar_t[maxWidth];
textDyn.resize(linenum + 1); if(!textDyn[linenum]) {
textDyn[linenum] = new (std::nothrow) wchar_t[maxWidth]; textDyn.resize(linenum);
if(!textDyn[linenum]) { break;
textDyn.resize(linenum);
break;
}
}
textDyn[linenum][i] = text[ch];
textDyn[linenum][i + 1] = 0;
currentWidth += font->getCharWidth(text[ch], currentSize, ch > 0 ? text[ch - 1] : 0x0000);
if (currentWidth >= maxWidth || (text[ch] == '\n'))
{
if(text[ch] == '\n')
{
lastSpace = -1;
lastSpaceIndex = -1;
} }
else if (lastSpace >= 0) }
{
textDyn[linenum][lastSpaceIndex] = 0; // discard space, and everything after
ch = lastSpace; // go backwards to the last space
lastSpace = -1; // we have used this space
lastSpaceIndex = -1;
}
if (linenum + 1 == linestodraw && text[ch + 1] != 0x0000) textDyn[linenum][i] = text[ch];
{ textDyn[linenum][i + 1] = 0;
if(i < 2)
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; i = 2;
textDyn[linenum][i - 2] = '.'; textDyn[linenum][i - 2] = '.';
textDyn[linenum][i - 1] = '.'; textDyn[linenum][i - 1] = '.';
textDyn[linenum][i] = '.'; textDyn[linenum][i] = '.';
textDyn[linenum][i + 1] = 0; textDyn[linenum][i + 1] = 0;
} }
currentWidth = 0; currentWidth = 0;
++linenum; ++linenum;
i = -1; i = -1;
} }
if (text[ch] == ' ' && i >= 0) if (text[ch] == ' ' && i >= 0) {
{ lastSpace = ch;
lastSpace = ch; lastSpaceIndex = i;
lastSpaceIndex = i; }
} ++ch;
++ch; ++i;
++i; }
}
} }
/** /**
* Draw the text on screen * Draw the text on screen
*/ */
void GuiText::draw(CVideo *pVideo) void GuiText::draw(CVideo *pVideo) {
{ if(!text)
if(!text) return;
return;
if(!isVisible()) if(!isVisible())
return; return;
color[3] = getAlpha(); color[3] = getAlpha();
blurGlowColor[3] = blurAlpha * getAlpha(); blurGlowColor[3] = blurAlpha * getAlpha();
float finalRenderingScale = 2.0f * internalRenderingScale; float finalRenderingScale = 2.0f * internalRenderingScale;
s32 newSize = size * getScale() * finalRenderingScale; int32_t newSize = size * getScale() * finalRenderingScale;
s32 normal_size = size * getScale(); int32_t normal_size = size * getScale();
if(newSize != currentSize) if(newSize != currentSize) {
{ currentSize = normal_size;
currentSize = normal_size;
if(text) if(text)
textWidth = font->getWidth(text, normal_size); textWidth = font->getWidth(text, normal_size);
} }
f32 x_pos = getCenterX() * finalRenderingScale; float x_pos = getCenterX() * finalRenderingScale;
f32 y_pos = getCenterY() * finalRenderingScale; float y_pos = getCenterY() * finalRenderingScale;
if(maxWidth > 0 && maxWidth <= textWidth) if(maxWidth > 0 && maxWidth <= textWidth) {
{ if(wrapMode == DOTTED) { // text dotted
if(wrapMode == DOTTED) // text dotted if(textDyn.size() == 0)
{ makeDottedText();
if(textDyn.size() == 0)
makeDottedText();
if(textDynWidth.size() != textDyn.size()) if(textDynWidth.size() != textDyn.size()) {
{
textDynWidth.resize(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); textDynWidth[i] = font->getWidth(textDyn[i], newSize);
} }
if(textDyn.size() > 0) 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); 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) else if(wrapMode == SCROLL_HORIZONTAL) {
{ scrollText(pVideo->getFrameCount());
scrollText(pVideo->getFrameCount());
if(textDyn.size() > 0) 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); 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) {
else if(wrapMode == WRAP) int32_t lineheight = newSize + 6;
{ int32_t yoffset = 0;
s32 lineheight = newSize + 6; int32_t voffset = 0;
s32 yoffset = 0;
s32 voffset = 0;
if(textDyn.size() == 0) if(textDyn.size() == 0)
wrapText(); wrapText();
if(textDynWidth.size() != textDyn.size()) if(textDynWidth.size() != textDyn.size()) {
{
textDynWidth.resize(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); textDynWidth[i] = font->getWidth(textDyn[i], newSize);
} }
if(alignment & ALIGN_MIDDLE) if(alignment & ALIGN_MIDDLE)
voffset = (lineheight * (textDyn.size()-1)) >> 1; voffset = (lineheight * (textDyn.size()-1)) >> 1;
for(u32 i = 0; i < textDyn.size(); i++) 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);
font->drawText(pVideo, x_pos, y_pos + voffset + yoffset, getDepth(), textDyn[i], newSize, color, alignment, textDynWidth[i], defaultBlur, blurGlowIntensity, blurGlowColor,finalRenderingScale);
yoffset -= lineheight; yoffset -= lineheight;
} }
} }
} } else {
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);
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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "GuiToggle.h" #include <gui/GuiToggle.h>
/** /**
* Constructor for the GuiToggle class. * Constructor for the GuiToggle class.
*/ */
GuiToggle::GuiToggle(bool checked,f32 width,f32 height) GuiToggle::GuiToggle(bool checked,float width,float height)
: GuiButton(width,height) : GuiButton(width,height) {
{
bChanged = false; bChanged = false;
selected = checked; selected = checked;
clicked.connect(this,&GuiToggle::OnToggleClick); clicked.connect(this,&GuiToggle::OnToggleClick);
@ -30,23 +29,22 @@ GuiToggle::GuiToggle(bool checked,f32 width,f32 height)
/** /**
* Destructor for the GuiButton class. * Destructor for the GuiButton class.
*/ */
GuiToggle::~GuiToggle() GuiToggle::~GuiToggle() {
{
bChanged = false; bChanged = false;
selected = false; selected = false;
} }
void GuiToggle::OnToggleClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger){ void GuiToggle::OnToggleClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
if(!isStateSet(STATE_DISABLED | STATE_HIDDEN | STATE_DISABLE_INPUT)){ if(!isStateSet(STATE_DISABLED | STATE_HIDDEN | STATE_DISABLE_INPUT)) {
if(selected){ if(selected) {
setUnchecked(); setUnchecked();
}else{ } else {
setChecked(); setChecked();
} }
} }
} }
void GuiToggle::update(GuiController * c){ void GuiToggle::update(GuiController * c) {
GuiButton::update(c); GuiButton::update(c);
} }

View File

@ -14,9 +14,9 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "GuiElement.h" #include <gui/GuiElement.h>
#include "GuiController.h" #include <gui/GuiController.h>
#include "GuiTrigger.h" #include <gui/GuiTrigger.h>
/** /**
* Constructor for the GuiTrigger class. * Constructor for the GuiTrigger class.
@ -27,25 +27,22 @@ GuiTrigger::GuiTrigger()
, bClickEverywhere(false) , bClickEverywhere(false)
, bHoldEverywhere(false) , bHoldEverywhere(false)
, bSelectionClickEverywhere(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) : chan(ch)
, btns(btn) , btns(btn)
, bClickEverywhere(clickEverywhere) , bClickEverywhere(clickEverywhere)
, bHoldEverywhere(holdEverywhere) , bHoldEverywhere(holdEverywhere)
, bSelectionClickEverywhere(selectionClickEverywhere) , bSelectionClickEverywhere(selectionClickEverywhere)
, bLastTouched(false) , bLastTouched(false) {
{
} }
/** /**
* Destructor for the GuiTrigger class. * Destructor for the GuiTrigger class.
*/ */
GuiTrigger::~GuiTrigger() GuiTrigger::~GuiTrigger() {
{
} }
/** /**
@ -53,103 +50,87 @@ GuiTrigger::~GuiTrigger()
* - Element is selected * - Element is selected
* - Trigger button is pressed * - Trigger button is pressed
*/ */
void GuiTrigger::setTrigger(u32 ch, u32 btn) void GuiTrigger::setTrigger(uint32_t ch, uint32_t btn) {
{ chan = ch;
chan = ch; btns = btn;
btns = btn;
} }
bool GuiTrigger::left(const GuiController *controller) const bool GuiTrigger::left(const GuiController *controller) const {
{
if((controller->chan & chan) == 0) { if((controller->chan & chan) == 0) {
return false; return false;
} }
if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_LEFT | STICK_L_LEFT)) if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_LEFT | STICK_L_LEFT)) {
{ return true;
return true; }
} return false;
return false;
} }
bool GuiTrigger::right(const GuiController *controller) const bool GuiTrigger::right(const GuiController *controller) const {
{
if((controller->chan & chan) == 0) { if((controller->chan & chan) == 0) {
return false; return false;
} }
if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_RIGHT | STICK_L_RIGHT)) if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_RIGHT | STICK_L_RIGHT)) {
{ return true;
return true; }
} return false;
return false;
} }
bool GuiTrigger::up(const GuiController *controller) const bool GuiTrigger::up(const GuiController *controller) const {
{
if((controller->chan & chan) == 0) { if((controller->chan & chan) == 0) {
return false; return false;
} }
if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_UP | STICK_L_UP)) if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_UP | STICK_L_UP)) {
{ return true;
return true; }
} return false;
return false;
} }
bool GuiTrigger::down(const GuiController *controller) const bool GuiTrigger::down(const GuiController *controller) const {
{
if((controller->chan & chan) == 0) { if((controller->chan & chan) == 0) {
return false; return false;
} }
if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_DOWN | STICK_L_DOWN)) if((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_DOWN | STICK_L_DOWN)) {
{ return true;
return true; }
} return false;
return false;
} }
s32 GuiTrigger::clicked(const GuiController *controller) const int32_t GuiTrigger::clicked(const GuiController *controller) const {
{
if((controller->chan & chan) == 0) { if((controller->chan & chan) == 0) {
return CLICKED_NONE; 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; bResult = CLICKED_TOUCH;
} }
if(controller->data.buttons_d & btns) if(controller->data.buttons_d & btns) {
{ bResult = CLICKED_BUTTON;
bResult = CLICKED_BUTTON; }
} return bResult;
return bResult;
} }
bool GuiTrigger::held(const GuiController *controller) const bool GuiTrigger::held(const GuiController *controller) const {
{
if((controller->chan & chan) == 0) { if((controller->chan & chan) == 0) {
return false; return false;
} }
bool bResult = 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; bResult = true;
} }
if(controller->data.buttons_h & btns) if(controller->data.buttons_h & btns) {
{ bResult = true;
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) { if((controller->chan & chan) == 0) {
return false; return false;
} }
@ -159,16 +140,14 @@ bool GuiTrigger::released(const GuiController *controller) const
bool bResult = false; 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; bResult = true;
} }
if(controller->data.buttons_r & btns) if(controller->data.buttons_r & btns) {
{ bResult = true;
bResult = true; }
}
return bResult; return bResult;
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,206 +0,0 @@
#include <malloc.h>
#include <string.h>
#include "Resources.h"
#include "filelist.h"
#include <system/AsyncDeleter.h>
#include <fs/FSUtils.h>
#include "gui/GuiImageAsync.h"
#include "gui/GuiSound.h"
Resources * Resources::instance = NULL;
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;
}
if(ResourceList[i].CustomFileSize != 0)
ResourceList[i].CustomFileSize = 0;
}
if(instance)
delete instance;
instance = NULL;
}
bool Resources::LoadFiles(const char * path)
{
if(!path)
return false;
bool result = false;
Clear();
ResourceFile * ResourceList = getResourceList();
if(ResourceList == NULL) return false;
for(s32 i = 0; ResourceList[i].filename != NULL; ++i)
{
std::string fullpath(path);
fullpath += "/";
fullpath += ResourceList[i].filename;
u8 * buffer = NULL;
u32 filesize = 0;
FSUtils::LoadFileToMem(fullpath.c_str(), &buffer, &filesize);
ResourceList[i].CustomFile = buffer;
ResourceList[i].CustomFileSize = (u32) filesize;
result |= (buffer != 0);
}
return result;
}
const u8 * 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);
}
}
return NULL;
}
u32 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;
}
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())
{
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;
if(buff == NULL)
return NULL;
GuiImageData * image = new GuiImageData(buff, size);
instance->imageDataMap[std::string(filename)].first = 1;
instance->imageDataMap[std::string(filename)].second = image;
return image;
}
}
return NULL;
}
void Resources::RemoveImageData(GuiImageData * image)
{
std::map<std::string, std::pair<u32, GuiImageData *> >::iterator itr;
for(itr = instance->imageDataMap.begin(); itr != instance->imageDataMap.end(); itr++)
{
if(itr->second.second == image)
{
itr->second.first--;
if(itr->second.first == 0)
{
AsyncDeleter::pushForDelete( itr->second.second );
instance->imageDataMap.erase(itr);
}
break;
}
}
}
GuiSound * Resources::GetSound(const char * filename)
{
if(!instance)
instance = new Resources;
std::map<std::string, std::pair<u32, GuiSound *> >::iterator itr = instance->soundDataMap.find(std::string(filename));
if(itr != instance->soundDataMap.end())
{
itr->second.first++;
return itr->second.second;
}
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;
if(buff == NULL)
return NULL;
GuiSound * sound = new GuiSound(buff, size);
instance->soundDataMap[std::string(filename)].first = 1;
instance->soundDataMap[std::string(filename)].second = sound;
return sound;
}
}
return NULL;
}
void Resources::RemoveSound(GuiSound * sound)
{
std::map<std::string, std::pair<u32, GuiSound *> >::iterator itr;
for(itr = instance->soundDataMap.begin(); itr != instance->soundDataMap.end(); itr++)
{
if(itr->second.second == sound)
{
itr->second.first--;
if(itr->second.first == 0)
{
AsyncDeleter::pushForDelete( itr->second.second );
instance->soundDataMap.erase(itr);
}
break;
}
}
}

View File

@ -1,34 +0,0 @@
#ifndef RECOURCES_H_
#define RECOURCES_H_
#include <map>
#include <dynamic_libs/os_types.h>
//! forward declaration
class GuiImageData;
class GuiSound;
class Resources
{
public:
static void Clear();
static bool LoadFiles(const char * path);
static const u8 * GetFile(const char * filename);
static u32 GetFileSize(const char * filename);
static GuiImageData * GetImageData(const char * filename);
static void RemoveImageData(GuiImageData * image);
static GuiSound * GetSound(const char * filename);
static void RemoveSound(GuiSound * sound);
private:
static Resources *instance;
Resources() {}
~Resources() {}
std::map<std::string, std::pair<u32, GuiImageData *> > imageDataMap;
std::map<std::string, std::pair<u32, GuiSound *> > soundDataMap;
};
#endif

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 * for WiiXplorer 2010
***************************************************************************/ ***************************************************************************/
#include <malloc.h> #include <malloc.h>
#include "utils/utils.h" #include <utils/utils.h>
#include "BufferCircle.hpp" #include <gui/sounds/BufferCircle.hpp>
BufferCircle::BufferCircle() BufferCircle::BufferCircle() {
{ which = 0;
which = 0; BufferBlockSize = 0;
BufferBlockSize = 0;
} }
BufferCircle::~BufferCircle() BufferCircle::~BufferCircle() {
{ FreeBuffer();
FreeBuffer(); SoundBuffer.clear();
SoundBuffer.clear(); BufferSize.clear();
BufferSize.clear(); BufferReady.clear();
BufferReady.clear();
} }
void BufferCircle::SetBufferBlockSize(s32 size) void BufferCircle::SetBufferBlockSize(int32_t size) {
{ if(size < 0)
if(size < 0) return;
return;
BufferBlockSize = size; BufferBlockSize = size;
for(s32 i = 0; i < Size(); i++) for(int32_t i = 0; i < Size(); i++) {
{ if(SoundBuffer[i] != NULL)
if(SoundBuffer[i] != NULL) free(SoundBuffer[i]);
free(SoundBuffer[i]);
SoundBuffer[i] = (u8 *) memalign(32, ALIGN32(BufferBlockSize)); SoundBuffer[i] = (uint8_t *) memalign(32, ALIGN32(BufferBlockSize));
BufferSize[i] = 0; BufferSize[i] = 0;
BufferReady[i] = false; BufferReady[i] = false;
} }
} }
void BufferCircle::Resize(s32 size) void BufferCircle::Resize(int32_t size) {
{ while(size < Size())
while(size < Size()) RemoveBuffer(Size()-1);
RemoveBuffer(Size()-1);
s32 oldSize = Size(); int32_t oldSize = Size();
SoundBuffer.resize(size); SoundBuffer.resize(size);
BufferSize.resize(size); BufferSize.resize(size);
BufferReady.resize(size); BufferReady.resize(size);
for(s32 i = oldSize; i < Size(); i++) for(int32_t i = oldSize; i < Size(); i++) {
{ if(BufferBlockSize > 0)
if(BufferBlockSize > 0) SoundBuffer[i] = (uint8_t *) memalign(32, ALIGN32(BufferBlockSize));
SoundBuffer[i] = (u8 *) memalign(32, ALIGN32(BufferBlockSize)); else
else SoundBuffer[i] = NULL;
SoundBuffer[i] = NULL; BufferSize[i] = 0;
BufferSize[i] = 0; BufferReady[i] = false;
BufferReady[i] = false; }
}
} }
void BufferCircle::RemoveBuffer(s32 pos) void BufferCircle::RemoveBuffer(int32_t pos) {
{ if(!Valid(pos))
if(!Valid(pos)) return;
return;
if(SoundBuffer[pos] != NULL) if(SoundBuffer[pos] != NULL)
free(SoundBuffer[pos]); free(SoundBuffer[pos]);
SoundBuffer.erase(SoundBuffer.begin()+pos); SoundBuffer.erase(SoundBuffer.begin()+pos);
BufferSize.erase(BufferSize.begin()+pos); BufferSize.erase(BufferSize.begin()+pos);
BufferReady.erase(BufferReady.begin()+pos); BufferReady.erase(BufferReady.begin()+pos);
} }
void BufferCircle::ClearBuffer() void BufferCircle::ClearBuffer() {
{ for(int32_t i = 0; i < Size(); i++) {
for(s32 i = 0; i < Size(); i++) BufferSize[i] = 0;
{ BufferReady[i] = false;
BufferSize[i] = 0; }
BufferReady[i] = false; which = 0;
}
which = 0;
} }
void BufferCircle::FreeBuffer() void BufferCircle::FreeBuffer() {
{ for(int32_t i = 0; i < Size(); i++) {
for(s32 i = 0; i < Size(); i++) if(SoundBuffer[i] != NULL)
{ free(SoundBuffer[i]);
if(SoundBuffer[i] != NULL)
free(SoundBuffer[i]);
SoundBuffer[i] = NULL; SoundBuffer[i] = NULL;
BufferSize[i] = 0; BufferSize[i] = 0;
BufferReady[i] = false; BufferReady[i] = false;
} }
} }
void BufferCircle::LoadNext() void BufferCircle::LoadNext() {
{ BufferReady[which] = false;
BufferReady[which] = false; BufferSize[which] = 0;
BufferSize[which] = 0;
which = Next(); which = Next();
} }
void BufferCircle::SetBufferReady(s32 pos, bool state) void BufferCircle::SetBufferReady(int32_t pos, bool state) {
{ if(!Valid(pos))
if(!Valid(pos)) return;
return;
BufferReady[pos] = state; BufferReady[pos] = state;
} }
void BufferCircle::SetBufferSize(s32 pos, s32 size) void BufferCircle::SetBufferSize(int32_t pos, int32_t size) {
{ if(!Valid(pos))
if(!Valid(pos)) return;
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,10 @@
#include <unistd.h> #include <unistd.h>
#include <malloc.h> #include <malloc.h>
#include <math.h> #include <math.h>
#include <dynamic_libs/os_functions.h> #include <coreinit/time.h>
#include "Mp3Decoder.hpp" #include <coreinit/thread.h>
#include <gui/sounds/Mp3Decoder.hpp>
#include "fs/CFile.hpp"
Mp3Decoder::Mp3Decoder(const char * filepath) Mp3Decoder::Mp3Decoder(const char * filepath)
: SoundDecoder(filepath) : SoundDecoder(filepath)
@ -48,7 +50,7 @@ Mp3Decoder::Mp3Decoder(const char * filepath)
OpenFile(); OpenFile();
} }
Mp3Decoder::Mp3Decoder(const u8 * snd, s32 len) Mp3Decoder::Mp3Decoder(const uint8_t * snd, int32_t len)
: SoundDecoder(snd, len) : SoundDecoder(snd, len)
{ {
SoundType = SOUND_MP3; SoundType = SOUND_MP3;
@ -68,7 +70,7 @@ Mp3Decoder::~Mp3Decoder()
{ {
ExitRequested = true; ExitRequested = true;
while(Decoding) while(Decoding)
os_usleep(100); OSSleepTicks(OSMicrosecondsToTicks(100));
mad_synth_finish(&Synth); mad_synth_finish(&Synth);
mad_frame_finish(&Frame); mad_frame_finish(&Frame);
@ -82,7 +84,7 @@ Mp3Decoder::~Mp3Decoder()
void Mp3Decoder::OpenFile() void Mp3Decoder::OpenFile()
{ {
GuardPtr = NULL; GuardPtr = NULL;
ReadBuffer = (u8 *) memalign(32, SoundBlockSize*SoundBlocks); ReadBuffer = (uint8_t *) memalign(32, SoundBlockSize*SoundBlocks);
if(!ReadBuffer) if(!ReadBuffer)
{ {
if(file_fd) if(file_fd)
@ -91,8 +93,8 @@ void Mp3Decoder::OpenFile()
return; return;
} }
u8 dummybuff[4096]; uint8_t dummybuff[4096];
s32 ret = Read(dummybuff, 4096, 0); int32_t ret = Read(dummybuff, 4096, 0);
if(ret <= 0) if(ret <= 0)
{ {
if(file_fd) if(file_fd)
@ -101,12 +103,12 @@ void Mp3Decoder::OpenFile()
return; 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)); Format = ((MAD_NCHANNELS(&Frame.header) == 2) ? (FORMAT_PCM_16_BIT | CHANNELS_STEREO) : (FORMAT_PCM_16_BIT | CHANNELS_MONO));
Rewind(); Rewind();
} }
s32 Mp3Decoder::Rewind() int32_t Mp3Decoder::Rewind()
{ {
mad_synth_finish(&Synth); mad_synth_finish(&Synth);
mad_frame_finish(&Frame); mad_frame_finish(&Frame);
@ -124,7 +126,7 @@ s32 Mp3Decoder::Rewind()
return SoundDecoder::Rewind(); return SoundDecoder::Rewind();
} }
static inline s16 FixedToShort(mad_fixed_t Fixed) static inline int16_t FixedToShort(mad_fixed_t Fixed)
{ {
/* Clipping */ /* Clipping */
if(Fixed>=MAD_F_ONE) if(Fixed>=MAD_F_ONE)
@ -133,10 +135,10 @@ static inline s16 FixedToShort(mad_fixed_t Fixed)
return(-SHRT_MAX); return(-SHRT_MAX);
Fixed=Fixed>>(MAD_F_FRACBITS-15); 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) if(!file_fd)
return -1; return -1;
@ -146,8 +148,8 @@ s32 Mp3Decoder::Read(u8 * buffer, s32 buffer_size, s32 pos)
else else
buffer_size &= ~0x0001; buffer_size &= ~0x0001;
u8 * write_pos = buffer; uint8_t * write_pos = buffer;
u8 * write_end = buffer+buffer_size; uint8_t * write_end = buffer+buffer_size;
while(1) while(1)
{ {
@ -156,12 +158,12 @@ s32 Mp3Decoder::Read(u8 * buffer, s32 buffer_size, s32 pos)
if(write_pos >= write_end) if(write_pos >= write_end)
return write_pos-buffer; 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; write_pos += 2;
if(MAD_NCHANNELS(&Frame.header) == 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; write_pos += 2;
} }
SynthPos++; SynthPos++;
@ -169,9 +171,9 @@ s32 Mp3Decoder::Read(u8 * buffer, s32 buffer_size, s32 pos)
if(Stream.buffer == NULL || Stream.error == MAD_ERROR_BUFLEN) if(Stream.buffer == NULL || Stream.error == MAD_ERROR_BUFLEN)
{ {
u8 * ReadStart = ReadBuffer; uint8_t * ReadStart = ReadBuffer;
s32 ReadSize = SoundBlockSize*SoundBlocks; int32_t ReadSize = SoundBlockSize*SoundBlocks;
s32 Remaining = 0; int32_t Remaining = 0;
if(Stream.next_frame != NULL) if(Stream.next_frame != NULL)
{ {

View File

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

View File

@ -18,208 +18,193 @@
#include <malloc.h> #include <malloc.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <dynamic_libs/os_functions.h> #include <coreinit/time.h>
#include "SoundDecoder.hpp" #include <coreinit/thread.h>
#include <coreinit/cache.h>
#include <gui/sounds/SoundDecoder.hpp>
#include "fs/CFile.hpp"
static const u32 FixedPointShift = 15; static const uint32_t FixedPointShift = 15;
static const u32 FixedPointScale = 1 << FixedPointShift; static const uint32_t FixedPointScale = 1 << FixedPointShift;
SoundDecoder::SoundDecoder() SoundDecoder::SoundDecoder() {
{ file_fd = NULL;
file_fd = NULL; Init();
Init();
} }
SoundDecoder::SoundDecoder(const std::string & filepath) SoundDecoder::SoundDecoder(const std::string & filepath) {
{ file_fd = new CFile(filepath, CFile::ReadOnly);
file_fd = new CFile(filepath, CFile::ReadOnly); Init();
Init();
} }
SoundDecoder::SoundDecoder(const u8 * buffer, s32 size) SoundDecoder::SoundDecoder(const uint8_t * buffer, int32_t size) {
{ file_fd = new CFile(buffer, size);
file_fd = new CFile(buffer, size); Init();
Init();
} }
SoundDecoder::~SoundDecoder() SoundDecoder::~SoundDecoder() {
{ ExitRequested = true;
ExitRequested = true; while(Decoding)
while(Decoding) OSSleepTicks(OSMicrosecondsToTicks(1000));
os_usleep(1000);
//! lock unlock once to make sure it's really not decoding //! lock unlock once to make sure it's really not decoding
Lock(); Lock();
Unlock(); Unlock();
if(file_fd) if(file_fd)
delete file_fd; delete file_fd;
file_fd = NULL; file_fd = NULL;
if(ResampleBuffer) if(ResampleBuffer)
free(ResampleBuffer); free(ResampleBuffer);
} }
void SoundDecoder::Init() int32_t SoundDecoder::Seek(int32_t pos) {
{ CurPos = pos;
SoundType = SOUND_RAW; return file_fd->seek(CurPos, SEEK_SET);
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() void SoundDecoder::Init() {
{ SoundType = SOUND_RAW;
CurPos = 0; SoundBlocks = 8;
EndOfFile = false; SoundBlockSize = 0x4000;
file_fd->rewind(); ResampleTo48kHz = false;
CurPos = 0;
return 0; whichLoad = 0;
Loop = false;
EndOfFile = false;
Decoding = false;
ExitRequested = false;
SoundBuffer.SetBufferBlockSize(SoundBlockSize);
SoundBuffer.Resize(SoundBlocks);
ResampleBuffer = NULL;
ResampleRatio = 0;
} }
s32 SoundDecoder::Read(u8 * buffer, s32 buffer_size, s32 pos) int32_t SoundDecoder::Rewind() {
{ CurPos = 0;
s32 ret = file_fd->read(buffer, buffer_size); EndOfFile = false;
CurPos += ret; file_fd->rewind();
return ret; return 0;
} }
void SoundDecoder::EnableUpsample(void) int32_t SoundDecoder::Read(uint8_t * buffer, int32_t buffer_size, int32_t pos) {
{ int32_t ret = file_fd->read(buffer, buffer_size);
if( (ResampleBuffer == NULL) CurPos += ret;
&& IsStereo() && Is16Bit()
&& SampleRate != 32000 return ret;
&& SampleRate != 48000)
{
ResampleBuffer = (u8*)memalign(32, SoundBlockSize);
ResampleRatio = ( FixedPointScale * SampleRate ) / 48000;
SoundBlockSize = ( SoundBlockSize * ResampleRatio ) / FixedPointScale;
SoundBlockSize &= ~0x03;
// set new sample rate
SampleRate = 48000;
}
} }
void SoundDecoder::Upsample(s16 *src, s16 *dst, u32 nr_src_samples, u32 nr_dst_samples) void SoundDecoder::EnableUpsample(void) {
{ if( (ResampleBuffer == NULL)
s32 timer = 0; && IsStereo() && Is16Bit()
&& SampleRate != 32000
for(u32 i = 0, n = 0; i < nr_dst_samples; i += 2) && SampleRate != 48000) {
{ ResampleBuffer = (uint8_t*)memalign(32, SoundBlockSize);
if((n+3) < nr_src_samples) { ResampleRatio = ( FixedPointScale * SampleRate ) / 48000;
// simple fixed point linear interpolation SoundBlockSize = ( SoundBlockSize * ResampleRatio ) / FixedPointScale;
dst[i] = src[n] + ( ((src[n+2] - src[n] ) * timer) >> FixedPointShift ); SoundBlockSize &= ~0x03;
dst[i+1] = src[n+1] + ( ((src[n+3] - src[n+1]) * timer) >> FixedPointShift ); // set new sample rate
} SampleRate = 48000;
else { }
dst[i] = src[n];
dst[i+1] = src[n+1];
}
timer += ResampleRatio;
if(timer >= (s32)FixedPointScale) {
n += 2;
timer -= FixedPointScale;
}
}
} }
void SoundDecoder::Decode() void SoundDecoder::Upsample(int16_t *src, int16_t *dst, uint32_t nr_src_samples, uint32_t nr_dst_samples) {
{ int32_t timer = 0;
if(!file_fd || ExitRequested || EndOfFile)
return;
// check if we are not at the pre-last buffer (last buffer is playing) for(uint32_t i = 0, n = 0; i < nr_dst_samples; i += 2) {
u16 whichPlaying = SoundBuffer.Which(); if((n+3) < nr_src_samples) {
if( ((whichPlaying == 0) && (whichLoad == SoundBuffer.Size()-2)) // simple fixed point linear interpolation
|| ((whichPlaying == 1) && (whichLoad == SoundBuffer.Size()-1)) dst[i] = src[n] + ( ((src[n+2] - src[n] ) * timer) >> FixedPointShift );
|| (whichLoad == (whichPlaying-2))) dst[i+1] = src[n+1] + ( ((src[n+3] - src[n+1]) * timer) >> FixedPointShift );
{ } else {
return; dst[i] = src[n];
} dst[i+1] = src[n+1];
}
Decoding = true; timer += ResampleRatio;
s32 done = 0; if(timer >= (int32_t)FixedPointScale) {
u8 * write_buf = SoundBuffer.GetBuffer(whichLoad); n += 2;
if(!write_buf) timer -= FixedPointScale;
{ }
ExitRequested = true; }
Decoding = false; }
return;
}
if(ResampleTo48kHz && !ResampleBuffer) void SoundDecoder::Decode() {
EnableUpsample(); if(!file_fd || ExitRequested || EndOfFile)
return;
while(done < SoundBlockSize) // check if we are not at the pre-last buffer (last buffer is playing)
{ uint16_t whichPlaying = SoundBuffer.Which();
s32 ret = Read(&write_buf[done], SoundBlockSize-done, Tell()); if( ((whichPlaying == 0) && (whichLoad == SoundBuffer.Size()-2))
|| ((whichPlaying == 1) && (whichLoad == SoundBuffer.Size()-1))
|| (whichLoad == (whichPlaying-2))) {
return;
}
if(ret <= 0) Decoding = true;
{
if(Loop)
{
Rewind();
continue;
}
else
{
EndOfFile = true;
break;
}
}
done += ret; int32_t done = 0;
} uint8_t * write_buf = SoundBuffer.GetBuffer(whichLoad);
if(!write_buf) {
ExitRequested = true;
Decoding = false;
return;
}
if(done > 0) if(ResampleTo48kHz && !ResampleBuffer)
{ EnableUpsample();
// check if we need to resample
if(ResampleBuffer && ResampleRatio)
{
memcpy(ResampleBuffer, write_buf, done);
s32 src_samples = done >> 1; while(done < SoundBlockSize) {
s32 dest_samples = ( src_samples * FixedPointScale ) / ResampleRatio; int32_t ret = Read(&write_buf[done], SoundBlockSize-done, Tell());
dest_samples &= ~0x01;
Upsample((s16*)ResampleBuffer, (s16*)write_buf, src_samples, dest_samples);
done = dest_samples << 1;
}
//! TODO: remove this later and add STEREO support with two voices, for now we convert to MONO if(ret <= 0) {
if(IsStereo()) if(Loop) {
{ Rewind();
s16* monoBuf = (s16*)write_buf; continue;
done = done >> 1; } else {
EndOfFile = true;
break;
}
}
for(s32 i = 0; i < done; i++) done += ret;
}
if(done > 0) {
// check if we need to resample
if(ResampleBuffer && ResampleRatio) {
memcpy(ResampleBuffer, write_buf, done);
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()) {
int16_t* monoBuf = (int16_t*)write_buf;
done = done >> 1;
for(int32_t i = 0; i < done; i++)
monoBuf[i] = monoBuf[i << 1]; monoBuf[i] = monoBuf[i << 1];
} }
DCFlushRange(write_buf, done); DCFlushRange(write_buf, done);
SoundBuffer.SetBufferSize(whichLoad, done); SoundBuffer.SetBufferSize(whichLoad, done);
SoundBuffer.SetBufferReady(whichLoad, true); SoundBuffer.SetBufferReady(whichLoad, true);
if(++whichLoad >= SoundBuffer.Size()) if(++whichLoad >= SoundBuffer.Size())
whichLoad = 0; whichLoad = 0;
} }
// check if next in queue needs to be filled as well and do so // check if next in queue needs to be filled as well and do so
if(!SoundBuffer.IsBufferReady(whichLoad)) if(!SoundBuffer.IsBufferReady(whichLoad))
Decode(); 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 <unistd.h>
#include <malloc.h> #include <malloc.h>
//#include "common/common.h" #include <fs/CFile.hpp>
#include <dynamic_libs/ax_functions.h> #include <gui/sounds/SoundHandler.hpp>
#include "fs/CFile.hpp" #include <gui/sounds/WavDecoder.hpp>
#include "SoundHandler.hpp" #include <gui/sounds/Mp3Decoder.hpp>
#include "WavDecoder.hpp" #include <gui/sounds/OggDecoder.hpp>
#include "Mp3Decoder.hpp" #include <sndcore2/core.h>
#include "OggDecoder.hpp"
SoundHandler * SoundHandler::handlerInstance = NULL; SoundHandler * SoundHandler::handlerInstance = NULL;
SoundHandler::SoundHandler() SoundHandler::SoundHandler()
: CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 0, 0x8000) : CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 0, 0x8000) {
{ Decoding = false;
Decoding = false; ExitRequested = false;
ExitRequested = false; for(uint32_t i = 0; i < MAX_DECODERS; ++i) {
for(u32 i = 0; i < MAX_DECODERS; ++i) DecoderList[i] = NULL;
{
DecoderList[i] = NULL;
voiceList[i] = NULL; voiceList[i] = NULL;
} }
@ -50,302 +47,267 @@ SoundHandler::SoundHandler()
//! wait for initialization //! wait for initialization
while(!isThreadSuspended()) while(!isThreadSuspended())
os_usleep(1000); OSSleepTicks(OSMicrosecondsToTicks(1000));
} }
SoundHandler::~SoundHandler() SoundHandler::~SoundHandler() {
{ ExitRequested = true;
ExitRequested = true; ThreadSignal();
ThreadSignal();
ClearDecoderList(); ClearDecoderList();
} }
void SoundHandler::AddDecoder(s32 voice, const char * filepath) void SoundHandler::AddDecoder(int32_t voice, const char * filepath) {
{ if(voice < 0 || voice >= MAX_DECODERS)
if(voice < 0 || voice >= MAX_DECODERS) return;
return;
if(DecoderList[voice] != NULL) if(DecoderList[voice] != NULL)
RemoveDecoder(voice); RemoveDecoder(voice);
DecoderList[voice] = GetSoundDecoder(filepath); DecoderList[voice] = GetSoundDecoder(filepath);
} }
void SoundHandler::AddDecoder(s32 voice, const u8 * snd, s32 len) void SoundHandler::AddDecoder(int32_t voice, const uint8_t * snd, int32_t len) {
{ if(voice < 0 || voice >= MAX_DECODERS)
if(voice < 0 || voice >= MAX_DECODERS) return;
return;
if(DecoderList[voice] != NULL) if(DecoderList[voice] != NULL)
RemoveDecoder(voice); RemoveDecoder(voice);
DecoderList[voice] = GetSoundDecoder(snd, len); DecoderList[voice] = GetSoundDecoder(snd, len);
} }
void SoundHandler::RemoveDecoder(s32 voice) void SoundHandler::RemoveDecoder(int32_t voice) {
{ if(voice < 0 || voice >= MAX_DECODERS)
if(voice < 0 || voice >= MAX_DECODERS) return;
return;
if(DecoderList[voice] != NULL) if(DecoderList[voice] != NULL) {
{ if(voiceList[voice] && voiceList[voice]->getState() != Voice::STATE_STOPPED) {
if(voiceList[voice] && voiceList[voice]->getState() != Voice::STATE_STOPPED)
{
if(voiceList[voice]->getState() != Voice::STATE_STOP) if(voiceList[voice]->getState() != Voice::STATE_STOP)
voiceList[voice]->setState(Voice::STATE_STOP); voiceList[voice]->setState(Voice::STATE_STOP);
while(voiceList[voice]->getState() != Voice::STATE_STOPPED) // it shouldn't take longer than 3 ms actually but we wait up to 20
os_usleep(1000); // on application quit the AX frame callback is not called anymore
// therefore this would end in endless loop if no timeout is defined
int timeOut = 20;
while(--timeOut && (voiceList[voice]->getState() != Voice::STATE_STOPPED))
OSSleepTicks(OSMicrosecondsToTicks(1000));
} }
SoundDecoder *decoder = DecoderList[voice]; SoundDecoder *decoder = DecoderList[voice];
decoder->Lock(); decoder->Lock();
DecoderList[voice] = NULL; DecoderList[voice] = NULL;
decoder->Unlock(); decoder->Unlock();
delete decoder; delete decoder;
} }
} }
void SoundHandler::ClearDecoderList() void SoundHandler::ClearDecoderList() {
{ for(uint32_t i = 0; i < MAX_DECODERS; ++i)
for(u32 i = 0; i < MAX_DECODERS; ++i) RemoveDecoder(i);
RemoveDecoder(i);
} }
static inline bool CheckMP3Signature(const u8 * buffer) static inline bool CheckMP3Signature(const uint8_t * buffer) {
{ const char MP3_Magic[][3] = {
const char MP3_Magic[][3] = {'I', 'D', '3'}, //'ID3'
{ {0xff, 0xfe}, //'MPEG ADTS, layer III, v1.0 [protected]', 'mp3', 'audio/mpeg'),
{'I', 'D', '3'}, //'ID3' {0xff, 0xff}, //'MPEG ADTS, layer III, v1.0', 'mp3', 'audio/mpeg'),
{0xff, 0xfe}, //'MPEG ADTS, layer III, v1.0 [protected]', 'mp3', 'audio/mpeg'), {0xff, 0xfa}, //'MPEG ADTS, layer III, v1.0 [protected]', 'mp3', 'audio/mpeg'),
{0xff, 0xff}, //'MPEG ADTS, layer III, v1.0', 'mp3', 'audio/mpeg'), {0xff, 0xfb}, //'MPEG ADTS, layer III, v1.0', 'mp3', 'audio/mpeg'),
{0xff, 0xfa}, //'MPEG ADTS, layer III, v1.0 [protected]', 'mp3', 'audio/mpeg'), {0xff, 0xf2}, //'MPEG ADTS, layer III, v2.0 [protected]', 'mp3', 'audio/mpeg'),
{0xff, 0xfb}, //'MPEG ADTS, layer III, v1.0', 'mp3', 'audio/mpeg'), {0xff, 0xf3}, //'MPEG ADTS, layer III, v2.0', 'mp3', 'audio/mpeg'),
{0xff, 0xf2}, //'MPEG ADTS, layer III, v2.0 [protected]', 'mp3', 'audio/mpeg'), {0xff, 0xf4}, //'MPEG ADTS, layer III, v2.0 [protected]', 'mp3', 'audio/mpeg'),
{0xff, 0xf3}, //'MPEG ADTS, layer III, v2.0', 'mp3', 'audio/mpeg'), {0xff, 0xf5}, //'MPEG ADTS, layer III, v2.0', 'mp3', 'audio/mpeg'),
{0xff, 0xf4}, //'MPEG ADTS, layer III, v2.0 [protected]', 'mp3', 'audio/mpeg'), {0xff, 0xf6}, //'MPEG ADTS, layer III, v2.0 [protected]', 'mp3', 'audio/mpeg'),
{0xff, 0xf5}, //'MPEG ADTS, layer III, v2.0', 'mp3', 'audio/mpeg'), {0xff, 0xf7}, //'MPEG ADTS, layer III, v2.0', 'mp3', 'audio/mpeg'),
{0xff, 0xf6}, //'MPEG ADTS, layer III, v2.0 [protected]', 'mp3', 'audio/mpeg'), {0xff, 0xe2}, //'MPEG ADTS, layer III, v2.5 [protected]', 'mp3', 'audio/mpeg'),
{0xff, 0xf7}, //'MPEG ADTS, layer III, v2.0', 'mp3', 'audio/mpeg'), {0xff, 0xe3}, //'MPEG ADTS, layer III, v2.5', '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] && if(buffer[0] == MP3_Magic[0][0] && buffer[1] == MP3_Magic[0][1] &&
buffer[2] == MP3_Magic[0][2]) buffer[2] == MP3_Magic[0][2]) {
{ return true;
return true; }
}
for(s32 i = 1; i < 13; i++) for(int32_t i = 1; i < 13; i++) {
{ if(buffer[0] == MP3_Magic[i][0] && buffer[1] == MP3_Magic[i][1])
if(buffer[0] == MP3_Magic[i][0] && buffer[1] == MP3_Magic[i][1]) return true;
return true; }
}
return false; return false;
} }
SoundDecoder * SoundHandler::GetSoundDecoder(const char * filepath) SoundDecoder * SoundHandler::GetSoundDecoder(const char * filepath) {
{ uint32_t magic;
u32 magic; CFile f(filepath, CFile::ReadOnly);
CFile f(filepath, CFile::ReadOnly); if(f.size() == 0)
if(f.size() == 0) return NULL;
return NULL;
do do {
{ f.read((uint8_t *) &magic, 1);
f.read((u8 *) &magic, 1); } while(((uint8_t *) &magic)[0] == 0 && f.tell() < f.size());
}
while(((u8 *) &magic)[0] == 0 && f.tell() < f.size());
if(f.tell() == f.size()) if(f.tell() == f.size())
return NULL; return NULL;
f.seek(f.tell()-1, SEEK_SET); f.seek(f.tell()-1, SEEK_SET);
f.read((u8 *) &magic, 4); f.read((uint8_t *) &magic, 4);
f.close(); f.close();
if(magic == 0x4f676753) // 'OggS' if(magic == 0x4f676753) { // 'OggS'
{ return new OggDecoder(filepath);
return new OggDecoder(filepath); } else if(magic == 0x52494646) { // 'RIFF'
} return new WavDecoder(filepath);
else if(magic == 0x52494646) // 'RIFF' } else if(CheckMP3Signature((uint8_t *) &magic) == true) {
{ return new Mp3Decoder(filepath);
return new WavDecoder(filepath); }
}
else if(CheckMP3Signature((u8 *) &magic) == true)
{
return new Mp3Decoder(filepath);
}
return new SoundDecoder(filepath); return new SoundDecoder(filepath);
} }
SoundDecoder * SoundHandler::GetSoundDecoder(const u8 * sound, s32 length) SoundDecoder * SoundHandler::GetSoundDecoder(const uint8_t * sound, int32_t length) {
{ const uint8_t * check = sound;
const u8 * check = sound; int32_t counter = 0;
s32 counter = 0;
while(check[0] == 0 && counter < length) while(check[0] == 0 && counter < length) {
{ check++;
check++; counter++;
counter++; }
}
if(counter >= length) if(counter >= length)
return NULL; return NULL;
u32 * magic = (u32 *) check; uint32_t * magic = (uint32_t *) check;
if(magic[0] == 0x4f676753) // 'OggS' if(magic[0] == 0x4f676753) { // 'OggS'
{ return new OggDecoder(sound, length);
return new OggDecoder(sound, length); } else if(magic[0] == 0x52494646) { // 'RIFF'
} return new WavDecoder(sound, length);
else if(magic[0] == 0x52494646) // 'RIFF' } else if(CheckMP3Signature(check) == true) {
{ return new Mp3Decoder(sound, length);
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() void SoundHandler::executeThread() {
{ /*// v2 sound lib can not properly end transition audio on old firmwares
// v2 sound lib can not properly end transition audio on old firmwares
if (OS_FIRMWARE >= 400 && OS_FIRMWARE <= 410) if (OS_FIRMWARE >= 400 && OS_FIRMWARE <= 410)
{ {
ProperlyEndTransitionAudio(); ProperlyEndTransitionAudio();
} }*/
//! initialize 48 kHz renderer //! 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) // TODO: handle support for 3.1.0 with dynamic libs instead of static linking it
AXInitWithParams(params); //if(AXInitWithParams != 0)
else AXInitWithParams(&params);
AXInit(); //else
// AXInit();
// The problem with last voice on 500 was caused by it having priority 0 // 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 to change this priority distribution if for some reason
// we would need MAX_DECODERS > Voice::PRIO_MAX // we would need MAX_DECODERS > Voice::PRIO_MAX
for(u32 i = 0; i < MAX_DECODERS; ++i) for(uint32_t i = 0; i < MAX_DECODERS; ++i) {
{ int32_t priority = (MAX_DECODERS - i) * Voice::PRIO_MAX / MAX_DECODERS;
s32 priority = (MAX_DECODERS - i) * Voice::PRIO_MAX / MAX_DECODERS;
voiceList[i] = new Voice(priority); // allocate voice 0 with highest priority voiceList[i] = new Voice(priority); // allocate voice 0 with highest priority
} }
AXRegisterFrameCallback((void*)&axFrameCallback); AXRegisterAppFrameCallback(SoundHandler::axFrameCallback);
u16 i = 0; uint16_t i = 0;
while (!ExitRequested) while (!ExitRequested) {
{ suspendThread();
suspendThread();
for(i = 0; i < MAX_DECODERS; ++i) for(i = 0; i < MAX_DECODERS; ++i) {
{ if(DecoderList[i] == NULL)
if(DecoderList[i] == NULL) continue;
continue;
Decoding = true; Decoding = true;
if(DecoderList[i]) if(DecoderList[i])
DecoderList[i]->Lock(); DecoderList[i]->Lock();
if(DecoderList[i]) if(DecoderList[i])
DecoderList[i]->Decode(); DecoderList[i]->Decode();
if(DecoderList[i]) if(DecoderList[i])
DecoderList[i]->Unlock(); 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(); voiceList[i]->stop();
AXRegisterFrameCallback(NULL); AXRegisterAppFrameCallback(NULL);
AXQuit(); AXQuit();
for(u32 i = 0; i < MAX_DECODERS; ++i) for(uint32_t i = 0; i < MAX_DECODERS; ++i) {
{
delete voiceList[i]; delete voiceList[i];
voiceList[i] = NULL; voiceList[i] = NULL;
} }
} }
void SoundHandler::axFrameCallback(void) void SoundHandler::axFrameCallback(void) {
{ for (uint32_t i = 0; i < MAX_DECODERS; i++) {
for (u32 i = 0; i < MAX_DECODERS; i++)
{
Voice *voice = handlerInstance->getVoice(i); Voice *voice = handlerInstance->getVoice(i);
switch (voice->getState()) switch (voice->getState()) {
{ default:
default: case Voice::STATE_STOPPED:
case Voice::STATE_STOPPED: break;
break;
case Voice::STATE_START: { case Voice::STATE_START: {
SoundDecoder * decoder = handlerInstance->getDecoder(i); SoundDecoder * decoder = handlerInstance->getDecoder(i);
decoder->Lock(); decoder->Lock();
if(decoder->IsBufferReady()) if(decoder->IsBufferReady()) {
{ const uint8_t *buffer = decoder->GetBuffer();
const u8 *buffer = decoder->GetBuffer(); const uint32_t bufferSize = decoder->GetBufferSize();
const u32 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(); 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: decoder->Unlock();
if(voice->getInternState() == 1) break;
{ }
if(voice->isBufferSwitched()) case Voice::STATE_PLAYING:
{ if(voice->getInternState() == 1) {
SoundDecoder * decoder = handlerInstance->getDecoder(i); if(voice->isBufferSwitched()) {
decoder->Lock(); SoundDecoder * decoder = handlerInstance->getDecoder(i);
if(decoder->IsBufferReady()) decoder->Lock();
{ if(decoder->IsBufferReady()) {
voice->setNextBuffer(decoder->GetBuffer(), decoder->GetBufferSize()); voice->setNextBuffer(decoder->GetBuffer(), decoder->GetBufferSize());
decoder->LoadNext(); decoder->LoadNext();
handlerInstance->ThreadSignal(); handlerInstance->ThreadSignal();
} } else if(decoder->IsEOF()) {
else if(decoder->IsEOF()) voice->setState(Voice::STATE_STOP);
{
voice->setState(Voice::STATE_STOP);
}
decoder->Unlock();
} }
decoder->Unlock();
} }
else } else {
{
voice->setState(Voice::STATE_STOPPED);
}
break;
case Voice::STATE_STOP:
if(voice->getInternState() != 0)
voice->stop();
voice->setState(Voice::STATE_STOPPED); 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,117 @@
* for WiiXplorer 2010 * for WiiXplorer 2010
***************************************************************************/ ***************************************************************************/
#include <string.h> #include <string.h>
#include "WavDecoder.hpp" #include <gui/sounds/WavDecoder.hpp>
#include "fs/CFile.hpp"
#include "utils/utils.h" #include "utils/utils.h"
WavDecoder::WavDecoder(const char * filepath) WavDecoder::WavDecoder(const char * filepath)
: SoundDecoder(filepath) : SoundDecoder(filepath) {
{ SoundType = SOUND_WAV;
SoundType = SOUND_WAV; SampleRate = 48000;
SampleRate = 48000; Format = CHANNELS_STEREO | FORMAT_PCM_16_BIT;
Format = CHANNELS_STEREO | FORMAT_PCM_16_BIT;
if(!file_fd) if(!file_fd)
return; return;
OpenFile(); OpenFile();
} }
WavDecoder::WavDecoder(const u8 * snd, s32 len) WavDecoder::WavDecoder(const uint8_t * snd, int32_t len)
: SoundDecoder(snd, len) : SoundDecoder(snd, len) {
{ SoundType = SOUND_WAV;
SoundType = SOUND_WAV; SampleRate = 48000;
SampleRate = 48000; Format = CHANNELS_STEREO | FORMAT_PCM_16_BIT;
Format = CHANNELS_STEREO | FORMAT_PCM_16_BIT;
if(!file_fd) if(!file_fd)
return; return;
OpenFile(); OpenFile();
} }
WavDecoder::~WavDecoder() WavDecoder::~WavDecoder() {
{
} }
void WavDecoder::OpenFile() void WavDecoder::OpenFile() {
{ SWaveHdr Header;
SWaveHdr Header; SWaveFmtChunk FmtChunk;
SWaveFmtChunk FmtChunk; memset(&Header, 0, sizeof(SWaveHdr));
memset(&Header, 0, sizeof(SWaveHdr)); memset(&FmtChunk, 0, sizeof(SWaveFmtChunk));
memset(&FmtChunk, 0, sizeof(SWaveFmtChunk));
file_fd->read((u8 *) &Header, sizeof(SWaveHdr)); file_fd->read((uint8_t *) &Header, sizeof(SWaveHdr));
file_fd->read((u8 *) &FmtChunk, sizeof(SWaveFmtChunk)); file_fd->read((uint8_t *) &FmtChunk, sizeof(SWaveFmtChunk));
if (Header.magicRIFF != 0x52494646) // 'RIFF' if (Header.magicRIFF != 0x52494646) { // 'RIFF'
{ CloseFile();
CloseFile(); return;
return; } else if(Header.magicWAVE != 0x57415645) { // 'WAVE'
} CloseFile();
else if(Header.magicWAVE != 0x57415645) // 'WAVE' return;
{ } else if(FmtChunk.magicFMT != 0x666d7420) { // 'fmt '
CloseFile(); CloseFile();
return; return;
} }
else if(FmtChunk.magicFMT != 0x666d7420) // 'fmt '
{
CloseFile();
return;
}
DataOffset = sizeof(SWaveHdr)+le32(FmtChunk.size)+8; DataOffset = sizeof(SWaveHdr)+le32(FmtChunk.size)+8;
file_fd->seek(DataOffset, SEEK_SET); file_fd->seek(DataOffset, SEEK_SET);
SWaveChunk DataChunk; SWaveChunk DataChunk;
file_fd->read((u8 *) &DataChunk, sizeof(SWaveChunk)); file_fd->read((uint8_t *) &DataChunk, sizeof(SWaveChunk));
while(DataChunk.magicDATA != 0x64617461) // 'data' while(DataChunk.magicDATA != 0x64617461) { // 'data'
{ DataOffset += 8+le32(DataChunk.size);
DataOffset += 8+le32(DataChunk.size); file_fd->seek(DataOffset, SEEK_SET);
file_fd->seek(DataOffset, SEEK_SET); int32_t ret = file_fd->read((uint8_t *) &DataChunk, sizeof(SWaveChunk));
s32 ret = file_fd->read((u8 *) &DataChunk, sizeof(SWaveChunk)); if(ret <= 0) {
if(ret <= 0) CloseFile();
{ return;
CloseFile(); }
return; }
}
}
DataOffset += 8; DataOffset += 8;
DataSize = le32(DataChunk.size); DataSize = le32(DataChunk.size);
Is16Bit = (le16(FmtChunk.bps) == 16); Is16Bit = (le16(FmtChunk.bps) == 16);
SampleRate = le32(FmtChunk.freq); SampleRate = le32(FmtChunk.freq);
if (le16(FmtChunk.channels) == 1 && le16(FmtChunk.bps) == 8 && le16(FmtChunk.alignment) <= 1) if (le16(FmtChunk.channels) == 1 && le16(FmtChunk.bps) == 8 && le16(FmtChunk.alignment) <= 1)
Format = CHANNELS_MONO | FORMAT_PCM_8_BIT; Format = CHANNELS_MONO | FORMAT_PCM_8_BIT;
else if (le16(FmtChunk.channels) == 1 && le16(FmtChunk.bps) == 16 && le16(FmtChunk.alignment) <= 2) else if (le16(FmtChunk.channels) == 1 && le16(FmtChunk.bps) == 16 && le16(FmtChunk.alignment) <= 2)
Format = CHANNELS_MONO | FORMAT_PCM_16_BIT; Format = CHANNELS_MONO | FORMAT_PCM_16_BIT;
else if (le16(FmtChunk.channels) == 2 && le16(FmtChunk.bps) == 8 && le16(FmtChunk.alignment) <= 2) else if (le16(FmtChunk.channels) == 2 && le16(FmtChunk.bps) == 8 && le16(FmtChunk.alignment) <= 2)
Format = CHANNELS_STEREO | FORMAT_PCM_8_BIT; Format = CHANNELS_STEREO | FORMAT_PCM_8_BIT;
else if (le16(FmtChunk.channels) == 2 && le16(FmtChunk.bps) == 16 && le16(FmtChunk.alignment) <= 4) else if (le16(FmtChunk.channels) == 2 && le16(FmtChunk.bps) == 16 && le16(FmtChunk.alignment) <= 4)
Format = CHANNELS_STEREO | FORMAT_PCM_16_BIT; Format = CHANNELS_STEREO | FORMAT_PCM_16_BIT;
} }
void WavDecoder::CloseFile() void WavDecoder::CloseFile() {
{ if(file_fd)
if(file_fd) delete file_fd;
delete file_fd;
file_fd = NULL; file_fd = NULL;
} }
s32 WavDecoder::Read(u8 * buffer, s32 buffer_size, s32 pos) int32_t WavDecoder::Read(uint8_t * buffer, int32_t buffer_size, int32_t pos) {
{ if(!file_fd)
if(!file_fd) return -1;
return -1;
if(CurPos >= (s32) DataSize) if(CurPos >= (int32_t) DataSize)
return 0; return 0;
file_fd->seek(DataOffset+CurPos, SEEK_SET); file_fd->seek(DataOffset+CurPos, SEEK_SET);
if(buffer_size > (s32) DataSize-CurPos) if(buffer_size > (int32_t) DataSize-CurPos)
buffer_size = DataSize-CurPos; buffer_size = DataSize-CurPos;
s32 read = file_fd->read(buffer, buffer_size); int32_t read = file_fd->read(buffer, buffer_size);
if(read > 0) if(read > 0) {
{ if (Is16Bit) {
if (Is16Bit) read &= ~0x0001;
{
read &= ~0x0001;
for (u32 i = 0; i < (u32) (read / sizeof (u16)); ++i) for (uint32_t i = 0; i < (uint32_t) (read / sizeof (uint16_t)); ++i)
((u16 *) buffer)[i] = le16(((u16 *) buffer)[i]); ((uint16_t *) buffer)[i] = le16(((uint16_t *) buffer)[i]);
} }
CurPos += read; CurPos += read;
} }
return read; return read;
} }

View File

@ -14,30 +14,29 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#ifndef __GUI_H #ifndef __MEMORY_H_
#define __GUI_H #define __MEMORY_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"
#ifdef __cplusplus
extern "C" {
#endif #endif
#include <malloc.h>
void memoryInitialize(void);
void memoryRelease(void);
void * MEM2_alloc(uint32_t size, uint32_t align);
void MEM2_free(void *ptr);
void * MEM1_alloc(uint32_t size, uint32_t align);
void MEM1_free(void *ptr);
void * MEMBucket_alloc(uint32_t size, uint32_t align);
void MEMBucket_free(void *ptr);
#ifdef __cplusplus
}
#endif
#endif // __MEMORY_H_

35
source/utils/utils.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef __UTILS_H_
#define __UTILS_H_
#include <malloc.h>
#ifdef __cplusplus
extern "C" {
#endif
#define LIMIT(x, min, max) \
({ \
typeof( x ) _x = x; \
typeof( min ) _min = min; \
typeof( max ) _max = max; \
( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \
})
#define DegToRad(a) ( (a) * 0.01745329252f )
#define RadToDeg(a) ( (a) * 57.29577951f )
#define ALIGN4(x) (((x) + 3) & ~3)
#define ALIGN32(x) (((x) + 31) & ~31)
#define le16(i) ((((uint16_t) ((i) & 0xFF)) << 8) | ((uint16_t) (((i) & 0xFF00) >> 8)))
#define le32(i) ((((uint32_t)le16((i) & 0xFFFF)) << 16) | ((uint32_t)le16(((i) & 0xFFFF0000) >> 16)))
#define le64(i) ((((uint64_t)le32((i) & 0xFFFFFFFFLL)) << 32) | ((uint64_t)le32(((i) & 0xFFFFFFFF00000000LL) >> 32)))
//Needs to have log_init() called beforehand.
void dumpHex(const void* data, size_t size);
#ifdef __cplusplus
}
#endif
#endif // __UTILS_H_

View File

@ -16,17 +16,16 @@
****************************************************************************/ ****************************************************************************/
#include <malloc.h> #include <malloc.h>
#include <string.h> #include <string.h>
#include "CVideo.h" #include <gui/video/CVideo.h>
#include <system/memory.h> #include "system/memory.h"
#include "shaders/Texture2DShader.h" #include <gui/video/shaders/Texture2DShader.h>
#include "shaders/ColorShader.h" #include <gui/video/shaders/ColorShader.h>
#include "shaders/Shader3D.h" #include <gui/video/shaders/Shader3D.h>
#include "shaders/ShaderFractalColor.h" #include <gui/video/shaders/ShaderFractalColor.h>
#include "shaders/FXAAShader.h" #include <gui/video/shaders/FXAAShader.h>
#include <dynamic_libs/os_functions.h> #include "utils/utils.h"
CVideo::CVideo(s32 forceTvScanMode, s32 forceDrcScanMode) CVideo::CVideo(int32_t forceTvScanMode, int32_t forceDrcScanMode) {
{
tvEnabled = false; tvEnabled = false;
drcEnabled = false; drcEnabled = false;
@ -34,134 +33,128 @@ CVideo::CVideo(s32 forceTvScanMode, s32 forceDrcScanMode)
gx2CommandBuffer = MEM2_alloc(GX2_COMMAND_BUFFER_SIZE, 0x40); gx2CommandBuffer = MEM2_alloc(GX2_COMMAND_BUFFER_SIZE, 0x40);
//! initialize GX2 command buffer //! initialize GX2 command buffer
u32 gx2_init_attributes[9]; uint32_t gx2_init_attributes[9];
gx2_init_attributes[0] = GX2_INIT_ATTRIB_CB_BASE; gx2_init_attributes[0] = GX2_INIT_CMD_BUF_BASE;
gx2_init_attributes[1] = (u32)gx2CommandBuffer; gx2_init_attributes[1] = (uint32_t)gx2CommandBuffer;
gx2_init_attributes[2] = GX2_INIT_ATTRIB_CB_SIZE; gx2_init_attributes[2] = GX2_INIT_CMD_BUF_POOL_SIZE;
gx2_init_attributes[3] = GX2_COMMAND_BUFFER_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[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[7] = 0;
gx2_init_attributes[8] = GX2_INIT_ATTRIB_NULL; gx2_init_attributes[8] = GX2_INIT_END;
GX2Init(gx2_init_attributes); GX2Init(gx2_init_attributes);
//! GX2 resources are not used in this application but if needed, the allocator is setup uint32_t scanBufferSize = 0;
GX2RSetAllocator(&CVideo::GX2RAlloc, &CVideo::GX2RFree); uint32_t scaleNeeded = 0;
u32 scanBufferSize = 0; int32_t tvScanMode = ((forceTvScanMode >= 0) ? forceTvScanMode : (int32_t)GX2GetSystemTVScanMode());
s32 scaleNeeded = 0; int32_t drcScanMode = ((forceDrcScanMode >= 0) ? forceDrcScanMode : (int32_t)GX2GetSystemDRCScanMode());
s32 tvScanMode = (forceTvScanMode >= 0) ? forceTvScanMode : GX2GetSystemTVScanMode(); int32_t tvRenderMode;
s32 drcScanMode = (forceDrcScanMode >= 0) ? forceDrcScanMode : GX2GetSystemDRCScanMode(); uint32_t tvWidth = 0;
uint32_t tvHeight = 0;
s32 tvRenderMode; switch(tvScanMode) {
u32 tvWidth = 0;
u32 tvHeight = 0;
switch(tvScanMode)
{
case GX2_TV_SCAN_MODE_480I: case GX2_TV_SCAN_MODE_480I:
case GX2_TV_SCAN_MODE_480P: case GX2_TV_SCAN_MODE_480P:
tvWidth = 854; tvWidth = 854;
tvHeight = 480; tvHeight = 480;
tvRenderMode = GX2_TV_RENDER_480_WIDE; tvRenderMode = GX2_TV_RENDER_MODE_WIDE_480P;
break; break;
case GX2_TV_SCAN_MODE_1080I: case GX2_TV_SCAN_MODE_1080I:
case GX2_TV_SCAN_MODE_1080P: case GX2_TV_SCAN_MODE_1080P:
tvWidth = 1920; tvWidth = 1920;
tvHeight = 1080; tvHeight = 1080;
tvRenderMode = GX2_TV_RENDER_1080; tvRenderMode = GX2_TV_RENDER_MODE_WIDE_1080P;
break; break;
case GX2_TV_SCAN_MODE_720P: case GX2_TV_SCAN_MODE_720P:
default: default:
tvWidth = 1280; tvWidth = 1280;
tvHeight = 720; tvHeight = 720;
tvRenderMode = GX2_TV_RENDER_720; tvRenderMode = GX2_TV_RENDER_MODE_WIDE_720P;
break; break;
} }
s32 tvAAMode = GX2_AA_MODE_1X; int32_t tvAAMode = GX2_AA_MODE1X;
s32 drcAAMode = GX2_AA_MODE_4X; int32_t drcAAMode = GX2_AA_MODE4X;
//! calculate the scale factor for later texture resize //! calculate the scale factor for later texture resize
widthScaleFactor = 1.0f / (f32)tvWidth; widthScaleFactor = 1.0f / (float)tvWidth;
heightScaleFactor = 1.0f / (f32)tvHeight; heightScaleFactor = 1.0f / (float)tvHeight;
depthScaleFactor = widthScaleFactor; depthScaleFactor = widthScaleFactor;
//! calculate the size needed for the TV scan buffer and allocate the buffer from bucket memory //! 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); tvScanBuffer = MEMBucket_alloc(scanBufferSize, GX2_SCAN_BUFFER_ALIGNMENT);
GX2Invalidate(GX2_INVALIDATE_CPU, tvScanBuffer, scanBufferSize); GX2Invalidate(GX2_INVALIDATE_MODE_CPU, tvScanBuffer, scanBufferSize);
GX2SetTVBuffer(tvScanBuffer, scanBufferSize, tvRenderMode, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GX2_BUFFERING_DOUBLE); 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 //! 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); drcScanBuffer = MEMBucket_alloc(scanBufferSize, GX2_SCAN_BUFFER_ALIGNMENT);
GX2Invalidate(GX2_INVALIDATE_CPU, drcScanBuffer, scanBufferSize); GX2Invalidate(GX2_INVALIDATE_MODE_CPU, drcScanBuffer, scanBufferSize);
GX2SetDRCBuffer(drcScanBuffer, scanBufferSize, drcScanMode, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GX2_BUFFERING_DOUBLE); GX2SetDRCBuffer(drcScanBuffer, scanBufferSize, (GX2DrcRenderMode)drcScanMode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE);
//! Setup color buffer for TV rendering //! 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); GX2InitColorBuffer(&tvColorBuffer, GX2_SURFACE_DIM_TEXTURE_2D, tvWidth, tvHeight, 1, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, (GX2AAMode)tvAAMode);
tvColorBuffer.surface.image_data = MEM1_alloc(tvColorBuffer.surface.image_size, tvColorBuffer.surface.align); tvColorBuffer.surface.image = MEM1_alloc(tvColorBuffer.surface.imageSize, tvColorBuffer.surface.alignment);
GX2Invalidate(GX2_INVALIDATE_CPU, tvColorBuffer.surface.image_data, tvColorBuffer.surface.image_size); 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 //! 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 //! this should be ok for our purpose i guess
//! Setup TV depth buffer (can be the same for both if rendered one after another) //! Setup TV depth buffer (can be the same for both if rendered one after another)
u32 size, align; uint32_t size, align;
GX2InitDepthBuffer(&tvDepthBuffer, GX2_SURFACE_DIM_2D, tvColorBuffer.surface.width, tvColorBuffer.surface.height, 1, GX2_SURFACE_FORMAT_TCD_R32_FLOAT, tvAAMode); GX2InitDepthBuffer(&tvDepthBuffer, GX2_SURFACE_DIM_TEXTURE_2D, tvColorBuffer.surface.width, tvColorBuffer.surface.height, 1, GX2_SURFACE_FORMAT_FLOAT_R32, (GX2AAMode)tvAAMode);
tvDepthBuffer.surface.image_data = MEM1_alloc(tvDepthBuffer.surface.image_size, tvDepthBuffer.surface.align); tvDepthBuffer.surface.image = MEM1_alloc(tvDepthBuffer.surface.imageSize, tvDepthBuffer.surface.alignment);
GX2Invalidate(GX2_INVALIDATE_CPU, tvDepthBuffer.surface.image_data, tvDepthBuffer.surface.image_size); GX2Invalidate(GX2_INVALIDATE_MODE_CPU, tvDepthBuffer.surface.image, tvDepthBuffer.surface.imageSize);
//! Setup TV HiZ buffer //! Setup TV HiZ buffer
GX2CalcDepthBufferHiZInfo(&tvDepthBuffer, &size, &align); GX2CalcDepthBufferHiZInfo(&tvDepthBuffer, &size, &align);
tvDepthBuffer.hiZ_data = MEM1_alloc(size, align); tvDepthBuffer.hiZPtr = MEM1_alloc(size, align);
GX2Invalidate(GX2_INVALIDATE_CPU, tvDepthBuffer.hiZ_data, size); GX2Invalidate(GX2_INVALIDATE_MODE_CPU, tvDepthBuffer.hiZPtr, size);
GX2InitDepthBufferHiZEnable(&tvDepthBuffer, GX2_ENABLE); GX2InitDepthBufferHiZEnable(&tvDepthBuffer, GX2_ENABLE);
//! Setup color buffer for DRC rendering //! 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); GX2InitColorBuffer(&drcColorBuffer, GX2_SURFACE_DIM_TEXTURE_2D, 854, 480, 1, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, (GX2AAMode)drcAAMode);
drcColorBuffer.surface.image_data = MEM1_alloc(drcColorBuffer.surface.image_size, drcColorBuffer.surface.align); drcColorBuffer.surface.image = MEM1_alloc(drcColorBuffer.surface.imageSize, drcColorBuffer.surface.alignment);
GX2Invalidate(GX2_INVALIDATE_CPU, drcColorBuffer.surface.image_data, drcColorBuffer.surface.image_size); 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) //! 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); GX2InitDepthBuffer(&drcDepthBuffer, GX2_SURFACE_DIM_TEXTURE_2D, drcColorBuffer.surface.width, drcColorBuffer.surface.height, 1, GX2_SURFACE_FORMAT_FLOAT_R32, (GX2AAMode)drcAAMode);
drcDepthBuffer.surface.image_data = MEM1_alloc(drcDepthBuffer.surface.image_size, drcDepthBuffer.surface.align); drcDepthBuffer.surface.image = MEM1_alloc(drcDepthBuffer.surface.imageSize, drcDepthBuffer.surface.alignment);
GX2Invalidate(GX2_INVALIDATE_CPU, drcDepthBuffer.surface.image_data, drcDepthBuffer.surface.image_size); GX2Invalidate(GX2_INVALIDATE_MODE_CPU, drcDepthBuffer.surface.image, drcDepthBuffer.surface.imageSize);
//! Setup DRC HiZ buffer //! Setup DRC HiZ buffer
GX2CalcDepthBufferHiZInfo(&drcDepthBuffer, &size, &align); GX2CalcDepthBufferHiZInfo(&drcDepthBuffer, &size, &align);
drcDepthBuffer.hiZ_data = MEM1_alloc(size, align); drcDepthBuffer.hiZPtr = MEM1_alloc(size, align);
GX2Invalidate(GX2_INVALIDATE_CPU, drcDepthBuffer.hiZ_data, size); GX2Invalidate(GX2_INVALIDATE_MODE_CPU, drcDepthBuffer.hiZPtr, size);
GX2InitDepthBufferHiZEnable(&drcDepthBuffer, GX2_ENABLE); GX2InitDepthBufferHiZEnable(&drcDepthBuffer, GX2_ENABLE);
//! allocate auxilary buffer last as there might not be enough MEM1 left for other stuff after that //! allocate auxilary buffer last as there might not be enough MEM1 left for other stuff after that
if (tvColorBuffer.surface.aa) if (tvColorBuffer.surface.aa) {
{ uint32_t auxSize, auxAlign;
u32 auxSize, auxAlign;
GX2CalcColorBufferAuxInfo(&tvColorBuffer, &auxSize, &auxAlign); GX2CalcColorBufferAuxInfo(&tvColorBuffer, &auxSize, &auxAlign);
tvColorBuffer.aux_data = MEM1_alloc(auxSize, auxAlign); tvColorBuffer.aaBuffer = MEM1_alloc(auxSize, auxAlign);
if(!tvColorBuffer.aux_data) if(!tvColorBuffer.aaBuffer)
tvColorBuffer.aux_data = MEM2_alloc(auxSize, auxAlign); tvColorBuffer.aaBuffer = MEM2_alloc(auxSize, auxAlign);
tvColorBuffer.aux_size = auxSize; tvColorBuffer.aaSize = auxSize;
memset(tvColorBuffer.aux_data, GX2_AUX_BUFFER_CLEAR_VALUE, auxSize); memset(tvColorBuffer.aaBuffer, GX2_AA_BUFFER_CLEAR_VALUE, auxSize);
GX2Invalidate(GX2_INVALIDATE_CPU, tvColorBuffer.aux_data, auxSize); GX2Invalidate(GX2_INVALIDATE_MODE_CPU, tvColorBuffer.aaBuffer, auxSize);
} }
if (drcColorBuffer.surface.aa) if (drcColorBuffer.surface.aa) {
{ uint32_t auxSize, auxAlign;
u32 auxSize, auxAlign;
GX2CalcColorBufferAuxInfo(&drcColorBuffer, &auxSize, &auxAlign); GX2CalcColorBufferAuxInfo(&drcColorBuffer, &auxSize, &auxAlign);
drcColorBuffer.aux_data = MEM1_alloc(auxSize, auxAlign); drcColorBuffer.aaBuffer = MEM1_alloc(auxSize, auxAlign);
if(!drcColorBuffer.aux_data) if(!drcColorBuffer.aaBuffer)
drcColorBuffer.aux_data = MEM2_alloc(auxSize, auxAlign); drcColorBuffer.aaBuffer = MEM2_alloc(auxSize, auxAlign);
drcColorBuffer.aux_size = auxSize; drcColorBuffer.aaSize = auxSize;
memset(drcColorBuffer.aux_data, GX2_AUX_BUFFER_CLEAR_VALUE, auxSize); memset(drcColorBuffer.aaBuffer, GX2_AA_BUFFER_CLEAR_VALUE, auxSize);
GX2Invalidate(GX2_INVALIDATE_CPU, drcColorBuffer.aux_data, auxSize ); GX2Invalidate(GX2_INVALIDATE_MODE_CPU, drcColorBuffer.aaBuffer, auxSize);
} }
//! allocate memory and setup context state TV //! allocate memory and setup context state TV
@ -192,23 +185,22 @@ CVideo::CVideo(s32 forceTvScanMode, s32 forceDrcScanMode)
//GX2SetDRCGamma(0.8f); //GX2SetDRCGamma(0.8f);
//! initialize perspective matrix //! 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::mat4(1.0f);
viewMtx = glm::translate(viewMtx, glm::vec3(0.0f, 0.0f, -2.5f)); 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::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); 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_TCS_R8_G8_B8_A8_UNORM, GX2_SURFACE_DIM_2D, GX2_TILE_MODE_DEFAULT); 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_data = tvColorBuffer.surface.image_data; tvAaTexture.surface.image = tvColorBuffer.surface.image;
tvAaTexture.surface.image_size = tvColorBuffer.surface.image_size; tvAaTexture.surface.imageSize = tvColorBuffer.surface.imageSize;
tvAaTexture.surface.mip_data = tvColorBuffer.surface.mip_data; tvAaTexture.surface.mipmaps = tvColorBuffer.surface.mipmaps;
} }
CVideo::~CVideo() CVideo::~CVideo() {
{
//! flush buffers //! flush buffers
GX2Flush(); GX2Flush();
GX2DrawDone(); GX2DrawDone();
@ -220,71 +212,47 @@ CVideo::~CVideo()
MEMBucket_free(tvScanBuffer); MEMBucket_free(tvScanBuffer);
MEMBucket_free(drcScanBuffer); MEMBucket_free(drcScanBuffer);
//! free color buffers //! free color buffers
MEM1_free(tvColorBuffer.surface.image_data); MEM1_free(tvColorBuffer.surface.image);
MEM1_free(drcColorBuffer.surface.image_data); MEM1_free(drcColorBuffer.surface.image);
//! free depth buffers //! free depth buffers
MEM1_free(tvDepthBuffer.surface.image_data); MEM1_free(tvDepthBuffer.surface.image);
MEM1_free(tvDepthBuffer.hiZ_data); MEM1_free(tvDepthBuffer.hiZPtr);
MEM1_free(drcDepthBuffer.surface.image_data); MEM1_free(drcDepthBuffer.surface.image);
MEM1_free(drcDepthBuffer.hiZ_data); MEM1_free(drcDepthBuffer.hiZPtr);
//! free context buffers //! free context buffers
MEM2_free(tvContextState); MEM2_free(tvContextState);
MEM2_free(drcContextState); MEM2_free(drcContextState);
//! free aux buffer //! free aux buffer
if(tvColorBuffer.aux_data) if(tvColorBuffer.aaBuffer) {
{ if(((uint32_t)tvColorBuffer.aaBuffer & 0xF0000000) == 0xF0000000)
if(((u32)tvColorBuffer.aux_data & 0xF0000000) == 0xF0000000) MEM1_free(tvColorBuffer.aaBuffer);
MEM1_free(tvColorBuffer.aux_data);
else else
MEM2_free(tvColorBuffer.aux_data); MEM2_free(tvColorBuffer.aaBuffer);
} }
if(drcColorBuffer.aux_data) if(drcColorBuffer.aaBuffer) {
{ if(((uint32_t)drcColorBuffer.aaBuffer & 0xF0000000) == 0xF0000000)
if(((u32)drcColorBuffer.aux_data & 0xF0000000) == 0xF0000000) MEM1_free(drcColorBuffer.aaBuffer);
MEM1_free(drcColorBuffer.aux_data);
else else
MEM2_free(drcColorBuffer.aux_data); MEM2_free(drcColorBuffer.aaBuffer);
} }
//! destroy shaders //! destroy shaders
ColorShader::destroyInstance(); ColorShader::destroyInstance();
FXAAShader::destroyInstance(); FXAAShader::destroyInstance();
Shader3D::destroyInstance(); Shader3D::destroyInstance();
ShaderFractalColor::destroyInstance();
Texture2DShader::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[0] = texture->surface.width;
resolution[1] = texture->surface.height; 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()->setShaders();
FXAAShader::instance()->setAttributeBuffer(); FXAAShader::instance()->setAttributeBuffer();
FXAAShader::instance()->setResolution(resolution); FXAAShader::instance()->setResolution(resolution);
FXAAShader::instance()->setTextureAndSampler(texture, sampler); FXAAShader::instance()->setTextureAndSampler(texture, sampler);
FXAAShader::instance()->draw(); FXAAShader::instance()->draw();
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL); GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_FUNC_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);
} }

View File

@ -18,58 +18,54 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <dynamic_libs/gx2_functions.h> #include <gui/video/shaders/ColorShader.h>
#include "video/shaders/ColorShader.h" #include <gui/video/shaders/FXAAShader.h>
#include "video/shaders/FXAAShader.h" #include <gui/video/shaders/Shader3D.h>
#include "video/shaders/Shader3D.h" #include <gui/video/shaders/ShaderFractalColor.h>
#include "video/shaders/ShaderFractalColor.h" #include <gui/video/shaders/Texture2DShader.h>
#include "video/shaders/Texture2DShader.h" #include <gui/video/CursorDrawer.h>
#include "CursorDrawer.h"
CursorDrawer *CursorDrawer::instance = NULL; CursorDrawer *CursorDrawer::instance = NULL;
CursorDrawer::CursorDrawer() CursorDrawer::CursorDrawer() {
{
init_colorVtxs(); init_colorVtxs();
} }
CursorDrawer::~CursorDrawer() CursorDrawer::~CursorDrawer() {
{
//! destroy shaders //! destroy shaders
ColorShader::destroyInstance(); ColorShader::destroyInstance();
FXAAShader::destroyInstance(); FXAAShader::destroyInstance();
Shader3D::destroyInstance(); Shader3D::destroyInstance();
ShaderFractalColor::destroyInstance(); ShaderFractalColor::destroyInstance();
Texture2DShader::destroyInstance(); Texture2DShader::destroyInstance();
if(this->colorVtxs){ if(this->colorVtxs) {
free(this->colorVtxs); free(this->colorVtxs);
this->colorVtxs = NULL; this->colorVtxs = NULL;
} }
} }
void CursorDrawer::init_colorVtxs(){ void CursorDrawer::init_colorVtxs() {
if(!this->colorVtxs){ if(!this->colorVtxs) {
this->colorVtxs = (u8*)memalign(0x40, sizeof(u8) * 16); this->colorVtxs = (uint8_t*)memalign(0x40, sizeof(uint8_t) * 16);
if(this->colorVtxs == NULL) return; 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. // Could be improved. It be more generic.
void CursorDrawer::draw_Cursor(f32 x,f32 y) void CursorDrawer::draw_Cursor(float x,float y) {
{ if(this->colorVtxs == NULL) {
if(this->colorVtxs == NULL){
init_colorVtxs(); init_colorVtxs();
return; return;
} }
f32 widthScaleFactor = 1.0f / (f32)1280; float widthScaleFactor = 1.0f / (float)1280;
f32 heightScaleFactor = 1.0f / (f32)720; float heightScaleFactor = 1.0f / (float)720;
s32 width = 20; int32_t width = 20;
glm::vec3 positionOffsets = glm::vec3(0.0f); 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()->setOffset(positionOffsets);
ColorShader::instance()->setScale(scale); ColorShader::instance()->setScale(scale);
ColorShader::instance()->setColorIntensity(glm::vec4(1.0f)); 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 <malloc.h>
#include <string.h> #include <string.h>
#include "ColorShader.h" #include <gui/video/shaders/ColorShader.h>
static const u32 cpVertexShaderProgram[] = static const uint32_t cpVertexShaderProgram[] = {
{
0x00000000,0x00008009,0x20000000,0x000078a0, 0x00000000,0x00008009,0x20000000,0x000078a0,
0x3c200000,0x88060094,0x00c00000,0x88062014, 0x3c200000,0x88060094,0x00c00000,0x88062014,
0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,
@ -55,7 +54,7 @@ static const u32 cpVertexShaderProgram[] =
0xfbbdb2ab,0x768ac733 0xfbbdb2ab,0x768ac733
}; };
static const u32 cpVertexShaderRegs[] = { static const uint32_t cpVertexShaderRegs[] = {
0x00000103,0x00000000,0x00000000,0x00000001, 0x00000103,0x00000000,0x00000000,0x00000001,
0xffffff00,0xffffffff,0xffffffff,0xffffffff, 0xffffff00,0xffffffff,0xffffffff,0xffffffff,
0xffffffff,0xffffffff,0xffffffff,0xffffffff, 0xffffffff,0xffffffff,0xffffffff,0xffffffff,
@ -71,8 +70,7 @@ static const u32 cpVertexShaderRegs[] = {
0x000000ff,0x00000000,0x0000000e,0x00000010 0x000000ff,0x00000000,0x0000000e,0x00000010
}; };
static const u32 cpPixelShaderProgram[] = static const uint32_t cpPixelShaderProgram[] = {
{
0x20000000,0x00000ca0,0x00000000,0x88062094, 0x20000000,0x00000ca0,0x00000000,0x88062094,
0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,
@ -93,7 +91,7 @@ static const u32 cpPixelShaderProgram[] =
0x00082001,0x90000040,0x000ca081,0x90000060, 0x00082001,0x90000040,0x000ca081,0x90000060,
0xbb7dd898,0x9746c59c,0xc69b00e7,0x03c36218 0xbb7dd898,0x9746c59c,0xc69b00e7,0x03c36218
}; };
static const u32 cpPixelShaderRegs[] = { static const uint32_t cpPixelShaderRegs[] = {
0x00000001,0x00000002,0x14000001,0x00000000, 0x00000001,0x00000002,0x14000001,0x00000000,
0x00000001,0x00000100,0x00000000,0x00000000, 0x00000001,0x00000100,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,
@ -110,13 +108,14 @@ static const u32 cpPixelShaderRegs[] = {
ColorShader * ColorShader::shaderInstance = NULL; ColorShader * ColorShader::shaderInstance = NULL;
ColorShader::ColorShader() ColorShader::ColorShader()
: vertexShader(cuAttributeCount) : vertexShader(cuAttributeCount) {
{
//! create pixel shader //! create pixel shader
pixelShader.setProgram(cpPixelShaderProgram, sizeof(cpPixelShaderProgram), cpPixelShaderRegs, sizeof(cpPixelShaderRegs)); pixelShader.setProgram(cpPixelShaderProgram, sizeof(cpPixelShaderProgram), cpPixelShaderRegs, sizeof(cpPixelShaderRegs));
colorIntensityLocation = 0; 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 //! create vertex shader
vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs)); vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));
@ -124,40 +123,55 @@ ColorShader::ColorShader()
angleLocation = 0; angleLocation = 0;
offsetLocation = 4; offsetLocation = 4;
scaleLocation = 8; scaleLocation = 8;
vertexShader.addUniformVar((GX2UniformVar){ "unf_angle", GX2_VAR_TYPE_FLOAT, 1, angleLocation, 0xffffffff }); vertexShader.addUniformVar((GX2UniformVar) {
vertexShader.addUniformVar((GX2UniformVar){ "unf_offset", GX2_VAR_TYPE_VEC3, 1, offsetLocation, 0xffffffff }); "unf_angle", GX2_SHADER_VAR_TYPE_FLOAT, 1, angleLocation, -1
vertexShader.addUniformVar((GX2UniformVar){ "unf_scale", GX2_VAR_TYPE_VEC3, 1, scaleLocation, 0xffffffff }); });
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; colorLocation = 1;
positionLocation = 0; positionLocation = 0;
vertexShader.addAttribVar((GX2AttribVar){ "attr_color", GX2_VAR_TYPE_VEC4, 0, colorLocation }); vertexShader.addAttribVar((GX2AttribVar) {
vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation }); "attr_color", GX2_SHADER_VAR_TYPE_FLOAT4, 0, colorLocation
});
vertexShader.addAttribVar((GX2AttribVar) {
"attr_position", GX2_SHADER_VAR_TYPE_FLOAT3, 0, positionLocation
});
//! setup attribute streams //! setup attribute streams
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT); GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32);
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), colorLocation, 1, 0, GX2_ATTRIB_FORMAT_8_8_8_8_UNORM); GX2InitAttribStream(vertexShader.getAttributeBuffer(1), colorLocation, 1, 0, GX2_ATTRIB_FORMAT_UNORM_8_8_8_8);
//! create fetch shader //! create fetch shader
fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount()); fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());
//! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000 //! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
positionVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, cuPositionVtxsSize); positionVtxs = (float*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, cuPositionVtxsSize);
if(positionVtxs) if(positionVtxs) {
{
//! position vertex structure //! position vertex structure
s32 i = 0; 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++] = -1.0f; positionVtxs[i++] = 0.0f; positionVtxs[i++] = -1.0f;
positionVtxs[i++] = 1.0f; positionVtxs[i++] = 1.0f; positionVtxs[i++] = 0.0f; positionVtxs[i++] = 0.0f;
positionVtxs[i++] = -1.0f; positionVtxs[i++] = 1.0f; positionVtxs[i++] = 0.0f; positionVtxs[i++] = 1.0f;
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, positionVtxs, cuPositionVtxsSize); 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() ColorShader::~ColorShader() {
{ if(positionVtxs) {
if(positionVtxs)
{
free(positionVtxs); free(positionVtxs);
positionVtxs = NULL; positionVtxs = NULL;
} }

View File

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

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