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){
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;
doUpdateTexture = true;
}
void GuiText::updateSize() {
auto height = FC_GetColumnHeight(fc_font, maxWidth, text.c_str());
auto width = FC_GetWidth(fc_font, text.c_str());
width = width > maxWidth ? maxWidth : width;
this->setSize(width, height);
}
void GuiText::updateTexture(Renderer *renderer) {
if(!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,26 +1,26 @@
#pragma once
class SDLControllerMouse: public SDLController {
public:
explicit SDLControllerMouse(int32_t channel) : SDLController(channel) {
}
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;
} else if (e->type == SDL_MOUSEBUTTONUP && e->button.button == SDL_BUTTON_LEFT) {
data.buttons_h &= ~GuiTrigger::TOUCHED;
}else{
DEBUG_FUNCTION_LINE("Unknown event");
return false;
}
return true;
}
};
#pragma once
class SDLControllerMouse: public SDLController {
public:
explicit SDLControllerMouse(int32_t channel) : SDLController(channel) {
}
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;
} else if (e->type == SDL_MOUSEBUTTONUP && e->button.button == SDL_BUTTON_LEFT) {
data.buttons_h &= ~GuiTrigger::TOUCHED;
}else{
DEBUG_FUNCTION_LINE("Unknown event");
return false;
}
return true;
}
};

View File

@ -1,50 +1,50 @@
#pragma once
#pragma once
#include "SDLController.h"
static GuiTrigger::eButtons vpad_button_map[] = {
GuiTrigger::BUTTON_A,
GuiTrigger::BUTTON_B,
GuiTrigger::BUTTON_X,
GuiTrigger::BUTTON_Y,
GuiTrigger::BUTTON_STICK_L, GuiTrigger::BUTTON_STICK_R,
GuiTrigger::BUTTON_L, GuiTrigger::BUTTON_R,
GuiTrigger::BUTTON_ZL, GuiTrigger::BUTTON_ZR,
GuiTrigger::BUTTON_PLUS, GuiTrigger::BUTTON_MINUS,
GuiTrigger::BUTTON_LEFT, GuiTrigger::BUTTON_UP, GuiTrigger::BUTTON_RIGHT, GuiTrigger::BUTTON_DOWN,
GuiTrigger::STICK_L_LEFT, GuiTrigger::STICK_L_UP, GuiTrigger::STICK_L_RIGHT, GuiTrigger::STICK_L_DOWN,
GuiTrigger::STICK_R_LEFT, GuiTrigger::STICK_R_UP, GuiTrigger::STICK_R_RIGHT, GuiTrigger::STICK_R_DOWN,
};
class SDLControllerWiiUGamepad : public SDLController {
public:
explicit SDLControllerWiiUGamepad(int32_t channel) : SDLController(channel) {
}
bool update(SDL_Event *e, int32_t screenWidth, int32_t screenHeight) override {
if (e->type == SDL_FINGERMOTION) {
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;
} else if (e->type == SDL_JOYBUTTONDOWN) {
data.buttons_h |= vpad_button_map[e->jbutton.button];
} else if (e->type == SDL_JOYBUTTONUP) {
data.buttons_h &= ~vpad_button_map[e->jbutton.button];
} else {
DEBUG_FUNCTION_LINE("Unknown event");
return false;
}
return true;
}
};
#pragma once
#pragma once
#include "SDLController.h"
static GuiTrigger::eButtons vpad_button_map[] = {
GuiTrigger::BUTTON_A,
GuiTrigger::BUTTON_B,
GuiTrigger::BUTTON_X,
GuiTrigger::BUTTON_Y,
GuiTrigger::BUTTON_STICK_L, GuiTrigger::BUTTON_STICK_R,
GuiTrigger::BUTTON_L, GuiTrigger::BUTTON_R,
GuiTrigger::BUTTON_ZL, GuiTrigger::BUTTON_ZR,
GuiTrigger::BUTTON_PLUS, GuiTrigger::BUTTON_MINUS,
GuiTrigger::BUTTON_LEFT, GuiTrigger::BUTTON_UP, GuiTrigger::BUTTON_RIGHT, GuiTrigger::BUTTON_DOWN,
GuiTrigger::STICK_L_LEFT, GuiTrigger::STICK_L_UP, GuiTrigger::STICK_L_RIGHT, GuiTrigger::STICK_L_DOWN,
GuiTrigger::STICK_R_LEFT, GuiTrigger::STICK_R_UP, GuiTrigger::STICK_R_RIGHT, GuiTrigger::STICK_R_DOWN,
};
class SDLControllerWiiUGamepad : public SDLController {
public:
explicit SDLControllerWiiUGamepad(int32_t channel) : SDLController(channel) {
}
bool update(SDL_Event *e, int32_t screenWidth, int32_t screenHeight) override {
if (e->type == SDL_FINGERMOTION) {
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;
} else if (e->type == SDL_JOYBUTTONDOWN) {
data.buttons_h |= vpad_button_map[e->jbutton.button];
} else if (e->type == SDL_JOYBUTTONUP) {
data.buttons_h &= ~vpad_button_map[e->jbutton.button];
} else {
DEBUG_FUNCTION_LINE("Unknown event");
return false;
}
return true;
}
};

View File

@ -1,11 +1,11 @@
#pragma once
#include "SDLControllerWiiUGamepad.h"
class SDLControllerWiiUProContoller : public SDLControllerWiiUGamepad {
public:
explicit SDLControllerWiiUProContoller(int32_t channel) : SDLControllerWiiUGamepad(channel){
}
};
#pragma once
#include "SDLControllerWiiUGamepad.h"
class SDLControllerWiiUProContoller : public SDLControllerWiiUGamepad {
public:
explicit SDLControllerWiiUProContoller(int32_t channel) : SDLControllerWiiUGamepad(channel){
}
};

View File

@ -1,106 +1,106 @@
#pragma once
#include "SDLController.h"
static GuiTrigger::eButtons xbox_button_map[] =
{
GuiTrigger::BUTTON_A,
GuiTrigger::BUTTON_B,
GuiTrigger::BUTTON_X,
GuiTrigger::BUTTON_Y,
GuiTrigger::BUTTON_L,
GuiTrigger::BUTTON_R,
GuiTrigger::BUTTON_MINUS,
GuiTrigger::BUTTON_PLUS,
GuiTrigger::BUTTON_STICK_L,
GuiTrigger::BUTTON_STICK_R,
};
#define getDigitalAxis(axis, targetAxis, value, hold, first, second) \
if(axis == targetAxis){ \
if (value < 0x4000 && value > -0x4000){ \
hold &= ~first; \
hold &= ~second; \
}else if(value < -0x4000){ \
hold |= first; \
hold &= ~second; \
}else if(value > 0x4000){ \
hold |= second; \
hold &= ~first; \
} \
} \
#define getDigitalTrigger(axis, targetAxis, value, hold, first) \
if(axis == targetAxis){ \
if(value > 0){ \
hold |= first; \
}else{ \
hold &= ~first; \
} \
} \
class SDLControllerXboxOne : public SDLController {
public:
explicit SDLControllerXboxOne(int32_t channel) : SDLController(channel) {
}
bool update(SDL_Event *e, int32_t screenWidth, int32_t screenHeight) override {
if (e->type == SDL_JOYBUTTONDOWN) {
data.buttons_h |= xbox_button_map[e->jbutton.button];
} else if (e->type == SDL_JOYBUTTONUP) {
data.buttons_h &= ~xbox_button_map[e->jbutton.button];
} else if (e->type == SDL_JOYHATMOTION) {
auto val = e->jhat.value;
auto hatMask = (GuiTrigger::BUTTON_LEFT | GuiTrigger::BUTTON_UP | GuiTrigger::BUTTON_DOWN | GuiTrigger::BUTTON_RIGHT);
// Remove hat values so we can add the new values.
data.buttons_h &= ~hatMask;
switch (val) {
case SDL_HAT_LEFTUP:
data.buttons_h |= GuiTrigger::BUTTON_LEFT;
data.buttons_h |= GuiTrigger::BUTTON_UP;
break;
case SDL_HAT_LEFT:
data.buttons_h |= GuiTrigger::BUTTON_LEFT;
break;
case SDL_HAT_LEFTDOWN:
data.buttons_h |= GuiTrigger::BUTTON_LEFT;
data.buttons_h |= GuiTrigger::BUTTON_DOWN;
break;
case SDL_HAT_UP:
data.buttons_h |= GuiTrigger::BUTTON_UP;
break;
case SDL_HAT_DOWN:
data.buttons_h |= GuiTrigger::BUTTON_DOWN;
break;
case SDL_HAT_RIGHTUP:
data.buttons_h |= GuiTrigger::BUTTON_RIGHT;
data.buttons_h |= GuiTrigger::BUTTON_UP;
break;
case SDL_HAT_RIGHT:
data.buttons_h |= GuiTrigger::BUTTON_RIGHT;
break;
case SDL_HAT_RIGHTDOWN:
data.buttons_h |= GuiTrigger::BUTTON_RIGHT;
data.buttons_h |= GuiTrigger::BUTTON_DOWN;
break;
}
} else if (e->type == SDL_JOYAXISMOTION) {
getDigitalTrigger(e->jaxis.axis, 2, e->jaxis.value, data.buttons_h, GuiTrigger::BUTTON_ZL);
getDigitalTrigger(e->jaxis.axis, 5, e->jaxis.value, data.buttons_h, GuiTrigger::BUTTON_ZR);
getDigitalAxis(e->jaxis.axis, 0, e->jaxis.value, data.buttons_h, GuiTrigger::STICK_L_LEFT, GuiTrigger::STICK_L_RIGHT);
getDigitalAxis(e->jaxis.axis, 1, e->jaxis.value, data.buttons_h, GuiTrigger::STICK_L_UP, GuiTrigger::STICK_L_DOWN);
getDigitalAxis(e->jaxis.axis, 3, e->jaxis.value, data.buttons_h, GuiTrigger::STICK_R_LEFT, GuiTrigger::STICK_R_RIGHT);
getDigitalAxis(e->jaxis.axis, 4, e->jaxis.value, data.buttons_h, GuiTrigger::STICK_R_UP, GuiTrigger::STICK_R_DOWN);
} else {
DEBUG_FUNCTION_LINE("Unknown event");
return false;
}
return true;
}
};
#pragma once
#include "SDLController.h"
static GuiTrigger::eButtons xbox_button_map[] =
{
GuiTrigger::BUTTON_A,
GuiTrigger::BUTTON_B,
GuiTrigger::BUTTON_X,
GuiTrigger::BUTTON_Y,
GuiTrigger::BUTTON_L,
GuiTrigger::BUTTON_R,
GuiTrigger::BUTTON_MINUS,
GuiTrigger::BUTTON_PLUS,
GuiTrigger::BUTTON_STICK_L,
GuiTrigger::BUTTON_STICK_R,
};
#define getDigitalAxis(axis, targetAxis, value, hold, first, second) \
if(axis == targetAxis){ \
if (value < 0x4000 && value > -0x4000){ \
hold &= ~first; \
hold &= ~second; \
}else if(value < -0x4000){ \
hold |= first; \
hold &= ~second; \
}else if(value > 0x4000){ \
hold |= second; \
hold &= ~first; \
} \
} \
#define getDigitalTrigger(axis, targetAxis, value, hold, first) \
if(axis == targetAxis){ \
if(value > 0){ \
hold |= first; \
}else{ \
hold &= ~first; \
} \
} \
class SDLControllerXboxOne : public SDLController {
public:
explicit SDLControllerXboxOne(int32_t channel) : SDLController(channel) {
}
bool update(SDL_Event *e, int32_t screenWidth, int32_t screenHeight) override {
if (e->type == SDL_JOYBUTTONDOWN) {
data.buttons_h |= xbox_button_map[e->jbutton.button];
} else if (e->type == SDL_JOYBUTTONUP) {
data.buttons_h &= ~xbox_button_map[e->jbutton.button];
} else if (e->type == SDL_JOYHATMOTION) {
auto val = e->jhat.value;
auto hatMask = (GuiTrigger::BUTTON_LEFT | GuiTrigger::BUTTON_UP | GuiTrigger::BUTTON_DOWN | GuiTrigger::BUTTON_RIGHT);
// Remove hat values so we can add the new values.
data.buttons_h &= ~hatMask;
switch (val) {
case SDL_HAT_LEFTUP:
data.buttons_h |= GuiTrigger::BUTTON_LEFT;
data.buttons_h |= GuiTrigger::BUTTON_UP;
break;
case SDL_HAT_LEFT:
data.buttons_h |= GuiTrigger::BUTTON_LEFT;
break;
case SDL_HAT_LEFTDOWN:
data.buttons_h |= GuiTrigger::BUTTON_LEFT;
data.buttons_h |= GuiTrigger::BUTTON_DOWN;
break;
case SDL_HAT_UP:
data.buttons_h |= GuiTrigger::BUTTON_UP;
break;
case SDL_HAT_DOWN:
data.buttons_h |= GuiTrigger::BUTTON_DOWN;
break;
case SDL_HAT_RIGHTUP:
data.buttons_h |= GuiTrigger::BUTTON_RIGHT;
data.buttons_h |= GuiTrigger::BUTTON_UP;
break;
case SDL_HAT_RIGHT:
data.buttons_h |= GuiTrigger::BUTTON_RIGHT;
break;
case SDL_HAT_RIGHTDOWN:
data.buttons_h |= GuiTrigger::BUTTON_RIGHT;
data.buttons_h |= GuiTrigger::BUTTON_DOWN;
break;
}
} else if (e->type == SDL_JOYAXISMOTION) {
getDigitalTrigger(e->jaxis.axis, 2, e->jaxis.value, data.buttons_h, GuiTrigger::BUTTON_ZL);
getDigitalTrigger(e->jaxis.axis, 5, e->jaxis.value, data.buttons_h, GuiTrigger::BUTTON_ZR);
getDigitalAxis(e->jaxis.axis, 0, e->jaxis.value, data.buttons_h, GuiTrigger::STICK_L_LEFT, GuiTrigger::STICK_L_RIGHT);
getDigitalAxis(e->jaxis.axis, 1, e->jaxis.value, data.buttons_h, GuiTrigger::STICK_L_UP, GuiTrigger::STICK_L_DOWN);
getDigitalAxis(e->jaxis.axis, 3, e->jaxis.value, data.buttons_h, GuiTrigger::STICK_R_LEFT, GuiTrigger::STICK_R_RIGHT);
getDigitalAxis(e->jaxis.axis, 4, e->jaxis.value, data.buttons_h, GuiTrigger::STICK_R_UP, GuiTrigger::STICK_R_DOWN);
} else {
DEBUG_FUNCTION_LINE("Unknown event");
return false;
}
return true;
}
};

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,89 +1,99 @@
#include "MainWindow.h"
#include "gui/SDL_FontCache.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;;
}
MainWindow::MainWindow(int32_t w, int32_t h) : GuiFrame(w, h) {
#if defined _WIN32
auto picture_path = "test.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);
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);
bgMusic = new GuiSound(bgMusic_path);
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);
button = new GuiButton(image5->getWidth(), image5->getHeight());
this->setAlignment(ALIGN_TOP_LEFT);
this->append(button);
this->append(image);
this->append(image2);
this->append(image3);
this->append(image4);
image->setAlignment(ALIGN_TOP_LEFT);
image2->setAlignment(ALIGN_TOP_RIGHT);
image3->setAlignment(ALIGN_BOTTOM | ALIGN_LEFT);
image4->setAlignment(ALIGN_BOTTOM | ALIGN_RIGHT);
button->setAlignment(ALIGN_CENTERED);
button->setImage(image5);
sound = new GuiSound(music_click);
touchTrigger = new GuiTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::TOUCHED);
touchTrigger = new GuiTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::TOUCHED);
button->setTrigger(touchTrigger);
button->setEffectGrow();
label->setAlignment(ALIGN_CENTERED);
button->setLabel(label);
label->setMaxWidth(button->getWidth());
button->setSoundClick(sound);
button->clicked.connect(this, &MainWindow::test);
}
void MainWindow::process() {
GuiFrame::process();
// Rotate the button for fun.
auto res = button->getAngle() + 1;
if(res > 360){
res = 0;
}
button->setAngle(res);
}
#include "MainWindow.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;;
}
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";
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);
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);
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);
button = new GuiButton(image5->getWidth(), image5->getHeight());
this->setAlignment(ALIGN_TOP_LEFT);
this->append(button);
this->append(image);
this->append(image2);
this->append(image3);
this->append(image4);
image->setAlignment(ALIGN_TOP_LEFT);
image2->setAlignment(ALIGN_TOP_RIGHT);
image3->setAlignment(ALIGN_BOTTOM | ALIGN_LEFT);
image4->setAlignment(ALIGN_BOTTOM | ALIGN_RIGHT);
button->setAlignment(ALIGN_CENTERED);
button->setImage(image5);
sound = new GuiSound(music_click);
touchTrigger = new GuiTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::TOUCHED);
touchTrigger = new GuiTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::TOUCHED);
button->setTrigger(touchTrigger);
button->setEffectGrow();
label->setAlignment(ALIGN_CENTERED);
button->setLabel(label);
label->setMaxWidth(button->getWidth());
button->setSoundClick(sound);
button->clicked.connect(this, &MainWindow::test);
}
void MainWindow::process() {
GuiFrame::process();
// Rotate the button for fun.
auto res = button->getAngle() + 1;
if(res > 360){
res = 0;
}
button->setAngle(res);
}
void MainWindow::test(GuiButton *, const GuiController *, GuiTrigger *) {
DEBUG_FUNCTION_LINE("Hello, you have clicked the button");
}

View File

@ -1,29 +1,27 @@
#pragma once
#include <iostream>
#include "gui/GuiFrame.h"
#include "gui/GuiButton.h"
#include "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");
}
~MainWindow();
MainWindow(int32_t w, int32_t h);
void process() override;
private:
GuiText *label = nullptr;
GuiTrigger *touchTrigger = nullptr;
GuiSound *sound = nullptr;
GuiImage *image = nullptr;
GuiImage *image2 = nullptr;
GuiImage *image3 = nullptr;
GuiImage *image4 = nullptr;
GuiImage *image5 = nullptr;
GuiButton *button = nullptr;
GuiSound *bgMusic = nullptr;
};
#pragma once
#include <iostream>
#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 *);
~MainWindow() override;
MainWindow(int32_t w, int32_t h, Renderer* renderer);
void process() override;
private:
GuiText *label = nullptr;
GuiTrigger *touchTrigger = nullptr;
GuiSound *sound = nullptr;
GuiImage *image = nullptr;
GuiImage *image2 = nullptr;
GuiImage *image3 = nullptr;
GuiImage *image4 = nullptr;
GuiImage *image5 = nullptr;
GuiButton *button = nullptr;
GuiSound *bgMusic = 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, ...);

View File

@ -1,32 +1,32 @@
#pragma once
#ifdef __WIIU__
#include <whb/log.h>
#include <whb/log_cafe.h>
#include <whb/log_udp.h>
#include <whb/log.h>
#endif
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
#ifdef __WIIU__
#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \
WHBLogPrintf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \
} while (0)
#else
#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \
printf("[%23s]%30s@L%04d: " FMT "\n",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \
} while (0)
#endif
#ifdef __cplusplus
}
#endif
#pragma once
#ifdef __WIIU__
#include <whb/log.h>
#include <whb/log_cafe.h>
#include <whb/log_udp.h>
#include <whb/log.h>
#endif
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
#ifdef __WIIU__
#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \
WHBLogPrintf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \
} while (0)
#else
#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \
printf("[%23s]%30s@L%04d: " FMT "\n",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \
} while (0)
#endif
#ifdef __cplusplus
}
#endif