mirror of
https://github.com/Maschell/SDL2_Playground.git
synced 2024-11-30 08:34:18 +01:00
Add simple Resource manager, fix isInside for rotated elements, optimize/fix mouse/touch inputs, refactor and optimize a lot of classes
This commit is contained in:
parent
afe7035e07
commit
158d97cf23
@ -8,14 +8,14 @@ add_executable(${PROJECT_NAME}
|
||||
src/gui/GuiElement.h
|
||||
src/gui/GuiFrame.cpp
|
||||
src/gui/GuiFrame.h
|
||||
src/gui/GuiImage.cpp
|
||||
src/gui/GuiImage.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
|
||||
@ -23,12 +23,16 @@ add_executable(${PROJECT_NAME}
|
||||
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/GuiTexture.cpp src/gui/GuiTexture.h
|
||||
src/gui/GuiTextureData.cpp src/gui/GuiTextureData.h
|
||||
src/system/video/SDL_FontCache.h
|
||||
src/system/video/SDL_FontCache.cpp
|
||||
|
||||
|
@ -22,12 +22,17 @@ TARGET := SDL2_Playground
|
||||
BUILD := build
|
||||
SOURCES := src \
|
||||
src/gui \
|
||||
src/fs \
|
||||
src/input \
|
||||
src/menu \
|
||||
src/resources \
|
||||
src/system \
|
||||
src/system/video \
|
||||
src/utils
|
||||
DATA := data
|
||||
DATA := data \
|
||||
data/images \
|
||||
data/sounds \
|
||||
data/fonts
|
||||
INCLUDES := source
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -45,14 +50,12 @@ LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := `$(PREFIX)pkg-config --libs SDL2_mixer SDL2_ttf SDL2_image`
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level
|
||||
# containing include and lib
|
||||
#-------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(WUT_ROOT) $(WUMS_ROOT)
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
@ -68,6 +71,7 @@ export VPATH := $(foreach dir,$(SOURCES),$(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)))
|
||||
@ -138,6 +142,26 @@ $(OFILES_SRC) : $(HFILES_BIN)
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
%.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)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.o: %.s
|
||||
@echo $(notdir $<)
|
||||
|
BIN
data/fonts/FreeSans.ttf
Normal file
BIN
data/fonts/FreeSans.ttf
Normal file
Binary file not shown.
BIN
data/images/button.png
Normal file
BIN
data/images/button.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
data/sounds/bgMusic.ogg
Normal file
BIN
data/sounds/bgMusic.ogg
Normal file
Binary file not shown.
BIN
data/sounds/button_click.mp3
Normal file
BIN
data/sounds/button_click.mp3
Normal file
Binary file not shown.
91
filelist.sh
Normal file
91
filelist.sh
Normal file
@ -0,0 +1,91 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# Automatic resource file list generation
|
||||
# Created by Dimok
|
||||
|
||||
outFile="./src/resources/filelist.h"
|
||||
count_old=$(cat $outFile 2>/dev/null | tr -d '\n\n' | sed 's/[^0-9]*\([0-9]*\).*/\1/')
|
||||
|
||||
count=0
|
||||
if [[ $OSTYPE == darwin* ]];
|
||||
then
|
||||
|
||||
for i in $(gfind ./data/images/ ./data/sounds/ ./data/fonts/ -maxdepth 1 -type f \( ! -printf "%f\n" \) | sort -f)
|
||||
do
|
||||
files[count]=$i
|
||||
count=$((count+1))
|
||||
done
|
||||
|
||||
else
|
||||
|
||||
for i in $(find ./data/images/ ./data/sounds/ ./data/fonts/ -maxdepth 1 -type f \( ! -printf "%f\n" \) | sort -f)
|
||||
do
|
||||
files[count]=$i
|
||||
count=$((count+1))
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
if [ "$count_old" != "$count" ] || [ ! -f $outFile ]
|
||||
then
|
||||
|
||||
echo "Generating filelist.h for $count files." >&2
|
||||
cat <<EOF > $outFile
|
||||
/****************************************************************************
|
||||
* Resource files.
|
||||
* This file is generated automatically.
|
||||
* Includes $count files.
|
||||
*
|
||||
* NOTE:
|
||||
* Any manual modification of this file will be overwriten by the generation.
|
||||
****************************************************************************/
|
||||
#ifndef _FILELIST_H_
|
||||
#define _FILELIST_H_
|
||||
|
||||
|
||||
#include "Resources.h"
|
||||
#ifdef __WIIU__
|
||||
EOF
|
||||
|
||||
for i in ${files[@]}
|
||||
do
|
||||
filename=${i%.*}
|
||||
extension=${i##*.}
|
||||
echo '#include "'$filename'_'$extension'.h"' >> $outFile
|
||||
done
|
||||
|
||||
echo '' >> $outFile
|
||||
|
||||
echo 'static RecourceFile RecourceList[] =' >> $outFile
|
||||
echo '{' >> $outFile
|
||||
|
||||
for i in ${files[@]}
|
||||
do
|
||||
filename=${i%.*}
|
||||
extension=${i##*.}
|
||||
echo -e '\t{"'$i'", '$filename'_'$extension', '$filename'_'$extension'_size, NULL, 0},' >> $outFile
|
||||
done
|
||||
|
||||
echo -e '\t{NULL, NULL, 0, NULL, 0}' >> $outFile
|
||||
echo '};' >> $outFile
|
||||
echo '' >> $outFile
|
||||
echo '#else' >> $outFile
|
||||
|
||||
echo 'static RecourceFile RecourceList[] =' >> $outFile
|
||||
echo '{' >> $outFile
|
||||
|
||||
for i in ${files[@]}
|
||||
do
|
||||
filename=${i%.*}
|
||||
extension=${i##*.}
|
||||
echo -e '\t{"'$i'", NULL, NULL, NULL, 0},' >> $outFile
|
||||
done
|
||||
|
||||
echo -e '\t{NULL, NULL, 0, NULL, 0}' >> $outFile
|
||||
echo '};' >> $outFile
|
||||
echo '' >> $outFile
|
||||
echo '#endif' >> $outFile
|
||||
|
||||
echo '#endif' >> $outFile
|
||||
|
||||
fi
|
173
src/fs/CFile.cpp
Normal file
173
src/fs/CFile.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <strings.h>
|
||||
#include "CFile.hpp"
|
||||
|
||||
CFile::CFile() {
|
||||
iFd = -1;
|
||||
mem_file = NULL;
|
||||
filesize = 0;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
CFile::CFile(const std::string &filepath, eOpenTypes mode) {
|
||||
iFd = -1;
|
||||
this->open(filepath, mode);
|
||||
}
|
||||
|
||||
CFile::CFile(const uint8_t *mem, int32_t size) {
|
||||
iFd = -1;
|
||||
this->open(mem, size);
|
||||
}
|
||||
|
||||
CFile::~CFile() {
|
||||
this->close();
|
||||
}
|
||||
|
||||
int32_t CFile::open(const std::string &filepath, eOpenTypes mode) {
|
||||
this->close();
|
||||
int32_t openMode = 0;
|
||||
|
||||
// This depend on the devoptab implementation.
|
||||
// see https://github.com/devkitPro/wut/blob/master/libraries/wutdevoptab/devoptab_fs_open.c#L21 fpr reference
|
||||
|
||||
switch (mode) {
|
||||
default:
|
||||
case ReadOnly: // file must exist
|
||||
openMode = O_RDONLY;
|
||||
break;
|
||||
case WriteOnly: // file will be created / zerod
|
||||
openMode = O_TRUNC | O_CREAT | O_WRONLY;
|
||||
break;
|
||||
case ReadWrite: // file must exist
|
||||
openMode = O_RDWR;
|
||||
break;
|
||||
case Append: // append to file, file will be created if missing. write only
|
||||
openMode = O_CREAT | O_APPEND | O_WRONLY;
|
||||
break;
|
||||
}
|
||||
|
||||
//! Using fopen works only on the first launch as expected
|
||||
//! on the second launch it causes issues because we don't overwrite
|
||||
//! the .data sections which is needed for a normal application to re-init
|
||||
//! this will be added with launching as RPX
|
||||
iFd = ::open(filepath.c_str(), openMode);
|
||||
if (iFd < 0)
|
||||
return iFd;
|
||||
|
||||
|
||||
filesize = ::lseek(iFd, 0, SEEK_END);
|
||||
::lseek(iFd, 0, SEEK_SET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CFile::open(const uint8_t *mem, int32_t size) {
|
||||
this->close();
|
||||
|
||||
mem_file = mem;
|
||||
filesize = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CFile::close() {
|
||||
if (iFd >= 0)
|
||||
::close(iFd);
|
||||
|
||||
iFd = -1;
|
||||
mem_file = NULL;
|
||||
filesize = 0;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
int32_t CFile::read(uint8_t *ptr, size_t size) {
|
||||
if (iFd >= 0) {
|
||||
int32_t ret = ::read(iFd, ptr, size);
|
||||
if (ret > 0)
|
||||
pos += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t readsize = size;
|
||||
|
||||
if (readsize > (int64_t) (filesize - pos))
|
||||
readsize = filesize - pos;
|
||||
|
||||
if (readsize <= 0)
|
||||
return readsize;
|
||||
|
||||
if (mem_file != NULL) {
|
||||
memcpy(ptr, mem_file + pos, readsize);
|
||||
pos += readsize;
|
||||
return readsize;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t CFile::write(const uint8_t *ptr, size_t size) {
|
||||
if (iFd >= 0) {
|
||||
size_t done = 0;
|
||||
while (done < size) {
|
||||
int32_t ret = ::write(iFd, ptr, size - done);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
ptr += ret;
|
||||
done += ret;
|
||||
pos += ret;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t CFile::seek(long int offset, int32_t origin) {
|
||||
int32_t ret = 0;
|
||||
int64_t newPos = pos;
|
||||
|
||||
if (origin == SEEK_SET) {
|
||||
newPos = offset;
|
||||
} else if (origin == SEEK_CUR) {
|
||||
newPos += offset;
|
||||
} else if (origin == SEEK_END) {
|
||||
newPos = filesize + offset;
|
||||
}
|
||||
|
||||
if (newPos < 0) {
|
||||
pos = 0;
|
||||
} else {
|
||||
pos = newPos;
|
||||
}
|
||||
|
||||
if (iFd >= 0)
|
||||
ret = ::lseek(iFd, pos, SEEK_SET);
|
||||
|
||||
if (mem_file != NULL) {
|
||||
if (pos > filesize) {
|
||||
pos = filesize;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t CFile::fwrite(const char *format, ...) {
|
||||
char tmp[512];
|
||||
tmp[0] = 0;
|
||||
int32_t result = -1;
|
||||
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
if ((vsprintf(tmp, format, va) >= 0)) {
|
||||
result = this->write((uint8_t *) tmp, strlen(tmp));
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
67
src/fs/CFile.hpp
Normal file
67
src/fs/CFile.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
class CFile {
|
||||
public:
|
||||
enum eOpenTypes {
|
||||
ReadOnly,
|
||||
WriteOnly,
|
||||
ReadWrite,
|
||||
Append
|
||||
};
|
||||
|
||||
CFile();
|
||||
|
||||
CFile(const std::string &filepath, eOpenTypes mode);
|
||||
|
||||
CFile(const uint8_t *memory, int32_t memsize);
|
||||
|
||||
virtual ~CFile();
|
||||
|
||||
int32_t open(const std::string &filepath, eOpenTypes mode);
|
||||
|
||||
int32_t open(const uint8_t *memory, int32_t memsize);
|
||||
|
||||
int32_t isOpen() const {
|
||||
if (iFd >= 0)
|
||||
return true;
|
||||
|
||||
if (mem_file)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void close();
|
||||
|
||||
int32_t read(uint8_t *ptr, size_t size);
|
||||
|
||||
int32_t write(const uint8_t *ptr, size_t size);
|
||||
|
||||
int32_t fwrite(const char *format, ...);
|
||||
|
||||
int32_t seek(long int offset, int32_t origin);
|
||||
|
||||
uint64_t tell() {
|
||||
return pos;
|
||||
};
|
||||
|
||||
uint64_t size() {
|
||||
return filesize;
|
||||
};
|
||||
|
||||
void rewind() {
|
||||
this->seek(0, SEEK_SET);
|
||||
};
|
||||
|
||||
protected:
|
||||
int32_t iFd;
|
||||
const uint8_t *mem_file;
|
||||
uint64_t filesize;
|
||||
uint64_t pos;
|
||||
};
|
190
src/fs/FSUtils.cpp
Normal file
190
src/fs/FSUtils.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
#include <malloc.h>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "FSUtils.h"
|
||||
#include "CFile.hpp"
|
||||
|
||||
#ifdef WIN32
|
||||
#include "../utils/dirent.h"
|
||||
#endif
|
||||
|
||||
|
||||
int32_t FSUtils::LoadFileToMem(const char *filepath, uint8_t **inbuffer, uint32_t *size) {
|
||||
//! always initialze input
|
||||
*inbuffer = nullptr;
|
||||
if (size)
|
||||
*size = 0;
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
int32_t iFd = open(filepath, O_RDONLY|O_BINARY);
|
||||
#else
|
||||
int32_t iFd = open(filepath, O_RDONLY);
|
||||
#endif
|
||||
if (iFd < 0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t filesize = lseek(iFd, 0, SEEK_END);
|
||||
lseek(iFd, 0, SEEK_SET);
|
||||
|
||||
uint8_t *buffer = (uint8_t *) malloc(filesize);
|
||||
if (buffer == nullptr) {
|
||||
close(iFd);
|
||||
return -2;
|
||||
}
|
||||
|
||||
uint32_t blocksize = 0x4000;
|
||||
uint32_t done = 0;
|
||||
int32_t readBytes = 0;
|
||||
|
||||
while (done < filesize) {
|
||||
if (done + blocksize > filesize) {
|
||||
blocksize = filesize - done;
|
||||
}
|
||||
readBytes = read(iFd, buffer + done, blocksize);
|
||||
if (readBytes <= 0)
|
||||
break;
|
||||
done += readBytes;
|
||||
}
|
||||
|
||||
close(iFd);
|
||||
|
||||
if (done != filesize) {
|
||||
free(buffer);
|
||||
buffer = nullptr;
|
||||
return -3;
|
||||
}
|
||||
|
||||
*inbuffer = buffer;
|
||||
|
||||
//! sign is optional input
|
||||
if (size) {
|
||||
*size = filesize;
|
||||
}
|
||||
|
||||
return filesize;
|
||||
}
|
||||
|
||||
int32_t FSUtils::CheckFile(const char *filepath) {
|
||||
if (!filepath)
|
||||
return 0;
|
||||
|
||||
struct stat filestat;
|
||||
|
||||
char dirnoslash[strlen(filepath) + 2];
|
||||
snprintf(dirnoslash, sizeof(dirnoslash), "%s", filepath);
|
||||
|
||||
while (dirnoslash[strlen(dirnoslash) - 1] == '/')
|
||||
dirnoslash[strlen(dirnoslash) - 1] = '\0';
|
||||
|
||||
char *notRoot = strrchr(dirnoslash, '/');
|
||||
if (!notRoot) {
|
||||
strcat(dirnoslash, "/");
|
||||
}
|
||||
|
||||
if (stat(dirnoslash, &filestat) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FSUtils::CreateSubfolder(const char *fullpath) {
|
||||
if (!fullpath)
|
||||
return 0;
|
||||
|
||||
int32_t result = 0;
|
||||
|
||||
char dirnoslash[strlen(fullpath) + 1];
|
||||
strcpy(dirnoslash, fullpath);
|
||||
|
||||
int32_t pos = strlen(dirnoslash) - 1;
|
||||
while (dirnoslash[pos] == '/') {
|
||||
dirnoslash[pos] = '\0';
|
||||
pos--;
|
||||
}
|
||||
|
||||
if (CheckFile(dirnoslash)) {
|
||||
return 1;
|
||||
} else {
|
||||
char parentpath[strlen(dirnoslash) + 2];
|
||||
strcpy(parentpath, dirnoslash);
|
||||
char *ptr = strrchr(parentpath, '/');
|
||||
|
||||
if (!ptr) {
|
||||
//!Device root directory (must be with '/')
|
||||
strcat(parentpath, "/");
|
||||
struct stat filestat;
|
||||
if (stat(parentpath, &filestat) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
ptr[0] = '\0';
|
||||
|
||||
result = CreateSubfolder(parentpath);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
return 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (mkdir(dirnoslash) == -1) {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
if (mkdir(dirnoslash, 0777) == -1) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool FSUtils::copyFile(const std::string &in, const std::string &out) {
|
||||
// Using C++ buffers is **really** slow. Copying in 1023 byte chunks.
|
||||
// Let's do it the old way.
|
||||
size_t size;
|
||||
|
||||
int source = open(in.c_str(), O_RDONLY, 0);
|
||||
int dest = open(out.c_str(), 0x602, 0644);
|
||||
if (source < 0) {
|
||||
return false;
|
||||
}
|
||||
if (dest < 0) {
|
||||
close(source);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto bufferSize = 1024 * 1024;
|
||||
char *buf = (char *) malloc(bufferSize);
|
||||
if (buf == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while ((size = read(source, buf, bufferSize)) > 0) {
|
||||
write(dest, buf, size);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
close(source);
|
||||
close(dest);
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t FSUtils::saveBufferToFile(const char *path, void *buffer, uint32_t size) {
|
||||
CFile file(path, CFile::WriteOnly);
|
||||
if (!file.isOpen()) {
|
||||
return -1;
|
||||
}
|
||||
int32_t written = file.write((const uint8_t *) buffer, size);
|
||||
file.close();
|
||||
return written;
|
||||
}
|
||||
|
16
src/fs/FSUtils.h
Normal file
16
src/fs/FSUtils.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class FSUtils {
|
||||
public:
|
||||
static int32_t LoadFileToMem(const char *filepath, uint8_t **inbuffer, uint32_t *size);
|
||||
|
||||
static int32_t CreateSubfolder(const char *fullpath);
|
||||
|
||||
static int32_t CheckFile(const char *filepath);
|
||||
|
||||
static bool copyFile(const std::string &in, const std::string &out);
|
||||
|
||||
static int32_t saveBufferToFile(const char *path, void *buffer, uint32_t size);
|
||||
};
|
@ -25,28 +25,28 @@
|
||||
GuiButton::GuiButton(float w, float h) {
|
||||
width = w;
|
||||
height = h;
|
||||
image = NULL;
|
||||
imageOver = NULL;
|
||||
imageHold = NULL;
|
||||
imageClick = NULL;
|
||||
icon = NULL;
|
||||
iconOver = NULL;
|
||||
image = nullptr;
|
||||
imageOver = nullptr;
|
||||
imageHold = nullptr;
|
||||
imageClick = nullptr;
|
||||
icon = nullptr;
|
||||
iconOver = nullptr;
|
||||
|
||||
for (int32_t i = 0; i < 4; i++) {
|
||||
label[i] = NULL;
|
||||
labelOver[i] = NULL;
|
||||
labelHold[i] = NULL;
|
||||
labelClick[i] = NULL;
|
||||
label[i] = nullptr;
|
||||
labelOver[i] = nullptr;
|
||||
labelHold[i] = nullptr;
|
||||
labelClick[i] = nullptr;
|
||||
}
|
||||
for (int32_t i = 0; i < iMaxGuiTriggers; i++) {
|
||||
trigger[i] = NULL;
|
||||
for (auto &i : trigger) {
|
||||
i = nullptr;
|
||||
}
|
||||
|
||||
soundOver = NULL;
|
||||
soundHold = NULL;
|
||||
soundClick = NULL;
|
||||
clickedTrigger = NULL;
|
||||
heldTrigger = NULL;
|
||||
soundOver = nullptr;
|
||||
soundHold = nullptr;
|
||||
soundClick = nullptr;
|
||||
clickedTrigger = nullptr;
|
||||
heldTrigger = nullptr;
|
||||
selectable = true;
|
||||
holdable = false;
|
||||
clickable = true;
|
||||
@ -55,8 +55,7 @@ GuiButton::GuiButton(float w, float h) {
|
||||
/**
|
||||
* Destructor for the GuiButton class.
|
||||
*/
|
||||
GuiButton::~GuiButton() {
|
||||
}
|
||||
GuiButton::~GuiButton() = default;
|
||||
|
||||
void GuiButton::setImage(GuiImage *img) {
|
||||
image = img;
|
||||
@ -124,9 +123,9 @@ void GuiButton::setTrigger(GuiTrigger *t, int32_t idx) {
|
||||
if (idx >= 0 && idx < iMaxGuiTriggers) {
|
||||
trigger[idx] = t;
|
||||
} else {
|
||||
for (int32_t i = 0; i < iMaxGuiTriggers; i++) {
|
||||
if (!trigger[i]) {
|
||||
trigger[i] = t;
|
||||
for (auto &i : trigger) {
|
||||
if (!i) {
|
||||
i = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -134,8 +133,8 @@ void GuiButton::setTrigger(GuiTrigger *t, int32_t idx) {
|
||||
}
|
||||
|
||||
void GuiButton::resetState() {
|
||||
clickedTrigger = NULL;
|
||||
heldTrigger = NULL;
|
||||
clickedTrigger = nullptr;
|
||||
heldTrigger = nullptr;
|
||||
GuiElement::resetState();
|
||||
}
|
||||
|
||||
@ -213,21 +212,21 @@ void GuiButton::update(GuiController *c) {
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < iMaxGuiTriggers; i++) {
|
||||
if (!trigger[i]) {
|
||||
for (auto & i : trigger) {
|
||||
if (!i) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// button triggers
|
||||
if (clickable) {
|
||||
int32_t isClicked = trigger[i]->clicked(c);
|
||||
int32_t isClicked = i->clicked(c);
|
||||
if (!clickedTrigger && (isClicked != GuiTrigger::CLICKED_NONE)
|
||||
&& (trigger[i]->isClickEverywhere() || (isStateSet(STATE_SELECTED | STATE_OVER, c->chanIdx) && trigger[i]->isSelectionClickEverywhere()) || this->isInside(c->data.x, c->data.y))) {
|
||||
&& (i->isClickEverywhere() || (isStateSet(STATE_SELECTED | STATE_OVER, c->chanIdx) && i->isSelectionClickEverywhere()) || this->isInside(c->data.x, c->data.y))) {
|
||||
if (soundClick) {
|
||||
soundClick->Play();
|
||||
}
|
||||
|
||||
clickedTrigger = trigger[i];
|
||||
clickedTrigger = i;
|
||||
|
||||
if (!isStateSet(STATE_CLICKED, c->chanIdx)) {
|
||||
if (isClicked == GuiTrigger::CLICKED_TOUCH) {
|
||||
@ -237,38 +236,38 @@ void GuiButton::update(GuiController *c) {
|
||||
}
|
||||
}
|
||||
|
||||
clicked(this, c, trigger[i]);
|
||||
} else if ((isStateSet(STATE_CLICKED, c->chanIdx) || isStateSet(STATE_CLICKED_TOUCH, c->chanIdx)) && (clickedTrigger == trigger[i]) && !isStateSet(STATE_HELD, c->chanIdx) && !trigger[i]->held(c) &&
|
||||
((isClicked == GuiTrigger::CLICKED_NONE) || trigger[i]->released(c))) {
|
||||
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, trigger[i]);
|
||||
released(this, c, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (holdable) {
|
||||
bool isHeld = trigger[i]->held(c);
|
||||
bool isHeld = i->held(c);
|
||||
|
||||
if ((!heldTrigger || heldTrigger == trigger[i]) && isHeld
|
||||
&& (trigger[i]->isHoldEverywhere() || (isStateSet(STATE_SELECTED | STATE_OVER, c->chanIdx) && trigger[i]->isSelectionClickEverywhere()) || this->isInside(c->data.x, c->data.y))) {
|
||||
heldTrigger = trigger[i];
|
||||
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, trigger[i]);
|
||||
} else if (isStateSet(STATE_HELD, c->chanIdx) && (heldTrigger == trigger[i]) && (!isHeld || trigger[i]->released(c))) {
|
||||
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 == trigger[i]) {
|
||||
if (clickedTrigger == i) {
|
||||
clickedTrigger = nullptr;
|
||||
clearState(STATE_CLICKED, c->chanIdx);
|
||||
}
|
||||
heldTrigger = nullptr;
|
||||
clearState(STATE_HELD, c->chanIdx);
|
||||
released(this, c, trigger[i]);
|
||||
released(this, c, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
int32_t y;
|
||||
} PadData;
|
||||
|
||||
int32_t chan;
|
||||
uint32_t chan;
|
||||
int32_t chanIdx;
|
||||
PadData data;
|
||||
PadData lastData;
|
||||
|
@ -33,11 +33,11 @@ GuiElement::GuiElement() {
|
||||
scaleX = 1.0f;
|
||||
scaleY = 1.0f;
|
||||
scaleZ = 1.0f;
|
||||
for (int32_t i = 0; i < 5; i++) {
|
||||
state[i] = STATE_DEFAULT;
|
||||
for (unsigned int & i : state) {
|
||||
i = STATE_DEFAULT;
|
||||
}
|
||||
stateChan = -1;
|
||||
parentElement = NULL;
|
||||
parentElement = nullptr;
|
||||
rumble = true;
|
||||
selectable = false;
|
||||
clickable = false;
|
||||
@ -120,7 +120,7 @@ float GuiElement::getTop() {
|
||||
return y + yoffset;
|
||||
}
|
||||
|
||||
void GuiElement::setEffect(int32_t eff, int32_t amount, int32_t target) {
|
||||
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) {
|
||||
@ -163,7 +163,7 @@ void GuiElement::setEffect(int32_t eff, int32_t amount, int32_t target) {
|
||||
//!\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(int32_t e, int32_t a, int32_t t) {
|
||||
void GuiElement::setEffectOnOver(uint32_t e, int32_t a, int32_t t) {
|
||||
effectsOver |= e;
|
||||
effectAmountOver = a;
|
||||
effectTargetOver = t;
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
GuiElement();
|
||||
|
||||
//!Destructor
|
||||
virtual ~GuiElement() {}
|
||||
virtual ~GuiElement() = default;
|
||||
|
||||
//!Set the element's parent
|
||||
//!\param e Pointer to parent element
|
||||
@ -105,7 +105,7 @@ public:
|
||||
return zParent + zoffset;
|
||||
}
|
||||
|
||||
virtual float getCenterX(void) {
|
||||
virtual float getCenterX() {
|
||||
float pCenterX = 0.0f;
|
||||
|
||||
if (parentElement) {
|
||||
@ -138,7 +138,7 @@ public:
|
||||
return pCenterX;
|
||||
}
|
||||
|
||||
virtual float getCenterY(void) {
|
||||
virtual float getCenterY() {
|
||||
float pCenterY = 0.0f;
|
||||
|
||||
if (parentElement) {
|
||||
@ -261,7 +261,7 @@ public:
|
||||
//!Sets the element's state
|
||||
//!\param s State (STATE_DEFAULT, STATE_SELECTED, STATE_CLICKED, STATE_DISABLED)
|
||||
//!\param c Controller channel (0-3, -1 = none)
|
||||
virtual void setState(int32_t s, int32_t c = -1) {
|
||||
virtual void setState(uint32_t s, int32_t c) {
|
||||
if (c >= 0 && c < 5) {
|
||||
state[c] |= s;
|
||||
} else {
|
||||
@ -273,24 +273,24 @@ public:
|
||||
stateChanged(this, s, c);
|
||||
}
|
||||
|
||||
virtual void clearState(int32_t s, int32_t c = -1) {
|
||||
virtual void clearState(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;
|
||||
for (unsigned int & i : state) {
|
||||
i &= ~s;
|
||||
}
|
||||
}
|
||||
stateChan = c;
|
||||
stateChanged(this, s, c);
|
||||
}
|
||||
|
||||
virtual bool isStateSet(int32_t s, int32_t c = -1) const {
|
||||
virtual bool isStateSet(uint32_t s, int32_t c = -1) const {
|
||||
if (c >= 0 && c < 5) {
|
||||
return (state[c] & s) != 0;
|
||||
} else {
|
||||
for (int32_t i = 0; i < 5; i++) {
|
||||
if ((state[i] & s) != 0) {
|
||||
for (unsigned int i : state) {
|
||||
if ((i & s) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -301,7 +301,7 @@ public:
|
||||
|
||||
//!Gets the element's current state
|
||||
//!\return state
|
||||
virtual int32_t getState(int32_t c = 0) {
|
||||
virtual int32_t getState(int32_t c) {
|
||||
return state[c];
|
||||
};
|
||||
|
||||
@ -313,8 +313,8 @@ public:
|
||||
|
||||
//!Resets the element's state to STATE_DEFAULT
|
||||
virtual void resetState() {
|
||||
for (int32_t i = 0; i < 5; i++) {
|
||||
state[i] = STATE_DEFAULT;
|
||||
for (unsigned int & i : state) {
|
||||
i = STATE_DEFAULT;
|
||||
}
|
||||
stateChan = -1;
|
||||
}
|
||||
@ -434,13 +434,13 @@ public:
|
||||
//!\param e Effect to enable
|
||||
//!\param a Amount of the effect (usage varies on effect)
|
||||
//!\param t Target amount of the effect (usage varies on effect)
|
||||
virtual void setEffect(int32_t e, int32_t a, int32_t t = 0);
|
||||
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(int32_t e, int32_t a, int32_t t = 0);
|
||||
virtual void setEffectOnOver(uint32_t e, int32_t a, int32_t t);
|
||||
|
||||
//!Shortcut to SetEffectOnOver(EFFECT_SCALE, 4, 110)
|
||||
virtual void setEffectGrow() {
|
||||
@ -466,10 +466,30 @@ public:
|
||||
//!\param y Y coordinate
|
||||
//!\return true if contained within, false otherwise
|
||||
virtual bool isInside(float x, float y) {
|
||||
return (x > (this->getCenterX() - getScaleX() * getWidth() * 0.5f)
|
||||
&& x < (this->getCenterX() + getScaleX() * getWidth() * 0.5f)
|
||||
&& y > (this->getCenterY() - getScaleY() * getHeight() * 0.5f)
|
||||
&& y < (this->getCenterY() + getScaleY() * getHeight() * 0.5f));
|
||||
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
|
||||
@ -586,8 +606,8 @@ protected:
|
||||
float scaleX; //!< Element scale (1 = 100%)
|
||||
float scaleY; //!< Element scale (1 = 100%)
|
||||
float scaleZ; //!< Element scale (1 = 100%)
|
||||
int32_t alignment; //!< Horizontal element alignment, respective to parent element
|
||||
int32_t state[5]; //!< Element state (DEFAULT, SELECTED, CLICKED, DISABLED)
|
||||
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
|
||||
|
||||
@ -596,10 +616,10 @@ protected:
|
||||
int32_t yoffsetDyn; //!< Element Y offset, dynamic (added to yoffset value for animation effects)
|
||||
float alphaDyn; //!< Element alpha, dynamic (multiplied by alpha value for blending/fading effects)
|
||||
float scaleDyn; //!< Element scale, dynamic (multiplied by alpha value for blending/fading effects)
|
||||
int32_t effects; //!< Currently enabled effect(s). 0 when no effects are enabled
|
||||
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
|
||||
int32_t effectsOver; //!< Effects to enable when wiimote cursor is over this element. Copied to effects variable on over event
|
||||
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
|
||||
};
|
||||
|
@ -16,6 +16,7 @@
|
||||
****************************************************************************/
|
||||
#include "GuiFrame.h"
|
||||
#include "../system/video/Renderer.h"
|
||||
#include "../utils/logger.h"
|
||||
|
||||
GuiFrame::GuiFrame(GuiFrame *p) {
|
||||
parent = p;
|
||||
@ -48,9 +49,10 @@ GuiFrame::~GuiFrame() {
|
||||
}
|
||||
|
||||
void GuiFrame::append(GuiElement *e) {
|
||||
if (e == NULL) {
|
||||
if (e == nullptr) {
|
||||
return;
|
||||
}
|
||||
DEBUG_FUNCTION_LINE("append %08X", e);
|
||||
|
||||
remove(e);
|
||||
mutex.lock();
|
||||
@ -60,7 +62,7 @@ void GuiFrame::append(GuiElement *e) {
|
||||
}
|
||||
|
||||
void GuiFrame::insert(GuiElement *e, uint32_t index) {
|
||||
if (e == NULL || (index >= elements.size())) {
|
||||
if (e == nullptr || (index >= elements.size())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -94,7 +96,7 @@ void GuiFrame::removeAll() {
|
||||
|
||||
GuiElement *GuiFrame::getGuiElementAt(uint32_t index) const {
|
||||
if (index >= elements.size()) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return elements[index];
|
||||
@ -108,13 +110,13 @@ void GuiFrame::resetState() {
|
||||
GuiElement::resetState();
|
||||
|
||||
mutex.lock();
|
||||
for (uint32_t i = 0; i < elements.size(); ++i) {
|
||||
elements[i]->resetState();
|
||||
for (auto & element : elements) {
|
||||
element->resetState();
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void GuiFrame::setState(int32_t s, int32_t c) {
|
||||
void GuiFrame::setState(uint32_t s, int32_t c) {
|
||||
GuiElement::setState(s, c);
|
||||
mutex.lock();
|
||||
for (uint32_t i = 0; i < elements.size(); ++i) {
|
||||
@ -123,7 +125,7 @@ void GuiFrame::setState(int32_t s, int32_t c) {
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void GuiFrame::clearState(int32_t s, int32_t c) {
|
||||
void GuiFrame::clearState(uint32_t s, int32_t c) {
|
||||
GuiElement::clearState(s, c);
|
||||
|
||||
mutex.lock();
|
||||
@ -137,8 +139,8 @@ void GuiFrame::setVisible(bool v) {
|
||||
visible = v;
|
||||
|
||||
mutex.lock();
|
||||
for (uint32_t i = 0; i < elements.size(); ++i) {
|
||||
elements[i]->setVisible(v);
|
||||
for (auto & element : elements) {
|
||||
element->setVisible(v);
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
@ -76,9 +76,9 @@ public:
|
||||
|
||||
//!Sets the window's state
|
||||
//!\param s State
|
||||
void setState(int32_t s, int32_t c = -1) override;
|
||||
void setState(uint32_t s, int32_t c = -1) override;
|
||||
|
||||
void clearState(int32_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
|
||||
|
@ -15,11 +15,40 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <iostream>
|
||||
#include "GuiImage.h"
|
||||
#include "../system/SDLSystem.h"
|
||||
#include "../utils/logger.h"
|
||||
|
||||
GuiImage::GuiImage(const std::string& path) : GuiTexture(path){
|
||||
GuiImage::GuiImage(GuiTextureData *texture) {
|
||||
setTexture(texture);
|
||||
}
|
||||
|
||||
GuiImage::~GuiImage() = default;
|
||||
GuiImage::~GuiImage() {
|
||||
if(this->texture && freeTextureData){
|
||||
delete this->texture;
|
||||
}
|
||||
}
|
||||
|
||||
void GuiImage::draw(Renderer *renderer) {
|
||||
if (!this->isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
SDL_Rect rect;
|
||||
rect.x = (int) getLeft();
|
||||
rect.y = (int) getTop();
|
||||
rect.w = (int) (getScaleX() * getWidth());
|
||||
rect.h = (int) (getScaleY() * getHeight());
|
||||
texture->draw(renderer, rect, getAngle());
|
||||
}
|
||||
}
|
||||
|
||||
void GuiImage::setTexture(GuiTextureData *tex) {
|
||||
if (tex) {
|
||||
if(this->texture && freeTextureData){
|
||||
delete this->texture;
|
||||
}
|
||||
this->texture = tex;
|
||||
this->setSize(tex->getWidth(), tex->getHeight());
|
||||
}
|
||||
}
|
||||
|
@ -18,15 +18,24 @@
|
||||
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include "GuiElement.h"
|
||||
#include "GuiTexture.h"
|
||||
#include "GuiTextureData.h"
|
||||
|
||||
//!Display, manage, and manipulate images in the GUI
|
||||
class GuiImage : public GuiTexture {
|
||||
class GuiImage : public GuiElement {
|
||||
public:
|
||||
//!\overload
|
||||
//!\param img Pointer to GuiImageData element
|
||||
explicit GuiImage(const std::string &path);
|
||||
GuiImage() = default;
|
||||
|
||||
explicit GuiImage(GuiTextureData *texture);
|
||||
|
||||
//!Destructor
|
||||
~GuiImage() override;
|
||||
|
||||
void draw(Renderer *r) override;
|
||||
|
||||
void setTexture(GuiTextureData *tex);
|
||||
private:
|
||||
GuiTextureData *texture = nullptr;
|
||||
bool freeTextureData = false;
|
||||
};
|
||||
|
@ -15,64 +15,65 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "GuiSound.h"
|
||||
#include "../utils/logger.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){
|
||||
if (music) {
|
||||
Mix_FreeChunk(music);
|
||||
music = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool GuiSound::Load(const char *filepath) {
|
||||
music = Mix_LoadWAV(filepath);
|
||||
DEBUG_FUNCTION_LINE("load %s %d", filepath, music);
|
||||
return music != nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GuiSound::Play() {
|
||||
playedOn = Mix_PlayChannel(-1,music, loops);
|
||||
if (music) {
|
||||
playedOn = Mix_PlayChannel(-1, music, loops);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiSound::Stop() {
|
||||
void GuiSound::Stop() const {
|
||||
Pause();
|
||||
}
|
||||
|
||||
void GuiSound::Pause() {
|
||||
Mix_HaltChannel(playedOn);
|
||||
void GuiSound::Pause() const {
|
||||
if (playedOn != -1) {
|
||||
Mix_HaltChannel(playedOn);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiSound::Resume() {
|
||||
Play();
|
||||
}
|
||||
|
||||
bool GuiSound::IsPlaying() {
|
||||
if(playedOn == -1){
|
||||
bool GuiSound::IsPlaying() const {
|
||||
if (playedOn == -1) {
|
||||
return false;
|
||||
}
|
||||
return Mix_Playing(playedOn);
|
||||
}
|
||||
|
||||
void GuiSound::SetVolume(uint32_t vol) {
|
||||
if(music != nullptr){
|
||||
Mix_VolumeChunk(music, vol);
|
||||
}
|
||||
void GuiSound::SetVolume(uint32_t vol) const {
|
||||
if (music) { Mix_VolumeChunk(music, vol); }
|
||||
}
|
||||
|
||||
void GuiSound::SetLoop(bool l) {
|
||||
if(l){
|
||||
loops = -1;
|
||||
}else{
|
||||
loops = 1;
|
||||
}
|
||||
// < 0 == infinitive loop
|
||||
loops = l ? -1 : 1;
|
||||
}
|
||||
|
||||
void GuiSound::Rewind() {
|
||||
void GuiSound::Rewind() const {
|
||||
// TODO: how to rewind?
|
||||
Stop();
|
||||
}
|
||||
|
@ -22,10 +22,12 @@
|
||||
//!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
|
||||
explicit GuiSound(const char *filepath);
|
||||
GuiSound(void *buffer, uint32_t filesize, bool freeSrc = false);
|
||||
|
||||
//!Destructor
|
||||
~GuiSound() override;
|
||||
@ -37,29 +39,29 @@ public:
|
||||
void Play();
|
||||
|
||||
//!Stop sound playback
|
||||
void Stop();
|
||||
void Stop() const;
|
||||
|
||||
//!Pause sound playback
|
||||
void Pause();
|
||||
void Pause() const;
|
||||
|
||||
//!Resume sound playback
|
||||
void Resume();
|
||||
|
||||
//!Checks if the sound is currently playing
|
||||
//!\return true if sound is playing, false otherwise
|
||||
bool IsPlaying();
|
||||
[[nodiscard]] bool IsPlaying() const;
|
||||
|
||||
//!Rewind the music
|
||||
void Rewind();
|
||||
void Rewind() const;
|
||||
|
||||
//!Set sound volume
|
||||
//!\param v Sound volume (0-100)
|
||||
void SetVolume(uint32_t v);
|
||||
void SetVolume(uint32_t v) const;
|
||||
|
||||
//!\param l Loop (true to loop)
|
||||
void SetLoop(bool l);
|
||||
|
||||
Mix_Chunk *music;
|
||||
Mix_Chunk *music = nullptr;
|
||||
int32_t loops = 0;
|
||||
int32_t playedOn = -1;
|
||||
};
|
@ -26,16 +26,12 @@ GuiText::GuiText(const std::string& text, SDL_Color c, FC_Font* gFont) {
|
||||
this->text = text;
|
||||
this->color = c;
|
||||
this->fc_font = gFont;
|
||||
updateSize();
|
||||
this->doUpdateTexture = true;
|
||||
this->texture.setParent(this);
|
||||
}
|
||||
|
||||
GuiText::~GuiText(){
|
||||
if(fc_font){
|
||||
FC_FreeFont(fc_font);
|
||||
fc_font = nullptr;
|
||||
}
|
||||
delete texture;
|
||||
GuiText::~GuiText() {
|
||||
delete textureData;
|
||||
}
|
||||
|
||||
void GuiText::draw(Renderer *renderer) {
|
||||
@ -45,9 +41,7 @@ void GuiText::draw(Renderer *renderer) {
|
||||
|
||||
updateTexture(renderer);
|
||||
|
||||
if(texture){
|
||||
texture->draw(renderer);
|
||||
}
|
||||
texture.draw(renderer);
|
||||
}
|
||||
|
||||
void GuiText::process() {
|
||||
@ -57,7 +51,7 @@ void GuiText::process() {
|
||||
void GuiText::setMaxWidth(float width) {
|
||||
this->maxWidth = width;
|
||||
|
||||
// Rebuild the texture cache.
|
||||
// Rebuild the texture cache on next draw
|
||||
doUpdateTexture = true;
|
||||
}
|
||||
|
||||
@ -69,20 +63,23 @@ void GuiText::updateSize() {
|
||||
}
|
||||
|
||||
void GuiText::updateTexture(Renderer *renderer) {
|
||||
if(!texture || doUpdateTexture) {
|
||||
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, (int) width, (int) height);
|
||||
SDL_Texture *temp = SDL_CreateTexture(renderer->getRenderer(), renderer->getPixelFormat(), SDL_TEXTUREACCESS_TARGET, tex_width, tex_height);
|
||||
if (temp) {
|
||||
delete texture;
|
||||
texture = new GuiTexture(temp);
|
||||
texture->setParent(this);
|
||||
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
texture.setTexture(nullptr);
|
||||
delete textureData;
|
||||
textureData = new GuiTextureData(temp);
|
||||
textureData->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
texture.setTexture(textureData);
|
||||
|
||||
FC_DrawColumnToTexture(fc_font, temp, 0, 0, maxWidth, text.c_str());
|
||||
doUpdateTexture = false;
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("Failed to create texture");
|
||||
}
|
||||
doUpdateTexture = false;
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "GuiElement.h"
|
||||
#include "GuiTexture.h"
|
||||
#include "GuiTextureData.h"
|
||||
#include "../system/video/SDL_FontCache.h"
|
||||
#include "GuiImage.h"
|
||||
#include <mutex>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
@ -39,7 +40,9 @@ public:
|
||||
void setMaxWidth(float width);
|
||||
|
||||
protected:
|
||||
GuiTexture* texture = nullptr;
|
||||
GuiImage texture;
|
||||
GuiTextureData* textureData = nullptr;
|
||||
|
||||
std::string text;
|
||||
SDL_Color color;
|
||||
FC_Font *fc_font = nullptr;
|
||||
|
@ -1,93 +0,0 @@
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include "GuiTexture.h"
|
||||
#include "../system/SDLSystem.h"
|
||||
#include "../utils/logger.h"
|
||||
|
||||
GuiTexture::GuiTexture(const std::string& path) {
|
||||
imgSurface = IMG_Load( path.c_str() );
|
||||
|
||||
if(!imgSurface){
|
||||
return;
|
||||
}
|
||||
this->width = imgSurface->w;
|
||||
this->height = imgSurface->h;
|
||||
}
|
||||
|
||||
GuiTexture::GuiTexture(SDL_Texture *texture) {
|
||||
if (this->texture) {
|
||||
SDL_DestroyTexture(this->texture);
|
||||
this->texture = NULL;
|
||||
}
|
||||
this->texture = texture;
|
||||
int w, h;
|
||||
SDL_QueryTexture(texture, nullptr, nullptr, &w, &h);
|
||||
this->setSize(w, h);
|
||||
|
||||
}
|
||||
|
||||
GuiTexture::GuiTexture(SDL_Surface *pSurface) {
|
||||
if(!pSurface){
|
||||
return;
|
||||
}
|
||||
imgSurface = pSurface;
|
||||
|
||||
this->width = imgSurface->w;
|
||||
this->height = imgSurface->h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor for the GuiImage class.
|
||||
*/
|
||||
GuiTexture::~GuiTexture() {
|
||||
if (this->imgSurface) {
|
||||
SDL_FreeSurface(this->imgSurface);
|
||||
this->imgSurface = nullptr;
|
||||
}
|
||||
if (this->texture) {
|
||||
SDL_DestroyTexture(this->texture);
|
||||
this->texture = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GuiTexture::draw(Renderer *renderer) {
|
||||
if (!this->isVisible()) {
|
||||
DEBUG_FUNCTION_LINE("not visible!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (texture == NULL && imgSurface) {
|
||||
SDL_Surface *optimizedSurface = SDL_ConvertSurfaceFormat(imgSurface, renderer->getPixelFormat(), 0);
|
||||
if (optimizedSurface != NULL) {
|
||||
SDL_FreeSurface(imgSurface);
|
||||
imgSurface = optimizedSurface;
|
||||
DEBUG_FUNCTION_LINE("Optimized surface");
|
||||
}
|
||||
texture = SDL_CreateTextureFromSurface(renderer->getRenderer(), imgSurface);
|
||||
}
|
||||
if (!texture) {
|
||||
DEBUG_FUNCTION_LINE("no texture!");
|
||||
return;
|
||||
}
|
||||
|
||||
float currScaleX = getScaleX();
|
||||
float currScaleY = getScaleY();
|
||||
|
||||
SDL_Rect rect;
|
||||
rect.x = getLeft();
|
||||
rect.y = getTop();
|
||||
rect.w = currScaleX * getWidth();
|
||||
rect.h = currScaleY * getHeight();
|
||||
|
||||
if (getAngle() == 0) {
|
||||
SDL_RenderCopy(renderer->getRenderer(), texture, nullptr, &rect);
|
||||
} else {
|
||||
SDL_RenderCopyEx(renderer->getRenderer(), texture, nullptr, &rect, getAngle(), nullptr, SDL_FLIP_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
int GuiTexture::setBlendMode(SDL_BlendMode) {
|
||||
if(texture){
|
||||
return SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
return SDL_BLENDMODE_INVALID;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include "GuiElement.h"
|
||||
|
||||
class GuiTexture : public GuiElement {
|
||||
public:
|
||||
explicit GuiTexture(const std::string &path);
|
||||
explicit GuiTexture(SDL_Texture * texture);
|
||||
explicit GuiTexture(SDL_Surface *pSurface);
|
||||
|
||||
//!Destructor
|
||||
~GuiTexture() override;
|
||||
|
||||
//!Constantly called to draw the image
|
||||
void draw(Renderer *pVideo) override;
|
||||
|
||||
int setBlendMode(SDL_BlendMode blendMode);
|
||||
|
||||
protected:
|
||||
SDL_Surface *imgSurface = nullptr;
|
||||
SDL_Texture *texture = nullptr;
|
||||
};
|
87
src/gui/GuiTextureData.cpp
Normal file
87
src/gui/GuiTextureData.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#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) {
|
||||
SDL_Surface *optimizedSurface = SDL_ConvertSurfaceFormat(imgSurface, renderer->getPixelFormat(), 0);
|
||||
if (optimizedSurface != nullptr) {
|
||||
SDL_FreeSurface(imgSurface);
|
||||
imgSurface = optimizedSurface;
|
||||
}
|
||||
texture = SDL_CreateTextureFromSurface(renderer->getRenderer(), imgSurface);
|
||||
}
|
||||
if (!texture) {
|
||||
DEBUG_FUNCTION_LINE("no texture!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (angle == 0) {
|
||||
SDL_RenderCopy(renderer->getRenderer(), texture, nullptr, &dest);
|
||||
} else {
|
||||
SDL_RenderCopyEx(renderer->getRenderer(), texture, nullptr, &dest, angle, nullptr, SDL_FLIP_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
int GuiTextureData::setBlendMode(SDL_BlendMode) {
|
||||
if(texture){ return SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); }
|
||||
return SDL_BLENDMODE_INVALID;
|
||||
}
|
40
src/gui/GuiTextureData.h
Normal file
40
src/gui/GuiTextureData.h
Normal file
@ -0,0 +1,40 @@
|
||||
#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;
|
||||
};
|
@ -14,10 +14,7 @@
|
||||
* 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 "GuiElement.h"
|
||||
#include "GuiController.h"
|
||||
#include "GuiTrigger.h"
|
||||
|
||||
/**
|
||||
* Constructor for the GuiTrigger class.
|
||||
@ -33,8 +30,7 @@ GuiTrigger::GuiTrigger(uint32_t ch, uint32_t btn, bool clickEverywhere, bool hol
|
||||
/**
|
||||
* Destructor for the GuiTrigger class.
|
||||
*/
|
||||
GuiTrigger::~GuiTrigger() {
|
||||
}
|
||||
GuiTrigger::~GuiTrigger() = default;
|
||||
|
||||
/**
|
||||
* Sets a simple trigger. Requires:
|
||||
@ -93,6 +89,7 @@ int32_t GuiTrigger::clicked(const GuiController *controller) const {
|
||||
|
||||
int32_t bResult = CLICKED_NONE;
|
||||
|
||||
|
||||
if (controller->data.touched && controller->data.validPointer && (btns & TOUCHED) && !controller->lastData.touched) {
|
||||
bResult = CLICKED_TOUCH;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
class GuiController;
|
||||
|
||||
//!Menu input trigger management. Determine if action is neccessary based on input data by comparing controller input data to a specific trigger element.
|
||||
//!Menu input trigger management. Determine if action is necessary based on input data by comparing controller input data to a specific trigger element.
|
||||
class GuiTrigger {
|
||||
public:
|
||||
enum eClicked {
|
||||
@ -96,15 +96,15 @@ public:
|
||||
bSelectionClickEverywhere = b;
|
||||
}
|
||||
|
||||
bool isClickEverywhere() const {
|
||||
[[nodiscard]] bool isClickEverywhere() const {
|
||||
return bClickEverywhere;
|
||||
}
|
||||
|
||||
bool isHoldEverywhere() const {
|
||||
[[nodiscard]] bool isHoldEverywhere() const {
|
||||
return bHoldEverywhere;
|
||||
}
|
||||
|
||||
bool isSelectionClickEverywhere() const {
|
||||
[[nodiscard]] bool isSelectionClickEverywhere() const {
|
||||
return bSelectionClickEverywhere;
|
||||
}
|
||||
|
||||
|
@ -7,15 +7,19 @@ public:
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
data.validPointer = true;
|
||||
} else if (e->type == SDL_MOUSEBUTTONDOWN && e->button.button == SDL_BUTTON_LEFT) {
|
||||
data.buttons_h |= GuiTrigger::TOUCHED;
|
||||
data.touched = true;
|
||||
} else if (e->type == SDL_MOUSEBUTTONUP && e->button.button == SDL_BUTTON_LEFT) {
|
||||
data.buttons_h &= ~GuiTrigger::TOUCHED;
|
||||
data.touched = false;
|
||||
}else{
|
||||
DEBUG_FUNCTION_LINE("Unknown event");
|
||||
return false;
|
||||
|
@ -26,16 +26,14 @@ public:
|
||||
}
|
||||
|
||||
bool update(SDL_Event *e, int32_t screenWidth, int32_t screenHeight) override {
|
||||
if (e->type == SDL_FINGERMOTION) {
|
||||
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;;
|
||||
data.validPointer = true;
|
||||
} else if (e->type == SDL_FINGERUP) {
|
||||
data.validPointer = false;
|
||||
data.buttons_h &= ~GuiTrigger::TOUCHED;
|
||||
} else if (e->type == SDL_FINGERDOWN) {
|
||||
data.validPointer = true;
|
||||
data.buttons_h |= GuiTrigger::TOUCHED;
|
||||
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) {
|
||||
@ -46,5 +44,10 @@ public:
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void after() override {
|
||||
data.validPointer = data.touched;
|
||||
SDLController::after();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,23 +1,16 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include "system/SDLSystem.h"
|
||||
#include "gui/GuiFrame.h"
|
||||
#include "gui/GuiImage.h"
|
||||
#include "gui/GuiButton.h"
|
||||
#include "gui/GuiController.h"
|
||||
#include "menu/MainWindow.h"
|
||||
#include "utils/logger.h"
|
||||
#include "input/SDLController.h"
|
||||
#include "input/SDLControllerMouse.h"
|
||||
#include "input/SDLControllerWiiUGamepad.h"
|
||||
#include "input/SDLControllerXboxOne.h"
|
||||
#include "input/SDLControllerWiiUProContoller.h"
|
||||
#include "input/SDLControllerJoystick.h"
|
||||
#include "input/ControllerManager.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
#if defined _WIN32
|
||||
#include <windows.h>
|
||||
|
@ -1,57 +1,91 @@
|
||||
#include "MainWindow.h"
|
||||
#include "../resources/Resources.h"
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
delete label;;
|
||||
delete touchTrigger;;
|
||||
delete sound;;
|
||||
delete image;;
|
||||
delete image2;;
|
||||
delete image3;;
|
||||
delete image4;;
|
||||
delete image5;;
|
||||
delete image;;
|
||||
delete label;;
|
||||
delete button;;
|
||||
delete bgMusic;;
|
||||
delete label;
|
||||
delete touchTrigger;
|
||||
delete buttonTrigger;
|
||||
delete sound;
|
||||
delete image;
|
||||
delete image2;
|
||||
delete image3;
|
||||
delete image4;
|
||||
delete image5;
|
||||
delete image;
|
||||
delete label;
|
||||
delete button;
|
||||
delete bgMusic;
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(int32_t w, int32_t h, Renderer* renderer) : GuiFrame(w, h) {
|
||||
#if defined _WIN32
|
||||
auto picture_path = "test.png";
|
||||
Resources::LoadFiles(".");
|
||||
#endif
|
||||
auto picture_path = "button.png";
|
||||
auto font_path = "FreeSans.ttf";
|
||||
auto bgMusic_path = "bgMusic.ogg";
|
||||
auto music_click = "button_click.mp3";
|
||||
#else
|
||||
auto picture_path = "fs:/vol/external01/test.png";
|
||||
auto font_path = "fs:/vol/external01/FreeSans.ttf";
|
||||
auto bgMusic_path = "fs:/vol/external01/bgMusic.ogg";
|
||||
auto music_click = "fs:/vol/external01/button_click.mp3";
|
||||
#endif
|
||||
|
||||
TTF_Init();
|
||||
TTF_Font *font;
|
||||
|
||||
font = TTF_OpenFont(font_path, 28);
|
||||
SDL_RWops *rw = SDL_RWFromMem((void *) Resources::GetFile(font_path), Resources::GetFileSize(font_path));
|
||||
|
||||
DEBUG_FUNCTION_LINE("load font %08X %d", Resources::GetFile(font_path), Resources::GetFileSize(font_path));
|
||||
|
||||
font = TTF_OpenFontRW(rw, 0, 28);
|
||||
if(!font){
|
||||
DEBUG_FUNCTION_LINE("Failed to load the font");
|
||||
return;
|
||||
}
|
||||
|
||||
FC_Font* fc_font = FC_CreateFont();
|
||||
if(!fc_font){
|
||||
DEBUG_FUNCTION_LINE("Failed to create font");
|
||||
}
|
||||
|
||||
FC_LoadFontFromTTF(fc_font, renderer->getRenderer(), font, {255, 255, 255, 255});
|
||||
auto res = FC_LoadFontFromTTF(fc_font, renderer->getRenderer(), font, {255, 255, 255, 255});
|
||||
DEBUG_FUNCTION_LINE("FontCache init %d", res);
|
||||
|
||||
label = new GuiText("This is a test.This is a test. This is a test.This is a test.This is a test.This is a test.", {255, 255, 0, 255}, fc_font);
|
||||
label = new GuiText("This is a test.", {255, 255, 0, 255}, fc_font);
|
||||
|
||||
bgMusic = new GuiSound(bgMusic_path);
|
||||
|
||||
bgMusic = Resources::GetSound(bgMusic_path);
|
||||
if(!bgMusic){
|
||||
DEBUG_FUNCTION_LINE("Failed to load %s", bgMusic_path);
|
||||
return;
|
||||
}
|
||||
bgMusic->SetLoop(true);
|
||||
bgMusic->Play();
|
||||
|
||||
image = new GuiImage(picture_path);
|
||||
image2 = new GuiImage(picture_path);
|
||||
image3 = new GuiImage(picture_path);
|
||||
image4 = new GuiImage(picture_path);
|
||||
image5 = new GuiImage(picture_path);
|
||||
image = new GuiImage(Resources::GetTexture(picture_path));
|
||||
image2 = new GuiImage(Resources::GetTexture(picture_path));
|
||||
image3 = new GuiImage(Resources::GetTexture(picture_path));
|
||||
image4 = new GuiImage(Resources::GetTexture(picture_path));
|
||||
image5 = new GuiImage(Resources::GetTexture(picture_path));
|
||||
if(!image){
|
||||
DEBUG_FUNCTION_LINE("Failed to add image");
|
||||
return;
|
||||
}
|
||||
if(!image2){
|
||||
DEBUG_FUNCTION_LINE("Failed to add image");
|
||||
return;
|
||||
}
|
||||
if(!image3){
|
||||
DEBUG_FUNCTION_LINE("Failed to add image");
|
||||
return;
|
||||
}
|
||||
if(!image4){
|
||||
DEBUG_FUNCTION_LINE("Failed to add image");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!image5){
|
||||
DEBUG_FUNCTION_LINE("Failed to add image");
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_FUNCTION_LINE("%d", image5->getWidth());
|
||||
button = new GuiButton(image5->getWidth(), image5->getHeight());
|
||||
|
||||
this->setAlignment(ALIGN_TOP_LEFT);
|
||||
@ -69,11 +103,12 @@ MainWindow::MainWindow(int32_t w, int32_t h, Renderer* renderer) : GuiFrame(w, h
|
||||
button->setAlignment(ALIGN_CENTERED);
|
||||
button->setImage(image5);
|
||||
|
||||
sound = new GuiSound(music_click);
|
||||
sound = Resources::GetSound(music_click);
|
||||
|
||||
touchTrigger = new GuiTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::TOUCHED);
|
||||
touchTrigger = new GuiTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::TOUCHED);
|
||||
buttonTrigger = new GuiTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_A, true);
|
||||
button->setTrigger(touchTrigger);
|
||||
button->setTrigger(buttonTrigger);
|
||||
button->setEffectGrow();
|
||||
label->setAlignment(ALIGN_CENTERED);
|
||||
button->setLabel(label);
|
||||
@ -86,8 +121,11 @@ MainWindow::MainWindow(int32_t w, int32_t h, Renderer* renderer) : GuiFrame(w, h
|
||||
void MainWindow::process() {
|
||||
GuiFrame::process();
|
||||
|
||||
if(!button){
|
||||
return;
|
||||
}
|
||||
// Rotate the button for fun.
|
||||
auto res = button->getAngle() + 1;
|
||||
auto res = button->getAngle() + 0.1f;
|
||||
if(res > 360){
|
||||
res = 0;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "../gui/GuiFrame.h"
|
||||
#include "../gui/GuiButton.h"
|
||||
#include "../utils/logger.h"
|
||||
#include "../gui/GuiImage.h"
|
||||
|
||||
class MainWindow : public GuiFrame, public sigslot::has_slots<> {
|
||||
public:
|
||||
@ -16,6 +17,7 @@ public:
|
||||
private:
|
||||
GuiText *label = nullptr;
|
||||
GuiTrigger *touchTrigger = nullptr;
|
||||
GuiTrigger *buttonTrigger = nullptr;
|
||||
GuiSound *sound = nullptr;
|
||||
GuiImage *image = nullptr;
|
||||
GuiImage *image2 = nullptr;
|
||||
|
177
src/resources/Resources.cpp
Normal file
177
src/resources/Resources.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
#include <malloc.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include "Resources.h"
|
||||
#include "../fs/FSUtils.h"
|
||||
#include "../gui/GuiSound.h"
|
||||
#include "../gui/GuiTextureData.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "filelist.h"
|
||||
#include "../utils/logger.h"
|
||||
|
||||
Resources *Resources::instance = nullptr;
|
||||
|
||||
void Resources::Clear() {
|
||||
for (int32_t i = 0; RecourceList[i].filename != nullptr; ++i) {
|
||||
if (RecourceList[i].CustomFile) {
|
||||
free(RecourceList[i].CustomFile);
|
||||
RecourceList[i].CustomFile = nullptr;
|
||||
}
|
||||
|
||||
if (RecourceList[i].CustomFileSize != 0) {
|
||||
RecourceList[i].CustomFileSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
delete instance;
|
||||
|
||||
instance = nullptr;
|
||||
}
|
||||
|
||||
bool Resources::LoadFiles(const char *path) {
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
Clear();
|
||||
|
||||
for (int32_t i = 0; RecourceList[i].filename != nullptr; ++i) {
|
||||
std::string fullpath(path);
|
||||
fullpath += "/";
|
||||
fullpath += RecourceList[i].filename;
|
||||
DEBUG_FUNCTION_LINE("%s", fullpath.c_str());
|
||||
|
||||
uint8_t *buffer = nullptr;
|
||||
uint32_t filesize = 0;
|
||||
|
||||
auto res = FSUtils::LoadFileToMem(fullpath.c_str(), &buffer, &filesize);
|
||||
if (filesize > 0) {
|
||||
RecourceList[i].CustomFile = buffer;
|
||||
RecourceList[i].CustomFileSize = (uint32_t) filesize;
|
||||
|
||||
}
|
||||
result |= (buffer != 0);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const uint8_t *Resources::GetFile(const char *filename) {
|
||||
for (int32_t i = 0; RecourceList[i].filename != nullptr; ++i) {
|
||||
if (strcasecmp(filename, RecourceList[i].filename) == 0) {
|
||||
return (RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t Resources::GetFileSize(const char *filename) {
|
||||
for (int32_t i = 0; RecourceList[i].filename != nullptr; ++i) {
|
||||
if (strcasecmp(filename, RecourceList[i].filename) == 0) {
|
||||
return (RecourceList[i].CustomFile ? RecourceList[i].CustomFileSize : RecourceList[i].DefaultFileSize);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
GuiTextureData *Resources::GetTexture(const char *filename) {
|
||||
if (!instance) {
|
||||
instance = new Resources;
|
||||
}
|
||||
|
||||
auto itr = instance->textureDataMap.find(std::string(filename));
|
||||
if (itr != instance->textureDataMap.end()) {
|
||||
itr->second.first++;
|
||||
return itr->second.second;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; RecourceList[i].filename != nullptr; ++i) {
|
||||
if (strcasecmp(filename, RecourceList[i].filename) == 0) {
|
||||
const uint8_t *buff = RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile;
|
||||
const uint32_t size = RecourceList[i].CustomFile ? RecourceList[i].CustomFileSize : RecourceList[i].DefaultFileSize;
|
||||
|
||||
if (buff == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto *image = new GuiTextureData((void *) buff, size, false);
|
||||
instance->textureDataMap[std::string(filename)].first = 1;
|
||||
instance->textureDataMap[std::string(filename)].second = image;
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Resources::RemoveTexture(GuiTextureData *image) {
|
||||
std::map<std::string, std::pair<uint32_t, GuiTextureData *> >::iterator itr;
|
||||
|
||||
for (itr = instance->textureDataMap.begin(); itr != instance->textureDataMap.end(); itr++) {
|
||||
if (itr->second.second == image) {
|
||||
itr->second.first--;
|
||||
|
||||
if (itr->second.first == 0) {
|
||||
delete itr->second.second;
|
||||
// AsyncExecutor::pushForDelete(itr->second.second);
|
||||
|
||||
instance->textureDataMap.erase(itr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
GuiSound *Resources::GetSound(const char *filename) {
|
||||
if (!instance) {
|
||||
instance = new Resources;
|
||||
}
|
||||
|
||||
auto itr = instance->soundDataMap.find(std::string(filename));
|
||||
if (itr != instance->soundDataMap.end()) {
|
||||
itr->second.first++;
|
||||
return itr->second.second;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; RecourceList[i].filename != nullptr; ++i) {
|
||||
if (strcasecmp(filename, RecourceList[i].filename) == 0) {
|
||||
const uint8_t *buff = RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile;
|
||||
const uint32_t size = RecourceList[i].CustomFile ? RecourceList[i].CustomFileSize : RecourceList[i].DefaultFileSize;
|
||||
|
||||
if (buff == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto *sound = new GuiSound((void *) buff, size);
|
||||
instance->soundDataMap[std::string(filename)].first = 1;
|
||||
instance->soundDataMap[std::string(filename)].second = sound;
|
||||
|
||||
return sound;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Resources::RemoveSound(GuiSound *sound) {
|
||||
std::map<std::string, std::pair<uint32_t, GuiSound *> >::iterator itr;
|
||||
|
||||
for (itr = instance->soundDataMap.begin(); itr != instance->soundDataMap.end(); itr++) {
|
||||
if (itr->second.second == sound) {
|
||||
itr->second.first--;
|
||||
|
||||
if (itr->second.first == 0) {
|
||||
// AsyncExecutor::pushForDelete(itr->second.second);
|
||||
delete itr->second.second;
|
||||
instance->soundDataMap.erase(itr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
48
src/resources/Resources.h
Normal file
48
src/resources/Resources.h
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
//! forward declaration
|
||||
class GuiTextureData;
|
||||
|
||||
class GuiSound;
|
||||
|
||||
typedef struct RecourceFile
|
||||
{
|
||||
const char *filename;
|
||||
const unsigned char *DefaultFile;
|
||||
const unsigned int &DefaultFileSize;
|
||||
unsigned char *CustomFile;
|
||||
unsigned int CustomFileSize;
|
||||
} RecourceFile;
|
||||
|
||||
class Resources {
|
||||
public:
|
||||
static void Clear();
|
||||
|
||||
static bool LoadFiles(const char *path);
|
||||
|
||||
static const uint8_t *GetFile(const char *filename);
|
||||
|
||||
static uint32_t GetFileSize(const char *filename);
|
||||
|
||||
static GuiTextureData *GetTexture(const char *filename);
|
||||
|
||||
static bool RemoveTexture(GuiTextureData *image);
|
||||
|
||||
static GuiSound *GetSound(const char *filename);
|
||||
|
||||
static void RemoveSound(GuiSound *sound);
|
||||
|
||||
private:
|
||||
static Resources *instance;
|
||||
|
||||
Resources() {}
|
||||
|
||||
~Resources() {}
|
||||
|
||||
std::map<std::string, std::pair<uint32_t, GuiTextureData *> > textureDataMap;
|
||||
std::map<std::string, std::pair<uint32_t, GuiSound *> > soundDataMap;
|
||||
};
|
40
src/resources/filelist.h
Normal file
40
src/resources/filelist.h
Normal file
@ -0,0 +1,40 @@
|
||||
/****************************************************************************
|
||||
* Resource files.
|
||||
* This file is generated automatically.
|
||||
* Includes 4 files.
|
||||
*
|
||||
* NOTE:
|
||||
* Any manual modification of this file will be overwriten by the generation.
|
||||
****************************************************************************/
|
||||
#ifndef _FILELIST_H_
|
||||
#define _FILELIST_H_
|
||||
|
||||
|
||||
#include "Resources.h"
|
||||
#ifdef __WIIU__
|
||||
#include "bgMusic_ogg.h"
|
||||
#include "button_png.h"
|
||||
#include "button_click_mp3.h"
|
||||
#include "FreeSans_ttf.h"
|
||||
|
||||
static RecourceFile RecourceList[] =
|
||||
{
|
||||
{"bgMusic.ogg", bgMusic_ogg, bgMusic_ogg_size, NULL, 0},
|
||||
{"button.png", button_png, button_png_size, NULL, 0},
|
||||
{"button_click.mp3", button_click_mp3, button_click_mp3_size, NULL, 0},
|
||||
{"FreeSans.ttf", FreeSans_ttf, FreeSans_ttf_size, NULL, 0},
|
||||
{NULL, NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
#else
|
||||
static RecourceFile RecourceList[] =
|
||||
{
|
||||
{"bgMusic.ogg", NULL, 0, NULL, 0},
|
||||
{"button.png", NULL, 0, NULL, 0},
|
||||
{"button_click.mp3", nullptr, 0, NULL, 0},
|
||||
{"FreeSans.ttf", NULL, 0, NULL, 0},
|
||||
{NULL, NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
@ -451,9 +451,9 @@ struct FC_Font
|
||||
FC_Image** glyph_cache;
|
||||
|
||||
char* loading_string;
|
||||
};
|
||||
|
||||
std::recursive_mutex mutex;
|
||||
std::recursive_mutex* mutex = nullptr;
|
||||
};
|
||||
|
||||
// Private
|
||||
static FC_GlyphData* FC_PackGlyphData(FC_Font* font, Uint32 codepoint, Uint16 width, Uint16 maxWidth, Uint16 maxHeight);
|
||||
@ -845,12 +845,7 @@ void FC_SetTabWidth(unsigned int width_in_spaces)
|
||||
fc_tab_width = width_in_spaces;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
static void FC_Init(FC_Font* font)
|
||||
{
|
||||
if(font == NULL)
|
||||
@ -895,6 +890,7 @@ static void FC_Init(FC_Font* font)
|
||||
font->glyph_cache_size = 3;
|
||||
font->glyph_cache_count = 0;
|
||||
|
||||
font->mutex = new std::recursive_mutex();
|
||||
|
||||
font->glyph_cache = (FC_Image**)malloc(font->glyph_cache_size * sizeof(FC_Image*));
|
||||
|
||||
@ -1181,7 +1177,7 @@ Uint8 FC_LoadFontFromTTF(FC_Font* font, SDL_Renderer* renderer, TTF_Font* ttf, S
|
||||
#endif
|
||||
|
||||
FC_ClearFont(font);
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
// Might as well check render target support here
|
||||
#ifdef FC_USE_SDL_GPU
|
||||
@ -1435,6 +1431,9 @@ void FC_ClearFont(FC_Font* font)
|
||||
}
|
||||
free(font->glyph_cache);
|
||||
font->glyph_cache = NULL;
|
||||
delete font->mutex;
|
||||
|
||||
font->mutex = nullptr;
|
||||
|
||||
// Reset font
|
||||
FC_Init(font);
|
||||
@ -1770,7 +1769,7 @@ FC_Rect FC_Draw(FC_Font* font, FC_Target* dest, float x, float y, const char* fo
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(x, y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
set_color_for_all_caches(font, font->default_color);
|
||||
|
||||
@ -2062,7 +2061,7 @@ FC_Rect FC_DrawBox(FC_Font* font, FC_Target* dest, FC_Rect box, const char* form
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(box.x, box.y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2096,7 +2095,7 @@ FC_Rect FC_DrawBoxAlign(FC_Font* font, FC_Target* dest, FC_Rect box, FC_AlignEnu
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(box.x, box.y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2129,7 +2128,7 @@ FC_Rect FC_DrawBoxScale(FC_Font* font, FC_Target* dest, FC_Rect box, FC_Scale sc
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(box.x, box.y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2162,7 +2161,7 @@ FC_Rect FC_DrawBoxColor(FC_Font* font, FC_Target* dest, FC_Rect box, SDL_Color c
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(box.x, box.y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2195,7 +2194,7 @@ FC_Rect FC_DrawBoxEffect(FC_Font* font, FC_Target* dest, FC_Rect box, FC_Effect
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(box.x, box.y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2230,7 +2229,7 @@ FC_Rect FC_DrawColumn(FC_Font* font, FC_Target* dest, float x, float y, Uint16 w
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(x, y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2245,7 +2244,7 @@ FC_Rect FC_DrawColumn(FC_Font* font, FC_Target* dest, float x, float y, Uint16 w
|
||||
|
||||
FC_Rect FC_DrawColumnToTexture(FC_Font* font, SDL_Texture* target, float x, float y, Uint16 width, const char* text)
|
||||
{
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
// Draw the text onto it
|
||||
SDL_SetRenderTarget(font->renderer, target);
|
||||
@ -2265,7 +2264,7 @@ FC_Rect FC_DrawColumnAlign(FC_Font* font, FC_Target* dest, float x, float y, Uin
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(x, y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2298,7 +2297,7 @@ FC_Rect FC_DrawColumnScale(FC_Font* font, FC_Target* dest, float x, float y, Uin
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(x, y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2321,7 +2320,7 @@ FC_Rect FC_DrawColumnColor(FC_Font* font, FC_Target* dest, float x, float y, Uin
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(x, y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2344,7 +2343,7 @@ FC_Rect FC_DrawColumnEffect(FC_Font* font, FC_Target* dest, float x, float y, Ui
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(x, y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2442,7 +2441,7 @@ FC_Rect FC_DrawScale(FC_Font* font, FC_Target* dest, float x, float y, FC_Scale
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(x, y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2460,7 +2459,7 @@ FC_Rect FC_DrawAlign(FC_Font* font, FC_Target* dest, float x, float y, FC_AlignE
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(x, y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2493,7 +2492,7 @@ FC_Rect FC_DrawColor(FC_Font* font, FC_Target* dest, float x, float y, SDL_Color
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(x, y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2512,7 +2511,7 @@ FC_Rect FC_DrawEffect(FC_Font* font, FC_Target* dest, float x, float y, FC_Effec
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return FC_MakeRect(x, y, 0, 0);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2567,7 +2566,7 @@ Uint16 FC_GetHeight(FC_Font* font, const char* formatted_text, ...)
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return 0;
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2593,7 +2592,7 @@ Uint16 FC_GetWidth(FC_Font* font, const char* formatted_text, ...)
|
||||
if(formatted_text == NULL || font == NULL)
|
||||
return 0;
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2633,7 +2632,7 @@ FC_Rect FC_GetCharacterOffset(FC_Font* font, Uint16 position_index, int column_w
|
||||
if(formatted_text == NULL || column_width == 0 || position_index == 0 || font == NULL)
|
||||
return result;
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2692,7 +2691,7 @@ Uint16 FC_GetColumnHeight(FC_Font* font, Uint16 width, const char* formatted_tex
|
||||
if(formatted_text == NULL || width == 0)
|
||||
return font->height;
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2744,7 +2743,7 @@ int FC_GetAscent(FC_Font* font, const char* formatted_text, ...)
|
||||
if(formatted_text == NULL)
|
||||
return font->ascent;
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2780,7 +2779,7 @@ int FC_GetDescent(FC_Font* font, const char* formatted_text, ...)
|
||||
if(formatted_text == NULL)
|
||||
return font->descent;
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2899,7 +2898,7 @@ Uint16 FC_GetPositionFromOffset(FC_Font* font, float x, float y, int column_widt
|
||||
if(formatted_text == NULL || column_width == 0 || font == NULL)
|
||||
return 0;
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
@ -2947,7 +2946,7 @@ int FC_GetWrappedText(FC_Font* font, char* result, int max_result_size, Uint16 w
|
||||
if(formatted_text == NULL || width == 0)
|
||||
return 0;
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
std::scoped_lock lock(*font->mutex);
|
||||
|
||||
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
|
||||
|
||||
|
1166
src/utils/dirent.h
Normal file
1166
src/utils/dirent.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@
|
||||
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
Loading…
Reference in New Issue
Block a user