Text:add and Text:addf now return index numbers which can be used as arguments to Text:getWidth and text:getHeight to determine the (pre-transformed) width and height of specific text within the Text object.

This commit is contained in:
Alex Szpakowski
2015-11-14 18:51:43 -04:00
parent 1d6cde226d
commit e9c75c342e
7 changed files with 89 additions and 56 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ Released: N/A
* Added love.math.compress and love.math.decompress. * Added love.math.compress and love.math.decompress.
* Added Channel:performAtomic. * Added Channel:performAtomic.
* Changed love.mousepressed], love.mousereleased, and love.mouse.isDown to use button numbers instead of named button constants. * Changed love.mousepressed, love.mousereleased, and love.mouse.isDown to use button numbers instead of named button constants.
* Changed love.keypressed to be love.keypressed(key, scancode, isrepeat). * Changed love.keypressed to be love.keypressed(key, scancode, isrepeat).
* Changed love.keyreleased to be love.keyreleased(key, scancode). * Changed love.keyreleased to be love.keyreleased(key, scancode).
* Changed Font:getWrap's second return value to be a table containing the text split into lines. * Changed Font:getWrap's second return value to be a table containing the text split into lines.
@@ -17,6 +17,7 @@
A9D307F2106635D3004FEDF8 /* physfs.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9D307E9106635C3004FEDF8 /* physfs.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; A9D307F2106635D3004FEDF8 /* physfs.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9D307E9106635C3004FEDF8 /* physfs.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
A9F169AC109E825000FC83D1 /* mpg123.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F169A6109E824900FC83D1 /* mpg123.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; A9F169AC109E825000FC83D1 /* mpg123.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F169A6109E824900FC83D1 /* mpg123.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F16926109E7BAD00FC83D1 /* libmodplug.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F16926109E7BAD00FC83D1 /* libmodplug.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
FA0797991BF480A200034B7C /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA0797981BF480A200034B7C /* GameController.framework */; };
FA08F69616C766E000F007B5 /* love.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; }; FA08F69616C766E000F007B5 /* love.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; };
FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
FA0B78D21A95814A000E1D17 /* love.icns in Resources */ = {isa = PBXBuildFile; fileRef = FA0B78D01A95814A000E1D17 /* love.icns */; }; FA0B78D21A95814A000E1D17 /* love.icns in Resources */ = {isa = PBXBuildFile; fileRef = FA0B78D01A95814A000E1D17 /* love.icns */; };
@@ -107,6 +108,7 @@
A9D307E9106635C3004FEDF8 /* physfs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = physfs.framework; path = /Library/Frameworks/physfs.framework; sourceTree = "<absolute>"; }; A9D307E9106635C3004FEDF8 /* physfs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = physfs.framework; path = /Library/Frameworks/physfs.framework; sourceTree = "<absolute>"; };
A9F16926109E7BAD00FC83D1 /* libmodplug.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libmodplug.framework; path = /Library/Frameworks/libmodplug.framework; sourceTree = "<absolute>"; }; A9F16926109E7BAD00FC83D1 /* libmodplug.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libmodplug.framework; path = /Library/Frameworks/libmodplug.framework; sourceTree = "<absolute>"; };
A9F169A6109E824900FC83D1 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = "<absolute>"; }; A9F169A6109E824900FC83D1 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = "<absolute>"; };
FA0797981BF480A200034B7C /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.1.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; };
FA08F69116C765A200F007B5 /* love.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FA08F69116C765A200F007B5 /* love.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; };
FA0B78D01A95814A000E1D17 /* love.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = love.icns; path = macosx/love.icns; sourceTree = "<group>"; }; FA0B78D01A95814A000E1D17 /* love.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = love.icns; path = macosx/love.icns; sourceTree = "<group>"; };
FA0B78D11A95814A000E1D17 /* lovedocument.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = lovedocument.icns; path = macosx/lovedocument.icns; sourceTree = "<group>"; }; FA0B78D11A95814A000E1D17 /* lovedocument.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = lovedocument.icns; path = macosx/lovedocument.icns; sourceTree = "<group>"; };
@@ -148,6 +150,7 @@
FA5D24D11A96E73300C6FC8F /* liblove.a in Frameworks */, FA5D24D11A96E73300C6FC8F /* liblove.a in Frameworks */,
FA5D24C21A96D78000C6FC8F /* Foundation.framework in Frameworks */, FA5D24C21A96D78000C6FC8F /* Foundation.framework in Frameworks */,
FA5D24961A96CAC200C6FC8F /* CoreMotion.framework in Frameworks */, FA5D24961A96CAC200C6FC8F /* CoreMotion.framework in Frameworks */,
FA0797991BF480A200034B7C /* GameController.framework in Frameworks */,
FA5D24941A96CABA00C6FC8F /* libz.dylib in Frameworks */, FA5D24941A96CABA00C6FC8F /* libz.dylib in Frameworks */,
FA5D248E1A96CAA700C6FC8F /* CoreGraphics.framework in Frameworks */, FA5D248E1A96CAA700C6FC8F /* CoreGraphics.framework in Frameworks */,
FA5D248C1A96CA9E00C6FC8F /* QuartzCore.framework in Frameworks */, FA5D248C1A96CA9E00C6FC8F /* QuartzCore.framework in Frameworks */,
@@ -243,6 +246,7 @@
FA5D24801A96C97900C6FC8F /* ios */ = { FA5D24801A96C97900C6FC8F /* ios */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FA0797981BF480A200034B7C /* GameController.framework */,
FA5D24C11A96D78000C6FC8F /* Foundation.framework */, FA5D24C11A96D78000C6FC8F /* Foundation.framework */,
FA5D24891A96CA9600C6FC8F /* AudioToolbox.framework */, FA5D24891A96CA9600C6FC8F /* AudioToolbox.framework */,
FA5D248D1A96CAA700C6FC8F /* CoreGraphics.framework */, FA5D248D1A96CAA700C6FC8F /* CoreGraphics.framework */,
+27 -14
View File
@@ -33,7 +33,6 @@ namespace opengl
Text::Text(Font *font, const std::vector<Font::ColoredString> &text) Text::Text(Font *font, const std::vector<Font::ColoredString> &text)
: font(font) : font(font)
, vbo(nullptr) , vbo(nullptr)
, text_info()
, vert_offset(0) , vert_offset(0)
, texture_cache_id((uint32) -1) , texture_cache_id((uint32) -1)
{ {
@@ -82,7 +81,7 @@ void Text::uploadVertices(const std::vector<Font::GlyphVertex> &vertices, size_t
vbo = new_vbo; vbo = new_vbo;
} }
if (vbo != nullptr) if (vbo != nullptr && datasize > 0)
{ {
GLBuffer::Bind bind(*vbo); GLBuffer::Bind bind(*vbo);
vbodata = (uint8 *) vbo->map(); vbodata = (uint8 *) vbo->map();
@@ -113,6 +112,8 @@ void Text::addTextData(const TextData &t)
std::vector<Font::GlyphVertex> vertices; std::vector<Font::GlyphVertex> vertices;
std::vector<Font::DrawCommand> new_commands; std::vector<Font::DrawCommand> new_commands;
Font::TextInfo text_info;
// We only have formatted text if the align mode is valid. // We only have formatted text if the align mode is valid.
if (t.align == Font::ALIGN_MAX_ENUM) if (t.align == Font::ALIGN_MAX_ENUM)
new_commands = font->generateVertices(t.codepoints, vertices, 0.0f, Vector(0.0f, 0.0f), &text_info); new_commands = font->generateVertices(t.codepoints, vertices, 0.0f, Vector(0.0f, 0.0f), &text_info);
@@ -158,7 +159,9 @@ void Text::addTextData(const TextData &t)
} }
vert_offset = voffset + vertices.size(); vert_offset = voffset + vertices.size();
text_data.push_back(t); text_data.push_back(t);
text_data.back().text_info = text_info;
// Font::generateVertices can invalidate the font's texture cache. // Font::generateVertices can invalidate the font's texture cache.
if (font->getTextureCacheID() != texture_cache_id) if (font->getTextureCacheID() != texture_cache_id)
@@ -178,7 +181,7 @@ void Text::set(const std::vector<Font::ColoredString> &text, float wrap, Font::A
Font::ColoredCodepoints codepoints; Font::ColoredCodepoints codepoints;
Font::getCodepointsFromString(text, codepoints); Font::getCodepointsFromString(text, codepoints);
addTextData({codepoints, wrap, align, false, false, Matrix3()}); addTextData({codepoints, wrap, align, {}, false, false, Matrix3()});
} }
void Text::set() void Text::set()
@@ -186,22 +189,21 @@ void Text::set()
clear(); clear();
} }
void Text::add(const std::vector<Font::ColoredString> &text, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) int Text::add(const std::vector<Font::ColoredString> &text, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
{ {
return addf(text, -1.0f, Font::ALIGN_MAX_ENUM, x, y, angle, sx, sy, ox, oy, kx, ky); return addf(text, -1.0f, Font::ALIGN_MAX_ENUM, x, y, angle, sx, sy, ox, oy, kx, ky);
} }
void Text::addf(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) int Text::addf(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
{ {
if (text.empty() || (text.size() == 1 && text[0].str.empty()))
return;
Font::ColoredCodepoints codepoints; Font::ColoredCodepoints codepoints;
Font::getCodepointsFromString(text, codepoints); Font::getCodepointsFromString(text, codepoints);
Matrix3 m(x, y, angle, sx, sy, ox, oy, kx, ky); Matrix3 m(x, y, angle, sx, sy, ox, oy, kx, ky);
addTextData({codepoints, wrap, align, true, true, m}); addTextData({codepoints, wrap, align, {}, true, true, m});
return (int) text_data.size() - 1;
} }
void Text::clear() void Text::clear()
@@ -209,7 +211,6 @@ void Text::clear()
text_data.clear(); text_data.clear();
draw_commands.clear(); draw_commands.clear();
texture_cache_id = font->getTextureCacheID(); texture_cache_id = font->getTextureCacheID();
text_info = {};
vert_offset = 0; vert_offset = 0;
} }
@@ -262,14 +263,26 @@ Font *Text::getFont() const
return font.get(); return font.get();
} }
int Text::getWidth() const int Text::getWidth(int index) const
{ {
return text_info.width; if (index < 0)
index = std::max((int) text_data.size() - 1, 0);
if (index >= (int) text_data.size())
return 0;
return text_data[index].text_info.width;
} }
int Text::getHeight() const int Text::getHeight(int index) const
{ {
return text_info.height; if (index < 0)
index = std::max((int) text_data.size() - 1, 0);
if (index >= (int) text_data.size())
return 0;
return text_data[index].text_info.height;
} }
} // opengl } // opengl
+5 -5
View File
@@ -45,8 +45,8 @@ public:
void set(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align); void set(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align);
void set(); void set();
void add(const std::vector<Font::ColoredString> &text, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky); int add(const std::vector<Font::ColoredString> &text, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
void addf(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky); int addf(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
void clear(); void clear();
// Implements Drawable. // Implements Drawable.
@@ -58,12 +58,12 @@ public:
/** /**
* Gets the width of the currently set text. * Gets the width of the currently set text.
**/ **/
int getWidth() const; int getWidth(int index = 0) const;
/** /**
* Gets the height of the currently set text. * Gets the height of the currently set text.
**/ **/
int getHeight() const; int getHeight(int index = 0) const;
private: private:
@@ -72,6 +72,7 @@ private:
Font::ColoredCodepoints codepoints; Font::ColoredCodepoints codepoints;
float wrap; float wrap;
Font::AlignMode align; Font::AlignMode align;
Font::TextInfo text_info;
bool use_matrix; bool use_matrix;
bool append_vertices; bool append_vertices;
Matrix3 matrix; Matrix3 matrix;
@@ -87,7 +88,6 @@ private:
std::vector<Font::DrawCommand> draw_commands; std::vector<Font::DrawCommand> draw_commands;
std::vector<TextData> text_data; std::vector<TextData> text_data;
Font::TextInfo text_info;
size_t vert_offset; size_t vert_offset;
+14 -6
View File
@@ -144,8 +144,11 @@ int w_Text_add(lua_State *L)
float kx = (float) luaL_optnumber(L, 10, 0.0); float kx = (float) luaL_optnumber(L, 10, 0.0);
float ky = (float) luaL_optnumber(L, 11, 0.0); float ky = (float) luaL_optnumber(L, 11, 0.0);
luax_catchexcept(L, [&](){ t->add(text, x, y, a, sx, sy, ox, oy, kx, ky); }); int index = 0;
return 0; luax_catchexcept(L, [&](){ index = t->add(text, x, y, a, sx, sy, ox, oy, kx, ky); });
lua_pushnumber(L, index + 1);
return 1;
} }
int w_Text_addf(lua_State *L) int w_Text_addf(lua_State *L)
@@ -173,8 +176,11 @@ int w_Text_addf(lua_State *L)
float kx = (float) luaL_optnumber(L, 12, 0.0); float kx = (float) luaL_optnumber(L, 12, 0.0);
float ky = (float) luaL_optnumber(L, 13, 0.0); float ky = (float) luaL_optnumber(L, 13, 0.0);
luax_catchexcept(L, [&](){ t->addf(text, wrap, align, x, y, a, sx, sy, ox, oy, kx, ky); }); int index = 0;
return 0; luax_catchexcept(L, [&](){ index = t->addf(text, wrap, align, x, y, a, sx, sy, ox, oy, kx, ky); });
lua_pushnumber(L, index + 1);
return 1;
} }
int w_Text_clear(lua_State *L) int w_Text_clear(lua_State *L)
@@ -203,14 +209,16 @@ int w_Text_getFont(lua_State *L)
int w_Text_getWidth(lua_State *L) int w_Text_getWidth(lua_State *L)
{ {
Text *t = luax_checktext(L, 1); Text *t = luax_checktext(L, 1);
lua_pushnumber(L, t->getWidth()); int index = (int) luaL_optnumber(L, 2, 0) - 1;
lua_pushnumber(L, t->getWidth(index));
return 1; return 1;
} }
int w_Text_getHeight(lua_State *L) int w_Text_getHeight(lua_State *L)
{ {
Text *t = luax_checktext(L, 1); Text *t = luax_checktext(L, 1);
lua_pushnumber(L, t->getHeight()); int index = (int) luaL_optnumber(L, 2, 0) - 1;
lua_pushnumber(L, t->getHeight(index));
return 1; return 1;
} }
+8 -6
View File
@@ -761,11 +761,13 @@ function love.nogame()
return COLORS[love.math.random(1, #COLORS)] return COLORS[love.math.random(1, #COLORS)]
end end
-- When using the higher-resolution mosaic sprite sheet we want to draw -- When using the higher-res mosaic sprite sheet, we want to draw its
-- its sprites at the same scale as the regular-resolution one. -- sprites at the same scale as the regular-resolution one, because
-- We can avoid a lot of scaling by taking advantage of the fact that -- we'll globally love.graphics.scale *everything* by the screen's
-- Quads use normalized texture coordinates internally - if we use the -- pixel density ratio.
-- 'source image size' and quad size of the @1x image for the Quads -- We can avoid a lot of Quad scaling by taking advantage of the fact
-- that Quads use normalized texture coordinates internally - if we use
-- the 'source image size' and quad size of the @1x image for the Quads
-- even when rendering them using the @2x image, it will automatically -- even when rendering them using the @2x image, it will automatically
-- scale as expected. -- scale as expected.
local QUADS = { local QUADS = {
@@ -889,7 +891,7 @@ function love.nogame()
love.graphics.setBackgroundColor(136, 193, 206) love.graphics.setBackgroundColor(136, 193, 206)
local function load_image(file, name) local function load_image(file, name)
return love.graphics.newImage(love.image.newImageData(love.filesystem.newFileData(file, name:gsub("_", "."), "base64"))) return love.graphics.newImage(love.filesystem.newFileData(file, name:gsub("_", "."), "base64"))
end end
g_images = {} g_images = {}
+30 -24
View File
@@ -3187,26 +3187,33 @@ const unsigned char nogame_lua[] =
0x20, 0x23, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x53, 0x29, 0x5d, 0x0a, 0x20, 0x23, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x53, 0x29, 0x5d, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68,
0x65, 0x20, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x65, 0x20, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72, 0x2d, 0x72, 0x65, 0x73, 0x20, 0x6d, 0x6f, 0x73, 0x61, 0x69,
0x6e, 0x20, 0x6d, 0x6f, 0x73, 0x61, 0x69, 0x63, 0x20, 0x73, 0x70, 0x72, 0x69, 0x74, 0x65, 0x20, 0x73, 0x68, 0x63, 0x20, 0x73, 0x70, 0x72, 0x69, 0x74, 0x65, 0x20, 0x73, 0x68, 0x65, 0x65, 0x74, 0x2c, 0x20, 0x77, 0x65,
0x65, 0x65, 0x74, 0x20, 0x77, 0x65, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x72, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x72, 0x61, 0x77, 0x20, 0x69, 0x74, 0x73, 0x0a,
0x77, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x73, 0x70, 0x72, 0x69, 0x74, 0x65, 0x73, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68,
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x69, 0x74, 0x73, 0x20, 0x73, 0x70, 0x72, 0x69, 0x74, 0x65, 0x73, 0x20, 0x61, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68,
0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x61, 0x65, 0x20, 0x72, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69,
0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x2c, 0x20, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x0a,
0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x2e, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x77, 0x65, 0x27, 0x6c, 0x6c, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x6c,
0x79, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x63,
0x61, 0x6c, 0x65, 0x20, 0x2a, 0x65, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x2a, 0x20, 0x62,
0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x27, 0x73, 0x0a,
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x64, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79,
0x20, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x2e, 0x0a,
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x57, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x57, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x20,
0x61, 0x20, 0x6c, 0x6f, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x61, 0x20, 0x6c, 0x6f, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x51, 0x75, 0x61, 0x64, 0x20, 0x73, 0x63, 0x61, 0x6c,
0x79, 0x20, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x79, 0x20, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x64, 0x76, 0x61,
0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x61, 0x63, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 0x0a, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x61, 0x63, 0x74, 0x0a,
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x51, 0x75, 0x61, 0x64, 0x73, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x51, 0x75, 0x61, 0x64, 0x73, 0x20, 0x75, 0x73,
0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75,
0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x72, 0x65, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x74,
0x6c, 0x79, 0x20, 0x2d, 0x20, 0x69, 0x66, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x2d, 0x20, 0x69, 0x66, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73,
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x27, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x65, 0x20, 0x0a,
0x20, 0x73, 0x69, 0x7a, 0x65, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x71, 0x75, 0x61, 0x64, 0x20, 0x73, 0x69, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x69,
0x7a, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x40, 0x31, 0x78, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x71, 0x75, 0x61,
0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x51, 0x75, 0x61, 0x64, 0x73, 0x0a, 0x64, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x40, 0x31, 0x78, 0x20,
0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x51, 0x75, 0x61, 0x64,
0x73, 0x0a,
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x6e, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x6e,
0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20,
0x74, 0x68, 0x65, 0x20, 0x40, 0x32, 0x78, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x40, 0x32, 0x78, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20,
@@ -3463,11 +3470,10 @@ const unsigned char nogame_lua[] =
0x6d, 0x65, 0x29, 0x0a, 0x6d, 0x65, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61,
0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x6c, 0x6f, 0x76, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x6c, 0x6f, 0x76,
0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x6e, 0x65, 0x77, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x44, 0x61, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x46, 0x69,
0x74, 0x61, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x28, 0x66, 0x69, 0x6c, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a,
0x2e, 0x6e, 0x65, 0x77, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x28, 0x66, 0x69, 0x6c, 0x65, 0x2c, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5f, 0x22, 0x2c, 0x20, 0x22, 0x2e, 0x22, 0x29, 0x2c, 0x20, 0x22, 0x62,
0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5f, 0x22, 0x2c, 0x20, 0x22, 0x2e, 0x61, 0x73, 0x65, 0x36, 0x34, 0x22, 0x29, 0x29, 0x0a,
0x22, 0x29, 0x2c, 0x20, 0x22, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x22, 0x29, 0x29, 0x29, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x67, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x09, 0x09, 0x67, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a,
0x09, 0x09, 0x67, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x74, 0x6f, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x09, 0x09, 0x67, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x74, 0x6f, 0x61, 0x73, 0x74, 0x20, 0x3d,