Skip to content
Snippets Groups Projects
Commit 4a150213 authored by David Maul's avatar David Maul :crab:
Browse files

only load font once in main

parent fc8dbffb
No related branches found
No related tags found
No related merge requests found
......@@ -15,7 +15,8 @@
namespace advanced_wars
{
Engine::Engine(Window& window) : m_window(window), m_quit(false), m_unitConfig("../config.xml")
Engine::Engine(Window& window, Font& font)
: m_window(window), m_font(font), m_quit(false), m_unitConfig("../config.xml")
{
this->m_SDLRenderer = SDL_CreateRenderer(
......@@ -130,6 +131,11 @@ SDL_Renderer* Engine::renderer()
return this->m_SDLRenderer;
}
Font& Engine::getFont()
{
return this->m_font;
}
Engine::~Engine()
{
SDL_DestroyRenderer(m_SDLRenderer);
......
#pragma once
#include "Config.hpp"
#include "Font.hpp"
#include "SDL_events.h"
#include "Scene.hpp"
#include "Spritesheet.hpp"
......@@ -24,7 +25,7 @@ class Config;
class Engine
{
public:
Engine(Window& window);
Engine(Window& window, Font& font);
Engine(const Engine&) = delete;
Engine& operator=(const Engine&) = delete;
......@@ -55,6 +56,8 @@ class Engine
SDL_Renderer* renderer();
Font& getFont();
~Engine();
private:
......@@ -63,6 +66,7 @@ class Engine
std::vector<std::shared_ptr<Scene>> m_scenes;
std::optional<Spritesheet*> m_spritesheet;
std::deque<SDL_Event> m_events;
Font& m_font;
bool m_quit;
int m_stage;
......
#include "Font.hpp"
#include "SDL_ttf.h"
#include <stdexcept>
#include <vector>
namespace advanced_wars
{
Font::Font(std::string path) : m_fonts()
{
std::vector<std::pair<FontSize, int>> sizes({
std::pair(FontSize::NORMAL, 16),
std::pair(FontSize::MENU, 24),
std::pair(FontSize::TITLE, 48),
});
for (auto& [fontSize, size] : sizes)
{
TTF_Font* font = TTF_OpenFont(path.c_str(), size);
if (!font)
{
throw std::runtime_error(
"Failed to load font: " + std::string(TTF_GetError()) + " with size " +
std::to_string(size));
}
m_fonts.push_back(std::pair(font, size));
}
}
TTF_Font* Font::getFont(FontSize size)
{
return this->m_fonts.at(static_cast<int>(size)).first;
}
int Font::getSize(FontSize size)
{
return this->m_fonts.at(static_cast<int>(size)).second;
}
Font::~Font()
{
for (auto& [font, size] : this->m_fonts)
{
TTF_CloseFont(font);
}
}
} // namespace advanced_wars
\ No newline at end of file
#pragma once
#include "SDL_ttf.h"
#include <string>
#include <vector>
namespace advanced_wars
{
enum class FontSize
{
NORMAL = 0,
MENU = 1,
TITLE = 2,
};
class Font
{
public:
Font(std::string path);
TTF_Font* getFont(FontSize size);
int getSize(FontSize size);
~Font();
Font(const Font&) = delete;
Font& operator=(const Font&) = delete;
private:
std::vector<std::pair<TTF_Font*, int>> m_fonts;
};
} // namespace advanced_wars
\ No newline at end of file
#include "Engine.hpp"
#include "Font.hpp"
#include "Spritesheet.hpp"
#include "Window.hpp"
#include "ui/Contextmenu.hpp"
......@@ -7,7 +8,6 @@
#include <SDL_image.h>
#include <memory>
#include <stdexcept>
#include <vector>
using namespace advanced_wars;
......@@ -26,9 +26,21 @@ int main()
"SDL_image could not initialize! SDL_image Error: " + std::string(IMG_GetError()));
}
if (TTF_Init() != 0)
{
throw std::runtime_error("Failed to initialize TTF: " + std::string(TTF_GetError()));
}
// We need this extra scope to ensure font ist dropped before TTF_Quit()
{
std::string fontPath =
std::string(SDL_GetBasePath()) + std::string("res/ARCADECLASSIC.TTF");
Font font(fontPath);
Window window("Advanced Wars", 960, 960);
Engine engine(window);
Engine engine(window, font);
Spritesheet spritesheet("res/spritesheet.h5", engine);
......@@ -50,6 +62,12 @@ int main()
engine.pump();
engine.render();
}
}
// Cleanup
TTF_Quit();
IMG_Quit();
SDL_Quit();
return 0;
}
......@@ -18,28 +18,12 @@ void ContextMenu::setOptions(const std::vector<std::string>& newOptions)
void ContextMenu::render(Engine& engine)
{
if (TTF_Init() == -1)
{
std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
return;
}
if (m_options.empty())
{
// TODO handle somehow
return;
}
std::string basePath = SDL_GetBasePath();
std::string relativePath = "res/ARCADECLASSIC.TTF";
std::string fullPath = basePath + relativePath;
TTF_Font* font = TTF_OpenFont(fullPath.c_str(), 16);
if (!font)
{
std::cerr << "Failed to load font: " << TTF_GetError() << std::endl;
return;
}
SDL_Color white = {255, 255, 255, 255};
SDL_Color yellow = {192, 255, 0, 255};
......@@ -54,7 +38,8 @@ void ContextMenu::render(Engine& engine)
for (size_t i = 0; i < m_options.size(); ++i)
{
SDL_Surface* textSurface = TTF_RenderText_Solid(
font, m_options[i].c_str(), (i == m_selectedOption) ? yellow : white);
engine.getFont().getFont(FontSize::NORMAL), m_options[i].c_str(),
(i == m_selectedOption) ? yellow : white);
if (!textSurface)
{
continue;
......@@ -68,9 +53,6 @@ void ContextMenu::render(Engine& engine)
SDL_DestroyTexture(textTexture);
SDL_FreeSurface(textSurface);
}
TTF_CloseFont(font);
TTF_Quit();
}
void ContextMenu::handleEvent(Engine& engine, SDL_Event& event)
......
......@@ -30,11 +30,6 @@ Menu::~Menu()
void Menu::render(Engine& engine)
{
if (TTF_Init() == -1)
{
std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
return;
}
if (m_backgroundTexture)
{
......@@ -46,28 +41,11 @@ void Menu::render(Engine& engine)
SDL_RenderClear(engine.renderer());
}
std::string basePath = SDL_GetBasePath();
std::string relativePath = "res/ARCADECLASSIC.TTF";
std::string fullPath = basePath + relativePath;
TTF_Font* titleFont = TTF_OpenFont(fullPath.c_str(), 48);
if (!titleFont)
{
std::cerr << "Failed to load title font: " << fullPath << TTF_GetError() << std::endl;
return;
}
TTF_Font* menuFont = TTF_OpenFont(fullPath.c_str(), 24);
if (!menuFont)
{
TTF_CloseFont(titleFont);
std::cerr << "Failed to load menu font: " << fullPath << TTF_GetError() << std::endl;
return;
}
SDL_Color white = {255, 255, 255, 255};
SDL_Color yellow = {255, 255, 0, 255};
SDL_Surface* titleSurface = TTF_RenderText_Solid(titleFont, "Advanced Wars", white);
SDL_Surface* titleSurface =
TTF_RenderText_Solid(engine.getFont().getFont(FontSize::TITLE), "Advanced Wars", white);
if (titleSurface)
{
SDL_Texture* titleTexture = SDL_CreateTextureFromSurface(engine.renderer(), titleSurface);
......@@ -81,7 +59,8 @@ void Menu::render(Engine& engine)
for (size_t i = 0; i < m_options.size(); ++i)
{
SDL_Surface* textSurface = TTF_RenderText_Solid(
menuFont, m_options[i].c_str(), (i == m_selectedOption) ? yellow : white);
engine.getFont().getFont(FontSize::MENU), m_options[i].c_str(),
(i == m_selectedOption) ? yellow : white);
if (!textSurface)
{
continue;
......@@ -96,11 +75,6 @@ void Menu::render(Engine& engine)
SDL_DestroyTexture(textTexture);
SDL_FreeSurface(textSurface);
}
TTF_CloseFont(titleFont);
TTF_CloseFont(menuFont);
TTF_Quit();
}
void Menu::handleEvent(Engine& engine, SDL_Event& event)
......
......@@ -9,11 +9,6 @@ PauseMenu::PauseMenu(int selectedOption, SDL_Texture* backgroundTexture)
: m_selectedOption(selectedOption), m_options({"Resume", "Options", "Exit"}),
m_backgroundTexture(backgroundTexture)
{
// Initialize SDL_ttf
if (TTF_Init() == -1)
{
std::cerr << "Failed to initialize SDL_ttf: " << TTF_GetError() << std::endl;
}
if (!m_backgroundTexture)
{
......@@ -28,15 +23,10 @@ PauseMenu::~PauseMenu()
SDL_DestroyTexture(m_backgroundTexture);
m_backgroundTexture = nullptr;
}
TTF_Quit();
}
void PauseMenu::render(Engine& engine)
{
if (TTF_Init() == -1)
{
std::cerr << "Failed to initialize SDL_ttf: " << TTF_GetError() << std::endl;
}
SDL_Renderer* renderer = engine.renderer();
......@@ -49,25 +39,14 @@ void PauseMenu::render(Engine& engine)
SDL_RenderCopy(renderer, m_backgroundTexture, nullptr, nullptr);
}
// Render the dialog options on top of the background
std::string basePath = SDL_GetBasePath();
std::string relativePath = "res/ARCADECLASSIC.TTF";
std::string fullPath = basePath + relativePath;
TTF_Font* font = TTF_OpenFont(fullPath.c_str(), 24);
if (!font)
{
std::cerr << "Failed to load menu font: " << fullPath << " " << TTF_GetError() << std::endl;
return;
}
SDL_Color white = {255, 255, 255, 255};
SDL_Color yellow = {255, 255, 0, 255};
for (size_t i = 0; i < m_options.size(); ++i)
{
SDL_Surface* textSurface = TTF_RenderText_Solid(
font, m_options[i].c_str(), (i == m_selectedOption) ? yellow : white);
engine.getFont().getFont(FontSize::MENU), m_options[i].c_str(),
(i == m_selectedOption) ? yellow : white);
SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
SDL_Rect destRect = {100, static_cast<int>(100 + i * 50), textSurface->w, textSurface->h};
......@@ -76,8 +55,6 @@ void PauseMenu::render(Engine& engine)
SDL_FreeSurface(textSurface);
SDL_DestroyTexture(textTexture);
}
TTF_CloseFont(font);
TTF_Quit();
}
void PauseMenu::handleEvent(Engine& engine, SDL_Event& event)
......
#include "Recruitingmenu.hpp"
#include <iostream>
#include <SDL_ttf.h>
#include <iostream>
namespace advanced_wars
{
RecruitingMenu::RecruitingMenu() : m_selectedOption(0), unitNames({
RecruitingMenu::RecruitingMenu()
: m_selectedOption(0), unitNames({
{ UnitId::INFANTERY, {"Infantry", 100}},
{ UnitId::MECHANIZED_INFANTERY, {"Bazooka", 200}},
{ UnitId::RECON, {"Recon", 300}},
......@@ -24,18 +25,19 @@ namespace advanced_wars
{ UnitId::BATTLE_HELICOPTER, {"Helicopter", 1700}},
{ UnitId::FIGHTER, {"Fighter", 1800}},
{ UnitId::BOMBER, {"Bomber", 1900}}
}) {
})
{
}
void RecruitingMenu::setOptions(const std::vector<UnitId> recruitableUnits) {
void RecruitingMenu::setOptions(const std::vector<UnitId> recruitableUnits)
{
std::vector<std::pair<std::string, int>> options;
for (UnitId id : recruitableUnits) {
for (UnitId id : recruitableUnits)
{
options.push_back(unitNames.at(id));
cost2UnitId.insert(std::make_pair(unitNames.at(id).second, id));
}
m_options = options;
......@@ -47,28 +49,12 @@ namespace advanced_wars
Spritesheet* spritesheet = engine.getSpritesheet();
if (TTF_Init() == -1)
{
std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
return;
}
if (m_options.empty())
{
// TODO handle somehow
return;
}
std::string basePath = SDL_GetBasePath();
std::string relativePath = "res/ARCADECLASSIC.TTF";
std::string fullPath = basePath + relativePath;
TTF_Font* font = TTF_OpenFont(fullPath.c_str(), 16);
if (!font)
{
std::cerr << "Failed to load font: " << TTF_GetError() << std::endl;
return;
}
SDL_Color white = {255, 255, 255, 255};
SDL_Color yellow = {192, 255, 0, 255};
......@@ -84,12 +70,14 @@ namespace advanced_wars
for (auto& [render_name, cost] : m_options)
{
// std::pair<std::string, int> unit_option = unitNames.at(cost2UnitId.at(cost));
if(i == m_selectedOption) {
if (i == m_selectedOption)
{
m_selectedId = cost2UnitId.at(cost);
}
SDL_Surface* textSurface = TTF_RenderText_Solid(
font, render_name.c_str(), (i == m_selectedOption) ? yellow : white);
engine.getFont().getFont(FontSize::NORMAL), render_name.c_str(),
(i == m_selectedOption) ? yellow : white);
if (!textSurface)
{
continue;
......@@ -100,31 +88,21 @@ namespace advanced_wars
m_x + 10 + 16, m_y + static_cast<int>(i * spacing), textSurface->w, textSurface->h};
SDL_RenderCopy(engine.renderer(), textTexture, nullptr, &textRect);
SDL_Texture* unit_texture = spritesheet->getUnitTextures()
.at(static_cast<int>(UnitFaction::URED))
.at(static_cast<int>(cost2UnitId.at(cost)))
.at(static_cast<int>(UnitState::IDLE))
.first;
SDL_Rect trgt_rect = {
m_x + 5,
m_y + static_cast<int>(i * spacing),
16,
16
};
SDL_Rect trgt_rect = {m_x + 5, m_y + static_cast<int>(i * spacing), 16, 16};
SDL_Rect src_rect = {
5,
0,
10,
10
};
SDL_Rect src_rect = {5, 0, 10, 10};
SDL_RenderCopy(engine.renderer(), unit_texture, &src_rect, &trgt_rect);
SDL_Surface* costSurface = TTF_RenderText_Solid(
font, std::to_string(cost).c_str(), (i == m_selectedOption) ? yellow : white);
engine.getFont().getFont(FontSize::NORMAL), std::to_string(cost).c_str(),
(i == m_selectedOption) ? yellow : white);
if (!textSurface)
{
continue;
......@@ -133,11 +111,7 @@ namespace advanced_wars
SDL_Texture* costTexture = SDL_CreateTextureFromSurface(engine.renderer(), costSurface);
SDL_Rect cost_rect{
m_x + 120 ,
m_y + static_cast<int>(i * spacing),
costSurface->w,
costSurface->h
};
m_x + 120, m_y + static_cast<int>(i * spacing), costSurface->w, costSurface->h};
SDL_RenderCopy(engine.renderer(), costTexture, nullptr, &cost_rect);
SDL_DestroyTexture(costTexture);
......@@ -146,9 +120,6 @@ namespace advanced_wars
SDL_FreeSurface(textSurface);
i++;
}
TTF_CloseFont(font);
TTF_Quit();
}
void RecruitingMenu::handleEvent(Engine& engine, SDL_Event& event)
......@@ -172,8 +143,9 @@ void RecruitingMenu::update(int x, int y)
this->m_y = y;
}
UnitId RecruitingMenu::getSelectedOption(){
UnitId RecruitingMenu::getSelectedOption()
{
return m_selectedId;
}
}//namespace advance_wars
\ No newline at end of file
} // namespace advanced_wars
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment