Something went wrong. Try again.
the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
Something went wrong. Try again.
15 kB · 617 lines
C++
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618#include "stdafx.h"#include "Textures.h"#include "Font.h"#include "Options.h"#include "Tesselator.h"#include "ResourceLocation.h"#include "..\Minecraft.World\IntBuffer.h"#include "..\Minecraft.World\net.minecraft.h"#include "..\Minecraft.World\StringHelpers.h"#include "..\Minecraft.World\Random.h"
Font::Font(Options *options, const wstring& name, Textures* textures, bool enforceUnicode, ResourceLocation *textureLocation, int cols, int rows, int charWidth, int charHeight, unsigned short charMap[]/* = nullptr */) : textures(textures){ int charC = cols * rows; // Number of characters in the font
charWidths = new int[charC];
// 4J - added initialisers memset(charWidths, 0, charC);
enforceUnicodeSheet = false; bidirectional = false; xPos = yPos = 0.0f;
// Set up member variables m_cols = cols; m_rows = rows; m_charWidth = charWidth; m_charHeight = charHeight; m_textureLocation = textureLocation;
// Build character map if (charMap != NULL) { for(int i = 0; i < charC; i++) { m_charMap.insert(std::make_pair(charMap[i], i)); } }
random = new Random();
// Load the image BufferedImage *img = textures->readImage(textureLocation->getTexture(), name);
/* - 4J - TODO try { img = ImageIO.read(Textures.class.getResourceAsStream(name)); } catch (IOException e) { throw new RuntimeException(e); } */
int w = img->getWidth(); int h = img->getHeight(); intArray rawPixels(w * h); img->getRGB(0, 0, w, h, rawPixels, 0, w);
for (int i = 0; i < charC; i++) { int xt = i % m_cols; int yt = i / m_cols; int x = 7; for (; x >= 0; x--) { int xPixel = xt * 8 + x; bool emptyColumn = true; for (int y = 0; y < 8 && emptyColumn; y++) { int yPixel = (yt * 8 + y) * w; bool emptyPixel = (rawPixels[xPixel + yPixel] >> 24) == 0; // Check the alpha value if (!emptyPixel) emptyColumn = false; } if (!emptyColumn) { break; } }
if (i == ' ') x = 4 - 2; charWidths[i] = x + 2; }
delete img;
// calculate colors for (int colorN = 0; colorN < 32; ++colorN) { int var10 = (colorN >> 3 & 1) * 85; int red = (colorN >> 2 & 1) * 170 + var10; int green = (colorN >> 1 & 1) * 170 + var10; int blue = (colorN >> 0 & 1) * 170 + var10;
if (colorN == 6) { red += 85; }
if (options->anaglyph3d) { int tmpRed = (red * 30 + green * 59 + blue * 11) / 100; int tmpGreen = (red * 30 + green * 70) / 100; int tmpBlue = (red * 30 + blue * 70) / 100; red = tmpRed; green = tmpGreen; blue = tmpBlue; }
if (colorN >= 16) { red /= 4; green /= 4; blue /= 4; }
colors[colorN] = (red & 255) << 16 | (green & 255) << 8 | (blue & 255); }}
#ifndef _XBOX// 4J Stu - This dtor clashes with one in xui! We never delete these anyway so take it out for now. Can go back when we have got rid of XUIFont::~Font(){ delete[] charWidths;}#endif
void Font::renderCharacter(wchar_t c){ float xOff = c % m_cols * m_charWidth; float yOff = c / m_cols * m_charWidth;
float width = charWidths[c] - .01f; float height = m_charHeight - .01f; float fontWidth = m_cols * m_charWidth; float fontHeight = m_rows * m_charHeight;
Tesselator *t = Tesselator::getInstance(); // 4J Stu - Changed to a quad so that we can use within a command buffer#if 1 t->begin(); t->tex(xOff / fontWidth, (yOff + 7.99f) / fontHeight); t->vertex(xPos, yPos + height, 0.0f);
t->tex((xOff + width) / fontWidth, (yOff + 7.99f) / fontHeight); t->vertex(xPos + width, yPos + height, 0.0f);
t->tex((xOff + width) / fontWidth, yOff / fontHeight); t->vertex(xPos + width, yPos, 0.0f);
t->tex(xOff / fontWidth, yOff / fontHeight); t->vertex(xPos, yPos, 0.0f);
t->end();#else t->begin(GL_TRIANGLE_STRIP); t->tex(xOff / 128.0F, yOff / 128.0F); t->vertex(xPos, yPos, 0.0f); t->tex(xOff / 128.0F, (yOff + 7.99f) / 128.0F); t->vertex(xPos, yPos + 7.99f, 0.0f); t->tex((xOff + width) / 128.0F, yOff / 128.0F); t->vertex(xPos + width, yPos, 0.0f); t->tex((xOff + width) / 128.0F, (yOff + 7.99f) / 128.0F); t->vertex(xPos + width, yPos + 7.99f, 0.0f); t->end();#endif
xPos += (float) charWidths[c];}
void Font::drawShadow(const wstring& str, int x, int y, int color){ draw(str, x + 1, y + 1, color, true); draw(str, x, y, color, false);}
void Font::drawShadowWordWrap(const wstring &str, int x, int y, int w, int color, int h){ drawWordWrapInternal(str, x + 1, y + 1, w, color, true, h); drawWordWrapInternal(str, x, y, w, color, h);}
void Font::draw(const wstring& str, int x, int y, int color){ draw(str, x, y, color, false);}
wstring Font::reorderBidi(const wstring &str){ // 4J Not implemented return str;}
void Font::draw(const wstring &str, bool dropShadow){ // Bind the texture textures->bindTexture(m_textureLocation);
bool noise = false; wstring cleanStr = sanitize(str);
for (int i = 0; i < (int)cleanStr.length(); ++i) { // Map character wchar_t c = cleanStr.at(i);
if (c == 167 && i + 1 < cleanStr.length()) { // 4J - following block was: // int colorN = L"0123456789abcdefk".indexOf(str.toLowerCase().charAt(i + 1)); wchar_t ca = cleanStr[i+1]; int colorN = 16; if(( ca >= L'0' ) && (ca <= L'9')) colorN = ca - L'0'; else if(( ca >= L'a' ) && (ca <= L'f')) colorN = (ca - L'a') + 10; else if(( ca >= L'A' ) && (ca <= L'F')) colorN = (ca - L'A') + 10;
if (colorN == 16) { noise = true; } else { noise = false; if (colorN < 0 || colorN > 15) colorN = 15;
if (dropShadow) colorN += 16;
int color = colors[colorN]; glColor3f((color >> 16) / 255.0F, ((color >> 8) & 255) / 255.0F, (color & 255) / 255.0F); }
i += 1; continue; } // "noise" for crazy splash screen message if (noise) { int newc; do { newc = random->nextInt(SharedConstants::acceptableLetters.length()); } while (charWidths[c + 32] != charWidths[newc + 32]); c = newc; }
renderCharacter(c); }}
void Font::draw(const wstring& str, int x, int y, int color, bool dropShadow){ if (!str.empty()) { if ((color & 0xFC000000) == 0) color |= 0xFF000000; // force alpha // if not set
if (dropShadow) // divide RGB by 4, preserve alpha color = (color & 0xfcfcfc) >> 2 | (color & (-1 << 24));
glColor4f((color >> 16 & 255) / 255.0F, (color >> 8 & 255) / 255.0F, (color & 255) / 255.0F, (color >> 24 & 255) / 255.0F);
xPos = x; yPos = y; draw(str, dropShadow); }}
int Font::width(const wstring& str){ wstring cleanStr = sanitize(str);
if (cleanStr == L"") return 0; // 4J - was NULL comparison int len = 0;
for (int i = 0; i < cleanStr.length(); ++i) { wchar_t c = cleanStr.at(i);
if(c == 167) { // Ignore the character used to define coloured text ++i; } else { len += charWidths[c]; } }
return len;}
wstring Font::sanitize(const wstring& str){ wstring sb = str;
for (unsigned int i = 0; i < sb.length(); i++) { if (CharacterExists(sb[i])) { sb[i] = MapCharacter(sb[i]); } else { // If this character isn't supported, just show the first character (empty square box character) sb[i] = 0; } } return sb;}
int Font::MapCharacter(wchar_t c){ if (!m_charMap.empty()) { // Don't map space character return c == ' ' ? c : m_charMap[c]; } else { return c; }}
bool Font::CharacterExists(wchar_t c){ if (!m_charMap.empty()) { return m_charMap.find(c) != m_charMap.end(); } else { return c >= 0 && c <= m_rows*m_cols; }}
void Font::drawWordWrap(const wstring &string, int x, int y, int w, int col, int h){ //if (bidirectional) //{ // string = reorderBidi(string); //} drawWordWrapInternal(string, x, y, w, col, h);}
void Font::drawWordWrapInternal(const wstring &string, int x, int y, int w, int col, int h){ drawWordWrapInternal(string, x, y, w, col, false, h);}
void Font::drawWordWrap(const wstring &string, int x, int y, int w, int col, bool darken, int h){ //if (bidirectional) //{ // string = reorderBidi(string); //} drawWordWrapInternal(string, x, y, w, col, darken, h);}
void Font::drawWordWrapInternal(const wstring& string, int x, int y, int w, int col, bool darken, int h){ vector<wstring>lines = stringSplit(string,L'\n'); if (lines.size() > 1) { AUTO_VAR(itEnd, lines.end()); for (AUTO_VAR(it, lines.begin()); it != itEnd; it++) { // 4J Stu - Don't draw text that will be partially cutoff/overlap something it shouldn't if( (y + this->wordWrapHeight(*it, w)) > h) break; drawWordWrapInternal(*it, x, y, w, col, h); y += this->wordWrapHeight(*it, w); } return; } vector<wstring> words = stringSplit(string,L' '); unsigned int pos = 0; while (pos < words.size()) { wstring line = words[pos++] + L" "; while (pos < words.size() && width(line + words[pos]) < w) { line += words[pos++] + L" "; } while (width(line) > w) { int l = 0; while (width(line.substr(0, l + 1)) <= w) { l++; } if (trimString(line.substr(0, l)).length() > 0) { draw(line.substr(0, l), x, y, col); y += 8; } line = line.substr(l);
// 4J Stu - Don't draw text that will be partially cutoff/overlap something it shouldn't if( (y + 8) > h) break; } // 4J Stu - Don't draw text that will be partially cutoff/overlap something it shouldn't if (trimString(line).length() > 0 && !( (y + 8) > h) ) { draw(line, x, y, col); y += 8; } }
}
int Font::wordWrapHeight(const wstring& string, int w){ vector<wstring> lines = stringSplit(string,L'\n'); if (lines.size() > 1) { int h = 0; AUTO_VAR(itEnd, lines.end()); for (AUTO_VAR(it, lines.begin()); it != itEnd; it++) { h += this->wordWrapHeight(*it, w); } return h; } vector<wstring> words = stringSplit(string,L' '); unsigned int pos = 0; int y = 0; while (pos < words.size()) { wstring line = words[pos++] + L" "; while (pos < words.size() && width(line + words[pos]) < w) { line += words[pos++] + L" "; } while (width(line) > w) { int l = 0; while (width(line.substr(0, l + 1)) <= w) { l++; } if (trimString(line.substr(0, l)).length() > 0) { y += 8; } line = line.substr(l); } if (trimString(line).length() > 0) { y += 8; } } if (y < 8) y += 8; return y;
}
void Font::setEnforceUnicodeSheet(bool enforceUnicodeSheet){ this->enforceUnicodeSheet = enforceUnicodeSheet;}
void Font::setBidirectional(bool bidirectional){ this->bidirectional = bidirectional;}
bool Font::AllCharactersValid(const wstring &str){ for (int i = 0; i < (int)str.length(); ++i) { wchar_t c = str.at(i);
if (c == 167 && i + 1 < str.length()) { // skip special color setting i += 1; continue; }
int index = SharedConstants::acceptableLetters.find(c);
if ((c != ' ') && !(index > 0 && !enforceUnicodeSheet)) { return false; } } return true;}
// Not in use/*// 4J - this code is lifted from #if 0 section above, so that we can directly create what would have gone in each of our 256 + 32 command buffersvoid Font::renderFakeCB(IntBuffer *ib){ Tesselator *t = Tesselator::getInstance();
int i;
for(unsigned int j = 0; j < ib->limit(); j++) { int cb = ib->get(j);
if( cb < 256 ) { i = cb; t->begin(); int ix = i % 16 * 8; int iy = i / 16 * 8; // float s = 7.99f; float s = 7.99f;
float uo = (0.0f) / 128.0f; float vo = (0.0f) / 128.0f;
t->vertexUV((float)(0), (float)( 0 + s), (float)( 0), (float)( ix / 128.0f + uo), (float)( (iy + s) / 128.0f + vo)); t->vertexUV((float)(0 + s), (float)( 0 + s), (float)( 0), (float)( (ix + s) / 128.0f + uo), (float)( (iy + s) / 128.0f + vo)); t->vertexUV((float)(0 + s), (float)( 0), (float)( 0), (float)( (ix + s) / 128.0f + uo), (float)( iy / 128.0f + vo)); t->vertexUV((float)(0), (float)( 0), (float)( 0), (float)( ix / 128.0f + uo), (float)( iy / 128.0f + vo)); // target.colorBlit(texture, x + xo, y, color, ix, iy, // charWidths[chars[i]], 8); t->end();
glTranslatef((float)charWidths[i], 0, 0); } else { i = cb - 256;
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;
// color = r << 16 | g << 8 | b; if (darken) { r /= 4; g /= 4; b /= 4; } glColor3f(r / 255.0f, g / 255.0f, b / 255.0f); } }}
void Font::loadUnicodePage(int page){ wchar_t fileName[25]; //String fileName = String.format("/1_2_2/font/glyph_%02X.png", page); swprintf(fileName,25,L"/1_2_2/font/glyph_%02X.png",page); BufferedImage *image = new BufferedImage(fileName); //try //{ // image = ImageIO.read(Textures.class.getResourceAsStream(fileName.toString())); //} //catch (IOException e) //{ // throw new RuntimeException(e); //}
unicodeTexID[page] = textures->getTexture(image); lastBoundTexture = unicodeTexID[page];}
void Font::renderUnicodeCharacter(wchar_t c){ if (unicodeWidth[c] == 0) { // System.out.println("no-width char " + c); return; }
int page = c / 256;
if (unicodeTexID[page] == 0) loadUnicodePage(page);
if (lastBoundTexture != unicodeTexID[page]) { glBindTexture(GL_TEXTURE_2D, unicodeTexID[page]); lastBoundTexture = unicodeTexID[page]; }
// first column with non-trans pixels int firstLeft = unicodeWidth[c] >> 4; // last column with non-trans pixels int firstRight = unicodeWidth[c] & 0xF;
float left = firstLeft; float right = firstRight + 1;
float xOff = c % 16 * 16 + left; float yOff = (c & 0xFF) / 16 * 16; float width = right - left - .02f; Tesselator *t = Tesselator::getInstance(); t->begin(GL_TRIANGLE_STRIP); t->tex(xOff / 256.0F, yOff / 256.0F); t->vertex(xPos, yPos, 0.0f); t->tex(xOff / 256.0F, (yOff + 15.98f) / 256.0F); t->vertex(xPos, yPos + 7.99f, 0.0f); t->tex((xOff + width) / 256.0F, yOff / 256.0F); t->vertex(xPos + width / 2, yPos, 0.0f); t->tex((xOff + width) / 256.0F, (yOff + 15.98f) / 256.0F); t->vertex(xPos + width / 2, yPos + 7.99f, 0.0f); t->end();
xPos += (right - left) / 2 + 1;}*/