mirror of
https://github.com/Maschell/SDL2_Playground.git
synced 2024-11-30 08:34:18 +01:00
WIP
This commit is contained in:
parent
6875dc981d
commit
00080e5a2e
@ -5,38 +5,14 @@ set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
src/main.cpp
|
||||
src/gui/GuiElement.h
|
||||
src/gui/GuiFrame.cpp
|
||||
src/gui/GuiFrame.h
|
||||
src/gui/sigslot.h
|
||||
src/system/SDLSystem.cpp
|
||||
src/system/SDLSystem.h
|
||||
src/gui/GuiElement.cpp
|
||||
src/gui/GuiText.cpp
|
||||
src/gui/GuiText.h
|
||||
src/gui/GuiImage.cpp
|
||||
src/gui/GuiImage.h
|
||||
src/gui/GuiSound.cpp
|
||||
src/gui/GuiSound.h
|
||||
src/gui/GuiTrigger.cpp
|
||||
src/gui/GuiTrigger.h
|
||||
src/gui/GuiController.h
|
||||
src/gui/GuiButton.cpp
|
||||
src/gui/GuiButton.h
|
||||
src/resources/Resources.cpp
|
||||
src/resources/Resources.h
|
||||
src/fs/CFile.cpp
|
||||
src/fs/CFile.hpp
|
||||
src/fs/FSUtils.cpp
|
||||
src/fs/FSUtils.h
|
||||
src/input/SDLController.h src/menu/MainWindow.cpp src/menu/MainWindow.h src/input/SDLControllerJoystick.h src/input/SDLControllerMouse.h
|
||||
src/input/SDLControllerWiiUGamepad.h
|
||||
src/input/SDLControllerWiiUProContoller.h
|
||||
src/gui/GuiTextureData.cpp src/gui/GuiTextureData.h
|
||||
src/system/video/SDL_FontCache.h
|
||||
src/system/video/SDL_FontCache.cpp
|
||||
|
||||
src/system/video/Renderer.h src/input/ControllerManager.cpp src/input/ControllerManager.h)
|
||||
src/menu/MainWindow.cpp
|
||||
src/menu/MainWindow.h )
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
|
||||
|
||||
@ -45,9 +21,27 @@ find_package(SDL2_image REQUIRED)
|
||||
find_package(SDL2_ttf REQUIRED)
|
||||
find_package(SDL2_mixer REQUIRED)
|
||||
|
||||
enable_language(ASM )
|
||||
enable_language(ASM)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(libgui-sdl_git
|
||||
PREFIX vendor/
|
||||
GIT_REPOSITORY https://github.com/Maschell/libgui-sdl
|
||||
GIT_TAG master
|
||||
GIT_SUBMODULES
|
||||
UPDATE_COMMAND ""
|
||||
PATCH_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
CMAKE_ARGS
|
||||
INSTALL_COMMAND
|
||||
"${CMAKE_COMMAND}")
|
||||
|
||||
add_library (libgui-sdl STATIC IMPORTED GLOBAL)
|
||||
set_target_properties (libgui-sdl PROPERTIES
|
||||
IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/vendor/src/libgui-sdl_git-build/libgui-sdl.a
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/vendor/src/libgui-sdl_git/include/gui-sdl)
|
||||
add_dependencies(libgui-sdl libgui-sdl_git)
|
||||
|
||||
ExternalProject_Add(bin2s_git
|
||||
PREFIX vendor/
|
||||
GIT_REPOSITORY https://github.com/Maschell/bin2s
|
||||
@ -92,7 +86,8 @@ function(add_binfile_library target_name)
|
||||
add_library(${target_name} ${_output_file})
|
||||
endfunction()
|
||||
|
||||
add_binfile_library(resources data/fonts/FreeSans.ttf
|
||||
add_binfile_library(resources
|
||||
data/fonts/FreeSans.ttf
|
||||
data/sounds/bgMusic.ogg
|
||||
data/sounds/button_click.mp3
|
||||
data/images/button.png
|
||||
@ -100,4 +95,4 @@ add_binfile_library(resources data/fonts/FreeSans.ttf
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CMAKE_BUILD_")
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} SDL2::Main SDL2::Image SDL2::TTF SDL2::Mixer resources)
|
||||
target_link_libraries(${PROJECT_NAME} libgui-sdl SDL2::Main SDL2::Image SDL2::TTF SDL2::Mixer resources)
|
||||
|
@ -1,22 +0,0 @@
|
||||
FROM dockcross/windows-shared-x64:latest
|
||||
|
||||
RUN apt-get update && apt-get install -y gnupg
|
||||
#Use http://mirror.mxe.cc/
|
||||
#First add the repository and install the static gcc compiler. This ensures that everything basic is setup.
|
||||
RUN echo "deb http://pkg.mxe.cc/repos/apt xenial main" > \
|
||||
/etc/apt/sources.list.d/mxeapt.list && \
|
||||
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 86B72ED9 && \
|
||||
apt-get update && \
|
||||
apt-get install -y mxe-i686-w64-mingw32.static-gcc \
|
||||
nsis \
|
||||
zip \
|
||||
libtool
|
||||
|
||||
RUN apt-get update && wget -O - http://mirror.mxe.cc/repos/apt/dists/stretch/main/binary-amd64/Packages | grep Package | grep shared | grep sdl2 | awk '{print $2}' | xargs apt-get install -y
|
||||
|
||||
ENV MINGW64_PREFIX=/usr/src/mxe/usr/bin/x86_64-w64-mingw32.shared-
|
||||
ENV CONFIG_PREFIX=/usr/lib/mxe/usr/bin/x86_64-w64-mingw32.shared-
|
||||
ENV EXTRA_CFLAGS=-I/usr/lib/mxe/usr/x86_64-w64-mingw32.shared/include
|
||||
ENV EXTRA_LDFLAGS=-L/usr/lib/mxe/usr/x86_64-w64-mingw32.shared/lib
|
||||
|
||||
WORKDIR /project
|
@ -1,3 +1,5 @@
|
||||
FROM wiiuenv/devkitppc-with-sdl2:20201002
|
||||
|
||||
COPY --from=maschell/libgui-sdl:20201002 /artifacts $DEVKITPRO
|
||||
|
||||
WORKDIR project
|
197
Makefile.pc-win
197
Makefile.pc-win
@ -1,197 +0,0 @@
|
||||
#-------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#-------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(MINGW64_PREFIX)),)
|
||||
$(error "Please set MINGW64_PREFIX in your environment. export MINGW64_PREFIX=<path to>/mingw64/bin/")
|
||||
endif
|
||||
|
||||
CXX := $(MINGW64_PREFIX)g++
|
||||
C := $(MINGW64_PREFIX)gcc
|
||||
OBJCOPY := $(MINGW64_PREFIX)objcopy
|
||||
LD := $(MINGW64_PREFIX)ld
|
||||
PREFIX := $(MINGW64_PREFIX)
|
||||
|
||||
ifeq ($(strip $(CONFIG_PREFIX)),)
|
||||
PKG-CONFIG := $(PREFIX)pkg-config
|
||||
else
|
||||
PKG-CONFIG := $(CONFIG_PREFIX)pkg-config
|
||||
endif
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
#-------------------------------------------------------------------------------
|
||||
TARGET := SDL2_Playground
|
||||
BUILD := build-pc-win
|
||||
SOURCES := src \
|
||||
src/gui \
|
||||
src/fs \
|
||||
src/input \
|
||||
src/menu \
|
||||
src/resources \
|
||||
src/system \
|
||||
src/system/video \
|
||||
src/utils
|
||||
DATA := data \
|
||||
data/images \
|
||||
data/sounds \
|
||||
data/fonts
|
||||
INCLUDES := source
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#-------------------------------------------------------------------------------
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections `$(PKG-CONFIG) --cflags SDL2_mixer SDL2_ttf SDL2_image` \
|
||||
$(MACHDEP)
|
||||
|
||||
CFLAGS += $(INCLUDE)
|
||||
|
||||
|
||||
ifeq ($(strip $(EXTRA_CFLAGS)),)
|
||||
else
|
||||
CFLAGS += $(EXTRA_CFLAGS)
|
||||
endif
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -std=c++17
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -g $(ARCH)
|
||||
|
||||
LIBS := `$(PKG-CONFIG) --libs SDL2_mixer SDL2_ttf SDL2_image`
|
||||
|
||||
ifeq ($(strip $(EXTRA_LDFLAGS)),)
|
||||
else
|
||||
LDFLAGS += $(EXTRA_LDFLAGS)
|
||||
endif
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level
|
||||
# containing include and lib
|
||||
#-------------------------------------------------------------------------------
|
||||
LIBDIRS :=
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#-------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
FILELIST := $(shell bash ./filelist.sh)
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
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_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.pc-win
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(TARGET).exe
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
all : $(OUTPUT).exe
|
||||
|
||||
$(OUTPUT).exe : $(OFILES)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
|
||||
$(OUTPUT).exe:
|
||||
@echo linking ... $(notdir $@)
|
||||
@$(CXX) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@ $(ERROR_FILTER)
|
||||
|
||||
%.o: %.cpp
|
||||
@echo "$(notdir $<)"
|
||||
@$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
||||
|
||||
%.png.o %.png.h : %.png
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
%.jpg.o %.jpg.h : %.jpg
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
%.ogg.o %.ogg.h : %.ogg
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
%.mp3.o %.mp3.h : %.mp3
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
%.ttf.o %.ttf.h : %.ttf
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
define bin2o
|
||||
@$(LD) -r -b binary $< -o $(<F).o
|
||||
@$(OBJCOPY) $(<F).o --redefine-sym _binary_`(echo $< | tr . _| tr / _)`_start=`(echo $(<F) | tr . _)`
|
||||
@$(OBJCOPY) $(<F).o --redefine-sym _binary_`(echo $< | tr . _| tr / _)`_end=`(echo $(<F) | tr . _)`_end
|
||||
echo "#pragma once \n\
|
||||
#include <stddef.h> \n\
|
||||
#include <stdint.h> \n\
|
||||
\n\
|
||||
extern const uint8_t `(echo $(<F) | tr . _)`[]; \n\
|
||||
extern const uint8_t `(echo $(<F) | tr . _)`_end[]; \n\
|
||||
static const size_t `(echo $(<F) | tr . _)`_size=`(stat -c %s $<)`;" > `(echo $(<F) | tr . _)`.h
|
||||
endef
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
endif
|
||||
#-------------------------------------------------------------------------------
|
@ -48,7 +48,7 @@ CXXFLAGS := $(CFLAGS) -std=c++20
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := `$(PREFIX)pkg-config --libs SDL2_mixer SDL2_ttf SDL2_image`
|
||||
LIBS := -lgui-sdl `$(PREFIX)pkg-config --libs SDL2_mixer SDL2_ttf SDL2_image`
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level
|
||||
@ -98,9 +98,9 @@ export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
-I$(CURDIR)/$(BUILD) -I$(WUT_ROOT)/usr/include/gui-sdl
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) -L$(WUT_ROOT)/usr/lib
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
|
34
README.md
34
README.md
@ -28,40 +28,12 @@ docker run -it --rm -v ${PWD}:/project sdl2_playground-builder-pc make
|
||||
|
||||
## Windows binaries
|
||||
|
||||
### Windows with devkitPros version of msys2
|
||||
Setup mingw:
|
||||
1. Add the mingw64 repository to `/etc/pacman.conf`.
|
||||
```
|
||||
[mingw64]
|
||||
Server = https://repo.msys2.org/mingw/x86_64
|
||||
```
|
||||
2. Install packages (List taken from [here](https://gist.github.com/thales17/fb2e4cff60890a51d9dddd4c6e832ad2))
|
||||
```
|
||||
pacman -Syu
|
||||
pacman -S git mingw-w64-x86_64-toolchain mingw64/mingw-w64-x86_64-SDL2 mingw64/mingw-w64-x86_64-SDL2_mixer mingw64/mingw-w64-x86_64-SDL2_image mingw64/mingw-w64-x86_64-SDL2_ttf mingw64/mingw-w64-x86_64-SDL2_net mingw64/mingw-w64-x86_64-cmake make
|
||||
```
|
||||
3. Set the environment variable `MINGW64_PREFIX` to `C:/devkitPro/msys2/mingw64/bin/`
|
||||
|
||||
4. Build!
|
||||
```
|
||||
make -f .\Makefile.pc-win
|
||||
```
|
||||
|
||||
### Windows with docker
|
||||
|
||||
```
|
||||
docker build . -f .\Dockerfile.pc-win -t sdl2_playground-builder-pc-win
|
||||
docker run -it --rm -v ${PWD}:/project sdl2_playground-builder-pc-win make -f .\Makefile.pc-win -j16
|
||||
```
|
||||
|
||||
## Wii U binaries
|
||||
|
||||
### With docker
|
||||
|
||||
```
|
||||
docker build . -f .\Dockerfile.wiiu -t sdl2_playground-builder-wiiu
|
||||
docker build . -f .\Dockerfile.wiiu -t sdl2_playground-use-lib-builder-wiiu
|
||||
|
||||
docker run -it --rm -v ${PWD}:/project sdl2_playground-builder-wiiu make -f Makefile.wiiu -j16
|
||||
docker run --rm -v ${PWD}:/project sdl2_playground-use-lib-builder-wiiu make -f Makefile.wiiu -j16
|
||||
```
|
||||
|
||||
### With local installation
|
||||
@ -71,6 +43,8 @@ Install the following packages via [devkitPros pacman](https://devkitpro.org/wik
|
||||
(dkp)pacman -S devkitPPC wut-tools wut wiiu-portlibs wiiu-sdl2-libs
|
||||
```
|
||||
|
||||
Also install [libgui-sdl](https://github.com/Maschell/libgui-sdl) according to the README.
|
||||
|
||||
Build via:
|
||||
```
|
||||
make -f Makefile.wiiu
|
||||
|
@ -1,295 +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/>.
|
||||
****************************************************************************/
|
||||
#include <iostream>
|
||||
#include "GuiButton.h"
|
||||
#include "GuiController.h"
|
||||
|
||||
/**
|
||||
* Constructor for the GuiButton class.
|
||||
*/
|
||||
|
||||
GuiButton::GuiButton(float w, float h) {
|
||||
width = w;
|
||||
height = h;
|
||||
image = nullptr;
|
||||
imageOver = nullptr;
|
||||
imageHold = nullptr;
|
||||
imageClick = nullptr;
|
||||
icon = nullptr;
|
||||
iconOver = nullptr;
|
||||
|
||||
for (int32_t i = 0; i < 4; i++) {
|
||||
label[i] = nullptr;
|
||||
labelOver[i] = nullptr;
|
||||
labelHold[i] = nullptr;
|
||||
labelClick[i] = nullptr;
|
||||
}
|
||||
for (auto &i : trigger) {
|
||||
i = nullptr;
|
||||
}
|
||||
|
||||
soundOver = nullptr;
|
||||
soundHold = nullptr;
|
||||
soundClick = nullptr;
|
||||
clickedTrigger = nullptr;
|
||||
heldTrigger = nullptr;
|
||||
selectable = true;
|
||||
holdable = false;
|
||||
clickable = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor for the GuiButton class.
|
||||
*/
|
||||
GuiButton::~GuiButton() = default;
|
||||
|
||||
void GuiButton::setImage(GuiImage *img) {
|
||||
image = img;
|
||||
if (img) { img->setParent(this); }
|
||||
}
|
||||
|
||||
void GuiButton::setImageOver(GuiImage *img) {
|
||||
imageOver = img;
|
||||
if (img) { img->setParent(this); }
|
||||
}
|
||||
|
||||
void GuiButton::setImageHold(GuiImage *img) {
|
||||
imageHold = img;
|
||||
if (img) { img->setParent(this); }
|
||||
}
|
||||
|
||||
void GuiButton::setImageClick(GuiImage *img) {
|
||||
imageClick = img;
|
||||
if (img) { img->setParent(this); }
|
||||
}
|
||||
|
||||
void GuiButton::setIcon(GuiImage *img) {
|
||||
icon = img;
|
||||
if (img) { img->setParent(this); }
|
||||
}
|
||||
|
||||
void GuiButton::setIconOver(GuiImage *img) {
|
||||
iconOver = img;
|
||||
if (img) { img->setParent(this); }
|
||||
}
|
||||
|
||||
void GuiButton::setLabel(GuiText *txt, int32_t n) {
|
||||
label[n] = txt;
|
||||
if (txt) { txt->setParent(this); }
|
||||
}
|
||||
|
||||
void GuiButton::setLabelOver(GuiText *txt, int32_t n) {
|
||||
labelOver[n] = txt;
|
||||
if (txt) { txt->setParent(this); }
|
||||
}
|
||||
|
||||
void GuiButton::setLabelHold(GuiText *txt, int32_t n) {
|
||||
labelHold[n] = txt;
|
||||
if (txt) { txt->setParent(this); }
|
||||
}
|
||||
|
||||
void GuiButton::setLabelClick(GuiText *txt, int32_t n) {
|
||||
labelClick[n] = txt;
|
||||
if (txt) { txt->setParent(this); }
|
||||
}
|
||||
|
||||
void GuiButton::setSoundOver(GuiSound *snd) {
|
||||
soundOver = snd;
|
||||
}
|
||||
|
||||
void GuiButton::setSoundHold(GuiSound *snd) {
|
||||
soundHold = snd;
|
||||
}
|
||||
|
||||
void GuiButton::setSoundClick(GuiSound *snd) {
|
||||
soundClick = snd;
|
||||
}
|
||||
|
||||
void GuiButton::setTrigger(GuiTrigger *t, int32_t idx) {
|
||||
if (idx >= 0 && idx < iMaxGuiTriggers) {
|
||||
trigger[idx] = t;
|
||||
} else {
|
||||
for (auto &i : trigger) {
|
||||
if (!i) {
|
||||
i = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuiButton::resetState() {
|
||||
clickedTrigger = nullptr;
|
||||
heldTrigger = nullptr;
|
||||
GuiElement::resetState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the button on screen
|
||||
*/
|
||||
void GuiButton::draw(Renderer *v) {
|
||||
if (!this->isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// draw image
|
||||
if ((isDrawOverOnlyWhenSelected() && (isStateSet(STATE_SELECTED) && imageOver)) ||
|
||||
(!isDrawOverOnlyWhenSelected() && (isStateSet(STATE_OVER | STATE_SELECTED | STATE_CLICKED | STATE_HELD) && imageOver))) {
|
||||
imageOver->draw(v);
|
||||
} else if (image) {
|
||||
image->draw(v);
|
||||
}
|
||||
|
||||
if ((isDrawOverOnlyWhenSelected() && (isStateSet(STATE_SELECTED) && iconOver)) ||
|
||||
(!isDrawOverOnlyWhenSelected() && (isStateSet(STATE_OVER | STATE_SELECTED | STATE_CLICKED | STATE_HELD) && iconOver))) {
|
||||
iconOver->draw(v);
|
||||
} else if (icon) {
|
||||
icon->draw(v);
|
||||
}
|
||||
|
||||
// draw text
|
||||
for (int32_t i = 0; i < 4; i++) {
|
||||
if (isStateSet(STATE_OVER | STATE_SELECTED | STATE_CLICKED | STATE_HELD) && labelOver[i]) {
|
||||
labelOver[i]->draw(v);
|
||||
} else if (label[i]) {
|
||||
label[i]->draw(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuiButton::update(GuiController *c) {
|
||||
if (!c || isStateSet(STATE_DISABLED | STATE_HIDDEN | STATE_DISABLE_INPUT, c->chanIdx)) {
|
||||
return;
|
||||
} else if (parentElement && (parentElement->isStateSet(STATE_DISABLED | STATE_HIDDEN | STATE_DISABLE_INPUT, c->chanIdx))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectable) {
|
||||
if (c->data.validPointer && this->isInside(c->data.x, c->data.y)) {
|
||||
if (!isStateSet(STATE_OVER, c->chanIdx)) {
|
||||
setState(STATE_OVER, c->chanIdx);
|
||||
|
||||
//if(this->isRumbleActive())
|
||||
// this->rumble(t->chan);
|
||||
|
||||
if (soundOver) {
|
||||
soundOver->Play();
|
||||
}
|
||||
|
||||
if (effectsOver && !effects) {
|
||||
// initiate effects
|
||||
effects = effectsOver;
|
||||
effectAmount = effectAmountOver;
|
||||
effectTarget = effectTargetOver;
|
||||
}
|
||||
|
||||
pointedOn(this, c);
|
||||
}
|
||||
} else if (isStateSet(STATE_OVER, c->chanIdx)) {
|
||||
this->clearState(STATE_OVER, c->chanIdx);
|
||||
pointedOff(this, c);
|
||||
|
||||
if (effectTarget == effectTargetOver && effectAmount == effectAmountOver) {
|
||||
// initiate effects (in reverse)
|
||||
effects = effectsOver;
|
||||
effectAmount = -effectAmountOver;
|
||||
effectTarget = 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto & i : trigger) {
|
||||
if (!i) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// button triggers
|
||||
if (clickable) {
|
||||
int32_t isClicked = i->clicked(c);
|
||||
if (!clickedTrigger && (isClicked != GuiTrigger::CLICKED_NONE)
|
||||
&& (i->isClickEverywhere() || (isStateSet(STATE_SELECTED | STATE_OVER, c->chanIdx) && i->isSelectionClickEverywhere()) || this->isInside(c->data.x, c->data.y))) {
|
||||
if (soundClick) {
|
||||
soundClick->Play();
|
||||
}
|
||||
|
||||
clickedTrigger = i;
|
||||
|
||||
if (!isStateSet(STATE_CLICKED, c->chanIdx)) {
|
||||
if (isClicked == GuiTrigger::CLICKED_TOUCH) {
|
||||
setState(STATE_CLICKED_TOUCH, c->chanIdx);
|
||||
} else {
|
||||
setState(STATE_CLICKED, c->chanIdx);
|
||||
}
|
||||
}
|
||||
|
||||
clicked(this, c, i);
|
||||
} else if ((isStateSet(STATE_CLICKED, c->chanIdx) || isStateSet(STATE_CLICKED_TOUCH, c->chanIdx)) && (clickedTrigger == i) && !isStateSet(STATE_HELD, c->chanIdx) && !i->held(c) &&
|
||||
((isClicked == GuiTrigger::CLICKED_NONE) || i->released(c))) {
|
||||
if ((isStateSet(STATE_CLICKED_TOUCH, c->chanIdx) && this->isInside(c->data.x, c->data.y)) || (isStateSet(STATE_CLICKED, c->chanIdx))) {
|
||||
clickedTrigger = nullptr;
|
||||
clearState(STATE_CLICKED, c->chanIdx);
|
||||
released(this, c, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (holdable) {
|
||||
bool isHeld = i->held(c);
|
||||
|
||||
if ((!heldTrigger || heldTrigger == i) && isHeld
|
||||
&& (i->isHoldEverywhere() || (isStateSet(STATE_SELECTED | STATE_OVER, c->chanIdx) && i->isSelectionClickEverywhere()) || this->isInside(c->data.x, c->data.y))) {
|
||||
heldTrigger = i;
|
||||
|
||||
if (!isStateSet(STATE_HELD, c->chanIdx)) {
|
||||
setState(STATE_HELD, c->chanIdx);
|
||||
}
|
||||
|
||||
held(this, c, i);
|
||||
} else if (isStateSet(STATE_HELD, c->chanIdx) && (heldTrigger == i) && (!isHeld || i->released(c))) {
|
||||
//! click is removed at this point and converted to held
|
||||
if (clickedTrigger == i) {
|
||||
clickedTrigger = nullptr;
|
||||
clearState(STATE_CLICKED, c->chanIdx);
|
||||
}
|
||||
heldTrigger = nullptr;
|
||||
clearState(STATE_HELD, c->chanIdx);
|
||||
released(this, c, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuiButton::process() {
|
||||
GuiElement::process();
|
||||
|
||||
if(image) { image->process(); }
|
||||
if(imageOver) { imageOver->process(); }
|
||||
if(imageHold) { imageHold->process(); }
|
||||
if(imageClick) { imageClick->process(); }
|
||||
if(icon) { icon->process(); }
|
||||
if(iconOver) { iconOver->process(); }
|
||||
if(soundOver) { soundOver->process(); }
|
||||
if(soundHold) { soundHold->process(); }
|
||||
if(soundClick) { soundClick->process(); }
|
||||
|
||||
for(int i = 0;i<4;i++){
|
||||
if(label[i]) { label[i]->process(); }
|
||||
if(labelOver[i]) { labelOver[i]->process(); }
|
||||
if(labelHold[i]) { labelHold[i]->process(); }
|
||||
if(labelClick[i]) { labelClick[i]->process(); }
|
||||
}
|
||||
}
|
@ -1,131 +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/>.
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
#include "GuiElement.h"
|
||||
#include "GuiImage.h"
|
||||
#include "GuiText.h"
|
||||
#include "GuiSound.h"
|
||||
#include "GuiTrigger.h"
|
||||
#include "../system/SDLSystem.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) override;
|
||||
|
||||
//!Constantly called to draw the GuiButton
|
||||
void draw(Renderer *video) override;
|
||||
|
||||
//!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) override;
|
||||
|
||||
void process() override;
|
||||
|
||||
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;
|
||||
};
|
@ -1,68 +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/>.
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
#include "GuiTrigger.h"
|
||||
|
||||
class GuiController {
|
||||
public:
|
||||
//!Constructor
|
||||
GuiController(int32_t channel)
|
||||
: chan(channel) {
|
||||
memset(&lastData, 0, sizeof(lastData));
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
switch (chan) {
|
||||
default:
|
||||
case GuiTrigger::CHANNEL_1:
|
||||
chanIdx = 0;
|
||||
break;
|
||||
case GuiTrigger::CHANNEL_2:
|
||||
chanIdx = 1;
|
||||
break;
|
||||
case GuiTrigger::CHANNEL_3:
|
||||
chanIdx = 2;
|
||||
break;
|
||||
case GuiTrigger::CHANNEL_4:
|
||||
chanIdx = 3;
|
||||
break;
|
||||
case GuiTrigger::CHANNEL_5:
|
||||
chanIdx = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//!Destructor
|
||||
virtual ~GuiController() {}
|
||||
|
||||
typedef struct {
|
||||
uint32_t buttons_h;
|
||||
uint32_t buttons_d;
|
||||
uint32_t buttons_r;
|
||||
bool validPointer;
|
||||
bool touched;
|
||||
float pointerAngle;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
} PadData;
|
||||
|
||||
uint32_t chan;
|
||||
int32_t chanIdx;
|
||||
PadData data;
|
||||
PadData lastData;
|
||||
};
|
@ -1,290 +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/>.
|
||||
****************************************************************************/
|
||||
#include "GuiElement.h"
|
||||
|
||||
//! TODO remove this!
|
||||
static int32_t screenwidth = 1280;
|
||||
static int32_t screenheight = 720;
|
||||
|
||||
/**
|
||||
* Constructor for the Object class.
|
||||
*/
|
||||
GuiElement::GuiElement() {
|
||||
xoffset = 0.0f;
|
||||
yoffset = 0.0f;
|
||||
zoffset = 0.0f;
|
||||
width = 0.0f;
|
||||
height = 0.0f;
|
||||
alpha = 1.0f;
|
||||
scaleX = 1.0f;
|
||||
scaleY = 1.0f;
|
||||
scaleZ = 1.0f;
|
||||
for (unsigned int & i : state) {
|
||||
i = STATE_DEFAULT;
|
||||
}
|
||||
stateChan = -1;
|
||||
parentElement = nullptr;
|
||||
rumble = true;
|
||||
selectable = false;
|
||||
clickable = false;
|
||||
holdable = false;
|
||||
drawOverOnlyWhenSelected = false;
|
||||
visible = true;
|
||||
yoffsetDyn = 0;
|
||||
xoffsetDyn = 0;
|
||||
alphaDyn = -1;
|
||||
scaleDyn = 1;
|
||||
effects = EFFECT_NONE;
|
||||
effectAmount = 0;
|
||||
effectTarget = 0;
|
||||
effectsOver = EFFECT_NONE;
|
||||
effectAmountOver = 0;
|
||||
effectTargetOver = 0;
|
||||
angle = 0.0f;
|
||||
|
||||
// default alignment - align to top left
|
||||
alignment = (ALIGN_TOP_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the left position of the GuiElement.
|
||||
* @see SetLeft()
|
||||
* @return Left position in pixel.
|
||||
*/
|
||||
float GuiElement::getLeft() {
|
||||
float pWidth = 0;
|
||||
float pLeft = 0;
|
||||
float pScaleX = 1.0f;
|
||||
|
||||
if (parentElement) {
|
||||
pWidth = parentElement->getWidth();
|
||||
pLeft = parentElement->getLeft();
|
||||
pScaleX = parentElement->getScaleX();
|
||||
}
|
||||
|
||||
pLeft += xoffsetDyn;
|
||||
|
||||
float x = pLeft;
|
||||
|
||||
//! TODO: the conversion from int to float and back to int is bad for performance, change that
|
||||
if (alignment & ALIGN_CENTER) {
|
||||
x = pLeft + pWidth * 0.5f * pScaleX - width * 0.5f * getScaleX();
|
||||
} else if (alignment & ALIGN_RIGHT) {
|
||||
x = pLeft + pWidth * pScaleX - width * getScaleX();
|
||||
}
|
||||
|
||||
return x + xoffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the top position of the GuiElement.
|
||||
* @see SetTop()
|
||||
* @return Top position in pixel.
|
||||
*/
|
||||
float GuiElement::getTop() {
|
||||
float pHeight = 0;
|
||||
float pTop = 0;
|
||||
float pScaleY = 1.0f;
|
||||
|
||||
if (parentElement) {
|
||||
pHeight = parentElement->getHeight();
|
||||
pTop = parentElement->getTop();
|
||||
pScaleY = parentElement->getScaleY();
|
||||
}
|
||||
|
||||
pTop += yoffsetDyn;
|
||||
|
||||
float y = pTop;
|
||||
|
||||
//! TODO: the conversion from int to float and back to int is bad for performance, change that
|
||||
if (alignment & ALIGN_MIDDLE) {
|
||||
y = pTop + pHeight * 0.5f * pScaleY - getHeight() * 0.5f * getScaleY();
|
||||
} else if (alignment & ALIGN_BOTTOM) {
|
||||
y = pTop + pHeight * pScaleY - getHeight() * getScaleY();
|
||||
}
|
||||
|
||||
return y + yoffset;
|
||||
}
|
||||
|
||||
void GuiElement::setEffect(uint32_t eff, int32_t amount, int32_t target) {
|
||||
if (eff & EFFECT_SLIDE_IN) {
|
||||
// these calculations overcompensate a little
|
||||
if (eff & EFFECT_SLIDE_TOP) {
|
||||
if (eff & EFFECT_SLIDE_FROM) {
|
||||
yoffsetDyn = (int32_t) -getHeight() * scaleY;
|
||||
} else {
|
||||
yoffsetDyn = -screenheight;
|
||||
}
|
||||
} else if (eff & EFFECT_SLIDE_LEFT) {
|
||||
if (eff & EFFECT_SLIDE_FROM) {
|
||||
xoffsetDyn = (int32_t) -getWidth() * scaleX;
|
||||
} else {
|
||||
xoffsetDyn = -screenwidth;
|
||||
}
|
||||
} else if (eff & EFFECT_SLIDE_BOTTOM) {
|
||||
if (eff & EFFECT_SLIDE_FROM) {
|
||||
yoffsetDyn = (int32_t) getHeight() * scaleY;
|
||||
} else {
|
||||
yoffsetDyn = screenheight;
|
||||
}
|
||||
} else if (eff & EFFECT_SLIDE_RIGHT) {
|
||||
if (eff & EFFECT_SLIDE_FROM) {
|
||||
xoffsetDyn = (int32_t) getWidth() * scaleX;
|
||||
} else {
|
||||
xoffsetDyn = screenwidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((eff & EFFECT_FADE) && amount > 0) {
|
||||
alphaDyn = 0;
|
||||
} else if ((eff & EFFECT_FADE) && amount < 0) {
|
||||
alphaDyn = alpha;
|
||||
}
|
||||
effects |= eff;
|
||||
effectAmount = amount;
|
||||
effectTarget = target;
|
||||
}
|
||||
|
||||
//!Sets an effect to be enabled on wiimote cursor over
|
||||
//!\param e Effect to enable
|
||||
//!\param a Amount of the effect (usage varies on effect)
|
||||
//!\param t Target amount of the effect (usage varies on effect)
|
||||
void GuiElement::setEffectOnOver(uint32_t e, int32_t a, int32_t t) {
|
||||
effectsOver |= e;
|
||||
effectAmountOver = a;
|
||||
effectTargetOver = t;
|
||||
}
|
||||
|
||||
void GuiElement::resetEffects() {
|
||||
yoffsetDyn = 0;
|
||||
xoffsetDyn = 0;
|
||||
alphaDyn = -1;
|
||||
scaleDyn = 1;
|
||||
effects = EFFECT_NONE;
|
||||
effectAmount = 0;
|
||||
effectTarget = 0;
|
||||
effectsOver = EFFECT_NONE;
|
||||
effectAmountOver = 0;
|
||||
effectTargetOver = 0;
|
||||
}
|
||||
|
||||
void GuiElement::updateEffects() {
|
||||
if (!this->isVisible() && parentElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (effects & (EFFECT_SLIDE_IN | EFFECT_SLIDE_OUT | EFFECT_SLIDE_FROM)) {
|
||||
if (effects & EFFECT_SLIDE_IN) {
|
||||
if (effects & EFFECT_SLIDE_LEFT) {
|
||||
xoffsetDyn += effectAmount;
|
||||
|
||||
if (xoffsetDyn >= 0) {
|
||||
xoffsetDyn = 0;
|
||||
effects = 0;
|
||||
effectFinished(this);
|
||||
}
|
||||
} else if (effects & EFFECT_SLIDE_RIGHT) {
|
||||
xoffsetDyn -= effectAmount;
|
||||
|
||||
if (xoffsetDyn <= 0) {
|
||||
xoffsetDyn = 0;
|
||||
effects = 0;
|
||||
effectFinished(this);
|
||||
}
|
||||
} else if (effects & EFFECT_SLIDE_TOP) {
|
||||
yoffsetDyn += effectAmount;
|
||||
|
||||
if (yoffsetDyn >= 0) {
|
||||
yoffsetDyn = 0;
|
||||
effects = 0;
|
||||
effectFinished(this);
|
||||
}
|
||||
} else if (effects & EFFECT_SLIDE_BOTTOM) {
|
||||
yoffsetDyn -= effectAmount;
|
||||
|
||||
if (yoffsetDyn <= 0) {
|
||||
yoffsetDyn = 0;
|
||||
effects = 0;
|
||||
effectFinished(this);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (effects & EFFECT_SLIDE_LEFT) {
|
||||
xoffsetDyn -= effectAmount;
|
||||
|
||||
if (xoffsetDyn <= -screenwidth) {
|
||||
effects = 0; // shut off effect
|
||||
effectFinished(this);
|
||||
} else if ((effects & EFFECT_SLIDE_FROM) && xoffsetDyn <= -getWidth()) {
|
||||
effects = 0; // shut off effect
|
||||
effectFinished(this);
|
||||
}
|
||||
} else if (effects & EFFECT_SLIDE_RIGHT) {
|
||||
xoffsetDyn += effectAmount;
|
||||
|
||||
if (xoffsetDyn >= screenwidth) {
|
||||
effects = 0; // shut off effect
|
||||
effectFinished(this);
|
||||
} else if ((effects & EFFECT_SLIDE_FROM) && xoffsetDyn >= getWidth() * scaleX) {
|
||||
effects = 0; // shut off effect
|
||||
effectFinished(this);
|
||||
}
|
||||
} else if (effects & EFFECT_SLIDE_TOP) {
|
||||
yoffsetDyn -= effectAmount;
|
||||
|
||||
if (yoffsetDyn <= -screenheight) {
|
||||
effects = 0; // shut off effect
|
||||
effectFinished(this);
|
||||
} else if ((effects & EFFECT_SLIDE_FROM) && yoffsetDyn <= -getHeight()) {
|
||||
effects = 0; // shut off effect
|
||||
effectFinished(this);
|
||||
}
|
||||
} else if (effects & EFFECT_SLIDE_BOTTOM) {
|
||||
yoffsetDyn += effectAmount;
|
||||
|
||||
if (yoffsetDyn >= screenheight) {
|
||||
effects = 0; // shut off effect
|
||||
effectFinished(this);
|
||||
} else if ((effects & EFFECT_SLIDE_FROM) && yoffsetDyn >= getHeight()) {
|
||||
effects = 0; // shut off effect
|
||||
effectFinished(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (effects & EFFECT_FADE) {
|
||||
alphaDyn += effectAmount * (1.0f / 255.0f);
|
||||
|
||||
if (effectAmount < 0 && alphaDyn <= 0) {
|
||||
alphaDyn = 0;
|
||||
effects = 0; // shut off effect
|
||||
effectFinished(this);
|
||||
} else if (effectAmount > 0 && alphaDyn >= alpha) {
|
||||
alphaDyn = alpha;
|
||||
effects = 0; // shut off effect
|
||||
effectFinished(this);
|
||||
}
|
||||
} else if (effects & EFFECT_SCALE) {
|
||||
scaleDyn += effectAmount * 0.01f;
|
||||
|
||||
if ((effectAmount < 0 && scaleDyn <= (effectTarget * 0.01f))
|
||||
|| (effectAmount > 0 && scaleDyn >= (effectTarget * 0.01f))) {
|
||||
scaleDyn = effectTarget * 0.01f;
|
||||
effects = 0; // shut off effect
|
||||
effectFinished(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,629 +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/>.
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <malloc.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
#include <cwchar>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include "sigslot.h"
|
||||
#include "../system/video/Renderer.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
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 SDLSystem;
|
||||
|
||||
//!Primary GUI class. Most other classes inherit from this class.
|
||||
class GuiElement {
|
||||
public:
|
||||
//!Constructor
|
||||
GuiElement();
|
||||
|
||||
//!Destructor
|
||||
virtual ~GuiElement() = default;
|
||||
|
||||
//!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() {
|
||||
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() {
|
||||
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(uint32_t s, int32_t c) {
|
||||
if (c >= 0 && c < 5) {
|
||||
state[c] |= s;
|
||||
} else {
|
||||
for (int32_t i = 0; i < 5; i++) {
|
||||
state[i] |= s;
|
||||
}
|
||||
}
|
||||
stateChan = c;
|
||||
stateChanged(this, s, c);
|
||||
}
|
||||
|
||||
virtual void clearState(uint32_t s, int32_t c) {
|
||||
if (c >= 0 && c < 5) {
|
||||
state[c] &= ~s;
|
||||
} else {
|
||||
for (unsigned int & i : state) {
|
||||
i &= ~s;
|
||||
}
|
||||
}
|
||||
stateChan = c;
|
||||
stateChanged(this, s, c);
|
||||
}
|
||||
|
||||
virtual bool isStateSet(uint32_t s, int32_t c = -1) const {
|
||||
if (c >= 0 && c < 5) {
|
||||
return (state[c] & s) != 0;
|
||||
} else {
|
||||
for (unsigned int i : state) {
|
||||
if ((i & s) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//!Gets the element's current state
|
||||
//!\return state
|
||||
virtual int32_t getState(int32_t c) {
|
||||
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 (unsigned int & 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(uint32_t e, int32_t a, int32_t t);
|
||||
|
||||
//!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(uint32_t e, int32_t a, int32_t t);
|
||||
|
||||
//!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) {
|
||||
float rotatedX = x;
|
||||
float rotatedY = y;
|
||||
|
||||
if (getAngle() != 0.f) {
|
||||
// translate input point
|
||||
float tempX = x - getCenterX();
|
||||
float tempY = y - getCenterY();
|
||||
|
||||
// Conver to Rad
|
||||
auto angleInRad = (float) ((getAngle() * -1.0f) * M_PI / 180.0f);
|
||||
|
||||
// now apply rotation
|
||||
rotatedX = tempX * cos((angleInRad)) - tempY * sin(angleInRad);
|
||||
rotatedY = tempX * sin(angleInRad) + tempY * cos(angleInRad);
|
||||
|
||||
// translate back
|
||||
rotatedX = rotatedX + getCenterX();
|
||||
rotatedY = rotatedY + getCenterY();
|
||||
}
|
||||
|
||||
return (rotatedX > (this->getCenterX() - getScaleX() * getWidth() * 0.5f)
|
||||
&& rotatedX < (this->getCenterX() + getScaleX() * getWidth() * 0.5f)
|
||||
&& rotatedY > (this->getCenterY() - getScaleY() * getHeight() * 0.5f)
|
||||
&& rotatedY < (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(Renderer * 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%)
|
||||
uint32_t alignment; //!< Horizontal element alignment, respective to parent element
|
||||
uint32_t state[5]{}; //!< 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)
|
||||
uint32_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
|
||||
uint32_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
|
||||
};
|
@ -1,226 +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/>.
|
||||
****************************************************************************/
|
||||
#include "GuiFrame.h"
|
||||
|
||||
GuiFrame::GuiFrame(GuiFrame *p) {
|
||||
parent = p;
|
||||
width = 0;
|
||||
height = 0;
|
||||
dim = false;
|
||||
|
||||
if (parent) {
|
||||
parent->append(this);
|
||||
}
|
||||
}
|
||||
|
||||
GuiFrame::GuiFrame(float w, float h, GuiFrame *p) {
|
||||
parent = p;
|
||||
width = w;
|
||||
height = h;
|
||||
dim = false;
|
||||
|
||||
if (parent) {
|
||||
parent->append(this);
|
||||
}
|
||||
}
|
||||
|
||||
GuiFrame::~GuiFrame() {
|
||||
closing(this);
|
||||
|
||||
if (parent) {
|
||||
parent->remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiFrame::append(GuiElement *e) {
|
||||
if (e == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
remove(e);
|
||||
mutex.lock();
|
||||
elements.push_back(e);
|
||||
e->setParent(this);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void GuiFrame::insert(GuiElement *e, uint32_t index) {
|
||||
if (e == nullptr || (index >= elements.size())) {
|
||||
return;
|
||||
}
|
||||
|
||||
remove(e);
|
||||
mutex.lock();
|
||||
elements.insert(elements.begin() + index, e);
|
||||
e->setParent(this);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void GuiFrame::remove(GuiElement *e) {
|
||||
if (e == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mutex.lock();
|
||||
for (uint32_t i = 0; i < elements.size(); ++i) {
|
||||
if (e == elements[i]) {
|
||||
elements.erase(elements.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void GuiFrame::removeAll() {
|
||||
mutex.lock();
|
||||
elements.clear();
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
GuiElement *GuiFrame::getGuiElementAt(uint32_t index) const {
|
||||
if (index >= elements.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return elements[index];
|
||||
}
|
||||
|
||||
uint32_t GuiFrame::getSize() {
|
||||
return elements.size();
|
||||
}
|
||||
|
||||
void GuiFrame::resetState() {
|
||||
GuiElement::resetState();
|
||||
|
||||
mutex.lock();
|
||||
for (auto & element : elements) {
|
||||
element->resetState();
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void GuiFrame::setState(uint32_t s, int32_t c) {
|
||||
GuiElement::setState(s, c);
|
||||
mutex.lock();
|
||||
for (uint32_t i = 0; i < elements.size(); ++i) {
|
||||
elements[i]->setState(s, c);
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void GuiFrame::clearState(uint32_t s, int32_t c) {
|
||||
GuiElement::clearState(s, c);
|
||||
|
||||
mutex.lock();
|
||||
for (uint32_t i = 0; i < elements.size(); ++i) {
|
||||
elements[i]->clearState(s, c);
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void GuiFrame::setVisible(bool v) {
|
||||
visible = v;
|
||||
|
||||
mutex.lock();
|
||||
for (auto & element : elements) {
|
||||
element->setVisible(v);
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
int32_t GuiFrame::getSelected() {
|
||||
// find selected element
|
||||
int32_t found = -1;
|
||||
mutex.lock();
|
||||
for (uint32_t i = 0; i < elements.size(); ++i) {
|
||||
if (elements[i]->isStateSet(STATE_SELECTED | STATE_OVER)) {
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex.unlock();
|
||||
return found;
|
||||
}
|
||||
|
||||
void GuiFrame::draw(Renderer *v) {
|
||||
if (!this->isVisible() && parentElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parentElement && dim) {
|
||||
//GXColor dimColor = (GXColor){0, 0, 0, 0x70};
|
||||
//Menu_DrawRectangle(0, 0, GetZPosition(), screenwidth,screenheight, &dimColor, false, true);
|
||||
}
|
||||
|
||||
mutex.lock();
|
||||
//! render appended items next frame but allow stop of render if size is reached
|
||||
uint32_t size = elements.size();
|
||||
|
||||
for (uint32_t i = 0; i < size && i < elements.size(); ++i) {
|
||||
elements[i]->draw(v);
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void GuiFrame::updateEffects() {
|
||||
if (!this->isVisible() && parentElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
GuiElement::updateEffects();
|
||||
|
||||
mutex.lock();
|
||||
//! render appended items next frame but allow stop of render if size is reached
|
||||
uint32_t size = elements.size();
|
||||
|
||||
for (uint32_t i = 0; i < size && i < elements.size(); ++i) {
|
||||
elements[i]->updateEffects();
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void GuiFrame::process() {
|
||||
if (!this->isVisible() && parentElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
GuiElement::process();
|
||||
|
||||
mutex.lock();
|
||||
//! render appended items next frame but allow stop of render if size is reached
|
||||
uint32_t size = elements.size();
|
||||
|
||||
for (uint32_t i = 0; i < size && i < elements.size(); ++i) {
|
||||
elements[i]->process();
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void GuiFrame::update(GuiController *c) {
|
||||
if (isStateSet(STATE_DISABLED) && parentElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
mutex.lock();
|
||||
//! update appended items next frame
|
||||
uint32_t size = elements.size();
|
||||
|
||||
for (uint32_t i = 0; i < size && i < elements.size(); ++i) {
|
||||
elements[i]->update(c);
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
@ -1,109 +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/>.
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include "GuiElement.h"
|
||||
#include "sigslot.h"
|
||||
#include "../system/video/Renderer.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
|
||||
~GuiFrame() override;
|
||||
|
||||
//!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) override;
|
||||
|
||||
//!Resets the window's state to STATE_DEFAULT
|
||||
void resetState() override;
|
||||
|
||||
//!Sets the window's state
|
||||
//!\param s State
|
||||
void setState(uint32_t s, int32_t c = -1) override;
|
||||
|
||||
void clearState(uint32_t s, int32_t c = -1) override;
|
||||
|
||||
//!Gets the index of the GuiElement inside the window that is currently selected
|
||||
//!\return index of selected GuiElement
|
||||
int32_t getSelected() override;
|
||||
|
||||
//!Draws all the elements in this GuiFrame
|
||||
void draw(Renderer *v) override;
|
||||
|
||||
//!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) override;
|
||||
|
||||
//!virtual updateEffects which is called by the main loop
|
||||
void updateEffects() override;
|
||||
|
||||
//!virtual process which is called by the main loop
|
||||
void process() override;
|
||||
|
||||
//! 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
|
||||
std::recursive_mutex mutex;
|
||||
};
|
@ -1,66 +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/>.
|
||||
****************************************************************************/
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include "GuiImage.h"
|
||||
#include "../utils/logger.h"
|
||||
|
||||
GuiImage::GuiImage(GuiTextureData *texture) {
|
||||
setTexture(texture);
|
||||
}
|
||||
|
||||
GuiImage::GuiImage(SDL_Color color, float width, float height) {
|
||||
this->color = color;
|
||||
this->setSize(width, height);
|
||||
}
|
||||
|
||||
GuiImage::~GuiImage() {
|
||||
if (this->texture && freeTextureData) {
|
||||
delete this->texture;
|
||||
}
|
||||
}
|
||||
|
||||
void GuiImage::draw(Renderer *renderer) {
|
||||
if (!this->isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_Rect rect;
|
||||
rect.x = (int) getLeft();
|
||||
rect.y = (int) getTop();
|
||||
rect.w = (int) (getScaleX() * getWidth());
|
||||
rect.h = (int) (getScaleY() * getHeight());
|
||||
|
||||
if (texture) {
|
||||
texture->draw(renderer, rect, getAngle());
|
||||
} else {
|
||||
SDL_SetRenderDrawColor(renderer->getRenderer(), color.r, color.g, color.b, color.a);
|
||||
SDL_RenderFillRect(renderer->getRenderer(), &rect);
|
||||
if(getAngle() != 0.0f){
|
||||
DEBUG_FUNCTION_LINE("Drawing a rotated rect is not supported yet");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuiImage::setTexture(GuiTextureData *tex) {
|
||||
if (tex) {
|
||||
if(this->texture && freeTextureData){
|
||||
delete this->texture;
|
||||
}
|
||||
this->texture = tex;
|
||||
this->setSize(tex->getWidth(), tex->getHeight());
|
||||
}
|
||||
}
|
@ -1,50 +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/>.
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include "GuiElement.h"
|
||||
#include "GuiTextureData.h"
|
||||
|
||||
//!Display, manage, and manipulate images in the GUI
|
||||
class GuiImage : public GuiElement {
|
||||
public:
|
||||
|
||||
GuiImage() = default;
|
||||
|
||||
//! Draws an image from an existing texture
|
||||
//!\param texture Pointer to GuiTextureData element
|
||||
explicit GuiImage(GuiTextureData *texture);
|
||||
|
||||
//! Draws a colored rectangle
|
||||
//!\param texture Pointer to GuiTextureData element
|
||||
explicit GuiImage(SDL_Color color, float width, float height);
|
||||
|
||||
//!Destructor
|
||||
~GuiImage() override;
|
||||
|
||||
void draw(Renderer *r) override;
|
||||
|
||||
void setTexture(GuiTextureData *tex);
|
||||
|
||||
private:
|
||||
GuiTextureData *texture = nullptr;
|
||||
bool freeTextureData = false;
|
||||
|
||||
// Color of the rect that's drawn if the picture has no texture.
|
||||
SDL_Color color = {0, 0, 0, 0};
|
||||
};
|
@ -1,79 +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/>.
|
||||
****************************************************************************/
|
||||
#include "GuiSound.h"
|
||||
|
||||
GuiSound::GuiSound(void *buffer, uint32_t filesize, bool freeSrc) {
|
||||
SDL_RWops *rw = SDL_RWFromMem(buffer, filesize);
|
||||
music = Mix_LoadWAV_RW(rw, freeSrc);
|
||||
}
|
||||
|
||||
GuiSound::GuiSound(const char *filepath) {
|
||||
Load(filepath);
|
||||
}
|
||||
|
||||
GuiSound::~GuiSound() {
|
||||
if (music) {
|
||||
Mix_FreeChunk(music);
|
||||
music = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool GuiSound::Load(const char *filepath) {
|
||||
music = Mix_LoadWAV(filepath);
|
||||
return music != nullptr;
|
||||
}
|
||||
|
||||
void GuiSound::Play() {
|
||||
if (music) {
|
||||
playedOn = Mix_PlayChannel(-1, music, loops);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiSound::Stop() const {
|
||||
Pause();
|
||||
}
|
||||
|
||||
void GuiSound::Pause() const {
|
||||
if (playedOn != -1) {
|
||||
Mix_HaltChannel(playedOn);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiSound::Resume() {
|
||||
Play();
|
||||
}
|
||||
|
||||
bool GuiSound::IsPlaying() const {
|
||||
if (playedOn == -1) {
|
||||
return false;
|
||||
}
|
||||
return Mix_Playing(playedOn);
|
||||
}
|
||||
|
||||
void GuiSound::SetVolume(uint32_t vol) const {
|
||||
if (music) { Mix_VolumeChunk(music, vol); }
|
||||
}
|
||||
|
||||
void GuiSound::SetLoop(bool l) {
|
||||
// < 0 == infinitive loop
|
||||
loops = l ? -1 : 1;
|
||||
}
|
||||
|
||||
void GuiSound::Rewind() const {
|
||||
// TODO: how to rewind?
|
||||
Stop();
|
||||
}
|
@ -1,67 +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/>.
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "GuiElement.h"
|
||||
#include <SDL2/SDL_mixer.h>
|
||||
|
||||
//!Sound conversion and playback. A wrapper for other sound libraries - ASND, libmad, ltremor, etc
|
||||
class GuiSound : public GuiElement {
|
||||
public:
|
||||
explicit GuiSound(const char *filepath);
|
||||
|
||||
//!Constructor
|
||||
//!\param sound Pointer to the sound data
|
||||
//!\param filesize Length of sound data
|
||||
GuiSound(void *buffer, uint32_t filesize, bool freeSrc = false);
|
||||
|
||||
//!Destructor
|
||||
~GuiSound() override;
|
||||
|
||||
//!Load a file and replace the old one
|
||||
bool Load(const char *filepath);
|
||||
|
||||
//!Start sound playback
|
||||
void Play();
|
||||
|
||||
//!Stop sound playback
|
||||
void Stop() const;
|
||||
|
||||
//!Pause sound playback
|
||||
void Pause() const;
|
||||
|
||||
//!Resume sound playback
|
||||
void Resume();
|
||||
|
||||
//!Checks if the sound is currently playing
|
||||
//!\return true if sound is playing, false otherwise
|
||||
[[nodiscard]] bool IsPlaying() const;
|
||||
|
||||
//!Rewind the music
|
||||
void Rewind() const;
|
||||
|
||||
//!Set sound volume
|
||||
//!\param v Sound volume (0-100)
|
||||
void SetVolume(uint32_t v) const;
|
||||
|
||||
//!\param l Loop (true to loop)
|
||||
void SetLoop(bool l);
|
||||
|
||||
Mix_Chunk *music = nullptr;
|
||||
int32_t loops = 0;
|
||||
int32_t playedOn = -1;
|
||||
};
|
@ -1,96 +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/>.
|
||||
****************************************************************************/
|
||||
#include <cstdarg>
|
||||
#include <SDL2/SDL_surface.h>
|
||||
#include "GuiText.h"
|
||||
|
||||
/**
|
||||
* Constructor for the GuiText class.
|
||||
*/
|
||||
|
||||
GuiText::GuiText(const std::string& text, SDL_Color c, FC_Font* gFont) {
|
||||
this->text = text;
|
||||
this->color = c;
|
||||
this->fc_font = gFont;
|
||||
this->doUpdateTexture = true;
|
||||
this->texture.setParent(this);
|
||||
}
|
||||
|
||||
GuiText::~GuiText() {
|
||||
delete textureData;
|
||||
}
|
||||
|
||||
void GuiText::draw(Renderer *renderer) {
|
||||
if (!this->isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateTexture(renderer);
|
||||
|
||||
texture.draw(renderer);
|
||||
}
|
||||
|
||||
void GuiText::process() {
|
||||
GuiElement::process();
|
||||
}
|
||||
|
||||
void GuiText::setMaxWidth(float width) {
|
||||
this->maxWidth = width;
|
||||
|
||||
// Rebuild the texture cache on next draw
|
||||
doUpdateTexture = true;
|
||||
}
|
||||
|
||||
void GuiText::updateSize() {
|
||||
auto height = FC_GetColumnHeight(fc_font, maxWidth, text.c_str());
|
||||
auto width = FC_GetWidth(fc_font, text.c_str());
|
||||
width = width > maxWidth ? maxWidth : width;
|
||||
this->setSize(width, height);
|
||||
}
|
||||
|
||||
void GuiText::updateTexture(Renderer *renderer) {
|
||||
if(doUpdateTexture) {
|
||||
updateSize();
|
||||
int tex_width = tex_width = width == 0 ? 1 : (int) width;
|
||||
int tex_height = tex_height = height == 0 ? 1 : (int)height;
|
||||
|
||||
SDL_Texture *temp = SDL_CreateTexture(renderer->getRenderer(), renderer->getPixelFormat(), SDL_TEXTUREACCESS_TARGET, tex_width, tex_height);
|
||||
if (temp) {
|
||||
texture.setTexture(nullptr);
|
||||
delete textureData;
|
||||
textureData = new GuiTextureData(temp);
|
||||
textureData->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
texture.setTexture(textureData);
|
||||
|
||||
// Set render target to texture
|
||||
SDL_SetRenderTarget(renderer->getRenderer(), temp);
|
||||
|
||||
// Clear texture.
|
||||
SDL_SetRenderDrawColor(renderer->getRenderer(), 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer->getRenderer());
|
||||
|
||||
// Draw text to texture
|
||||
FC_DrawColumn(fc_font, renderer->getRenderer(), 0, 0, maxWidth, text.c_str());
|
||||
|
||||
// Restore render target
|
||||
SDL_SetRenderTarget(renderer->getRenderer(), nullptr);
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("Failed to create texture");
|
||||
}
|
||||
doUpdateTexture = false;
|
||||
}
|
||||
}
|
@ -1,56 +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/>.
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "GuiElement.h"
|
||||
#include "GuiTextureData.h"
|
||||
#include "../system/video/SDL_FontCache.h"
|
||||
#include "GuiImage.h"
|
||||
#include <mutex>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
//!Display, manage, and manipulate text in the GUI
|
||||
class GuiText : public GuiElement {
|
||||
public:
|
||||
|
||||
//!\param t Text
|
||||
//!\param s Font size
|
||||
//!\param c Font color
|
||||
GuiText(const std::string &t, SDL_Color c, FC_Font *font);
|
||||
~GuiText() override;
|
||||
|
||||
void draw(Renderer *pVideo) override;
|
||||
|
||||
void process() override;
|
||||
|
||||
void setMaxWidth(float width);
|
||||
|
||||
protected:
|
||||
GuiImage texture;
|
||||
GuiTextureData* textureData = nullptr;
|
||||
|
||||
std::string text;
|
||||
SDL_Color color;
|
||||
FC_Font *fc_font = nullptr;
|
||||
bool doUpdateTexture = true;
|
||||
|
||||
uint16_t maxWidth = 0xFFFF;
|
||||
|
||||
void updateSize();
|
||||
|
||||
void updateTexture(Renderer *renderer);
|
||||
};
|
@ -1,93 +0,0 @@
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include "GuiTextureData.h"
|
||||
#include "../system/SDLSystem.h"
|
||||
#include "../utils/logger.h"
|
||||
|
||||
GuiTextureData::GuiTextureData(const std::string& path) {
|
||||
SDL_Surface *surface = IMG_Load_RW(SDL_RWFromFile(path.c_str(), "rb"), 1);
|
||||
loadSurface(surface);
|
||||
}
|
||||
|
||||
GuiTextureData::GuiTextureData(void *buffer, const uint32_t filesize, bool freesrc) {
|
||||
SDL_RWops *rw = SDL_RWFromMem(buffer, filesize);
|
||||
SDL_Surface *surface = IMG_Load_RW(rw, freesrc);
|
||||
loadSurface(surface);
|
||||
}
|
||||
|
||||
GuiTextureData::GuiTextureData(SDL_Texture *texture) {
|
||||
if (this->texture) {
|
||||
SDL_DestroyTexture(this->texture);
|
||||
this->texture = nullptr;
|
||||
}
|
||||
this->texture = texture;
|
||||
int w, h;
|
||||
SDL_QueryTexture(this->texture, nullptr, nullptr, &w, &h);
|
||||
this->width = w;
|
||||
this->height = h;
|
||||
}
|
||||
|
||||
void GuiTextureData::loadSurface(SDL_Surface *pSurface) {
|
||||
if(!pSurface){
|
||||
return;
|
||||
}
|
||||
|
||||
cleanUp();
|
||||
|
||||
imgSurface = pSurface;
|
||||
|
||||
this->width = imgSurface->w;
|
||||
this->height = imgSurface->h;
|
||||
}
|
||||
|
||||
void GuiTextureData::cleanUp() {
|
||||
if (imgSurface) {
|
||||
SDL_FreeSurface(imgSurface);
|
||||
imgSurface = nullptr;
|
||||
}
|
||||
if (texture) {
|
||||
SDL_DestroyTexture(texture);
|
||||
texture = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor for the GuiImage class.
|
||||
*/
|
||||
GuiTextureData::~GuiTextureData() {
|
||||
cleanUp();
|
||||
}
|
||||
|
||||
void GuiTextureData::draw(Renderer *renderer, const SDL_Rect& dest, float angle) {
|
||||
if (texture == nullptr && imgSurface) {
|
||||
texture = SDL_CreateTextureFromSurface(renderer->getRenderer(), imgSurface);
|
||||
}
|
||||
if (!texture) {
|
||||
DEBUG_FUNCTION_LINE("no texture!");
|
||||
return;
|
||||
}
|
||||
|
||||
// copy the texture to the rendering context
|
||||
SDL_BlendMode mode;
|
||||
SDL_GetRenderDrawBlendMode(renderer->getRenderer(), &mode);
|
||||
|
||||
// adjust blend mode
|
||||
if(blendMode != mode){
|
||||
SDL_SetRenderDrawBlendMode(renderer->getRenderer(), blendMode);
|
||||
}
|
||||
|
||||
if (angle == 0) {
|
||||
SDL_RenderCopy(renderer->getRenderer(), texture, nullptr, &dest);
|
||||
} else {
|
||||
SDL_RenderCopyEx(renderer->getRenderer(), texture, nullptr, &dest, angle, nullptr, SDL_FLIP_NONE);
|
||||
}
|
||||
|
||||
if(blendMode != mode){
|
||||
SDL_SetRenderDrawBlendMode(renderer->getRenderer(), mode);
|
||||
}
|
||||
}
|
||||
|
||||
int GuiTextureData::setBlendMode(SDL_BlendMode blendMode) {
|
||||
this->blendMode = blendMode;
|
||||
if(texture){ return SDL_SetTextureBlendMode(texture, blendMode); }
|
||||
return SDL_BLENDMODE_INVALID;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include "GuiElement.h"
|
||||
|
||||
class GuiTextureData {
|
||||
public:
|
||||
GuiTextureData(void *buffer, uint32_t filesize, bool freesrc = false);
|
||||
|
||||
explicit GuiTextureData(SDL_Texture *texture);
|
||||
|
||||
explicit GuiTextureData(const std::string &path);
|
||||
|
||||
//!Destructor
|
||||
~GuiTextureData();
|
||||
|
||||
void draw(Renderer *pVideo, const SDL_Rect &rect, float angle);
|
||||
|
||||
int setBlendMode(SDL_BlendMode blendMode);
|
||||
|
||||
[[nodiscard]] int32_t getWidth() const {
|
||||
return width;
|
||||
}
|
||||
|
||||
[[nodiscard]] int32_t getHeight() const {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
void loadSurface(SDL_Surface *pSurface);
|
||||
|
||||
SDL_Surface *imgSurface = nullptr;
|
||||
|
||||
void cleanUp();
|
||||
|
||||
SDL_Texture *texture = nullptr;
|
||||
int32_t width = 0;
|
||||
int32_t height = 0;
|
||||
SDL_BlendMode blendMode;
|
||||
};
|
@ -1,142 +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/>.
|
||||
****************************************************************************/
|
||||
#include "GuiController.h"
|
||||
|
||||
/**
|
||||
* Constructor for the GuiTrigger class.
|
||||
*/
|
||||
GuiTrigger::GuiTrigger()
|
||||
: chan(CHANNEL_ALL), btns(BUTTON_NONE), bClickEverywhere(false), bHoldEverywhere(false), bSelectionClickEverywhere(false), bLastTouched(false) {
|
||||
}
|
||||
|
||||
GuiTrigger::GuiTrigger(uint32_t ch, uint32_t btn, bool clickEverywhere, bool holdEverywhere, bool selectionClickEverywhere)
|
||||
: chan(ch), btns(btn), bClickEverywhere(clickEverywhere), bHoldEverywhere(holdEverywhere), bSelectionClickEverywhere(selectionClickEverywhere), bLastTouched(false) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor for the GuiTrigger class.
|
||||
*/
|
||||
GuiTrigger::~GuiTrigger() = default;
|
||||
|
||||
/**
|
||||
* Sets a simple trigger. Requires:
|
||||
* - Element is selected
|
||||
* - Trigger button is pressed
|
||||
*/
|
||||
void GuiTrigger::setTrigger(uint32_t ch, uint32_t btn) {
|
||||
chan = ch;
|
||||
btns = btn;
|
||||
}
|
||||
|
||||
bool GuiTrigger::left(const GuiController *controller) const {
|
||||
if ((controller->chan & chan) == 0) {
|
||||
return false;
|
||||
}
|
||||
if ((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_LEFT | STICK_L_LEFT)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GuiTrigger::right(const GuiController *controller) const {
|
||||
if ((controller->chan & chan) == 0) {
|
||||
return false;
|
||||
}
|
||||
if ((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_RIGHT | STICK_L_RIGHT)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GuiTrigger::up(const GuiController *controller) const {
|
||||
if ((controller->chan & chan) == 0) {
|
||||
return false;
|
||||
}
|
||||
if ((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_UP | STICK_L_UP)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GuiTrigger::down(const GuiController *controller) const {
|
||||
if ((controller->chan & chan) == 0) {
|
||||
return false;
|
||||
}
|
||||
if ((controller->data.buttons_h | controller->data.buttons_d) & (BUTTON_DOWN | STICK_L_DOWN)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t GuiTrigger::clicked(const GuiController *controller) const {
|
||||
if ((controller->chan & chan) == 0) {
|
||||
return CLICKED_NONE;
|
||||
}
|
||||
|
||||
int32_t bResult = CLICKED_NONE;
|
||||
|
||||
|
||||
if (controller->data.touched && controller->data.validPointer && (btns & TOUCHED) && !controller->lastData.touched) {
|
||||
bResult = CLICKED_TOUCH;
|
||||
}
|
||||
|
||||
if (controller->data.buttons_d & btns) {
|
||||
bResult = CLICKED_BUTTON;
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
|
||||
bool GuiTrigger::held(const GuiController *controller) const {
|
||||
if ((controller->chan & chan) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bResult = false;
|
||||
|
||||
if (controller->data.touched && (btns & TOUCHED) && controller->data.validPointer && controller->lastData.touched && controller->lastData.validPointer) {
|
||||
bResult = true;
|
||||
}
|
||||
|
||||
if (controller->data.buttons_h & btns) {
|
||||
bResult = true;
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
bool GuiTrigger::released(const GuiController *controller) const {
|
||||
if ((controller->chan & chan) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (clicked(controller) || held(controller)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bResult = false;
|
||||
|
||||
if (!controller->data.touched && (btns & TOUCHED) && controller->lastData.touched && controller->lastData.validPointer) {
|
||||
bResult = true;
|
||||
}
|
||||
|
||||
if (controller->data.buttons_r & btns) {
|
||||
bResult = true;
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
@ -1,132 +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/>.
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class GuiController;
|
||||
|
||||
//!Menu input trigger management. Determine if action is necessary based on input data by comparing controller input data to a specific trigger element.
|
||||
class GuiTrigger {
|
||||
public:
|
||||
enum eClicked {
|
||||
CLICKED_NONE = 0x00,
|
||||
CLICKED_TOUCH = 0x01,
|
||||
CLICKED_BUTTON = 0x02,
|
||||
};
|
||||
enum eChannels {
|
||||
CHANNEL_1 = 0x01,
|
||||
CHANNEL_2 = 0x02,
|
||||
CHANNEL_3 = 0x04,
|
||||
CHANNEL_4 = 0x08,
|
||||
CHANNEL_5 = 0x10,
|
||||
CHANNEL_ALL = 0xFF
|
||||
};
|
||||
enum eButtons {
|
||||
BUTTON_NONE = 0x0000,
|
||||
TOUCHED = 0x80000000,
|
||||
VPAD_TOUCH = TOUCHED,
|
||||
BUTTON_Z = 0x20000,
|
||||
BUTTON_C = 0x10000,
|
||||
BUTTON_A = 0x8000,
|
||||
BUTTON_B = 0x4000,
|
||||
BUTTON_X = 0x2000,
|
||||
BUTTON_Y = 0x1000,
|
||||
BUTTON_1 = BUTTON_Y,
|
||||
BUTTON_2 = BUTTON_X,
|
||||
BUTTON_LEFT = 0x0800,
|
||||
BUTTON_RIGHT = 0x0400,
|
||||
BUTTON_UP = 0x0200,
|
||||
BUTTON_DOWN = 0x0100,
|
||||
BUTTON_ZL = 0x0080,
|
||||
BUTTON_ZR = 0x0040,
|
||||
BUTTON_L = 0x0020,
|
||||
BUTTON_R = 0x0010,
|
||||
BUTTON_PLUS = 0x0008,
|
||||
BUTTON_MINUS = 0x0004,
|
||||
BUTTON_HOME = 0x0002,
|
||||
BUTTON_SYNC = 0x0001,
|
||||
STICK_R_LEFT = 0x04000000,
|
||||
STICK_R_RIGHT = 0x02000000,
|
||||
STICK_R_UP = 0x01000000,
|
||||
STICK_R_DOWN = 0x00800000,
|
||||
STICK_L_LEFT = 0x40000000,
|
||||
STICK_L_RIGHT = 0x20000000,
|
||||
STICK_L_UP = 0x10000000,
|
||||
STICK_L_DOWN = 0x08000000,
|
||||
BUTTON_STICK_L = BUTTON_Z,
|
||||
BUTTON_STICK_R = BUTTON_C,
|
||||
};
|
||||
|
||||
//!Constructor
|
||||
GuiTrigger();
|
||||
|
||||
//!Constructor
|
||||
GuiTrigger(uint32_t ch, uint32_t btns, bool clickEverywhere = false, bool holdEverywhere = false, bool selectionClickEverywhere = false);
|
||||
|
||||
//!Destructor
|
||||
virtual ~GuiTrigger();
|
||||
|
||||
//!Sets a simple trigger. Requires: element is selected, and trigger button is pressed
|
||||
void setTrigger(uint32_t ch, uint32_t btns);
|
||||
|
||||
void setClickEverywhere(bool b) {
|
||||
bClickEverywhere = b;
|
||||
}
|
||||
|
||||
void setHoldOnly(bool b) {
|
||||
bHoldEverywhere = b;
|
||||
}
|
||||
|
||||
void setSelectionClickEverywhere(bool b) {
|
||||
bSelectionClickEverywhere = b;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isClickEverywhere() const {
|
||||
return bClickEverywhere;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isHoldEverywhere() const {
|
||||
return bHoldEverywhere;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isSelectionClickEverywhere() const {
|
||||
return bSelectionClickEverywhere;
|
||||
}
|
||||
|
||||
bool left(const GuiController *controller) const;
|
||||
|
||||
bool right(const GuiController *controller) const;
|
||||
|
||||
bool up(const GuiController *controller) const;
|
||||
|
||||
bool down(const GuiController *controller) const;
|
||||
|
||||
int32_t clicked(const GuiController *controller) const;
|
||||
|
||||
bool held(const GuiController *controller) const;
|
||||
|
||||
bool released(const GuiController *controller) const;
|
||||
|
||||
private:
|
||||
uint32_t chan;
|
||||
uint32_t btns;
|
||||
bool bClickEverywhere;
|
||||
bool bHoldEverywhere;
|
||||
bool bSelectionClickEverywhere;
|
||||
bool bLastTouched;
|
||||
};
|
2433
src/gui/sigslot.h
2433
src/gui/sigslot.h
File diff suppressed because it is too large
Load Diff
@ -1,104 +0,0 @@
|
||||
#include <functional>
|
||||
#include "ControllerManager.h"
|
||||
#include "SDLControllerWiiUGamepad.h"
|
||||
#include "SDLControllerXboxOne.h"
|
||||
#include "SDLControllerWiiUProContoller.h"
|
||||
#include "SDLControllerJoystick.h"
|
||||
|
||||
GuiTrigger::eChannels ControllerManager::increaseChannel(GuiTrigger::eChannels channel) {
|
||||
switch (channel) {
|
||||
case GuiTrigger::CHANNEL_1:
|
||||
return GuiTrigger::CHANNEL_2;
|
||||
case GuiTrigger::CHANNEL_2:
|
||||
return GuiTrigger::CHANNEL_3;
|
||||
case GuiTrigger::CHANNEL_3:
|
||||
return GuiTrigger::CHANNEL_4;
|
||||
case GuiTrigger::CHANNEL_4:
|
||||
return GuiTrigger::CHANNEL_5;
|
||||
case GuiTrigger::CHANNEL_5:
|
||||
case GuiTrigger::CHANNEL_ALL:
|
||||
return GuiTrigger::CHANNEL_ALL;
|
||||
}
|
||||
return GuiTrigger::CHANNEL_ALL;
|
||||
}
|
||||
|
||||
void ControllerManager::attachController(GuiTrigger::eChannels channel, SDLController *controller) {
|
||||
controllerList[channel] = controller;
|
||||
}
|
||||
|
||||
void ControllerManager::prepare() {
|
||||
//! Read out inputs
|
||||
for (auto const&[channel, controller] : controllerList) {
|
||||
controller->before();
|
||||
}
|
||||
}
|
||||
|
||||
bool ControllerManager::attachJoystick(int32_t deviceId) {
|
||||
auto joystick = SDL_JoystickOpen(deviceId);
|
||||
if (joystick == nullptr) {
|
||||
DEBUG_FUNCTION_LINE("SDL_JoystickOpen failed: %s\n", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
auto instanceId = SDL_JoystickInstanceID(joystick);
|
||||
if (std::string("WiiU Gamepad") == SDL_JoystickName(joystick)) {
|
||||
controllerList[GuiTrigger::CHANNEL_1] = new SDLControllerWiiUGamepad(GuiTrigger::CHANNEL_1);
|
||||
joystickToChannel[instanceId] = GuiTrigger::CHANNEL_1;
|
||||
} else {
|
||||
bool successfully_added = false;
|
||||
auto channel = GuiTrigger::CHANNEL_2;
|
||||
while (channel != GuiTrigger::CHANNEL_ALL) {
|
||||
if (controllerList.find(channel) == controllerList.end()) {
|
||||
if (std::string(SDL_JoystickName(joystick)).find("Xbox") != std::string::npos
|
||||
|| std::string(SDL_JoystickName(joystick)).find("X-Box") != std::string::npos) {
|
||||
controllerList[channel] = new SDLControllerXboxOne(channel);
|
||||
} else if (std::string(SDL_JoystickName(joystick)).find("WiiU Pro Controller") != std::string::npos) {
|
||||
controllerList[channel] = new SDLControllerWiiUProContoller(channel);
|
||||
} else {
|
||||
controllerList[channel] = new SDLControllerJoystick(channel, instanceId);
|
||||
}
|
||||
joystickToChannel[instanceId] = channel;
|
||||
successfully_added = true;
|
||||
break;
|
||||
}
|
||||
channel = increaseChannel(channel);
|
||||
}
|
||||
if (!successfully_added) {
|
||||
DEBUG_FUNCTION_LINE("Failed to add joystick. Closing it now");
|
||||
SDL_JoystickClose(joystick);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
DEBUG_FUNCTION_LINE("Added joystick %s", SDL_JoystickName(joystick));
|
||||
return true;
|
||||
}
|
||||
|
||||
void ControllerManager::detachJoystick(int32_t instanceId) {
|
||||
auto channel = joystickToChannel[instanceId];
|
||||
delete controllerList[channel];
|
||||
controllerList.erase(channel);
|
||||
joystickToChannel.erase(instanceId);
|
||||
DEBUG_FUNCTION_LINE("Removed joystick: %d", instanceId);
|
||||
}
|
||||
|
||||
void ControllerManager::processEvent(SDL_JoystickID joystickId, int32_t channel, SDL_Event *e) {
|
||||
if (joystickId != -1) {
|
||||
if (joystickToChannel.find(joystickId) != joystickToChannel.end()) {
|
||||
channel = joystickToChannel[joystickId];
|
||||
}
|
||||
}
|
||||
if (channel != -1 && controllerList.count(static_cast<const GuiTrigger::eChannels>(channel)) > 0) {
|
||||
controllerList[static_cast<GuiTrigger::eChannels>(channel)]->update(e, screenWidth, screenHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerManager::finish() {
|
||||
for (auto const&[joypad, controller] : controllerList) {
|
||||
controller->after();
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerManager::callPerController(std::function<void(GuiController*)> func) {
|
||||
for (auto const&[joypad, controller] : controllerList) {
|
||||
func(controller);
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include "../gui/GuiTrigger.h"
|
||||
#include "SDLController.h"
|
||||
#include "SDLControllerMouse.h"
|
||||
|
||||
class ControllerManager {
|
||||
public:
|
||||
ControllerManager(int32_t screenWidth, int32_t screenHeight) : screenWidth(screenWidth), screenHeight(screenHeight){
|
||||
|
||||
}
|
||||
|
||||
void attachController(GuiTrigger::eChannels channels, SDLController *controller);
|
||||
|
||||
void prepare();
|
||||
|
||||
bool attachJoystick(int32_t deviceId);
|
||||
|
||||
void detachJoystick(int32_t deviceId);
|
||||
|
||||
void processEvent(SDL_JoystickID joystickId, int32_t channel, SDL_Event *event);
|
||||
|
||||
void finish();
|
||||
|
||||
|
||||
void callPerController(std::function<void(GuiController*)> func);
|
||||
|
||||
private:
|
||||
GuiTrigger::eChannels increaseChannel(GuiTrigger::eChannels channel);
|
||||
|
||||
std::map<GuiTrigger::eChannels, SDLController *> controllerList;
|
||||
std::map<int32_t, GuiTrigger::eChannels> joystickToChannel;
|
||||
int32_t screenWidth;
|
||||
int32_t screenHeight;
|
||||
};
|
@ -1,60 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL2/SDL_mouse.h>
|
||||
#include <iostream>
|
||||
#include <SDL2/SDL_events.h>
|
||||
#include "../gui/GuiController.h"
|
||||
#include "../utils/logger.h"
|
||||
|
||||
#define printButton(chan, x) if(data.buttons_d & x) DEBUG_FUNCTION_LINE("Controller #%d %s", chan, #x)
|
||||
|
||||
class SDLController : public GuiController {
|
||||
public:
|
||||
explicit SDLController(int32_t channel) : GuiController(channel) {
|
||||
|
||||
}
|
||||
|
||||
virtual bool update(SDL_Event *e, int32_t screenWidth, int32_t screenHeight) = 0;
|
||||
|
||||
|
||||
virtual void before() {
|
||||
lastData = data;
|
||||
|
||||
data.buttons_d = 0;
|
||||
data.buttons_r = 0;
|
||||
}
|
||||
|
||||
virtual void after() {
|
||||
data.buttons_d |= (data.buttons_h & (~(lastData.buttons_h)));
|
||||
data.buttons_r |= ((lastData.buttons_h) & (~data.buttons_h));
|
||||
if (data.buttons_h != 0 || data.buttons_d != 0 || data.buttons_r != 0) {
|
||||
// DEBUG_FUNCTION_LINE("Controller #%d: h %08X d %08X r %08X", chanIdx, data.buttons_h, data.buttons_d, data.buttons_r);
|
||||
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_A);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_B);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_X);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_Y);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_STICK_L);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_STICK_R);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_L);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_R);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_ZL);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_ZR);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_PLUS);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_MINUS);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_LEFT);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_UP);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_RIGHT);
|
||||
printButton(chanIdx, GuiTrigger::BUTTON_DOWN);
|
||||
printButton(chanIdx, GuiTrigger::STICK_L_LEFT);
|
||||
printButton(chanIdx, GuiTrigger::STICK_L_UP);
|
||||
printButton(chanIdx, GuiTrigger::STICK_L_RIGHT);
|
||||
printButton(chanIdx, GuiTrigger::STICK_L_DOWN);
|
||||
printButton(chanIdx, GuiTrigger::STICK_R_LEFT);
|
||||
printButton(chanIdx, GuiTrigger::STICK_R_UP);
|
||||
printButton(chanIdx, GuiTrigger::STICK_R_RIGHT);
|
||||
printButton(chanIdx, GuiTrigger::STICK_R_DOWN);
|
||||
printButton(chanIdx, GuiTrigger::TOUCHED);
|
||||
}
|
||||
}
|
||||
};
|
@ -1,58 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
class SDLControllerJoystick : public SDLController {
|
||||
public:
|
||||
SDLControllerJoystick(int32_t channel, SDL_JoystickID joystickId) : SDLController(channel) {
|
||||
|
||||
}
|
||||
|
||||
bool update(SDL_Event *e, int32_t screenWidth, int32_t screenHeight) override {
|
||||
if (e->type == SDL_JOYBUTTONDOWN) {
|
||||
data.buttons_h |= (1 << e->jbutton.button);
|
||||
} else if (e->type == SDL_JOYBUTTONUP) {
|
||||
data.buttons_h &= ~(1 << e->jbutton.button);
|
||||
} else if (e->type == SDL_JOYHATMOTION) {
|
||||
auto val = e->jhat.value;
|
||||
|
||||
auto hatMask = (GuiTrigger::BUTTON_LEFT | GuiTrigger::BUTTON_UP | GuiTrigger::BUTTON_DOWN | GuiTrigger::BUTTON_RIGHT);
|
||||
|
||||
// Remove hat values so we can add the new value.
|
||||
data.buttons_h &= ~hatMask;
|
||||
|
||||
switch (val) {
|
||||
case SDL_HAT_LEFTUP:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_LEFT;
|
||||
data.buttons_h |= GuiTrigger::BUTTON_UP;
|
||||
break;
|
||||
case SDL_HAT_LEFT:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_LEFT;
|
||||
break;
|
||||
case SDL_HAT_LEFTDOWN:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_LEFT;
|
||||
data.buttons_h |= GuiTrigger::BUTTON_DOWN;
|
||||
break;
|
||||
case SDL_HAT_UP:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_UP;
|
||||
break;
|
||||
case SDL_HAT_DOWN:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_DOWN;
|
||||
break;
|
||||
case SDL_HAT_RIGHTUP:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_RIGHT;
|
||||
data.buttons_h |= GuiTrigger::BUTTON_UP;
|
||||
break;
|
||||
case SDL_HAT_RIGHT:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_RIGHT;
|
||||
break;
|
||||
case SDL_HAT_RIGHTDOWN:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_RIGHT;
|
||||
data.buttons_h |= GuiTrigger::BUTTON_DOWN;
|
||||
break;
|
||||
}
|
||||
} else if (e->type == SDL_JOYAXISMOTION) {
|
||||
//
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -1,30 +0,0 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
class SDLControllerMouse: public SDLController {
|
||||
public:
|
||||
explicit SDLControllerMouse(int32_t channel) : SDLController(channel) {
|
||||
|
||||
}
|
||||
|
||||
void before() override{
|
||||
SDLController::before();
|
||||
data.validPointer = true;
|
||||
}
|
||||
|
||||
virtual bool update(SDL_Event *e, int32_t screenWidth, int32_t screenHeight) override {
|
||||
if (e->type == SDL_MOUSEMOTION) {
|
||||
data.y = e->motion.y;
|
||||
data.x = e->motion.x;
|
||||
} else if (e->type == SDL_MOUSEBUTTONDOWN && e->button.button == SDL_BUTTON_LEFT) {
|
||||
data.touched = true;
|
||||
} else if (e->type == SDL_MOUSEBUTTONUP && e->button.button == SDL_BUTTON_LEFT) {
|
||||
data.touched = false;
|
||||
}else{
|
||||
DEBUG_FUNCTION_LINE("Unknown event");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -1,53 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SDLController.h"
|
||||
|
||||
static GuiTrigger::eButtons vpad_button_map[] = {
|
||||
GuiTrigger::BUTTON_A,
|
||||
GuiTrigger::BUTTON_B,
|
||||
GuiTrigger::BUTTON_X,
|
||||
GuiTrigger::BUTTON_Y,
|
||||
GuiTrigger::BUTTON_STICK_L, GuiTrigger::BUTTON_STICK_R,
|
||||
GuiTrigger::BUTTON_L, GuiTrigger::BUTTON_R,
|
||||
GuiTrigger::BUTTON_ZL, GuiTrigger::BUTTON_ZR,
|
||||
GuiTrigger::BUTTON_PLUS, GuiTrigger::BUTTON_MINUS,
|
||||
GuiTrigger::BUTTON_LEFT, GuiTrigger::BUTTON_UP, GuiTrigger::BUTTON_RIGHT, GuiTrigger::BUTTON_DOWN,
|
||||
GuiTrigger::STICK_L_LEFT, GuiTrigger::STICK_L_UP, GuiTrigger::STICK_L_RIGHT, GuiTrigger::STICK_L_DOWN,
|
||||
GuiTrigger::STICK_R_LEFT, GuiTrigger::STICK_R_UP, GuiTrigger::STICK_R_RIGHT, GuiTrigger::STICK_R_DOWN,
|
||||
};
|
||||
|
||||
class SDLControllerWiiUGamepad : public SDLController {
|
||||
public:
|
||||
explicit SDLControllerWiiUGamepad(int32_t channel) : SDLController(channel) {
|
||||
|
||||
}
|
||||
|
||||
bool update(SDL_Event *e, int32_t screenWidth, int32_t screenHeight) override {
|
||||
if (e->type == SDL_FINGERMOTION || e->type == SDL_FINGERUP || e->type == SDL_FINGERDOWN) {
|
||||
data.y = e->tfinger.y * screenHeight;
|
||||
data.x = e->tfinger.x * screenWidth;
|
||||
if (e->type == SDL_FINGERUP) {
|
||||
data.touched = false;
|
||||
} else if (e->type == SDL_FINGERDOWN) {
|
||||
data.touched = true;
|
||||
}
|
||||
} else if (e->type == SDL_JOYBUTTONDOWN) {
|
||||
data.buttons_h |= vpad_button_map[e->jbutton.button];
|
||||
} else if (e->type == SDL_JOYBUTTONUP) {
|
||||
data.buttons_h &= ~vpad_button_map[e->jbutton.button];
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("Unknown event");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void after() override {
|
||||
data.validPointer = data.touched;
|
||||
SDLController::after();
|
||||
}
|
||||
};
|
||||
|
@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "SDLControllerWiiUGamepad.h"
|
||||
|
||||
class SDLControllerWiiUProContoller : public SDLControllerWiiUGamepad {
|
||||
public:
|
||||
explicit SDLControllerWiiUProContoller(int32_t channel) : SDLControllerWiiUGamepad(channel){
|
||||
|
||||
}
|
||||
};
|
||||
|
@ -1,106 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "SDLController.h"
|
||||
|
||||
static GuiTrigger::eButtons xbox_button_map[] =
|
||||
{
|
||||
GuiTrigger::BUTTON_A,
|
||||
GuiTrigger::BUTTON_B,
|
||||
GuiTrigger::BUTTON_X,
|
||||
GuiTrigger::BUTTON_Y,
|
||||
GuiTrigger::BUTTON_L,
|
||||
GuiTrigger::BUTTON_R,
|
||||
GuiTrigger::BUTTON_MINUS,
|
||||
GuiTrigger::BUTTON_PLUS,
|
||||
GuiTrigger::BUTTON_STICK_L,
|
||||
GuiTrigger::BUTTON_STICK_R,
|
||||
};
|
||||
|
||||
#define getDigitalAxis(axis, targetAxis, value, hold, first, second) \
|
||||
if(axis == targetAxis){ \
|
||||
if (value < 0x4000 && value > -0x4000){ \
|
||||
hold &= ~first; \
|
||||
hold &= ~second; \
|
||||
}else if(value < -0x4000){ \
|
||||
hold |= first; \
|
||||
hold &= ~second; \
|
||||
}else if(value > 0x4000){ \
|
||||
hold |= second; \
|
||||
hold &= ~first; \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define getDigitalTrigger(axis, targetAxis, value, hold, first) \
|
||||
if(axis == targetAxis){ \
|
||||
if(value > 0){ \
|
||||
hold |= first; \
|
||||
}else{ \
|
||||
hold &= ~first; \
|
||||
} \
|
||||
} \
|
||||
|
||||
|
||||
class SDLControllerXboxOne : public SDLController {
|
||||
public:
|
||||
explicit SDLControllerXboxOne(int32_t channel) : SDLController(channel) {
|
||||
|
||||
}
|
||||
|
||||
bool update(SDL_Event *e, int32_t screenWidth, int32_t screenHeight) override {
|
||||
if (e->type == SDL_JOYBUTTONDOWN) {
|
||||
data.buttons_h |= xbox_button_map[e->jbutton.button];
|
||||
} else if (e->type == SDL_JOYBUTTONUP) {
|
||||
data.buttons_h &= ~xbox_button_map[e->jbutton.button];
|
||||
} else if (e->type == SDL_JOYHATMOTION) {
|
||||
auto val = e->jhat.value;
|
||||
|
||||
auto hatMask = (GuiTrigger::BUTTON_LEFT | GuiTrigger::BUTTON_UP | GuiTrigger::BUTTON_DOWN | GuiTrigger::BUTTON_RIGHT);
|
||||
|
||||
// Remove hat values so we can add the new values.
|
||||
data.buttons_h &= ~hatMask;
|
||||
|
||||
switch (val) {
|
||||
case SDL_HAT_LEFTUP:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_LEFT;
|
||||
data.buttons_h |= GuiTrigger::BUTTON_UP;
|
||||
break;
|
||||
case SDL_HAT_LEFT:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_LEFT;
|
||||
break;
|
||||
case SDL_HAT_LEFTDOWN:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_LEFT;
|
||||
data.buttons_h |= GuiTrigger::BUTTON_DOWN;
|
||||
break;
|
||||
case SDL_HAT_UP:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_UP;
|
||||
break;
|
||||
case SDL_HAT_DOWN:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_DOWN;
|
||||
break;
|
||||
case SDL_HAT_RIGHTUP:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_RIGHT;
|
||||
data.buttons_h |= GuiTrigger::BUTTON_UP;
|
||||
break;
|
||||
case SDL_HAT_RIGHT:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_RIGHT;
|
||||
break;
|
||||
case SDL_HAT_RIGHTDOWN:
|
||||
data.buttons_h |= GuiTrigger::BUTTON_RIGHT;
|
||||
data.buttons_h |= GuiTrigger::BUTTON_DOWN;
|
||||
break;
|
||||
}
|
||||
} else if (e->type == SDL_JOYAXISMOTION) {
|
||||
getDigitalTrigger(e->jaxis.axis, 2, e->jaxis.value, data.buttons_h, GuiTrigger::BUTTON_ZL);
|
||||
getDigitalTrigger(e->jaxis.axis, 5, e->jaxis.value, data.buttons_h, GuiTrigger::BUTTON_ZR);
|
||||
getDigitalAxis(e->jaxis.axis, 0, e->jaxis.value, data.buttons_h, GuiTrigger::STICK_L_LEFT, GuiTrigger::STICK_L_RIGHT);
|
||||
getDigitalAxis(e->jaxis.axis, 1, e->jaxis.value, data.buttons_h, GuiTrigger::STICK_L_UP, GuiTrigger::STICK_L_DOWN);
|
||||
getDigitalAxis(e->jaxis.axis, 3, e->jaxis.value, data.buttons_h, GuiTrigger::STICK_R_LEFT, GuiTrigger::STICK_R_RIGHT);
|
||||
getDigitalAxis(e->jaxis.axis, 4, e->jaxis.value, data.buttons_h, GuiTrigger::STICK_R_UP, GuiTrigger::STICK_R_DOWN);
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("Unknown event");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
14
src/main.cpp
14
src/main.cpp
@ -1,12 +1,12 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include "system/SDLSystem.h"
|
||||
#include "gui/GuiFrame.h"
|
||||
#include "gui/GuiButton.h"
|
||||
#include "gui/GuiController.h"
|
||||
#include <gui/system/SDLSystem.h>
|
||||
#include <gui/GuiFrame.h>
|
||||
#include <gui/GuiButton.h>
|
||||
#include <gui/GuiController.h>
|
||||
#include "menu/MainWindow.h"
|
||||
#include "input/SDLController.h"
|
||||
#include "input/SDLControllerMouse.h"
|
||||
#include "input/ControllerManager.h"
|
||||
#include <gui/input/SDLController.h>
|
||||
#include <gui/input/SDLControllerMouse.h>
|
||||
#include <gui/input/ControllerManager.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <fcntl.h>
|
||||
|
@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include "../gui/GuiFrame.h"
|
||||
#include "../gui/GuiButton.h"
|
||||
#include <gui/GuiFrame.h>
|
||||
#include <gui/GuiButton.h>
|
||||
#include "../utils/logger.h"
|
||||
#include "../gui/GuiImage.h"
|
||||
#include <gui/GuiImage.h>
|
||||
|
||||
class MainWindow : public GuiFrame, public sigslot::has_slots<> {
|
||||
public:
|
||||
|
@ -1,10 +1,9 @@
|
||||
#include <malloc.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include "Resources.h"
|
||||
#include "../fs/FSUtils.h"
|
||||
#include "../gui/GuiSound.h"
|
||||
#include "../gui/GuiTextureData.h"
|
||||
#include <gui/GuiSound.h>
|
||||
#include <gui/GuiTextureData.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
|
@ -1,84 +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/>.
|
||||
****************************************************************************/
|
||||
#include "SDLSystem.h"
|
||||
#include "../utils/logger.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_mixer.h>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
SDLSystem::SDLSystem() {
|
||||
SDL_Init(SDL_INIT_EVERYTHING);
|
||||
|
||||
auto SDLFlags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;
|
||||
|
||||
//Setup window
|
||||
window = SDL_CreateWindow(nullptr, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, 0);
|
||||
if (!window) {
|
||||
DEBUG_FUNCTION_LINE("Failed to create window");
|
||||
return;
|
||||
}
|
||||
auto sdl_renderer = SDL_CreateRenderer(window, -1, SDLFlags);
|
||||
if (!sdl_renderer) {
|
||||
DEBUG_FUNCTION_LINE("Failed to init sdl renderer");
|
||||
return;
|
||||
}
|
||||
SDL_SetRenderTarget(sdl_renderer, nullptr);
|
||||
this->renderer = new Renderer(sdl_renderer, SDL_GetWindowPixelFormat(window));
|
||||
if (!renderer) {
|
||||
DEBUG_FUNCTION_LINE("Failed to init renderer");
|
||||
return;
|
||||
}
|
||||
|
||||
if (SDL_Init(SDL_INIT_AUDIO) != 0) {
|
||||
DEBUG_FUNCTION_LINE("SDL init error: %s\n", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
int flags = 0;
|
||||
int result = 0;
|
||||
if (flags != (result = Mix_Init(flags))) {
|
||||
DEBUG_FUNCTION_LINE("Could not initialize mixer (result: %d).\n", result);
|
||||
DEBUG_FUNCTION_LINE("Mix_Init: %s\n", Mix_GetError());
|
||||
}
|
||||
|
||||
auto dev = Mix_OpenAudio(22050, AUDIO_S16SYS, 2, 640);
|
||||
SDL_PauseAudioDevice(dev, 0);
|
||||
|
||||
TTF_Init();
|
||||
}
|
||||
|
||||
SDLSystem::~SDLSystem() {
|
||||
SDL_DestroyWindow(window);
|
||||
delete renderer;
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
float SDLSystem::getHeight() {
|
||||
int h = 0;
|
||||
SDL_GetWindowSize(window, nullptr, &h);
|
||||
return h;
|
||||
}
|
||||
|
||||
float SDLSystem::getWidth() {
|
||||
int w = 0;
|
||||
SDL_GetWindowSize(window, &w, nullptr);
|
||||
return w;
|
||||
}
|
||||
|
||||
Renderer *SDLSystem::getRenderer() {
|
||||
return renderer;
|
||||
}
|
@ -1,35 +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/>.
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include "video/Renderer.h"
|
||||
|
||||
class SDLSystem {
|
||||
public:
|
||||
SDLSystem();
|
||||
|
||||
virtual ~SDLSystem();
|
||||
|
||||
Renderer *getRenderer();
|
||||
|
||||
float getHeight();
|
||||
float getWidth();
|
||||
|
||||
private:
|
||||
SDL_Window *window = NULL;
|
||||
Renderer *renderer = NULL;
|
||||
};
|
@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL2/SDL_render.h>
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
Renderer(SDL_Renderer *renderer, uint32_t pixelFormat) : sdl_renderer(renderer), pixelFormat(pixelFormat){
|
||||
|
||||
}
|
||||
|
||||
virtual ~Renderer() {
|
||||
if(sdl_renderer){
|
||||
SDL_DestroyRenderer(sdl_renderer);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Renderer *getRenderer(){
|
||||
return sdl_renderer;
|
||||
}
|
||||
|
||||
uint32_t getPixelFormat(){
|
||||
return pixelFormat;
|
||||
}
|
||||
|
||||
private:
|
||||
SDL_Renderer *sdl_renderer = NULL;
|
||||
uint32_t pixelFormat = SDL_PIXELFORMAT_RGBA8888;
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -1,320 +0,0 @@
|
||||
/*
|
||||
SDL_FontCache v0.10.0: A font cache for SDL and SDL_ttf
|
||||
by Jonathan Dearborn
|
||||
Dedicated to the memory of Florian Hufsky
|
||||
|
||||
License:
|
||||
The short:
|
||||
Use it however you'd like, but keep the copyright and license notice
|
||||
whenever these files or parts of them are distributed in uncompiled form.
|
||||
|
||||
The long:
|
||||
Copyright (c) 2019 Jonathan Dearborn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _SDL_FONTCACHE_H__
|
||||
#define _SDL_FONTCACHE_H__
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
#include <SDL2/SDL_pixels.h>
|
||||
#include "../../utils/logger.h"
|
||||
|
||||
#ifdef FC_USE_SDL_GPU
|
||||
#include "SDL_gpu.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Let's pretend this exists...
|
||||
#define TTF_STYLE_OUTLINE 16
|
||||
|
||||
|
||||
|
||||
// Differences between SDL_Renderer and SDL_gpu
|
||||
#ifdef FC_USE_SDL_GPU
|
||||
#define FC_Rect GPU_Rect
|
||||
#define FC_Target GPU_Target
|
||||
#define FC_Image GPU_Image
|
||||
#define FC_Log GPU_LogError
|
||||
#else
|
||||
#define FC_Rect SDL_Rect
|
||||
#define FC_Target SDL_Renderer
|
||||
#define FC_Image SDL_Texture
|
||||
#define FC_Log DEBUG_FUNCTION_LINE
|
||||
#endif
|
||||
|
||||
|
||||
// SDL_FontCache types
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FC_ALIGN_LEFT,
|
||||
FC_ALIGN_CENTER,
|
||||
FC_ALIGN_RIGHT
|
||||
} FC_AlignEnum;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FC_FILTER_NEAREST,
|
||||
FC_FILTER_LINEAR
|
||||
} FC_FilterEnum;
|
||||
|
||||
typedef struct FC_Scale
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
|
||||
} FC_Scale;
|
||||
|
||||
typedef struct FC_Effect
|
||||
{
|
||||
FC_AlignEnum alignment;
|
||||
FC_Scale scale;
|
||||
SDL_Color color;
|
||||
|
||||
} FC_Effect;
|
||||
|
||||
// Opaque type
|
||||
typedef struct FC_Font FC_Font;
|
||||
|
||||
|
||||
typedef struct FC_GlyphData
|
||||
{
|
||||
SDL_Rect rect;
|
||||
int cache_level;
|
||||
|
||||
} FC_GlyphData;
|
||||
|
||||
// Object creation
|
||||
FC_Rect FC_MakeRect(float x, float y, float w, float h);
|
||||
|
||||
FC_Scale FC_MakeScale(float x, float y);
|
||||
|
||||
SDL_Color FC_MakeColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||
|
||||
FC_Effect FC_MakeEffect(FC_AlignEnum alignment, FC_Scale scale, SDL_Color color);
|
||||
|
||||
FC_GlyphData FC_MakeGlyphData(int cache_level, Sint16 x, Sint16 y, Uint16 w, Uint16 h);
|
||||
|
||||
// Font object
|
||||
|
||||
FC_Font* FC_CreateFont(void);
|
||||
|
||||
#ifdef FC_USE_SDL_GPU
|
||||
Uint8 FC_LoadFont(FC_Font* font, const char* filename_ttf, Uint32 pointSize, SDL_Color color, int style);
|
||||
|
||||
Uint8 FC_LoadFontFromTTF(FC_Font* font, TTF_Font* ttf, SDL_Color color);
|
||||
|
||||
Uint8 FC_LoadFont_RW(FC_Font* font, SDL_RWops* file_rwops_ttf, Uint8 own_rwops, Uint32 pointSize, SDL_Color color, int style);
|
||||
#else
|
||||
Uint8 FC_LoadFont(FC_Font* font, SDL_Renderer* renderer, const char* filename_ttf, Uint32 pointSize, SDL_Color color, int style);
|
||||
|
||||
Uint8 FC_LoadFontFromTTF(FC_Font* font, SDL_Renderer* renderer, TTF_Font* ttf, SDL_Color color);
|
||||
|
||||
Uint8 FC_LoadFont_RW(FC_Font* font, SDL_Renderer* renderer, SDL_RWops* file_rwops_ttf, Uint8 own_rwops, Uint32 pointSize, SDL_Color color, int style);
|
||||
#endif
|
||||
|
||||
#ifndef FC_USE_SDL_GPU
|
||||
// note: handle SDL event types SDL_RENDER_TARGETS_RESET(>= SDL 2.0.2) and SDL_RENDER_DEVICE_RESET(>= SDL 2.0.4)
|
||||
void FC_ResetFontFromRendererReset(FC_Font* font, SDL_Renderer* renderer, Uint32 evType);
|
||||
#endif
|
||||
|
||||
void FC_ClearFont(FC_Font* font);
|
||||
|
||||
void FC_FreeFont(FC_Font* font);
|
||||
|
||||
|
||||
|
||||
// Built-in loading strings
|
||||
|
||||
char* FC_GetStringASCII(void);
|
||||
|
||||
char* FC_GetStringLatin1(void);
|
||||
|
||||
char* FC_GetStringASCII_Latin1(void);
|
||||
|
||||
|
||||
// UTF-8 to SDL_FontCache codepoint conversion
|
||||
|
||||
/*!
|
||||
Returns the Uint32 codepoint (not UTF-32) parsed from the given UTF-8 string.
|
||||
\param c A pointer to a string of proper UTF-8 character values.
|
||||
\param advance_pointer If true, the source pointer will be incremented to skip the extra bytes from multibyte codepoints.
|
||||
*/
|
||||
Uint32 FC_GetCodepointFromUTF8(const char** c, Uint8 advance_pointer);
|
||||
|
||||
/*!
|
||||
Parses the given codepoint and stores the UTF-8 bytes in 'result'. The result is NULL terminated.
|
||||
\param result A memory buffer for the UTF-8 values. Must be at least 5 bytes long.
|
||||
\param codepoint The Uint32 codepoint to parse (not UTF-32).
|
||||
*/
|
||||
void FC_GetUTF8FromCodepoint(char* result, Uint32 codepoint);
|
||||
|
||||
|
||||
// UTF-8 string operations
|
||||
|
||||
/*! Allocates a new string of 'size' bytes that is already NULL-terminated. The NULL byte counts toward the size limit, as usual. Returns NULL if size is 0. */
|
||||
char* U8_alloc(unsigned int size);
|
||||
|
||||
/*! Deallocates the given string. */
|
||||
void U8_free(char* string);
|
||||
|
||||
/*! Allocates a copy of the given string. */
|
||||
char* U8_strdup(const char* string);
|
||||
|
||||
/*! Returns the number of UTF-8 characters in the given string. */
|
||||
int U8_strlen(const char* string);
|
||||
|
||||
/*! Returns the number of bytes in the UTF-8 multibyte character pointed at by 'character'. */
|
||||
int U8_charsize(const char* character);
|
||||
|
||||
/*! Copies the source multibyte character into the given buffer without overrunning it. Returns 0 on failure. */
|
||||
int U8_charcpy(char* buffer, const char* source, int buffer_size);
|
||||
|
||||
/*! Returns a pointer to the next UTF-8 character. */
|
||||
const char* U8_next(const char* string);
|
||||
|
||||
/*! Inserts a UTF-8 string into 'string' at the given position. Use a position of -1 to append. Returns 0 when unable to insert the string. */
|
||||
int U8_strinsert(char* string, int position, const char* source, int max_bytes);
|
||||
|
||||
/*! Erases the UTF-8 character at the given position, moving the subsequent characters down. */
|
||||
void U8_strdel(char* string, int position);
|
||||
|
||||
|
||||
// Internal settings
|
||||
/*! Sets the string from which to load the initial glyphs. Use this if you need upfront loading for any reason (such as lack of render-target support). */
|
||||
void FC_SetLoadingString(FC_Font* font, const char* string);
|
||||
|
||||
/*! Returns the size of the internal buffer which is used for unpacking variadic text data. This buffer is shared by all FC_Fonts. */
|
||||
unsigned int FC_GetBufferSize(void);
|
||||
|
||||
/*! Changes the size of the internal buffer which is used for unpacking variadic text data. This buffer is shared by all FC_Fonts. */
|
||||
void FC_SetBufferSize(unsigned int size);
|
||||
|
||||
/*! Returns the width of a single horizontal tab in multiples of the width of a space (default: 4) */
|
||||
unsigned int FC_GetTabWidth(void);
|
||||
|
||||
/*! Changes the width of a horizontal tab in multiples of the width of a space (default: 4) */
|
||||
void FC_SetTabWidth(unsigned int width_in_spaces);
|
||||
|
||||
void FC_SetRenderCallback(FC_Rect (*callback)(FC_Image* src, FC_Rect* srcrect, FC_Target* dest, float x, float y, float xscale, float yscale));
|
||||
|
||||
FC_Rect FC_DefaultRenderCallback(FC_Image* src, FC_Rect* srcrect, FC_Target* dest, float x, float y, float xscale, float yscale);
|
||||
|
||||
|
||||
// Custom caching
|
||||
|
||||
/*! Returns the number of cache levels that are active. */
|
||||
int FC_GetNumCacheLevels(FC_Font* font);
|
||||
|
||||
/*! Returns the cache source texture at the given cache level. */
|
||||
FC_Image* FC_GetGlyphCacheLevel(FC_Font* font, int cache_level);
|
||||
|
||||
// TODO: Specify ownership of the texture (should be shareable)
|
||||
/*! Sets a cache source texture for rendering. New cache levels must be sequential. */
|
||||
Uint8 FC_SetGlyphCacheLevel(FC_Font* font, int cache_level, FC_Image* cache_texture);
|
||||
|
||||
/*! Copies the given surface to the given cache level as a texture. New cache levels must be sequential. */
|
||||
Uint8 FC_UploadGlyphCache(FC_Font* font, int cache_level, SDL_Surface* data_surface);
|
||||
|
||||
/*! Returns the number of codepoints that are stored in the font's glyph data map. */
|
||||
unsigned int FC_GetNumCodepoints(FC_Font* font);
|
||||
|
||||
/*! Copies the stored codepoints into the given array. */
|
||||
void FC_GetCodepoints(FC_Font* font, Uint32* result);
|
||||
|
||||
/*! Stores the glyph data for the given codepoint in 'result'. Returns 0 if the codepoint was not found in the cache. */
|
||||
Uint8 FC_GetGlyphData(FC_Font* font, FC_GlyphData* result, Uint32 codepoint);
|
||||
|
||||
/*! Sets the glyph data for the given codepoint. Duplicates are not checked. Returns a pointer to the stored data. */
|
||||
FC_GlyphData* FC_SetGlyphData(FC_Font* font, Uint32 codepoint, FC_GlyphData glyph_data);
|
||||
|
||||
// Rendering
|
||||
FC_Rect FC_Draw(FC_Font* font, FC_Target* dest, float x, float y, const char* formatted_text, ...);
|
||||
FC_Rect FC_DrawAlign(FC_Font* font, FC_Target* dest, float x, float y, FC_AlignEnum align, const char* formatted_text, ...);
|
||||
FC_Rect FC_DrawScale(FC_Font* font, FC_Target* dest, float x, float y, FC_Scale scale, const char* formatted_text, ...);
|
||||
FC_Rect FC_DrawColor(FC_Font* font, FC_Target* dest, float x, float y, SDL_Color color, const char* formatted_text, ...);
|
||||
FC_Rect FC_DrawEffect(FC_Font* font, FC_Target* dest, float x, float y, FC_Effect effect, const char* formatted_text, ...);
|
||||
|
||||
FC_Rect FC_DrawBox(FC_Font* font, FC_Target* dest, FC_Rect box, const char* formatted_text, ...);
|
||||
FC_Rect FC_DrawBoxAlign(FC_Font* font, FC_Target* dest, FC_Rect box, FC_AlignEnum align, const char* formatted_text, ...);
|
||||
FC_Rect FC_DrawBoxScale(FC_Font* font, FC_Target* dest, FC_Rect box, FC_Scale scale, const char* formatted_text, ...);
|
||||
FC_Rect FC_DrawBoxColor(FC_Font* font, FC_Target* dest, FC_Rect box, SDL_Color color, const char* formatted_text, ...);
|
||||
FC_Rect FC_DrawBoxEffect(FC_Font* font, FC_Target* dest, FC_Rect box, FC_Effect effect, const char* formatted_text, ...);
|
||||
|
||||
FC_Rect FC_DrawColumn(FC_Font* font, FC_Target* dest, float x, float y, Uint16 width, const char* formatted_text, ...);
|
||||
FC_Rect FC_DrawColumnToTexture(FC_Font* font, SDL_Texture* target, float x, float y, Uint16 width, const char* text);
|
||||
FC_Rect FC_DrawColumnAlign(FC_Font* font, FC_Target* dest, float x, float y, Uint16 width, FC_AlignEnum align, const char* formatted_text, ...);
|
||||
FC_Rect FC_DrawColumnScale(FC_Font* font, FC_Target* dest, float x, float y, Uint16 width, FC_Scale scale, const char* formatted_text, ...);
|
||||
FC_Rect FC_DrawColumnColor(FC_Font* font, FC_Target* dest, float x, float y, Uint16 width, SDL_Color color, const char* formatted_text, ...);
|
||||
FC_Rect FC_DrawColumnEffect(FC_Font* font, FC_Target* dest, float x, float y, Uint16 width, FC_Effect effect, const char* formatted_text, ...);
|
||||
|
||||
|
||||
// Getters
|
||||
|
||||
FC_FilterEnum FC_GetFilterMode(FC_Font* font);
|
||||
Uint16 FC_GetLineHeight(FC_Font* font);
|
||||
Uint16 FC_GetHeight(FC_Font* font, const char* formatted_text, ...);
|
||||
Uint16 FC_GetWidth(FC_Font* font, const char* formatted_text, ...);
|
||||
|
||||
// Returns a 1-pixel wide box in front of the character in the given position (index)
|
||||
FC_Rect FC_GetCharacterOffset(FC_Font* font, Uint16 position_index, int column_width, const char* formatted_text, ...);
|
||||
Uint16 FC_GetColumnHeight(FC_Font* font, Uint16 width, const char* formatted_text, ...);
|
||||
|
||||
int FC_GetAscent(FC_Font* font, const char* formatted_text, ...);
|
||||
int FC_GetDescent(FC_Font* font, const char* formatted_text, ...);
|
||||
int FC_GetBaseline(FC_Font* font);
|
||||
int FC_GetSpacing(FC_Font* font);
|
||||
int FC_GetLineSpacing(FC_Font* font);
|
||||
Uint16 FC_GetMaxWidth(FC_Font* font);
|
||||
SDL_Color FC_GetDefaultColor(FC_Font* font);
|
||||
|
||||
FC_Rect FC_GetBounds(FC_Font* font, float x, float y, FC_AlignEnum align, FC_Scale scale, const char* formatted_text, ...);
|
||||
|
||||
Uint8 FC_InRect(float x, float y, FC_Rect input_rect);
|
||||
// Given an offset (x,y) from the text draw position (the upper-left corner), returns the character position (UTF-8 index)
|
||||
Uint16 FC_GetPositionFromOffset(FC_Font* font, float x, float y, int column_width, FC_AlignEnum align, const char* formatted_text, ...);
|
||||
|
||||
// Returns the number of characters in the new wrapped text written into `result`.
|
||||
int FC_GetWrappedText(FC_Font* font, char* result, int max_result_size, Uint16 width, const char* formatted_text, ...);
|
||||
|
||||
// Setters
|
||||
|
||||
void FC_SetFilterMode(FC_Font* font, FC_FilterEnum filter);
|
||||
void FC_SetSpacing(FC_Font* font, int LetterSpacing);
|
||||
void FC_SetLineSpacing(FC_Font* font, int LineSpacing);
|
||||
void FC_SetDefaultColor(FC_Font* font, SDL_Color color);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user