mirror of
https://github.com/Maschell/SDL2_Playground.git
synced 2024-12-24 04:11:49 +01:00
Big refactoring, add github ci file
This commit is contained in:
parent
16862f2a88
commit
e29ebece97
18
.github/workflows/pc-win.yml
vendored
Normal file
18
.github/workflows/pc-win.yml
vendored
Normal 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"
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() {}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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){
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
103
src/input/ControllerManager.cpp
Normal file
103
src/input/ControllerManager.cpp
Normal 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);
|
||||
}
|
||||
}
|
37
src/input/ControllerManager.h
Normal file
37
src/input/ControllerManager.h
Normal 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;
|
||||
};
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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){
|
||||
|
||||
}
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
140
src/main.cpp
140
src/main.cpp
@ -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;
|
||||
}
|
@ -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");
|
||||
}
|
@ -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;
|
||||
};
|
@ -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;
|
||||
}
|
@ -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;
|
||||
};
|
28
src/system/video/Renderer.h
Normal file
28
src/system/video/Renderer.h
Normal 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;
|
||||
};
|
@ -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)
|
@ -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, ...);
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user