mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-29 19:55:37 +00:00
Refactored Font to use a Vertex struct and Vector2.
Fixed InputConfig error messages dumping to console and not logging. Fixed skipped inputs being saved.
This commit is contained in:
parent
023bc44abd
commit
aec15ba0a1
105
src/Font.cpp
105
src/Font.cpp
|
@ -5,6 +5,7 @@
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "Vector2.h"
|
||||||
|
|
||||||
FT_Library Font::sLibrary;
|
FT_Library Font::sLibrary;
|
||||||
bool Font::libraryInitialized = false;
|
bool Font::libraryInitialized = false;
|
||||||
|
@ -199,7 +200,7 @@ void Font::buildAtlas()
|
||||||
if((y + maxHeight) >= textureHeight)
|
if((y + maxHeight) >= textureHeight)
|
||||||
{
|
{
|
||||||
//failed to create a proper font texture
|
//failed to create a proper font texture
|
||||||
LOG(LogError) << "Error - font with size " << mSize << " exceeded texture size! Trying again...";
|
LOG(LogWarning) << "Font with size " << mSize << " exceeded max texture size! Trying again...";
|
||||||
//try a 3/4th smaller size and redo initialization
|
//try a 3/4th smaller size and redo initialization
|
||||||
fontScale *= 1.25f;
|
fontScale *= 1.25f;
|
||||||
mSize = (int)(mSize * (1.0f / fontScale));
|
mSize = (int)(mSize * (1.0f / fontScale));
|
||||||
|
@ -207,10 +208,8 @@ void Font::buildAtlas()
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG(LogInfo) << "Created font with size " << mSize << std::endl;
|
LOG(LogInfo) << "Created font with size " << mSize << ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
//std::cout << "generated texture \"" << textureID << "\" (w: " << w << " h: " << h << ")" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Font::~Font()
|
Font::~Font()
|
||||||
|
@ -220,33 +219,10 @@ Font::~Font()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct Vertex
|
||||||
//why these aren't in an array:
|
{
|
||||||
//openGL reads these in the order they are in memory
|
Vector2<GLfloat> pos;
|
||||||
//if I use an array, it will be 4 x values then 4 y values
|
Vector2<GLfloat> tex;
|
||||||
//it'll read XX, XX, YY instead of XY, XY, XY
|
|
||||||
//...
|
|
||||||
//that was the thinking at the time and honestly an array would have been smarter wow I'm dumb
|
|
||||||
struct point {
|
|
||||||
GLfloat pos0x;
|
|
||||||
GLfloat pos0y;
|
|
||||||
|
|
||||||
GLfloat pos1x;
|
|
||||||
GLfloat pos1y;
|
|
||||||
|
|
||||||
GLfloat pos2x;
|
|
||||||
GLfloat pos2y;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tex {
|
|
||||||
GLfloat tex0x;
|
|
||||||
GLfloat tex0y;
|
|
||||||
|
|
||||||
GLfloat tex1x;
|
|
||||||
GLfloat tex1y;
|
|
||||||
|
|
||||||
GLfloat tex2x;
|
|
||||||
GLfloat tex2y;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void Font::drawText(std::string text, int startx, int starty, int color)
|
void Font::drawText(std::string text, int startx, int starty, int color)
|
||||||
|
@ -257,10 +233,9 @@ void Font::drawText(std::string text, int startx, int starty, int color)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pointCount = text.length() * 2;
|
const int triCount = text.length() * 2;
|
||||||
point* points = new point[pointCount];
|
Vertex* vert = new Vertex[triCount * 3];
|
||||||
tex* texs = new tex[pointCount];
|
GLubyte* colors = new GLubyte[triCount * 3 * 4];
|
||||||
GLubyte* colors = new GLubyte[pointCount * 3 * 4];
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
@ -274,58 +249,51 @@ void Font::drawText(std::string text, int startx, int starty, int color)
|
||||||
float x = (float)startx;
|
float x = (float)startx;
|
||||||
float y = starty + mMaxGlyphHeight * 1.1f * fontScale; //padding (another 0.5% is added to the bottom through the sizeText function)
|
float y = starty + mMaxGlyphHeight * 1.1f * fontScale; //padding (another 0.5% is added to the bottom through the sizeText function)
|
||||||
|
|
||||||
int p = 0;
|
int charNum = 0;
|
||||||
for(int i = 0; p < pointCount; i++, p++)
|
for(int i = 0; i < triCount * 3; i += 6, charNum++)
|
||||||
{
|
{
|
||||||
unsigned char letter = text[i];
|
unsigned char letter = text[charNum];
|
||||||
|
|
||||||
if(letter < 32 || letter >= 128)
|
if(letter < 32 || letter >= 128)
|
||||||
letter = 127; //print [X] if character is not standard ASCII
|
letter = 127; //print [X] if character is not standard ASCII
|
||||||
|
|
||||||
points[p].pos0x = x;
|
//order is bottom left, top right, top left
|
||||||
points[p].pos0y = y + (charData[letter].texH - charData[letter].bearingY) * fontScale;
|
vert[i + 0].pos = Vector2<GLfloat>(x, y + (charData[letter].texH - charData[letter].bearingY) * fontScale);
|
||||||
points[p].pos1x = x + charData[letter].texW * fontScale;
|
vert[i + 1].pos = Vector2<GLfloat>(x + charData[letter].texW * fontScale, y - charData[letter].bearingY * fontScale);
|
||||||
points[p].pos1y = y - charData[letter].bearingY * fontScale;
|
vert[i + 2].pos = Vector2<GLfloat>(x, vert[i + 1].pos.y);
|
||||||
points[p].pos2x = x;
|
|
||||||
points[p].pos2y = points[p].pos1y;
|
|
||||||
|
|
||||||
texs[p].tex0x = charData[letter].texX / tw;
|
Vector2<int> charTexCoord(charData[letter].texX, charData[letter].texY);
|
||||||
texs[p].tex0y = (charData[letter].texY + charData[letter].texH) / th;
|
Vector2<int> charTexSize(charData[letter].texW, charData[letter].texH);
|
||||||
texs[p].tex1x = (charData[letter].texX + charData[letter].texW) / tw;
|
|
||||||
texs[p].tex1y = charData[letter].texY / th;
|
|
||||||
texs[p].tex2x = texs[p].tex0x;
|
|
||||||
texs[p].tex2y = texs[p].tex1y;
|
|
||||||
|
|
||||||
p++;
|
vert[i + 0].tex = Vector2<GLfloat>(charTexCoord.x / tw, (charTexCoord.y + charTexSize.y) / th);
|
||||||
|
vert[i + 1].tex = Vector2<GLfloat>((charTexCoord.x + charTexSize.x) / tw, charTexCoord.y / th);
|
||||||
|
vert[i + 2].tex = Vector2<GLfloat>(vert[i + 0].tex.x, vert[i + 1].tex.y);
|
||||||
|
|
||||||
points[p].pos0x = points[p-1].pos0x;
|
//next triangle (second half of the quad)
|
||||||
points[p].pos0y = points[p-1].pos0y;
|
vert[i + 3].pos = vert[i + 0].pos;
|
||||||
points[p].pos1x = points[p-1].pos1x;
|
vert[i + 4].pos = vert[i + 1].pos;
|
||||||
points[p].pos1y = points[p-1].pos1y;
|
vert[i + 5].pos.x = vert[i + 1].pos.x;
|
||||||
points[p].pos2x = points[p-1].pos1x;
|
vert[i + 5].pos.y = vert[i + 0].pos.y;
|
||||||
points[p].pos2y = points[p-1].pos0y;
|
|
||||||
|
|
||||||
texs[p].tex0x = texs[p-1].tex0x;
|
vert[i + 3].tex = vert[i + 0].tex;
|
||||||
texs[p].tex0y = texs[p-1].tex0y;
|
vert[i + 4].tex = vert[i + 1].tex;
|
||||||
texs[p].tex1x = texs[p-1].tex1x;
|
vert[i + 5].tex.x = vert[i + 1].tex.x;
|
||||||
texs[p].tex1y = texs[p-1].tex1y;
|
vert[i + 5].tex.y = vert[i + 0].tex.y;
|
||||||
texs[p].tex2x = texs[p-1].tex1x;
|
|
||||||
texs[p].tex2y = texs[p-1].tex0y;
|
|
||||||
|
|
||||||
x += charData[letter].advX * fontScale;
|
x += charData[letter].advX * fontScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::buildGLColorArray(colors, color, pointCount * 3);
|
Renderer::buildGLColorArray(colors, color, triCount * 3);
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
glVertexPointer(2, GL_FLOAT, 0, points);
|
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &vert[0].pos);
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, texs);
|
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vert[0].tex);
|
||||||
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
|
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, pointCount * 3);
|
glDrawArrays(GL_TRIANGLES, 0, triCount * 3);
|
||||||
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
@ -334,8 +302,7 @@ void Font::drawText(std::string text, int startx, int starty, int color)
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
delete[] points;
|
delete[] vert;
|
||||||
delete[] texs;
|
|
||||||
delete[] colors;
|
delete[] colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
//some util functions
|
//some util functions
|
||||||
std::string inputTypeToString(InputType type)
|
std::string inputTypeToString(InputType type)
|
||||||
|
@ -138,7 +139,7 @@ void InputConfig::loadFromXML(pugi::xml_node node, int playerNum)
|
||||||
|
|
||||||
if(typeEnum == TYPE_COUNT)
|
if(typeEnum == TYPE_COUNT)
|
||||||
{
|
{
|
||||||
std::cout << "ERROR - input type \"" << type << "\" is invalid! Skipping input \"" << name << "\".\n";
|
LOG(LogError) << "InputConfig load error - input of type \"" << type << "\" is invalid! Skipping input \"" << name << "\".\n";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +147,7 @@ void InputConfig::loadFromXML(pugi::xml_node node, int playerNum)
|
||||||
int value = input.attribute("value").as_int();
|
int value = input.attribute("value").as_int();
|
||||||
|
|
||||||
if(value == 0)
|
if(value == 0)
|
||||||
std::cout << "WARNING: InputConfig value is 0 for " << type << " " << id << "!\n";
|
LOG(LogWarning) << "WARNING: InputConfig value is 0 for " << type << " " << id << "!\n";
|
||||||
|
|
||||||
mNameMap[toLower(name)] = Input(mDeviceId, typeEnum, id, value, true);
|
mNameMap[toLower(name)] = Input(mDeviceId, typeEnum, id, value, true);
|
||||||
}
|
}
|
||||||
|
@ -167,6 +168,9 @@ void InputConfig::writeToXML(pugi::xml_node parent)
|
||||||
typedef std::map<std::string, Input>::iterator it_type;
|
typedef std::map<std::string, Input>::iterator it_type;
|
||||||
for(it_type iterator = mNameMap.begin(); iterator != mNameMap.end(); iterator++)
|
for(it_type iterator = mNameMap.begin(); iterator != mNameMap.end(); iterator++)
|
||||||
{
|
{
|
||||||
|
if(!iterator->second.configured)
|
||||||
|
continue;
|
||||||
|
|
||||||
pugi::xml_node input = cfg.append_child("input");
|
pugi::xml_node input = cfg.append_child("input");
|
||||||
input.append_attribute("name") = iterator->first.c_str();
|
input.append_attribute("name") = iterator->first.c_str();
|
||||||
input.append_attribute("type") = inputTypeToString(iterator->second.type).c_str();
|
input.append_attribute("type") = inputTypeToString(iterator->second.type).c_str();
|
||||||
|
|
|
@ -101,7 +101,7 @@ void GuiInputConfig::render()
|
||||||
if(Renderer::getScreenWidth() / 2.5f > textWidth)
|
if(Renderer::getScreenWidth() / 2.5f > textWidth)
|
||||||
textWidth = (int)(Renderer::getScreenWidth() / 2.5f);
|
textWidth = (int)(Renderer::getScreenWidth() / 2.5f);
|
||||||
|
|
||||||
Renderer::drawText("press A to skip", textWidth, y, 0x0000AAFF, font);
|
Renderer::drawText("press Accept to skip", textWidth, y, 0x0000AAFF, font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue