WIP multiscreen support

This commit is contained in:
Maschell 2020-09-07 20:26:22 +02:00
parent 1401714462
commit ed53c8bd1f
18 changed files with 592 additions and 230 deletions

View File

@ -29,7 +29,11 @@ add_executable(${PROJECT_NAME}
src/fs/CFile.hpp
src/fs/FSUtils.cpp
src/fs/FSUtils.h
src/input/SDLController.h src/menu/MainWindow.cpp src/menu/MainWindow.h src/input/SDLControllerJoystick.h src/input/SDLControllerMouse.h
src/menu/MainWindow.cpp
src/menu/MainWindow.h
src/menu/MainWindowDRC.cpp
src/menu/MainWindowDRC.h
src/input/SDLController.h src/menu/MainWindowTV.cpp src/menu/MainWindowTV.h src/input/SDLControllerJoystick.h src/input/SDLControllerMouse.h
src/input/SDLControllerWiiUGamepad.h
src/input/SDLControllerWiiUProContoller.h
src/gui/GuiTextureData.cpp src/gui/GuiTextureData.h

View File

@ -22,8 +22,13 @@ GuiImage::GuiImage(GuiTextureData *texture) {
setTexture(texture);
}
GuiImage::GuiImage(SDL_Color color, float width, float height) {
this->color = color;
this->setSize(width, height);
}
GuiImage::~GuiImage() {
if(this->texture && freeTextureData){
if (this->texture && freeTextureData) {
delete this->texture;
}
}
@ -33,13 +38,20 @@ void GuiImage::draw(Renderer *renderer) {
return;
}
if (texture) {
SDL_Rect rect;
rect.x = (int) getLeft();
rect.y = (int) getTop();
rect.w = (int) (getScaleX() * getWidth());
rect.h = (int) (getScaleY() * getHeight());
if (texture) {
texture->draw(renderer, rect, getAngle());
} else {
SDL_SetRenderDrawColor(renderer->getRenderer(), color.r, color.g, color.b, color.a);
SDL_RenderFillRect(renderer->getRenderer(), &rect);
if(getAngle() != 0.0f){
DEBUG_FUNCTION_LINE("Drawing a rotated rect is not supported yet");
}
}
}

View File

@ -23,19 +23,28 @@
//!Display, manage, and manipulate images in the GUI
class GuiImage : public GuiElement {
public:
//!\overload
//!\param img Pointer to GuiImageData element
GuiImage() = default;
//! Draws an image from an existing texture
//!\param texture Pointer to GuiTextureData element
explicit GuiImage(GuiTextureData *texture);
//! Draws a colored rectangle
//!\param texture Pointer to GuiTextureData element
explicit GuiImage(SDL_Color color, float width, float height);
//!Destructor
~GuiImage() override;
void draw(Renderer *r) override;
void setTexture(GuiTextureData *tex);
private:
GuiTextureData *texture = nullptr;
bool freeTextureData = false;
// Color of the rect that's drawn if the picture has no texture.
SDL_Color color = {0, 0, 0, 0};
};

View File

@ -76,10 +76,18 @@ void GuiText::updateTexture(Renderer *renderer) {
textureData->setBlendMode(SDL_BLENDMODE_BLEND);
texture.setTexture(textureData);
// Set render target to texture
SDL_SetRenderTarget(renderer->getRenderer(), temp);
// Clear texture.
SDL_SetRenderDrawColor(renderer->getRenderer(), 0, 0, 0, 0);
SDL_RenderClear(renderer->getRenderer());
// Draw text to texture
FC_DrawColumn(fc_font, renderer->getRenderer(), 0, 0, maxWidth, text.c_str());
SDL_SetRenderTarget(renderer->getRenderer(), NULL);
// Restore render target
SDL_SetRenderTarget(renderer->getRenderer(), nullptr);
} else {
DEBUG_FUNCTION_LINE("Failed to create texture");
}

View File

@ -59,11 +59,6 @@ GuiTextureData::~GuiTextureData() {
void GuiTextureData::draw(Renderer *renderer, const SDL_Rect& dest, float angle) {
if (texture == nullptr && imgSurface) {
SDL_Surface *optimizedSurface = SDL_ConvertSurfaceFormat(imgSurface, renderer->getPixelFormat(), 0);
if (optimizedSurface != nullptr) {
SDL_FreeSurface(imgSurface);
imgSurface = optimizedSurface;
}
texture = SDL_CreateTextureFromSurface(renderer->getRenderer(), imgSurface);
}
if (!texture) {

View File

@ -3,10 +3,11 @@
#include "gui/GuiFrame.h"
#include "gui/GuiButton.h"
#include "gui/GuiController.h"
#include "menu/MainWindow.h"
#include "menu/MainWindowTV.h"
#include "input/SDLController.h"
#include "input/SDLControllerMouse.h"
#include "input/ControllerManager.h"
#include "menu/MainWindow.h"
#include <cstdio>
#include <fcntl.h>
@ -70,7 +71,9 @@ int main(int argc, char *args[]) {
WHBLogUdpInit();
#endif
auto * frame = new MainWindow(system->getWidth(), system->getHeight(), system->getRenderer());
DEBUG_FUNCTION_LINE("%0.1f %0.1f", system->getWidth(), system->getHeight());
auto * frame = new MainWindow(system);
auto * controllerM = new ControllerManager(system->getWidth(), system->getHeight());
@ -132,16 +135,9 @@ int main(int argc, char *args[]) {
frame->process();
// clear the screen
SDL_RenderClear(system->getRenderer()->getRenderer());
frame->draw(system->getRenderer());
frame->draw();
frame->updateEffects();
// flip the backbuffer
// this means that everything that we prepared behind the screens is actually shown
SDL_RenderPresent(system->getRenderer()->getRenderer());
}
delete frame;

View File

@ -1,53 +1,39 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <string>
#include "MainWindow.h"
#include "../gui/GuiImage.h"
#include "MainWindowTV.h"
#include "../resources/Resources.h"
#include "MainWindowDRC.h"
MainWindow::~MainWindow() {
delete label;
delete touchTrigger;
delete buttonTrigger;
delete sound;
delete image;
delete image2;
delete image3;
delete image4;
delete image5;
delete image;
delete label;
delete button;
delete bgMusic;
}
MainWindow::MainWindow(SDLSystem* sdlSystem):
sdlSystem(sdlSystem){
if(TTF_Init() < 0){
DEBUG_FUNCTION_LINE("Failed to init TTF");
}
currentTvFrame = new MainWindowTV(sdlSystem->getWidth(), sdlSystem->getHeight(), sdlSystem->getRendererTV());
currentDrcFrame = new MainWindowDRC(sdlSystem->getWidth(), sdlSystem->getHeight(), sdlSystem->getRendererDRC());
MainWindow::MainWindow(int32_t w, int32_t h, Renderer* renderer) : GuiFrame(w, h) {
auto picture_path = "button.png";
auto font_path = "FreeSans.ttf";
auto bgMusic_path = "bgMusic.ogg";
auto music_click = "button_click.mp3";
TTF_Init();
TTF_Font *font;
SDL_RWops *rw = SDL_RWFromMem((void *) Resources::GetFile(font_path), Resources::GetFileSize(font_path));
DEBUG_FUNCTION_LINE("load font %08X %d", Resources::GetFile(font_path), Resources::GetFileSize(font_path));
font = TTF_OpenFontRW(rw, 0, 28);
if(!font){
DEBUG_FUNCTION_LINE("Failed to load the font");
return;
}
FC_Font* fc_font = FC_CreateFont();
if(!fc_font){
DEBUG_FUNCTION_LINE("Failed to create font");
}
auto res = FC_LoadFontFromTTF(fc_font, renderer->getRenderer(), font, {255, 255, 255, 255});
DEBUG_FUNCTION_LINE("FontCache init %d", res);
label = new GuiText("This is a test.", {255, 255, 0, 255}, fc_font);
bgMusic = Resources::GetSound(bgMusic_path);
bgMusic = Resources::GetSound(Renderer::TARGET_TV, bgMusic_path);
if(!bgMusic){
DEBUG_FUNCTION_LINE("Failed to load %s", bgMusic_path);
return;
@ -55,79 +41,35 @@ MainWindow::MainWindow(int32_t w, int32_t h, Renderer* renderer) : GuiFrame(w, h
bgMusic->SetLoop(true);
bgMusic->Play();
image = new GuiImage(Resources::GetTexture(picture_path));
image2 = new GuiImage(Resources::GetTexture(picture_path));
image3 = new GuiImage(Resources::GetTexture(picture_path));
image4 = new GuiImage(Resources::GetTexture(picture_path));
image5 = new GuiImage(Resources::GetTexture(picture_path));
if(!image){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
if(!image2){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
if(!image3){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
if(!image4){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
}
if(!image5){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
MainWindow::~MainWindow() {
delete currentTvFrame;
delete currentDrcFrame;
Resources::RemoveSound(Renderer::TARGET_TV, bgMusic);
}
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 = Resources::GetSound(music_click);
touchTrigger = new GuiTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::TOUCHED);
buttonTrigger = new GuiTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_A, true);
button->setTrigger(touchTrigger);
button->setTrigger(buttonTrigger);
button->setEffectGrow();
label->setAlignment(ALIGN_CENTERED);
button->setLabel(label);
label->setMaxWidth(button->getWidth());
button->setSoundClick(sound);
button->clicked.connect(this, &MainWindow::test);
void MainWindow::updateEffects() {
currentTvFrame->updateEffects();
currentDrcFrame->updateEffects();
}
void MainWindow::process() {
GuiFrame::process();
if(!button){
return;
}
// Rotate the button for fun.
auto res = button->getAngle() + 0.1f;
if(res > 360){
res = 0;
}
button->setAngle(res);
currentTvFrame->process();
currentDrcFrame->process();
}
void MainWindow::test(GuiButton *, const GuiController *, GuiTrigger *) {
DEBUG_FUNCTION_LINE("Hello, you have clicked the button");
void MainWindow::update(GuiController *controller) {
currentTvFrame->update(controller);
currentDrcFrame->update(controller);
}
void MainWindow::draw() {
SDL_RenderClear(sdlSystem->getRendererTV()->getRenderer());
currentTvFrame->draw(sdlSystem->getRendererTV());
SDL_RenderPresent(sdlSystem->getRendererTV()->getRenderer());
SDL_RenderClear(sdlSystem->getRendererDRC()->getRenderer());
currentDrcFrame->draw(sdlSystem->getRendererDRC());
SDL_RenderPresent(sdlSystem->getRendererDRC()->getRenderer());
}

View File

@ -1,29 +1,46 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#pragma once
#include <iostream>
#include <vector>
#include <queue>
#include "../gui/sigslot.h"
#include "../gui/GuiElement.h"
#include "../gui/GuiFrame.h"
#include "../gui/GuiButton.h"
#include "../utils/logger.h"
#include "../gui/GuiImage.h"
#include "../gui/GuiSound.h"
class MainWindow : public GuiFrame, public sigslot::has_slots<> {
class Renderer;
class MainWindow : public sigslot::has_slots<> {
public:
void test(GuiButton *, const GuiController *, GuiTrigger *);
explicit MainWindow(SDLSystem* sdlSystem);
~MainWindow() override;
MainWindow(int32_t w, int32_t h, Renderer* renderer);
void process() override;
void draw();
void update(GuiController *controller);
void updateEffects();
void process();
private:
GuiText *label = nullptr;
GuiTrigger *touchTrigger = nullptr;
GuiTrigger *buttonTrigger = 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;
int32_t width, height;
GuiFrame * currentTvFrame;
GuiFrame * currentDrcFrame;
SDLSystem* sdlSystem;
GuiSound* bgMusic;
};

123
src/menu/MainWindowDRC.cpp Normal file
View File

@ -0,0 +1,123 @@
#include "MainWindowDRC.h"
#include "../resources/Resources.h"
MainWindowDRC::~MainWindowDRC() {
delete label;
delete touchTrigger;
delete buttonTrigger;
delete sound;
delete image;
delete image2;
delete image3;
delete image4;
delete image5;
delete image;
delete label;
delete button;
}
MainWindowDRC::MainWindowDRC(int32_t w, int32_t h, Renderer* renderer) : GuiFrame(w, h), bgImage({100, 0, 0, 255}, w, h) {
auto picture_path = "button.png";
auto font_path = "FreeSans.ttf";
auto music_click = "button_click.mp3";
append(&bgImage);
TTF_Font *font;
SDL_RWops *rw = SDL_RWFromMem((void *) Resources::GetFile(font_path), Resources::GetFileSize(font_path));
DEBUG_FUNCTION_LINE("load font %08X %d", Resources::GetFile(font_path), Resources::GetFileSize(font_path));
font = TTF_OpenFontRW(rw, 0, 28);
if(!font){
DEBUG_FUNCTION_LINE("Failed to load the font %s", SDL_GetError());
return;
}
FC_Font* fc_font = FC_CreateFont();
if(!fc_font){
DEBUG_FUNCTION_LINE("Failed to create font");
}
auto res = FC_LoadFontFromTTF(fc_font, renderer->getRenderer(), font, {255, 255, 255, 255});
DEBUG_FUNCTION_LINE("FontCache init %d", res);
label = new GuiText("This is a test.", {255, 255, 0, 255}, fc_font);
image = new GuiImage(Resources::GetTexture(renderer->getTarget(), picture_path));
image2 = new GuiImage(Resources::GetTexture(renderer->getTarget(), picture_path));
image3 = new GuiImage(Resources::GetTexture(renderer->getTarget(), picture_path));
image4 = new GuiImage(Resources::GetTexture(renderer->getTarget(), picture_path));
image5 = new GuiImage(Resources::GetTexture(renderer->getTarget(), picture_path));
if(!image){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
if(!image2){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
if(!image3){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
if(!image4){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
if(!image5){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
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_CENTER);
image2->setAlignment(ALIGN_MIDDLE | ALIGN_LEFT);
image3->setAlignment(ALIGN_BOTTOM | ALIGN_CENTER);
image4->setAlignment(ALIGN_MIDDLE | ALIGN_RIGHT);
button->setAlignment(ALIGN_CENTERED);
button->setImage(image5);
sound = Resources::GetSound(renderer->getTarget(), music_click);
touchTrigger = new GuiTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::TOUCHED);
buttonTrigger = new GuiTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_A, true);
button->setTrigger(touchTrigger);
button->setTrigger(buttonTrigger);
button->setEffectGrow();
label->setAlignment(ALIGN_CENTERED);
button->setLabel(label);
label->setMaxWidth(button->getWidth());
button->setSoundClick(sound);
button->clicked.connect(this, &MainWindowDRC::test);
}
void MainWindowDRC::process() {
GuiFrame::process();
if(!button){
return;
}
// Rotate the button for fun.
auto res = button->getAngle() - 1.0f;
if(res > 360){
res = 0;
}
button->setAngle(res);
}
void MainWindowDRC::test(GuiButton *, const GuiController *, GuiTrigger *) {
DEBUG_FUNCTION_LINE("Hello, you have clicked the button");
}

31
src/menu/MainWindowDRC.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include <iostream>
#include "../gui/GuiFrame.h"
#include "../gui/GuiButton.h"
#include "../utils/logger.h"
#include "../gui/GuiImage.h"
class MainWindowDRC : public GuiFrame, public sigslot::has_slots<> {
public:
void test(GuiButton *, const GuiController *, GuiTrigger *);
~MainWindowDRC() override;
MainWindowDRC(int32_t w, int32_t h, Renderer *renderer);
void process() override;
private:
GuiText *label = nullptr;
GuiTrigger *touchTrigger = nullptr;
GuiTrigger *buttonTrigger = nullptr;
GuiSound *sound = nullptr;
GuiImage *image = nullptr;
GuiImage *image2 = nullptr;
GuiImage *image3 = nullptr;
GuiImage *image4 = nullptr;
GuiImage *image5 = nullptr;
GuiImage bgImage;
GuiButton *button = nullptr;
};

124
src/menu/MainWindowTV.cpp Normal file
View File

@ -0,0 +1,124 @@
#include "MainWindowTV.h"
#include "../resources/Resources.h"
MainWindowTV::~MainWindowTV() {
delete label;
delete touchTrigger;
delete buttonTrigger;
delete sound;
delete image;
delete image2;
delete image3;
delete image4;
delete image5;
delete image;
delete label;
delete button;
delete bgMusic;
}
MainWindowTV::MainWindowTV(int32_t w, int32_t h, Renderer* renderer) : GuiFrame(w, h), bgImage({100, 0, 0, 255}, w, h) {
auto picture_path = "button.png";
auto font_path = "FreeSans.ttf";
auto music_click = "button_click.mp3";
append(&bgImage);
TTF_Font *font;
SDL_RWops *rw = SDL_RWFromMem((void *) Resources::GetFile(font_path), Resources::GetFileSize(font_path));
DEBUG_FUNCTION_LINE("load font %08X %d", Resources::GetFile(font_path), Resources::GetFileSize(font_path));
font = TTF_OpenFontRW(rw, 0, 28);
if(!font){
DEBUG_FUNCTION_LINE("Failed to load the font %s", SDL_GetError());
return;
}
FC_Font* fc_font = FC_CreateFont();
if(!fc_font){
DEBUG_FUNCTION_LINE("Failed to create font");
}
auto res = FC_LoadFontFromTTF(fc_font, renderer->getRenderer(), font, {255, 255, 255, 255});
DEBUG_FUNCTION_LINE("FontCache init %d", res);
label = new GuiText("This is a test.", {255, 255, 0, 255}, fc_font);
image = new GuiImage(Resources::GetTexture(renderer->getTarget(), picture_path));
image2 = new GuiImage(Resources::GetTexture(renderer->getTarget(), picture_path));
image3 = new GuiImage(Resources::GetTexture(renderer->getTarget(), picture_path));
image4 = new GuiImage(Resources::GetTexture(renderer->getTarget(), picture_path));
image5 = new GuiImage(Resources::GetTexture(renderer->getTarget(), picture_path));
if(!image){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
if(!image2){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
if(!image3){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
if(!image4){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
if(!image5){
DEBUG_FUNCTION_LINE("Failed to add image");
return;
}
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 = Resources::GetSound(renderer->getTarget(), music_click);
buttonTrigger = new GuiTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_A, true);
button->setTrigger(buttonTrigger);
button->setEffectGrow();
label->setAlignment(ALIGN_CENTERED);
button->setLabel(label);
label->setMaxWidth(button->getWidth());
button->setSoundClick(sound);
button->clicked.connect(this, &MainWindowTV::test);
}
void MainWindowTV::process() {
GuiFrame::process();
if(!button){
return;
}
// Rotate the button for fun.
auto res = button->getAngle() + 1.0f;
if(res > 360){
res = 0;
}
button->setAngle(res);
}
void MainWindowTV::test(GuiButton *, const GuiController *, GuiTrigger *) {
DEBUG_FUNCTION_LINE("Hello, you have clicked the button");
}

30
src/menu/MainWindowTV.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <iostream>
#include "../gui/GuiFrame.h"
#include "../gui/GuiButton.h"
#include "../utils/logger.h"
#include "../gui/GuiImage.h"
class MainWindowTV : public GuiFrame, public sigslot::has_slots<> {
public:
void test(GuiButton *, const GuiController *, GuiTrigger *);
~MainWindowTV() override;
MainWindowTV(int32_t w, int32_t h, Renderer* renderer);
void process() override;
private:
GuiText *label = nullptr;
GuiTrigger *touchTrigger = nullptr;
GuiTrigger *buttonTrigger = nullptr;
GuiSound *sound = nullptr;
GuiImage *image = nullptr;
GuiImage *image2 = nullptr;
GuiImage *image3 = nullptr;
GuiImage *image4 = nullptr;
GuiImage *image5 = nullptr;
GuiImage bgImage;
GuiButton *button = nullptr;
GuiSound *bgMusic = nullptr;
};

View File

@ -11,7 +11,8 @@
#include "filelist.h"
#include "../utils/logger.h"
Resources *Resources::instance = nullptr;
std::map<Renderer::Renderer::RendererTarget, Resources *> Resources::instances;
void Resources::Clear() {
for (int32_t i = 0; RecourceList[i].filename != nullptr; ++i) {
@ -19,15 +20,15 @@ void Resources::Clear() {
free(RecourceList[i].CustomFile);
RecourceList[i].CustomFile = nullptr;
}
if (RecourceList[i].CustomFileSize != 0) {
RecourceList[i].CustomFileSize = 0;
}
}
for (auto const&[target, instance] : instances) {
delete instance;
instance = nullptr;
}
instances.clear();
}
bool Resources::LoadFiles(const char *path) {
@ -78,11 +79,13 @@ uint32_t Resources::GetFileSize(const char *filename) {
return 0;
}
GuiTextureData *Resources::GetTexture(const char *filename) {
if (!instance) {
instance = new Resources;
GuiTextureData *Resources::GetTexture(Renderer::RendererTarget target, const char *filename) {
if (instances.count(target) == 0) {
instances[target] = new Resources();
}
Resources *instance = instances[target];
auto itr = instance->textureDataMap.find(std::string(filename));
if (itr != instance->textureDataMap.end()) {
itr->second.first++;
@ -109,7 +112,13 @@ GuiTextureData *Resources::GetTexture(const char *filename) {
return nullptr;
}
bool Resources::RemoveTexture(GuiTextureData *image) {
bool Resources::RemoveTexture(Renderer::RendererTarget target, GuiTextureData *image) {
if (instances.count(target) == 0) {
instances[target] = new Resources();
}
Resources *instance = instances[target];
std::map<std::string, std::pair<uint32_t, GuiTextureData *> >::iterator itr;
for (itr = instance->textureDataMap.begin(); itr != instance->textureDataMap.end(); itr++) {
@ -128,11 +137,13 @@ bool Resources::RemoveTexture(GuiTextureData *image) {
return false;
}
GuiSound *Resources::GetSound(const char *filename) {
if (!instance) {
instance = new Resources;
GuiSound *Resources::GetSound(Renderer::RendererTarget target, const char *filename) {
if (instances.count(target) == 0) {
instances[target] = new Resources();
}
Resources *instance = instances[target];
auto itr = instance->soundDataMap.find(std::string(filename));
if (itr != instance->soundDataMap.end()) {
itr->second.first++;
@ -159,7 +170,13 @@ GuiSound *Resources::GetSound(const char *filename) {
return nullptr;
}
void Resources::RemoveSound(GuiSound *sound) {
void Resources::RemoveSound(Renderer::RendererTarget target, GuiSound *sound) {
if (instances.count(target) == 0) {
instances[target] = new Resources();
}
Resources *instance = instances[target];
std::map<std::string, std::pair<uint32_t, GuiSound *> >::iterator itr;
for (itr = instance->soundDataMap.begin(); itr != instance->soundDataMap.end(); itr++) {

View File

@ -3,6 +3,7 @@
#include <map>
#include <string>
#include <cstdint>
#include "../system/video/Renderer.h"
//! forward declaration
class GuiTextureData;
@ -18,6 +19,8 @@ typedef struct RecourceFile
unsigned int CustomFileSize;
} RecourceFile;
class Resources {
public:
static void Clear();
@ -28,20 +31,20 @@ public:
static uint32_t GetFileSize(const char *filename);
static GuiTextureData *GetTexture(const char *filename);
static GuiTextureData *GetTexture(Renderer::RendererTarget target, const char *filename);
static bool RemoveTexture(GuiTextureData *image);
static bool RemoveTexture(Renderer::RendererTarget target, GuiTextureData *image);
static GuiSound *GetSound(const char *filename);
static GuiSound *GetSound(Renderer::RendererTarget target, const char *filename);
static void RemoveSound(GuiSound *sound);
static void RemoveSound(Renderer::RendererTarget target, GuiSound *sound);
private:
static Resources *instance;
Resources() = default;
Resources() {}
~Resources() = default;
~Resources() {}
static std::map<Renderer::RendererTarget, Resources * > instances;
std::map<std::string, std::pair<uint32_t, GuiTextureData *> > textureDataMap;
std::map<std::string, std::pair<uint32_t, GuiSound *> > soundDataMap;

View File

@ -18,27 +18,61 @@
#include "../utils/logger.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
#ifdef __WIIU__
#include <gx2/display.h>
#endif
SDLSystem::SDLSystem() {
SDL_Init(SDL_INIT_EVERYTHING);
int width = 1280;
int height = 720;
auto SDLFlags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;
#ifdef __WIIU__
window_tv = SDL_CreateWindow(nullptr, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_WIIU_TV_ONLY);
#else
window_tv = SDL_CreateWindow(nullptr, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0);
#endif
//Setup window
window = SDL_CreateWindow(nullptr, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, 0);
if (!window) {
if (!window_tv) {
DEBUG_FUNCTION_LINE("Failed to create window");
return;
}
auto sdl_renderer = SDL_CreateRenderer(window, -1, SDLFlags);
if (!sdl_renderer) {
auto sdl_renderer_tv = SDL_CreateRenderer(window_tv, -1, SDLFlags);
if (!sdl_renderer_tv) {
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");
SDL_SetRenderTarget(sdl_renderer_tv, nullptr);
this->renderer_tv = new Renderer(sdl_renderer_tv, SDL_GetWindowPixelFormat(window_tv), Renderer::TARGET_TV);
if (!renderer_tv) {
DEBUG_FUNCTION_LINE("Failed to init renderer_tv");
return;
}
#ifdef __WIIU__
window_drc = SDL_CreateWindow(nullptr, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_WIIU_GAMEPAD_ONLY );
#else
window_drc = SDL_CreateWindow(nullptr, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0);
#endif
//Setup window
if (!window_drc) {
DEBUG_FUNCTION_LINE("Failed to create window");
return;
}
auto sdl_renderer_drc = SDL_CreateRenderer(window_drc, -1, SDLFlags);
if (!sdl_renderer_drc) {
DEBUG_FUNCTION_LINE("Failed to init sdl renderer");
return;
}
SDL_SetRenderTarget(sdl_renderer_drc, nullptr);
this->renderer_drc = new Renderer(sdl_renderer_drc, SDL_GetWindowPixelFormat(window_drc), Renderer::TARGET_DRC);
if (!renderer_drc) {
DEBUG_FUNCTION_LINE("Failed to init renderer_tv");
return;
}
@ -59,23 +93,29 @@ SDLSystem::SDLSystem() {
}
SDLSystem::~SDLSystem() {
SDL_DestroyWindow(window);
delete renderer;
SDL_DestroyWindow(window_tv);
SDL_DestroyWindow(window_drc);
delete renderer_tv;
delete renderer_drc;
SDL_Quit();
}
float SDLSystem::getHeight() {
int h = 0;
SDL_GetWindowSize(window, nullptr, &h);
SDL_GetWindowSize(window_tv, nullptr, &h);
return h;
}
float SDLSystem::getWidth() {
int w = 0;
SDL_GetWindowSize(window, &w, nullptr);
SDL_GetWindowSize(window_tv, &w, nullptr);
return w;
}
Renderer *SDLSystem::getRenderer() {
return renderer;
Renderer *SDLSystem::getRendererTV() {
return renderer_tv;
}
Renderer *SDLSystem::getRendererDRC() {
return renderer_drc;
}

View File

@ -24,12 +24,15 @@ public:
virtual ~SDLSystem();
Renderer *getRenderer();
Renderer *getRendererTV();
Renderer *getRendererDRC();
float getHeight();
float getWidth();
private:
SDL_Window *window = NULL;
Renderer *renderer = NULL;
SDL_Window *window_tv = nullptr;
SDL_Window *window_drc = nullptr;
Renderer *renderer_tv = nullptr;
Renderer *renderer_drc = nullptr;
};

View File

@ -4,7 +4,16 @@
class Renderer {
public:
Renderer(SDL_Renderer *renderer, uint32_t pixelFormat) : sdl_renderer(renderer), pixelFormat(pixelFormat){
enum RendererTarget {
TARGET_TV = 0x00,
TARGET_DRC = 0x01,
};
Renderer(SDL_Renderer *renderer, uint32_t pixelFormat, RendererTarget renderTarget) :
sdl_renderer(renderer),
pixelFormat(pixelFormat),
renderTarget(renderTarget)
{
}
@ -22,7 +31,12 @@ public:
return pixelFormat;
}
RendererTarget getTarget(){
return renderTarget;
}
private:
SDL_Renderer *sdl_renderer = NULL;
uint32_t pixelFormat = SDL_PIXELFORMAT_RGBA8888;
RendererTarget renderTarget = TARGET_TV;
};

View File

@ -417,8 +417,6 @@ static FC_GlyphData* FC_MapFind(FC_Map* map, Uint32 codepoint)
return NULL;
}
struct FC_Font
{
#ifndef FC_USE_SDL_GPU
@ -451,10 +449,10 @@ struct FC_Font
FC_Image** glyph_cache;
char* loading_string;
std::recursive_mutex* mutex = nullptr;
};
std::recursive_mutex mutex;
// Private
static FC_GlyphData* FC_PackGlyphData(FC_Font* font, Uint32 codepoint, Uint16 width, Uint16 maxWidth, Uint16 maxHeight);
@ -702,6 +700,7 @@ FC_Rect FC_DefaultRenderCallback(FC_Image* src, FC_Rect* srcrect, FC_Target* des
SDL_Rect r = *srcrect;
SDL_Rect dr = {(int)x, (int)y, (int)(xscale*r.w), (int)(yscale*r.h)};
DEBUG_FUNCTION_LINE("Src. %08X",src);
SDL_RenderCopyEx(dest, src, &r, &dr, 0, NULL, flip);
}
#endif
@ -890,8 +889,6 @@ static void FC_Init(FC_Font* font)
font->glyph_cache_size = 3;
font->glyph_cache_count = 0;
font->mutex = new std::recursive_mutex();
font->glyph_cache = (FC_Image**)malloc(font->glyph_cache_size * sizeof(FC_Image*));
if (font->loading_string == NULL)
@ -1177,7 +1174,7 @@ Uint8 FC_LoadFontFromTTF(FC_Font* font, SDL_Renderer* renderer, TTF_Font* ttf, S
#endif
FC_ClearFont(font);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
// Might as well check render target support here
#ifdef FC_USE_SDL_GPU
@ -1431,9 +1428,6 @@ void FC_ClearFont(FC_Font* font)
}
free(font->glyph_cache);
font->glyph_cache = NULL;
delete font->mutex;
font->mutex = nullptr;
// Reset font
FC_Init(font);
@ -1769,7 +1763,7 @@ FC_Rect FC_Draw(FC_Font* font, FC_Target* dest, float x, float y, const char* fo
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
set_color_for_all_caches(font, font->default_color);
@ -2061,7 +2055,7 @@ FC_Rect FC_DrawBox(FC_Font* font, FC_Target* dest, FC_Rect box, const char* form
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(box.x, box.y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2095,7 +2089,7 @@ FC_Rect FC_DrawBoxAlign(FC_Font* font, FC_Target* dest, FC_Rect box, FC_AlignEnu
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(box.x, box.y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2128,7 +2122,7 @@ FC_Rect FC_DrawBoxScale(FC_Font* font, FC_Target* dest, FC_Rect box, FC_Scale sc
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(box.x, box.y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2161,7 +2155,7 @@ FC_Rect FC_DrawBoxColor(FC_Font* font, FC_Target* dest, FC_Rect box, SDL_Color c
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(box.x, box.y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2194,7 +2188,7 @@ FC_Rect FC_DrawBoxEffect(FC_Font* font, FC_Target* dest, FC_Rect box, FC_Effect
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(box.x, box.y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2229,7 +2223,7 @@ FC_Rect FC_DrawColumn(FC_Font* font, FC_Target* dest, float x, float y, Uint16 w
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2244,7 +2238,7 @@ FC_Rect FC_DrawColumn(FC_Font* font, FC_Target* dest, float x, float y, Uint16 w
FC_Rect FC_DrawColumnToTexture(FC_Font* font, SDL_Texture* target, float x, float y, Uint16 width, const char* text)
{
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
// Draw the text onto it
SDL_SetRenderTarget(font->renderer, target);
@ -2264,7 +2258,7 @@ FC_Rect FC_DrawColumnAlign(FC_Font* font, FC_Target* dest, float x, float y, Uin
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2297,7 +2291,7 @@ FC_Rect FC_DrawColumnScale(FC_Font* font, FC_Target* dest, float x, float y, Uin
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2320,7 +2314,7 @@ FC_Rect FC_DrawColumnColor(FC_Font* font, FC_Target* dest, float x, float y, Uin
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2343,7 +2337,7 @@ FC_Rect FC_DrawColumnEffect(FC_Font* font, FC_Target* dest, float x, float y, Ui
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2441,7 +2435,7 @@ FC_Rect FC_DrawScale(FC_Font* font, FC_Target* dest, float x, float y, FC_Scale
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2459,7 +2453,7 @@ FC_Rect FC_DrawAlign(FC_Font* font, FC_Target* dest, float x, float y, FC_AlignE
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2492,7 +2486,7 @@ FC_Rect FC_DrawColor(FC_Font* font, FC_Target* dest, float x, float y, SDL_Color
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2511,7 +2505,7 @@ FC_Rect FC_DrawEffect(FC_Font* font, FC_Target* dest, float x, float y, FC_Effec
if(formatted_text == NULL || font == NULL)
return FC_MakeRect(x, y, 0, 0);
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2566,7 +2560,7 @@ Uint16 FC_GetHeight(FC_Font* font, const char* formatted_text, ...)
if(formatted_text == NULL || font == NULL)
return 0;
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2592,7 +2586,7 @@ Uint16 FC_GetWidth(FC_Font* font, const char* formatted_text, ...)
if(formatted_text == NULL || font == NULL)
return 0;
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2632,7 +2626,7 @@ FC_Rect FC_GetCharacterOffset(FC_Font* font, Uint16 position_index, int column_w
if(formatted_text == NULL || column_width == 0 || position_index == 0 || font == NULL)
return result;
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2691,7 +2685,7 @@ Uint16 FC_GetColumnHeight(FC_Font* font, Uint16 width, const char* formatted_tex
if(formatted_text == NULL || width == 0)
return font->height;
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2743,7 +2737,7 @@ int FC_GetAscent(FC_Font* font, const char* formatted_text, ...)
if(formatted_text == NULL)
return font->ascent;
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2779,7 +2773,7 @@ int FC_GetDescent(FC_Font* font, const char* formatted_text, ...)
if(formatted_text == NULL)
return font->descent;
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2898,7 +2892,7 @@ Uint16 FC_GetPositionFromOffset(FC_Font* font, float x, float y, int column_widt
if(formatted_text == NULL || column_width == 0 || font == NULL)
return 0;
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);
@ -2946,7 +2940,7 @@ int FC_GetWrappedText(FC_Font* font, char* result, int max_result_size, Uint16 w
if(formatted_text == NULL || width == 0)
return 0;
std::scoped_lock lock(*font->mutex);
std::scoped_lock lock(mutex);
FC_EXTRACT_VARARGS(fc_buffer, formatted_text);