the whole game

This commit is contained in:
Kolyah35
2026-03-02 22:04:18 +03:00
parent 816e9060b4
commit f0617a5d22
2069 changed files with 581500 additions and 0 deletions

372
src/client/gui/Font.cpp Executable file
View File

@@ -0,0 +1,372 @@
#include "Font.h"
//#include "SharedConstants.h"
#include "../Options.h"
#include "../renderer/Textures.h"
#include "../renderer/Tesselator.h"
#include "../../util/Mth.h"
#include <cstring>
Font::Font( Options* options, const std::string& name, Textures* textures )
: options(options),
fontTexture(0),
fontName(name),
index(0),
count(0),
_textures(textures),
_x(0), _y(0),
_cols(16), _rows(16),
_charOffset(0),
lineHeight(DefaultLineHeight)
{
init(options);
}
//Font::Font( Options* options, const std::string& name, Textures* textures, int imgW, int imgH, int x, int y, int cols, int rows, unsigned char charOffset )
//: options(options),
// fontTexture(0),
// fontName(name),
// index(0),
// count(0),
// _textures(textures),
// _x(x), _y(y),
// _cols(cols), _rows(rows),
// _charOffset(charOffset)
//{
// init(options);
//}
void Font::onGraphicsReset()
{
init(options);
}
void Font::init( Options* options )
{
TextureId fontTexture = _textures->loadTexture(fontName);
const TextureData* tex = _textures->getTemporaryTextureData(fontTexture);
if (!tex)
return;
unsigned char* rawPixels = tex->data;
const int numChars = _rows * _cols;
for (int i = 0; i < numChars; i++) {
int xt = i % _cols;
int yt = i / _cols;
int x = 7;
for (; x >= 0; x--) {
int xPixel = _x + xt * 8 + x;
bool emptyColumn = true;
for (int y = 0; y < 8 && emptyColumn; y++) {
int yPixel = _y + (yt * 8 + y) * tex->w;
unsigned char pixelalpha = rawPixels[(xPixel + yPixel) << 2];
if (pixelalpha > 0) emptyColumn = false;
}
if (!emptyColumn) {
break;
}
}
if (i == ' ') x = 4 - 2;
charWidths[i] = x + 2;
fcharWidths[i] = (float) charWidths[i];
}
#ifdef USE_VBO
return; // this <1
#endif
#ifndef USE_VBO
listPos = glGenLists(256 + 32);
Tesselator& t = Tesselator::instance;
for (int i = 0; i < 256; i++) {
glNewList(listPos + i, GL_COMPILE);
// @attn @huge @note: This is some dangerous code right here / Aron, added ^1
t.begin();
buildChar(i);
t.end(false, -1);
glTranslatef2((GLfloat)charWidths[i], 0.0f, 0.0f);
glEndList();
}
for (int i = 0; i < 32; i++) {
int br = ((i >> 3) & 1) * 0x55;
int r = ((i >> 2) & 1) * 0xaa + br;
int g = ((i >> 1) & 1) * 0xaa + br;
int b = ((i >> 0) & 1) * 0xaa + br;
if (i == 6) {
r += 0x55;
}
bool darken = i >= 16;
if (options->anaglyph3d) {
int cr = (r * 30 + g * 59 + b * 11) / 100;
int cg = (r * 30 + g * 70) / (100);
int cb = (r * 30 + b * 70) / (100);
r = cr;
g = cg;
b = cb;
}
// color = r << 16 | g << 8 | b;
if (darken) {
r /= 4;
g /= 4;
b /= 4;
}
glNewList(listPos + 256 + i, GL_COMPILE);
glColor3f(r / 255.0f, g / 255.0f, b / 255.0f);
glEndList();
}
#endif
}
void Font::drawShadow( const std::string& str, float x, float y, int color )
{
draw(str, x + 1, y + 1, color, true);
draw(str, x, y, color);
}
void Font::drawShadow( const char* str, float x, float y, int color )
{
draw(str, x + 1, y + 1, color, true);
draw(str, x, y, color);
}
void Font::draw( const std::string& str, float x, float y, int color )
{
draw(str, x, y, color, false);
}
void Font::draw( const char* str, float x, float y, int color )
{
draw(str, x, y, color, false);
}
void Font::draw( const char* str, float x, float y, int color, bool darken )
{
#ifdef USE_VBO
drawSlow(str, x, y, color, darken);
#endif
}
void Font::draw( const std::string& str, float x, float y, int color, bool darken )
{
#ifdef USE_VBO
drawSlow(str, x, y, color, darken);
return;
#endif
if (str.empty()) return;
if (darken) {
int oldAlpha = color & 0xff000000;
color = (color & 0xfcfcfc) >> 2;
color += oldAlpha;
}
_textures->loadAndBindTexture(fontName);
float r = ((color >> 16) & 0xff) / 255.0f;
float g = ((color >> 8) & 0xff) / 255.0f;
float b = ((color) & 0xff) / 255.0f;
float a = ((color >> 24) & 0xff) / 255.0f;
if (a == 0) a = 1;
glColor4f2(r, g, b, a);
static const std::string hex("0123456789abcdef");
index = 0;
glPushMatrix2();
glTranslatef2((GLfloat)x, (GLfloat)y, 0.0f);
for (unsigned int i = 0; i < str.length(); i++) {
while (str.length() > i + 1 && str[i] == '<EFBFBD>') {
int cc = hex.find((char)tolower(str[i + 1]));
if (cc < 0 || cc > 15) cc = 15;
lists[index++] = listPos + 256 + cc + (darken ? 16 : 0);
if (index == 1024) {
count = index;
index = 0;
#ifndef USE_VBO
glCallLists(count, GL_UNSIGNED_INT, lists);
#endif
count = 1024;
}
i += 2;
}
if (i < str.length()) {
//int ch = SharedConstants.acceptableLetters.indexOf(str.charAt(i));
char ch = str[i];
if (ch >= 0) {
//ib.put(listPos + ch + 32);
lists[index++] = listPos + ch;
}
}
if (index == 1024) {
count = index;
index = 0;
#ifndef USE_VBO
glCallLists(count, GL_UNSIGNED_INT, lists);
#endif
count = 1024;
}
}
count = index;
index = 0;
#ifndef USE_VBO
glCallLists(count, GL_UNSIGNED_INT, lists);
#endif
glPopMatrix2();
}
int Font::width( const std::string& str )
{
int maxLen = 0;
int len = 0;
for (unsigned int i = 0; i < str.length(); i++) {
if (str[i] == '<EFBFBD>') {
i++;
} else {
//int ch = SharedConstants.acceptableLetters.indexOf(str.charAt(i));
//if (ch >= 0) {
// len += charWidths[ch + 32];
//}
if (str[i] == '\n') {
if (len > maxLen) maxLen = len;
len = 0;
}
else {
int charWidth = charWidths[ (unsigned char) str[i] ];
len += charWidth;
}
}
}
return maxLen>len? maxLen : len;
}
int Font::height( const std::string& str ) {
int h = 0;
bool hasLine = false;
for (unsigned int i = 0; i < str.length(); ++i) {
if (str[i] == '\n') hasLine = true;
else {
if (hasLine) h += lineHeight;
hasLine = false;
}
}
return h;
}
std::string Font::sanitize( const std::string& str )
{
std::string sanitized(str.length() + 1, 0);
int j = 0;
for (unsigned int i = 0; i < str.length(); i++) {
if (str[i] == '<EFBFBD>') {
i++;
//} else if (SharedConstants.acceptableLetters.indexOf(str.charAt(i)) >= 0) {
} else {
sanitized[j++] = str[i];
}
}
return sanitized.erase(j);
}
void Font::drawWordWrap( const std::string& str, float x, float y, float w, int col )
{
char* cstr = new char[str.length() + 1];
strncpy(cstr, str.c_str(), str.length());
cstr[str.length()] = 0;
const char* lims = " \n\t\r";
char* ptok = strtok(cstr, lims);
std::vector<std::string> words;
while (ptok != NULL) {
words.push_back( ptok );
ptok = strtok(NULL, lims);
}
delete[] cstr;
int pos = 0;
while (pos < (int)words.size()) {
std::string line = words[pos++] + " ";
while (pos < (int)words.size() && width(line + words[pos]) < w) {
line += words[pos++] + " ";
}
drawShadow(line, x, y, col);
y += lineHeight;
}
}
void Font::drawSlow( const std::string& str, float x, float y, int color, bool darken /*= false*/ ) {
drawSlow(str.c_str(), x, y, color, darken);
}
void Font::drawSlow( const char* str, float x, float y, int color, bool darken /*= false*/ )
{
if (!str) return;
if (darken) {
int oldAlpha = color & 0xff000000;
color = (color & 0xfcfcfc) >> 2;
color += oldAlpha;
}
_textures->loadAndBindTexture(fontName);
Tesselator& t = Tesselator::instance;
t.begin();
int alpha = (0xff000000 & color) >> 24;
if (!alpha) alpha = 0xff;
t.color((color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, alpha);
t.addOffset((float)x, (float)y, 0);
float xOffset = 0;
float yOffset = 0;
while (unsigned char ch = *(str++)) {
if (ch == '\n') {
xOffset = 0;
yOffset += lineHeight;
} else {
buildChar(ch, xOffset, yOffset);
xOffset += fcharWidths[ch];
}
}
t.draw();
t.addOffset(-(float)x, -(float)y, 0);
}
void Font::buildChar( unsigned char i, float x /*= 0*/, float y /*=0*/ )
{
Tesselator& t = Tesselator::instance;
//i -= _charOffset;
//int ix = (i % _cols) * 8 + _x;
//int iy = (i / _cols) * 8 + _y;
float ix = (float)((i & 15) * 8);
float iy = (float)((i >> 4) * 8);
float s = 7.99f;
float uo = (0.0f) / 128.0f;
float vo = (0.0f) / 128.0f;
t.vertexUV(x, y + s, 0, ix / 128.0f + uo, (iy + s) / 128.0f + vo);
t.vertexUV(x + s, y + s, 0, (ix + s) / 128.0f + uo, (iy + s) / 128.0f + vo);
t.vertexUV(x + s, y, 0, (ix + s) / 128.0f + uo, iy / 128.0f + vo);
t.vertexUV(x, y, 0, ix / 128.0f + uo, iy / 128.0f + vo);
}