Big refactoring, add github ci file

This commit is contained in:
Maschell 2020-09-01 16:59:15 +02:00
parent 16862f2a88
commit e29ebece97
32 changed files with 829 additions and 612 deletions

18
.github/workflows/pc-win.yml vendored Normal file
View File

@ -0,0 +1,18 @@
name: Windows building.
on:
push:
branches:
- master
jobs:
build-binary:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: build binary
run: |
docker build . -f .\Dockerfile.pc-win -t sdl2_playground-builder-pc-win
docker run --rm -v ${PWD}:/project sdl2_playground-builder-pc-win make -f .\Makefile.pc-win
- uses: actions/upload-artifact@master
with:
name: binary
path: "*.exe"

View File

@ -11,8 +11,8 @@ add_executable(${PROJECT_NAME}
src/gui/GuiImage.cpp
src/gui/GuiImage.h
src/gui/sigslot.h
src/CVideo.cpp
src/CVideo.h
src/system/SDLSystem.cpp
src/system/SDLSystem.h
src/gui/GuiElement.cpp
src/gui/GuiText.cpp
src/gui/GuiText.h
@ -25,13 +25,14 @@ add_executable(${PROJECT_NAME}
src/gui/GuiButton.h
src/gui/SDLController.h src/MainWindow.cpp src/MainWindow.h src/gui/SDLControllerJoystick.h src/gui/SDLControllerMouse.h
src/gui/SDLControllerWiiUGamepad.h
src/gui/SDLControllerWiiUProContoller.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/SDL_FontCache.h src/gui/SDL_FontCache.c
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)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)

View File

@ -28,7 +28,12 @@ endif
TARGET := SDL2_Playground
BUILD := build-pc-win
SOURCES := src \
src/gui
src/gui \
src/input \
src/menu \
src/system \
src/system/video \
src/utils
DATA := data
INCLUDES := source

View File

@ -21,7 +21,12 @@ WUMS_ROOT := $(DEVKITPRO)/wums
TARGET := SDL2_Playground
BUILD := build
SOURCES := src \
src/gui
src/gui \
src/input \
src/menu \
src/system \
src/system/video \
src/utils
DATA := data
INCLUDES := source

View File

@ -133,7 +133,7 @@ void GuiButton::setTrigger(GuiTrigger *t, int32_t idx) {
}
}
void GuiButton::resetState(void) {
void GuiButton::resetState() {
clickedTrigger = NULL;
heldTrigger = NULL;
GuiElement::resetState();
@ -142,7 +142,7 @@ void GuiButton::resetState(void) {
/**
* Draw the button on screen
*/
void GuiButton::draw(CVideo *v) {
void GuiButton::draw(Renderer *v) {
if (!this->isVisible()) {
return;
}

View File

@ -20,7 +20,7 @@
#include "GuiText.h"
#include "GuiSound.h"
#include "GuiTrigger.h"
#include "../CVideo.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 {
@ -94,7 +94,7 @@ public:
void resetState(void) override;
//!Constantly called to draw the GuiButton
void draw(CVideo *video) override;
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

View File

@ -20,14 +20,15 @@
#include <vector>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <wchar.h>
#include <math.h>
#include <cwchar>
#include <cmath>
#include <iostream>
#include "sigslot.h"
#include "../system/video/Renderer.h"
enum {
EFFECT_NONE = 0x00,
@ -59,7 +60,7 @@ enum {
//!Forward declaration
class GuiController;
class CVideo;
class SDLSystem;
//!Primary GUI class. Most other classes inherit from this class.
class GuiElement {
@ -524,7 +525,7 @@ public:
virtual void update(GuiController *t) {}
//!Called constantly to redraw the element
virtual void draw(CVideo *v) {}
virtual void draw(Renderer * v) {}
//!Called constantly to process stuff in the element
virtual void process() {}

View File

@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "GuiFrame.h"
#include "../system/video/Renderer.h"
GuiFrame::GuiFrame(GuiFrame *p) {
parent = p;
@ -156,12 +157,12 @@ int32_t GuiFrame::getSelected() {
return found;
}
void GuiFrame::draw(CVideo *v) {
void GuiFrame::draw(Renderer *v) {
if (!this->isVisible() && parentElement) {
return;
}
if (parentElement && dim == true) {
if (parentElement && dim) {
//GXColor dimColor = (GXColor){0, 0, 0, 0x70};
//Menu_DrawRectangle(0, 0, GetZPosition(), screenwidth,screenheight, &dimColor, false, true);
}

View File

@ -20,6 +20,7 @@
#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 {
@ -33,7 +34,7 @@ public:
GuiFrame(float w, float h, GuiFrame *parent = 0);
//!Destructor
virtual ~GuiFrame();
~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
@ -84,7 +85,7 @@ public:
int32_t getSelected() override;
//!Draws all the elements in this GuiFrame
void draw(CVideo *v) override;
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

View File

@ -17,7 +17,7 @@
#include <SDL2/SDL_image.h>
#include <iostream>
#include "GuiImage.h"
#include "../CVideo.h"
#include "../system/SDLSystem.h"
GuiImage::GuiImage(const std::string& path) : GuiTexture(path){
}

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "GuiSound.h"
#include "../logger.h"
#include "../utils/logger.h"
GuiSound::GuiSound(const char *filepath) {
Load(filepath);

View File

@ -17,23 +17,17 @@
#include <cstdarg>
#include <SDL2/SDL_surface.h>
#include "GuiText.h"
#include "../CVideo.h"
#include "../logger.h"
#include "SDL_FontCache.h"
/**
* Constructor for the GuiText class.
*/
GuiText::GuiText(const std::string& text, int32_t s, SDL_Color c, TTF_Font* gFont) {
GuiText::GuiText(const std::string& text, SDL_Color c, FC_Font* gFont) {
this->text = text;
this->size = s;
this->color = c;
this->ttf_font = gFont;
this->invalid = true;
this->updateText = true;
this->maxWidth = 200;
this->fc_font = gFont;
updateSize();
this->doUpdateTexture = true;
}
GuiText::~GuiText(){
@ -44,61 +38,51 @@ GuiText::~GuiText(){
delete texture;
}
void GuiText::draw(CVideo *pVideo) {
void GuiText::draw(Renderer *renderer) {
if (!this->isVisible()) {
return;
}
if(invalid){
if(fc_font){
FC_FreeFont(fc_font);
fc_font = nullptr;
}
fc_font = FC_CreateFont();
invalid = !FC_LoadFontFromTTF(fc_font, pVideo->getRenderer(), this->ttf_font, color);
DEBUG_FUNCTION_LINE("FC_CACHE init done");
}
if(updateText || !texture){
delete texture;
// Create the intermediate texture target
SDL_Texture* temp = SDL_CreateTexture(pVideo->getRenderer(), pVideo->getPixelFormat(), SDL_TEXTUREACCESS_TARGET, width, height);
if(temp){
texture = new GuiTexture(temp);
texture->setParent(this);
texture->setBlendMode(SDL_BLENDMODE_BLEND);
// Draw the text onto it
SDL_SetRenderTarget(pVideo->getRenderer(), temp);
// make sure the texture is clean.
SDL_RenderClear(pVideo->getRenderer());
FC_DrawColumn(fc_font, pVideo->getRenderer(), 0, 0, maxWidth, text.c_str());
SDL_SetRenderTarget(pVideo->getRenderer(), NULL);
updateText = false;
}else{
DEBUG_FUNCTION_LINE("Failed to create texture");
}
}
updateTexture(renderer);
if(texture){
texture->draw(pVideo);
texture->draw(renderer);
}
}
void GuiText::process() {
GuiElement::process();
}
if(updateText && fc_font){
void GuiText::setMaxWidth(float width) {
this->maxWidth = width;
// Rebuild the texture cache.
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::setMaxWidth(float width) {
this->maxWidth = width;
// Rebuild the texture cache.
updateText = true;
void GuiText::updateTexture(Renderer *renderer) {
if(!texture || doUpdateTexture) {
updateSize();
SDL_Texture *temp = SDL_CreateTexture(renderer->getRenderer(), renderer->getPixelFormat(), SDL_TEXTUREACCESS_TARGET, (int) width, (int) height);
if (temp) {
delete texture;
texture = new GuiTexture(temp);
texture->setParent(this);
texture->setBlendMode(SDL_BLENDMODE_BLEND);
FC_DrawColumnToTexture(fc_font, temp, 0, 0, maxWidth, text.c_str());
doUpdateTexture = false;
} else {
DEBUG_FUNCTION_LINE("Failed to create texture");
}
}
}

View File

@ -17,12 +17,11 @@
#pragma once
#include "GuiElement.h"
#include "SDL_FontCache.h"
#include "GuiTexture.h"
#include "../system/video/SDL_FontCache.h"
#include <mutex>
#include <SDL2/SDL_ttf.h>
//!Display, manage, and manipulate text in the GUI
class GuiText : public GuiElement {
public:
@ -30,10 +29,10 @@ public:
//!\param t Text
//!\param s Font size
//!\param c Font color
GuiText(const std::string &t, int32_t s, SDL_Color c, TTF_Font *gFont);
GuiText(const std::string &t, SDL_Color c, FC_Font *font);
~GuiText() override;
void draw(CVideo *pVideo) override;
void draw(Renderer *pVideo) override;
void process() override;
@ -42,12 +41,13 @@ public:
protected:
GuiTexture* texture = nullptr;
std::string text;
int32_t size;
SDL_Color color;
TTF_Font *ttf_font = nullptr;
FC_Font *fc_font = nullptr;
bool invalid = true;
bool updateText = true;
bool doUpdateTexture = true;
uint16_t maxWidth = 0xFFFF;
void updateSize();
void updateTexture(Renderer *renderer);
};

View File

@ -1,7 +1,7 @@
#include <SDL2/SDL_image.h>
#include "GuiTexture.h"
#include "../CVideo.h"
#include "../logger.h"
#include "../system/SDLSystem.h"
#include "../utils/logger.h"
GuiTexture::GuiTexture(const std::string& path) {
imgSurface = IMG_Load( path.c_str() );
@ -49,20 +49,20 @@ GuiTexture::~GuiTexture() {
}
}
void GuiTexture::draw(CVideo *pVideo) {
void GuiTexture::draw(Renderer *renderer) {
if (!this->isVisible()) {
DEBUG_FUNCTION_LINE("not visible!");
return;
}
if (texture == NULL && imgSurface) {
SDL_Surface *optimizedSurface = SDL_ConvertSurfaceFormat(imgSurface, pVideo->getPixelFormat(), 0);
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(pVideo->getRenderer(), imgSurface);
texture = SDL_CreateTextureFromSurface(renderer->getRenderer(), imgSurface);
}
if (!texture) {
DEBUG_FUNCTION_LINE("no texture!");
@ -79,9 +79,9 @@ void GuiTexture::draw(CVideo *pVideo) {
rect.h = currScaleY * getHeight();
if (getAngle() == 0) {
SDL_RenderCopy(pVideo->getRenderer(), texture, nullptr, &rect);
SDL_RenderCopy(renderer->getRenderer(), texture, nullptr, &rect);
} else {
SDL_RenderCopyEx(pVideo->getRenderer(), texture, nullptr, &rect, getAngle(), nullptr, SDL_FLIP_NONE);
SDL_RenderCopyEx(renderer->getRenderer(), texture, nullptr, &rect, getAngle(), nullptr, SDL_FLIP_NONE);
}
}

View File

@ -12,7 +12,7 @@ public:
~GuiTexture() override;
//!Constantly called to draw the image
void draw(CVideo *pVideo) override;
void draw(Renderer *pVideo) override;
int setBlendMode(SDL_BlendMode blendMode);

View File

@ -0,0 +1,103 @@
#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) {
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[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);
}
}

View File

@ -0,0 +1,37 @@
#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;
};

View File

@ -3,8 +3,8 @@
#include <SDL2/SDL_mouse.h>
#include <iostream>
#include <SDL2/SDL_events.h>
#include "GuiController.h"
#include "../logger.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)

View File

@ -1,17 +1,18 @@
#include <SDL2/SDL.h>
#include "CVideo.h"
#include "system/SDLSystem.h"
#include "gui/GuiFrame.h"
#include "gui/GuiImage.h"
#include "gui/GuiButton.h"
#include "gui/GuiController.h"
#include "gui/SDLController.h"
#include "MainWindow.h"
#include "logger.h"
#include "gui/SDLControllerJoystick.h"
#include "gui/SDLControllerMouse.h"
#include "gui/SDLControllerWiiUGamepad.h"
#include "gui/SDLControllerXboxOne.h"
#include "gui/SDLControllerWiiUProContoller.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>
@ -51,14 +52,9 @@ bool CheckRunning(){
}
#endif
bool addJoystick(int deviceId, std::map<GuiTrigger::eChannels, SDLController *> &controllerList, std::map<int32_t, GuiTrigger::eChannels>& joystickToChannel);
GuiTrigger::eChannels increaseChannel(GuiTrigger::eChannels channel);
void removeJoystick(int32_t instanceId, std::map<GuiTrigger::eChannels, SDLController *> &controllerList, std::map<int32_t, GuiTrigger::eChannels>& joystickToChannel);
int main(int argc, char *args[]) {
auto *video = new CVideo();
auto *system = new SDLSystem();
#if defined _WIN32
// Create the Console
@ -82,14 +78,14 @@ int main(int argc, char *args[]) {
WHBLogUdpInit();
#endif
GuiFrame *frame = new MainWindow(video->getWidth(), video->getHeight());
auto * frame = new MainWindow(system->getWidth(), system->getHeight(), system->getRenderer());
auto * controllerM = new ControllerManager(system->getWidth(), system->getHeight());
std::map<GuiTrigger::eChannels, SDLController*> controllerList;
std::map<int32_t , GuiTrigger::eChannels> joystickToChannel;
#if defined _WIN32
controllerList[GuiTrigger::CHANNEL_1] = new SDLControllerMouse(GuiTrigger::CHANNEL_1);
DEBUG_FUNCTION_LINE("Add mouse");
controllerM->attachController(GuiTrigger::CHANNEL_1, new SDLControllerMouse(GuiTrigger::CHANNEL_1));
DEBUG_FUNCTION_LINE("Added mouse");
#endif
while (true) {
@ -99,11 +95,8 @@ int main(int argc, char *args[]) {
break;
}
#endif
//! Read out inputs
for( auto const& [channel, controller] : controllerList ){
controller->before();
}
// Prepare to process new events.
controllerM->prepare();
bool quit = false;
SDL_Event e;
@ -111,12 +104,12 @@ int main(int argc, char *args[]) {
int32_t channel = -1;
SDL_JoystickID jId = -1;
if(e.type == SDL_JOYDEVICEADDED) {
addJoystick(e.jdevice.which, controllerList, joystickToChannel);
controllerM->attachJoystick(e.jdevice.which);
continue;
}else if(e.type == SDL_JOYDEVICEREMOVED) {
auto j = SDL_JoystickFromInstanceID(e.jdevice.which);
if (j) {
removeJoystick(e.jdevice.which, controllerList, joystickToChannel);
controllerM->detachJoystick(e.jdevice.which);
SDL_JoystickClose(j);
continue;
}
@ -133,105 +126,32 @@ int main(int argc, char *args[]) {
quit = true;
break;
}
if(jId != -1){
if(joystickToChannel.find(jId) != joystickToChannel.end()){
channel = joystickToChannel[jId];
}
}
if(channel != -1){
controllerList[static_cast<GuiTrigger::eChannels>(channel)]->update(&e, video->getWidth(), video->getHeight());
}
}
if(quit){
break;
controllerM->processEvent(jId, channel, &e);
}
for( auto const& [joypad, controller] : controllerList ){
controller->after();
if(quit){ break; }
frame->update(controller);
}
// Finish controller inputs
controllerM->finish();
// Update gui elements based on controller inputs
controllerM->callPerController([frame](GuiController* controller) { frame->update(controller);});
frame->process();
// clear the screen
SDL_RenderClear(video->getRenderer());
SDL_RenderClear(system->getRenderer()->getRenderer());
frame->draw(video);
frame->draw(system->getRenderer());
frame->updateEffects();
// flip the backbuffer
// this means that everything that we prepared behind the screens is actually shown
SDL_RenderPresent(video->getRenderer());
SDL_RenderPresent(system->getRenderer()->getRenderer());
}
delete frame;
return 0;
}
void removeJoystick(int32_t instanceId, std::map<GuiTrigger::eChannels, SDLController *> &controllerList, std::map<int32_t, GuiTrigger::eChannels>& joystickToChannel) {
auto channel = joystickToChannel[instanceId];
delete controllerList[channel];
controllerList.erase(channel);
joystickToChannel.erase(instanceId);
DEBUG_FUNCTION_LINE("Removed joystick: %d", instanceId);
}
bool addJoystick(int deviceId, std::map<GuiTrigger::eChannels, SDLController *> &controllerList, std::map<int32_t, GuiTrigger::eChannels>& joystickToChannel) {
auto joystick = SDL_JoystickOpen(deviceId);
if (joystick == NULL){
DEBUG_FUNCTION_LINE("SDL_JoystickOpen failed: %s\n", SDL_GetError());
return false;
}
auto instanceId = SDL_JoystickInstanceID(joystick);
if(std::string("WiiU Gamepad").compare(SDL_JoystickName(joystick)) == 0){
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){
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;
}
GuiTrigger::eChannels 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;
}

View File

@ -1,5 +1,4 @@
#include "MainWindow.h"
#include "gui/SDL_FontCache.h"
MainWindow::~MainWindow() {
delete label;;
@ -16,7 +15,7 @@ MainWindow::~MainWindow() {
delete bgMusic;;
}
MainWindow::MainWindow(int32_t w, int32_t h) : GuiFrame(w, h) {
MainWindow::MainWindow(int32_t w, int32_t h, Renderer* renderer) : GuiFrame(w, h) {
#if defined _WIN32
auto picture_path = "test.png";
auto font_path = "FreeSans.ttf";
@ -34,7 +33,14 @@ MainWindow::MainWindow(int32_t w, int32_t h) : GuiFrame(w, h) {
font = TTF_OpenFont(font_path, 28);
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.", 25, {255, 255, 0, 255}, font);
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});
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);
bgMusic = new GuiSound(bgMusic_path);
bgMusic->SetLoop(true);
@ -87,3 +93,7 @@ void MainWindow::process() {
}
button->setAngle(res);
}
void MainWindow::test(GuiButton *, const GuiController *, GuiTrigger *) {
DEBUG_FUNCTION_LINE("Hello, you have clicked the button");
}

View File

@ -1,19 +1,17 @@
#pragma once
#include <iostream>
#include "gui/GuiFrame.h"
#include "gui/GuiButton.h"
#include "logger.h"
#include "../gui/GuiFrame.h"
#include "../gui/GuiButton.h"
#include "../utils/logger.h"
class MainWindow : public GuiFrame, public sigslot::has_slots<> {
public:
void test(GuiButton *, const GuiController *, GuiTrigger *) {
DEBUG_FUNCTION_LINE("Hello, you have clicked the button");
}
void test(GuiButton *, const GuiController *, GuiTrigger *);
~MainWindow();
~MainWindow() override;
MainWindow(int32_t w, int32_t h);
MainWindow(int32_t w, int32_t h, Renderer* renderer);
void process() override;
private:
GuiText *label = nullptr;

View File

@ -14,22 +14,33 @@
* 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 "CVideo.h"
#include "logger.h"
#include "SDLSystem.h"
#include "../utils/logger.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
CVideo::CVideo() {
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) { return; }
renderer = SDL_CreateRenderer(window, -1, SDLFlags);
if (!renderer) { return; }
SDL_SetRenderTarget(renderer, NULL);
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());
@ -47,28 +58,24 @@ CVideo::CVideo() {
SDL_PauseAudioDevice(dev, 0);
}
CVideo::~CVideo() {
SDL_DestroyRenderer(renderer);
SDLSystem::~SDLSystem() {
SDL_DestroyWindow(window);
delete renderer;
SDL_Quit();
}
SDL_Renderer *CVideo::getRenderer() {
return renderer;
}
float CVideo::getHeight() {
float SDLSystem::getHeight() {
int h = 0;
SDL_GetWindowSize(window, NULL, &h);
SDL_GetWindowSize(window, nullptr, &h);
return h;
}
float CVideo::getWidth() {
float SDLSystem::getWidth() {
int w = 0;
SDL_GetWindowSize(window, &w, NULL);
SDL_GetWindowSize(window, &w, nullptr);
return w;
}
unsigned int CVideo::getPixelFormat() {
return SDL_GetWindowPixelFormat(window);
Renderer *SDLSystem::getRenderer() {
return renderer;
}

View File

@ -16,21 +16,20 @@
****************************************************************************/
#pragma once
#include <SDL2/SDL_render.h>
#include "video/Renderer.h"
class CVideo {
class SDLSystem {
public:
CVideo();
SDLSystem();
virtual ~CVideo();
virtual ~SDLSystem();
SDL_Renderer *getRenderer();
Renderer *getRenderer();
float getHeight();
float getWidth();
unsigned int getPixelFormat();
private:
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
Renderer *renderer = NULL;
};

View File

@ -0,0 +1,28 @@
#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;
};

View File

@ -10,6 +10,7 @@ See SDL_FontCache.h for license info.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mutex>
// Visual C does not support static inline
#ifndef static_inline
@ -81,7 +82,6 @@ __inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...)
#define FC_CACHE_PADDING 1
static Uint8 has_clip(FC_Target* dest)
{
#ifdef FC_USE_SDL_GPU
@ -236,7 +236,7 @@ char* FC_GetStringASCII_Latin1(void)
FC_Rect FC_MakeRect(float x, float y, float w, float h)
{
FC_Rect r = {x, y, w, h};
FC_Rect r = {(int) x, (int) y, (int) w, (int) h};
return r;
}
@ -451,9 +451,10 @@ struct FC_Font
FC_Image** glyph_cache;
char* loading_string;
};
std::recursive_mutex mutex;
// Private
static FC_GlyphData* FC_PackGlyphData(FC_Font* font, Uint32 codepoint, Uint16 width, Uint16 maxWidth, Uint16 maxHeight);
@ -622,7 +623,7 @@ static_inline FC_Rect FC_RectUnion(FC_Rect A, FC_Rect B)
x2 = FC_MAX(A.x+A.w, B.x+B.w);
y2 = FC_MAX(A.y+A.h, B.y+B.h);
{
FC_Rect result = {x, y, FC_MAX(0, x2 - x), FC_MAX(0, y2 - y)};
FC_Rect result = {(int) x, (int) y, (int) FC_MAX(0, x2 - x), (int) FC_MAX(0, y2 - y)};
return result;
}
}
@ -1180,7 +1181,7 @@ Uint8 FC_LoadFontFromTTF(FC_Font* font, SDL_Renderer* renderer, TTF_Font* ttf, S
#endif
FC_ClearFont(font);
std::scoped_lock lock(mutex);
// Might as well check render target support here
#ifdef FC_USE_SDL_GPU
@ -1288,6 +1289,8 @@ Uint8 FC_LoadFontFromTTF(FC_Font* font, SDL_Renderer* renderer, TTF_Font* ttf, S
}
}
return 1;
}
@ -1767,15 +1770,15 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
set_color_for_all_caches(font, font->default_color);
return FC_RenderLeft(font, dest, x, y, FC_MakeScale(1,1), fc_buffer);
auto res = FC_RenderLeft(font, dest, x, y, FC_MakeScale(1,1), fc_buffer);
return res;
}
typedef struct FC_StringList
{
char* value;
@ -2059,6 +2062,8 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
useClip = has_clip(dest);
@ -2091,6 +2096,8 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
useClip = has_clip(dest);
@ -2122,6 +2129,8 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
useClip = has_clip(dest);
@ -2153,6 +2162,8 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
useClip = has_clip(dest);
@ -2184,6 +2195,8 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
useClip = has_clip(dest);
@ -2211,29 +2224,49 @@ FC_Rect FC_DrawBoxEffect(FC_Font* font, FC_Target* dest, FC_Rect box, FC_Effect
FC_Rect FC_DrawColumn(FC_Font* font, FC_Target* dest, float x, float y, Uint16 width, const char* formatted_text, ...)
{
FC_Rect box = {x, y, width, 0};
FC_Rect box = {(int) x, (int) y, (int) width, (int) 0};
int total_height;
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
set_color_for_all_caches(font, font->default_color);
FC_DrawColumnFromBuffer(font, dest, box, &total_height, FC_MakeScale(1,1), FC_ALIGN_LEFT);
return FC_MakeRect(box.x, box.y, width, total_height);
auto res = FC_MakeRect(box.x, box.y, width, total_height);
return res;
}
FC_Rect FC_DrawColumnToTexture(FC_Font* font, SDL_Texture* target, float x, float y, Uint16 width, const char* text)
{
std::scoped_lock lock(mutex);
// Draw the text onto it
SDL_SetRenderTarget(font->renderer, target);
// make sure the texture is clean.
SDL_RenderClear(font->renderer);
FC_Rect res = FC_DrawColumn(font, font->renderer, x, y, width, text);
SDL_SetRenderTarget(font->renderer, NULL);
return res;
}
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 box = {x, y, width, 0};
FC_Rect box = {(int) x, (int) y, (int) width, (int) 0};
int total_height;
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
set_color_for_all_caches(font, font->default_color);
@ -2252,51 +2285,67 @@ FC_Rect FC_DrawColumnAlign(FC_Font* font, FC_Target* dest, float x, float y, Uin
FC_DrawColumnFromBuffer(font, dest, box, &total_height, FC_MakeScale(1,1), align);
return FC_MakeRect(box.x, box.y, width, total_height);
auto res = FC_MakeRect(box.x, box.y, width, total_height);
return res;
}
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 box = {x, y, width, 0};
FC_Rect box = {(int) x, (int) y, (int) width, (int) 0};
int total_height;
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
set_color_for_all_caches(font, font->default_color);
FC_DrawColumnFromBuffer(font, dest, box, &total_height, scale, FC_ALIGN_CENTER);
return FC_MakeRect(box.x, box.y, width, total_height);
auto res = FC_MakeRect(box.x, box.y, width, total_height);
return res;
}
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 box = {x, y, width, 0};
FC_Rect box = {(int) x, (int) y, (int) width, (int) 0};
int total_height;
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
set_color_for_all_caches(font, color);
FC_DrawColumnFromBuffer(font, dest, box, &total_height, FC_MakeScale(1,1), FC_ALIGN_LEFT);
return FC_MakeRect(box.x, box.y, width, total_height);
auto res = FC_MakeRect(box.x, box.y, width, total_height);
return res;
}
FC_Rect FC_DrawColumnEffect(FC_Font* font, FC_Target* dest, float x, float y, Uint16 width, FC_Effect effect, const char* formatted_text, ...)
{
FC_Rect box = {x, y, width, 0};
FC_Rect box = {(int) x, (int) y, (int) width, (int) 0};
int total_height;
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
set_color_for_all_caches(font, effect.color);
@ -2315,12 +2364,16 @@ FC_Rect FC_DrawColumnEffect(FC_Font* font, FC_Target* dest, float x, float y, Ui
FC_DrawColumnFromBuffer(font, dest, box, &total_height, effect.scale, effect.alignment);
return FC_MakeRect(box.x, box.y, width, total_height);
auto res = FC_MakeRect(box.x, box.y, width, total_height);
return res;
}
static FC_Rect FC_RenderCenter(FC_Font* font, FC_Target* dest, float x, float y, FC_Scale scale, const char* text)
{
FC_Rect result = {x, y, 0, 0};
FC_Rect result = {(int) x, (int) y, (int) 0, (int) 0};
if(text == NULL || font == NULL)
return result;
@ -2353,7 +2406,7 @@ static FC_Rect FC_RenderCenter(FC_Font* font, FC_Target* dest, float x, float y,
static FC_Rect FC_RenderRight(FC_Font* font, FC_Target* dest, float x, float y, FC_Scale scale, const char* text)
{
FC_Rect result = {x, y, 0, 0};
FC_Rect result = {(int) x, (int) y, (int) 0, (int) 0};
if(text == NULL || font == NULL)
return result;
@ -2389,11 +2442,17 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
set_color_for_all_caches(font, font->default_color);
return FC_RenderLeft(font, dest, x, y, scale, fc_buffer);
auto res = FC_RenderLeft(font, dest, x, y, scale, fc_buffer);
return res;
}
FC_Rect FC_DrawAlign(FC_Font* font, FC_Target* dest, float x, float y, FC_AlignEnum align, const char* formatted_text, ...)
@ -2401,6 +2460,8 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
set_color_for_all_caches(font, font->default_color);
@ -2422,6 +2483,8 @@ FC_Rect FC_DrawAlign(FC_Font* font, FC_Target* dest, float x, float y, FC_AlignE
break;
}
return result;
}
@ -2430,11 +2493,17 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
set_color_for_all_caches(font, color);
return FC_RenderLeft(font, dest, x, y, FC_MakeScale(1,1), fc_buffer);
auto res = FC_RenderLeft(font, dest, x, y, FC_MakeScale(1,1), fc_buffer);
return res;
}
@ -2443,6 +2512,8 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
set_color_for_all_caches(font, effect.color);
@ -2464,6 +2535,8 @@ FC_Rect FC_DrawEffect(FC_Font* font, FC_Target* dest, float x, float y, FC_Effec
break;
}
return result;
}
@ -2494,6 +2567,8 @@ Uint16 FC_GetHeight(FC_Font* font, const char* formatted_text, ...)
if(formatted_text == NULL || font == NULL)
return 0;
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
Uint16 numLines = 1;
@ -2506,7 +2581,11 @@ Uint16 FC_GetHeight(FC_Font* font, const char* formatted_text, ...)
}
// Actual height of letter region + line spacing
return font->height*numLines + font->lineSpacing*(numLines - 1); //height*numLines;
auto res = font->height*numLines + font->lineSpacing*(numLines - 1); //height*numLines;
return res;
}
Uint16 FC_GetWidth(FC_Font* font, const char* formatted_text, ...)
@ -2514,6 +2593,8 @@ Uint16 FC_GetWidth(FC_Font* font, const char* formatted_text, ...)
if(formatted_text == NULL || font == NULL)
return 0;
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
const char* c;
@ -2536,6 +2617,8 @@ Uint16 FC_GetWidth(FC_Font* font, const char* formatted_text, ...)
}
bigWidth = bigWidth >= width? bigWidth : width;
return bigWidth;
}
@ -2550,6 +2633,8 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
ls = FC_GetBufferFitToColumn(font, column_width, FC_MakeScale(1,1), 1);
@ -2589,6 +2674,8 @@ FC_Rect FC_GetCharacterOffset(FC_Font* font, Uint16 position_index, int column_w
result.y = (num_lines - 1) * FC_GetLineHeight(font);
}
return result;
}
@ -2605,6 +2692,8 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
ls = FC_GetBufferFitToColumn(font, width, FC_MakeScale(1,1), 0);
@ -2614,6 +2703,8 @@ Uint16 FC_GetColumnHeight(FC_Font* font, Uint16 width, const char* formatted_tex
}
FC_StringListFree(ls);
return y;
}
@ -2653,6 +2744,8 @@ int FC_GetAscent(FC_Font* font, const char* formatted_text, ...)
if(formatted_text == NULL)
return font->ascent;
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
max = 0;
@ -2669,6 +2762,9 @@ int FC_GetAscent(FC_Font* font, const char* formatted_text, ...)
}
++c;
}
return max;
}
@ -2684,6 +2780,8 @@ int FC_GetDescent(FC_Font* font, const char* formatted_text, ...)
if(formatted_text == NULL)
return font->descent;
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
max = 0;
@ -2700,6 +2798,9 @@ int FC_GetDescent(FC_Font* font, const char* formatted_text, ...)
}
++c;
}
return max;
}
@ -2748,7 +2849,7 @@ 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, ...)
{
FC_Rect result = {x, y, 0, 0};
FC_Rect result = {(int) x, (int) y, (int) 0, (int) 0};
if(formatted_text == NULL)
return result;
@ -2798,6 +2899,8 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
ls = FC_GetBufferFitToColumn(font, column_width, FC_MakeScale(1,1), 1);
@ -2829,6 +2932,8 @@ Uint16 FC_GetPositionFromOffset(FC_Font* font, float x, float y, int column_widt
}
FC_StringListFree(ls);
return position;
}
@ -2842,6 +2947,8 @@ 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);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
ls = FC_GetBufferFitToColumn(font, width, FC_MakeScale(1,1), 0);
@ -2867,14 +2974,14 @@ int FC_GetWrappedText(FC_Font* font, char* result, int max_result_size, Uint16 w
result[size_so_far] = '\0';
return size_so_far;
}
// Setters
void FC_SetFilterMode(FC_Font* font, FC_FilterEnum filter)
{
if(font == NULL)

View File

@ -35,7 +35,8 @@ THE SOFTWARE.
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include "../logger.h"
#include <SDL2/SDL_pixels.h>
#include "../../utils/logger.h"
#ifdef FC_USE_SDL_GPU
#include "SDL_gpu.h"
@ -109,11 +110,7 @@ typedef struct FC_GlyphData
} FC_GlyphData;
// Object creation
FC_Rect FC_MakeRect(float x, float y, float w, float h);
FC_Scale FC_MakeScale(float x, float y);
@ -124,8 +121,6 @@ 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);
@ -212,7 +207,6 @@ 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);
@ -248,7 +242,6 @@ Uint8 FC_SetGlyphCacheLevel(FC_Font* font, int cache_level, FC_Image* cache_text
/*! 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);
@ -261,9 +254,7 @@ 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, ...);
@ -277,6 +268,7 @@ FC_Rect FC_DrawBoxColor(FC_Font* font, FC_Target* dest, FC_Rect box, SDL_Color c
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, ...);