mirror of
https://github.com/love2d/love.git
synced 2026-08-19 20:19:42 +02:00
Internally compose and pass an array of shader source codes to OpenGL, instead of relying on #line to make sure the line number is correct for shader error messages (resolves issue #882)
This commit is contained in:
@@ -544,9 +544,9 @@ Canvas *Graphics::newCanvas(int width, int height, Texture::Format format, int f
|
|||||||
return NULL; // never reached
|
return NULL; // never reached
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader *Graphics::newShader(const Shader::ShaderSources &sources)
|
Shader *Graphics::newShader(const std::vector<std::string> &vertcode, const std::vector<std::string> &pixelcode)
|
||||||
{
|
{
|
||||||
return new Shader(sources);
|
return new Shader(vertcode, pixelcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh *Graphics::newMesh(const std::vector<Vertex> &vertices, Mesh::DrawMode mode)
|
Mesh *Graphics::newMesh(const std::vector<Vertex> &vertices, Mesh::DrawMode mode)
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ public:
|
|||||||
|
|
||||||
Canvas *newCanvas(int width, int height, Texture::Format format = Texture::FORMAT_NORMAL, int fsaa = 0);
|
Canvas *newCanvas(int width, int height, Texture::Format format = Texture::FORMAT_NORMAL, int fsaa = 0);
|
||||||
|
|
||||||
Shader *newShader(const Shader::ShaderSources &sources);
|
Shader *newShader(const std::vector<std::string> &vertcode, const std::vector<std::string> &pixelcode);
|
||||||
|
|
||||||
Mesh *newMesh(const std::vector<Vertex> &vertices, Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN);
|
Mesh *newMesh(const std::vector<Vertex> &vertices, Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN);
|
||||||
Mesh *newMesh(int vertexcount, Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN);
|
Mesh *newMesh(int vertexcount, Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN);
|
||||||
|
|||||||
@@ -66,21 +66,25 @@ Shader *Shader::current = nullptr;
|
|||||||
GLint Shader::maxTexUnits = 0;
|
GLint Shader::maxTexUnits = 0;
|
||||||
std::vector<int> Shader::textureCounters;
|
std::vector<int> Shader::textureCounters;
|
||||||
|
|
||||||
Shader::Shader(const ShaderSources &sources)
|
Shader::Shader(const std::vector<std::string> &vertcode, const std::vector<std::string> &pixelcode)
|
||||||
: shaderSources(sources)
|
: program(0)
|
||||||
, program(0)
|
|
||||||
, builtinUniforms()
|
, builtinUniforms()
|
||||||
, vertexAttributes()
|
, vertexAttributes()
|
||||||
, lastCanvas((Canvas *) -1)
|
, lastCanvas((Canvas *) -1)
|
||||||
, lastViewport()
|
, lastViewport()
|
||||||
{
|
{
|
||||||
if (shaderSources.empty())
|
if (vertcode.empty() && pixelcode.empty())
|
||||||
throw love::Exception("Cannot create shader: no source code!");
|
throw love::Exception("Cannot create shader: no source code!");
|
||||||
|
|
||||||
|
shaderSources[TYPE_VERTEX] = vertcode;
|
||||||
|
shaderSources[TYPE_PIXEL] = pixelcode;
|
||||||
|
|
||||||
if (maxTexUnits <= 0)
|
if (maxTexUnits <= 0)
|
||||||
{
|
{
|
||||||
GLint maxtexunits;
|
GLint maxtexunits;
|
||||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxtexunits);
|
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxtexunits);
|
||||||
|
|
||||||
|
// TU 0 is never used for stored Shader images.
|
||||||
maxTexUnits = std::max(maxtexunits - 1, 0);
|
maxTexUnits = std::max(maxtexunits - 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +110,7 @@ Shader::~Shader()
|
|||||||
unloadVolatile();
|
unloadVolatile();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint Shader::compileCode(ShaderType type, const std::string &code)
|
GLuint Shader::compileCode(ShaderType type, const std::vector<std::string> &code)
|
||||||
{
|
{
|
||||||
GLenum glshadertype;
|
GLenum glshadertype;
|
||||||
const char *typestr;
|
const char *typestr;
|
||||||
@@ -142,9 +146,18 @@ GLuint Shader::compileCode(ShaderType type, const std::string &code)
|
|||||||
throw love::Exception("Cannot create %s shader object.", typestr);
|
throw love::Exception("Cannot create %s shader object.", typestr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *src = code.c_str();
|
std::vector<const GLchar *> codelist;
|
||||||
size_t srclen = code.length();
|
std::vector<GLint> lengthlist;
|
||||||
glShaderSource(shaderid, 1, (const GLchar **)&src, (GLint *)&srclen);
|
|
||||||
|
for (size_t i = 0; i < code.size(); i++)
|
||||||
|
{
|
||||||
|
codelist.push_back((const GLchar *) code[i].c_str());
|
||||||
|
lengthlist.push_back((GLint) code[i].length());
|
||||||
|
}
|
||||||
|
|
||||||
|
// The code parameter is a list of source code "files." We can hand them
|
||||||
|
// all to OpenGL at once using glShaderSource.
|
||||||
|
glShaderSource(shaderid, codelist.size(), &codelist[0], &lengthlist[0]);
|
||||||
|
|
||||||
glCompileShader(shaderid);
|
glCompileShader(shaderid);
|
||||||
|
|
||||||
@@ -276,10 +289,12 @@ bool Shader::loadVolatile()
|
|||||||
|
|
||||||
std::vector<GLuint> shaderids;
|
std::vector<GLuint> shaderids;
|
||||||
|
|
||||||
ShaderSources::const_iterator source;
|
for (int i = 0; i < (int) TYPE_MAX_ENUM; i++)
|
||||||
for (source = shaderSources.begin(); source != shaderSources.end(); ++source)
|
|
||||||
{
|
{
|
||||||
GLuint shaderid = compileCode(source->first, source->second);
|
if (shaderSources[i].empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
GLuint shaderid = compileCode((ShaderType) i, shaderSources[i]);
|
||||||
shaderids.push_back(shaderid);
|
shaderids.push_back(shaderid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +303,7 @@ bool Shader::loadVolatile()
|
|||||||
|
|
||||||
createProgram(shaderids);
|
createProgram(shaderids);
|
||||||
|
|
||||||
// Retreive all active uniform variables in this shader from OpenGL.
|
// Get all active uniform variables in this shader from OpenGL.
|
||||||
mapActiveUniforms();
|
mapActiveUniforms();
|
||||||
|
|
||||||
for (int i = 0; i < int(OpenGL::ATTRIB_MAX_ENUM); i++)
|
for (int i = 0; i < int(OpenGL::ATTRIB_MAX_ENUM); i++)
|
||||||
|
|||||||
@@ -74,14 +74,11 @@ public:
|
|||||||
UNIFORM_MAX_ENUM
|
UNIFORM_MAX_ENUM
|
||||||
};
|
};
|
||||||
|
|
||||||
// Type for a list of shader source codes in the form of sources[shadertype] = code
|
|
||||||
typedef std::map<ShaderType, std::string> ShaderSources;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Shader using a list of source codes.
|
* Creates a new Shader using a list of source codes.
|
||||||
* Sources must contain either vertex or pixel shader code, or both.
|
* The sources must contain either vertex or pixel shader code, or both.
|
||||||
**/
|
**/
|
||||||
Shader(const ShaderSources &sources);
|
Shader(const std::vector<std::string> &vertcode, const std::vector<std::string> &pixelcode);
|
||||||
|
|
||||||
virtual ~Shader();
|
virtual ~Shader();
|
||||||
|
|
||||||
@@ -196,7 +193,7 @@ private:
|
|||||||
UniformType getUniformBaseType(GLenum type) const;
|
UniformType getUniformBaseType(GLenum type) const;
|
||||||
void checkSetUniformError(const Uniform &u, int size, int count, UniformType sendtype) const;
|
void checkSetUniformError(const Uniform &u, int size, int count, UniformType sendtype) const;
|
||||||
|
|
||||||
GLuint compileCode(ShaderType type, const std::string &code);
|
GLuint compileCode(ShaderType type, const std::vector<std::string> &code);
|
||||||
void createProgram(const std::vector<GLuint> &shaderids);
|
void createProgram(const std::vector<GLuint> &shaderids);
|
||||||
|
|
||||||
int getTextureUnit(const std::string &name);
|
int getTextureUnit(const std::string &name);
|
||||||
@@ -206,8 +203,9 @@ private:
|
|||||||
// Get any warnings or errors generated only by the shader program object.
|
// Get any warnings or errors generated only by the shader program object.
|
||||||
std::string getProgramWarnings() const;
|
std::string getProgramWarnings() const;
|
||||||
|
|
||||||
// List of all shader code attached to this Shader
|
// List of all shader code attached to this Shader. Each shader type has its
|
||||||
ShaderSources shaderSources;
|
// own list, which represents separate "files".
|
||||||
|
std::vector<std::string> shaderSources[TYPE_MAX_ENUM];
|
||||||
|
|
||||||
// Shader compiler warning strings for individual shader stages.
|
// Shader compiler warning strings for individual shader stages.
|
||||||
std::map<ShaderType, std::string> shaderWarnings;
|
std::map<ShaderType, std::string> shaderWarnings;
|
||||||
|
|||||||
@@ -353,16 +353,16 @@ int w_newShader(lua_State *L)
|
|||||||
if (!Shader::isSupported())
|
if (!Shader::isSupported())
|
||||||
return luaL_error(L, "Sorry, your graphics card does not support shaders.");
|
return luaL_error(L, "Sorry, your graphics card does not support shaders.");
|
||||||
|
|
||||||
// clamp stack to 2 elements
|
// Clamp stack to 2 elements.
|
||||||
lua_settop(L, 2);
|
lua_settop(L, 2);
|
||||||
|
|
||||||
// read any filepath arguments
|
// Read any filepath arguments.
|
||||||
for (int i = 1; i <= 2; i++)
|
for (int i = 1; i <= 2; i++)
|
||||||
{
|
{
|
||||||
if (!lua_isstring(L, i))
|
if (!lua_isstring(L, i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// call love.filesystem.isFile(arg_i)
|
// Call love.filesystem.isFile(arg_i)
|
||||||
luax_getfunction(L, "filesystem", "isFile");
|
luax_getfunction(L, "filesystem", "isFile");
|
||||||
lua_pushvalue(L, i);
|
lua_pushvalue(L, i);
|
||||||
lua_call(L, 1, 1);
|
lua_call(L, 1, 1);
|
||||||
@@ -382,43 +382,76 @@ int w_newShader(lua_State *L)
|
|||||||
bool has_arg1 = lua_isstring(L, 1);
|
bool has_arg1 = lua_isstring(L, 1);
|
||||||
bool has_arg2 = lua_isstring(L, 2);
|
bool has_arg2 = lua_isstring(L, 2);
|
||||||
|
|
||||||
// require at least one string argument
|
// Require at least one string argument.
|
||||||
if (!(has_arg1 || has_arg2))
|
if (!(has_arg1 || has_arg2))
|
||||||
luaL_checkstring(L, 1);
|
luaL_checkstring(L, 1);
|
||||||
|
|
||||||
luax_getfunction(L, "graphics", "_shaderCodeToGLSL");
|
luax_getfunction(L, "graphics", "_shaderCodeToGLSL");
|
||||||
|
|
||||||
// push vertexcode and pixelcode strings to the top of the stack
|
// Push vertexcode and pixelcode strings to the top of the stack.
|
||||||
lua_pushvalue(L, 1);
|
lua_pushvalue(L, 1);
|
||||||
lua_pushvalue(L, 2);
|
lua_pushvalue(L, 2);
|
||||||
|
|
||||||
// call effectCodeToGLSL, returned values will be at the top of the stack
|
// Call shaderCodeToGLSL, returned values will be at the top of the stack.
|
||||||
if (lua_pcall(L, 2, 2, 0) != 0)
|
if (lua_pcall(L, 2, 2, 0) != 0)
|
||||||
return luaL_error(L, "%s", lua_tostring(L, -1));
|
return luaL_error(L, "%s", lua_tostring(L, -1));
|
||||||
|
|
||||||
Shader::ShaderSources sources;
|
// Each shader type might contain several source code strings.
|
||||||
|
std::vector<std::string> sources[Shader::TYPE_MAX_ENUM];
|
||||||
|
|
||||||
// vertex shader code
|
// Vertex shader code.
|
||||||
if (lua_isstring(L, -2))
|
if (!lua_isnoneornil(L, -2))
|
||||||
{
|
{
|
||||||
std::string vertexcode(luaL_checkstring(L, -2));
|
std::vector<std::string> &source = sources[Shader::TYPE_VERTEX];
|
||||||
sources[Shader::TYPE_VERTEX] = vertexcode;
|
|
||||||
|
// The argument might be a Lua array containing strings for the code.
|
||||||
|
if (lua_istable(L, -2))
|
||||||
|
{
|
||||||
|
// Convert table index to absolute.
|
||||||
|
int idx = lua_gettop(L) + 1 - 2;
|
||||||
|
|
||||||
|
// Get all the shader code strings from the Lua array.
|
||||||
|
for (size_t i = 1; i <= lua_objlen(L, idx); i++)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, idx, i);
|
||||||
|
source.push_back(luax_checkstring(L, -1));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
source.push_back(luax_checkstring(L, -2));
|
||||||
}
|
}
|
||||||
else if (has_arg1 && has_arg2)
|
else if (has_arg1 && has_arg2)
|
||||||
return luaL_error(L, "Could not parse vertex shader code (missing 'position' function?)");
|
return luaL_error(L, "Could not parse vertex shader code (missing 'position' function?)");
|
||||||
|
|
||||||
// pixel shader code
|
// Pixel shader code.
|
||||||
if (lua_isstring(L, -1))
|
if (!lua_isnoneornil(L, -1))
|
||||||
{
|
{
|
||||||
std::string pixelcode(luaL_checkstring(L, -1));
|
std::vector<std::string> &source = sources[Shader::TYPE_PIXEL];
|
||||||
sources[Shader::TYPE_PIXEL] = pixelcode;
|
|
||||||
|
// The argument might be a Lua array containing strings for the code.
|
||||||
|
if (lua_istable(L, -1))
|
||||||
|
{
|
||||||
|
// Convert table index to absolute.
|
||||||
|
int idx = lua_gettop(L) + 1 - 1;
|
||||||
|
|
||||||
|
// Get all the shader code strings from the Lua array.
|
||||||
|
for (size_t i = 1; i <= lua_objlen(L, idx); i++)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, idx, i);
|
||||||
|
source.push_back(luax_checkstring(L, -1));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
source.push_back(luax_checkstring(L, -1));
|
||||||
}
|
}
|
||||||
else if (has_arg1 && has_arg2)
|
else if (has_arg1 && has_arg2)
|
||||||
return luaL_error(L, "Could not parse pixel shader code (missing 'effect' function?)");
|
return luaL_error(L, "Could not parse pixel shader code (missing 'effect' function?)");
|
||||||
|
|
||||||
if (sources.empty())
|
if (sources[Shader::TYPE_VERTEX].empty() && sources[Shader::TYPE_PIXEL].empty())
|
||||||
{
|
{
|
||||||
// Original args had source code, but effectCodeToGLSL couldn't translate it
|
// Original args had source code, but shaderCodeToGLSL couldn't translate it
|
||||||
for (int i = 1; i <= 2; i++)
|
for (int i = 1; i <= 2; i++)
|
||||||
{
|
{
|
||||||
if (lua_isstring(L, i))
|
if (lua_isstring(L, i))
|
||||||
@@ -429,7 +462,7 @@ int w_newShader(lua_State *L)
|
|||||||
bool should_error = false;
|
bool should_error = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Shader *shader = instance->newShader(sources);
|
Shader *shader = instance->newShader(sources[Shader::TYPE_VERTEX], sources[Shader::TYPE_PIXEL]);
|
||||||
luax_pushtype(L, "Shader", GRAPHICS_SHADER_T, shader);
|
luax_pushtype(L, "Shader", GRAPHICS_SHADER_T, shader);
|
||||||
}
|
}
|
||||||
catch (love::Exception &e)
|
catch (love::Exception &e)
|
||||||
|
|||||||
+22
-12
@@ -1365,25 +1365,35 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
local function createVertexCode(vertexcode)
|
local function createVertexCode(vertexcode)
|
||||||
|
-- If we return an array, each string in the array is considered separate to GLSL,
|
||||||
|
-- and the line numbers in GLSL errors/warnings maintain this.
|
||||||
local vertexcodes = {
|
local vertexcodes = {
|
||||||
GLSL_VERSION,
|
table_concat({
|
||||||
GLSL_SYNTAX, GLSL_VERTEX.HEADER, GLSL_UNIFORMS,
|
GLSL_VERSION,
|
||||||
"#line 1",
|
GLSL_SYNTAX, GLSL_VERTEX.HEADER, GLSL_UNIFORMS,
|
||||||
vertexcode,
|
}, "\n") .. "\n",
|
||||||
GLSL_VERTEX.FOOTER,
|
table_concat({
|
||||||
|
vertexcode,
|
||||||
|
GLSL_VERTEX.FOOTER
|
||||||
|
}, "\n"),
|
||||||
}
|
}
|
||||||
return table_concat(vertexcodes, "\n")
|
return vertexcodes
|
||||||
end
|
end
|
||||||
|
|
||||||
local function createPixelCode(pixelcode, is_multicanvas)
|
local function createPixelCode(pixelcode, is_multicanvas)
|
||||||
|
-- If we return an array, each string in the array is considered separate to GLSL,
|
||||||
|
-- and the line numbers in GLSL errors/warnings maintain this.
|
||||||
local pixelcodes = {
|
local pixelcodes = {
|
||||||
GLSL_VERSION,
|
table_concat({
|
||||||
GLSL_SYNTAX, GLSL_PIXEL.HEADER, GLSL_UNIFORMS,
|
GLSL_VERSION,
|
||||||
"#line 1",
|
GLSL_SYNTAX, GLSL_PIXEL.HEADER, GLSL_UNIFORMS,
|
||||||
pixelcode,
|
}, "\n") .. "\n",
|
||||||
is_multicanvas and GLSL_PIXEL.FOOTER_MULTI_CANVAS or GLSL_PIXEL.FOOTER,
|
table_concat({
|
||||||
|
pixelcode,
|
||||||
|
is_multicanvas and GLSL_PIXEL.FOOTER_MULTI_CANVAS or GLSL_PIXEL.FOOTER,
|
||||||
|
}, "\n"),
|
||||||
}
|
}
|
||||||
return table_concat(pixelcodes, "\n")
|
return pixelcodes
|
||||||
end
|
end
|
||||||
|
|
||||||
local function isVertexCode(code)
|
local function isVertexCode(code)
|
||||||
|
|||||||
+49
-25
@@ -6404,42 +6404,66 @@ const unsigned char graphics_lua[] =
|
|||||||
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72,
|
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72,
|
||||||
0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x76, 0x65, 0x72,
|
0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x76, 0x65, 0x72,
|
||||||
0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
|
0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
|
||||||
|
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x77, 0x65, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
|
||||||
|
0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2c, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x73, 0x74, 0x72,
|
||||||
|
0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69,
|
||||||
|
0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x73, 0x65, 0x70, 0x61, 0x72,
|
||||||
|
0x61, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x2c, 0x0a,
|
||||||
|
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20,
|
||||||
|
0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x20, 0x65, 0x72,
|
||||||
|
0x72, 0x6f, 0x72, 0x73, 0x2f, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6d, 0x61, 0x69, 0x6e,
|
||||||
|
0x74, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x0a,
|
||||||
0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65,
|
0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65,
|
||||||
0x73, 0x20, 0x3d, 0x20, 0x7b, 0x0a,
|
0x73, 0x20, 0x3d, 0x20, 0x7b, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x2c, 0x0a,
|
0x09, 0x09, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x7b, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x2c, 0x20, 0x47, 0x4c,
|
0x09, 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x2c, 0x0a,
|
||||||
0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x2e, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x2c, 0x20,
|
0x09, 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x2c, 0x20, 0x47,
|
||||||
0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x2c, 0x0a,
|
0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x2e, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x2c,
|
||||||
0x09, 0x09, 0x09, 0x22, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31, 0x22, 0x2c, 0x0a,
|
0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x2c, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x0a,
|
0x09, 0x09, 0x09, 0x7d, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x5c, 0x6e,
|
||||||
0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x2e, 0x46, 0x4f, 0x4f,
|
0x22, 0x2c, 0x0a,
|
||||||
0x54, 0x45, 0x52, 0x2c, 0x0a,
|
0x09, 0x09, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x7b, 0x0a,
|
||||||
|
0x09, 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x0a,
|
||||||
|
0x09, 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x2e, 0x46, 0x4f,
|
||||||
|
0x4f, 0x54, 0x45, 0x52, 0x0a,
|
||||||
|
0x09, 0x09, 0x09, 0x7d, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x2c, 0x0a,
|
||||||
0x09, 0x09, 0x7d, 0x0a,
|
0x09, 0x09, 0x7d, 0x0a,
|
||||||
0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
|
0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64,
|
||||||
0x63, 0x61, 0x74, 0x28, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x2c, 0x20, 0x22,
|
0x65, 0x73, 0x0a,
|
||||||
0x5c, 0x6e, 0x22, 0x29, 0x0a,
|
|
||||||
0x09, 0x65, 0x6e, 0x64, 0x0a,
|
0x09, 0x65, 0x6e, 0x64, 0x0a,
|
||||||
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72,
|
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72,
|
||||||
0x65, 0x61, 0x74, 0x65, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x70, 0x69, 0x78, 0x65,
|
0x65, 0x61, 0x74, 0x65, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x70, 0x69, 0x78, 0x65,
|
||||||
0x6c, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x6e,
|
0x6c, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x6e,
|
||||||
0x76, 0x61, 0x73, 0x29, 0x0a,
|
0x76, 0x61, 0x73, 0x29, 0x0a,
|
||||||
|
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x77, 0x65, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
|
||||||
|
0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x2c, 0x20, 0x65, 0x61, 0x63, 0x68, 0x20, 0x73, 0x74, 0x72,
|
||||||
|
0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69,
|
||||||
|
0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x73, 0x65, 0x70, 0x61, 0x72,
|
||||||
|
0x61, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x2c, 0x0a,
|
||||||
|
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20,
|
||||||
|
0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x20, 0x65, 0x72,
|
||||||
|
0x72, 0x6f, 0x72, 0x73, 0x2f, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6d, 0x61, 0x69, 0x6e,
|
||||||
|
0x74, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x0a,
|
||||||
0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x73,
|
0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x73,
|
||||||
0x20, 0x3d, 0x20, 0x7b, 0x0a,
|
0x20, 0x3d, 0x20, 0x7b, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x2c, 0x0a,
|
0x09, 0x09, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x7b, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x2c, 0x20, 0x47, 0x4c,
|
0x09, 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x2c, 0x0a,
|
||||||
0x53, 0x4c, 0x5f, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x2e, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x2c, 0x20, 0x47,
|
0x09, 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x2c, 0x20, 0x47,
|
||||||
0x4c, 0x53, 0x4c, 0x5f, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x2c, 0x0a,
|
0x4c, 0x53, 0x4c, 0x5f, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x2e, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x2c, 0x20,
|
||||||
0x09, 0x09, 0x09, 0x22, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31, 0x22, 0x2c, 0x0a,
|
0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x2c, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x0a,
|
0x09, 0x09, 0x09, 0x7d, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x5c, 0x6e,
|
||||||
0x09, 0x09, 0x09, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x20,
|
0x22, 0x2c, 0x0a,
|
||||||
0x61, 0x6e, 0x64, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x2e, 0x46, 0x4f, 0x4f,
|
0x09, 0x09, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x7b, 0x0a,
|
||||||
0x54, 0x45, 0x52, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x43, 0x41, 0x4e, 0x56, 0x41, 0x53, 0x20, 0x6f,
|
0x09, 0x09, 0x09, 0x09, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x0a,
|
||||||
0x72, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x2e, 0x46, 0x4f, 0x4f, 0x54, 0x45,
|
0x09, 0x09, 0x09, 0x09, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73,
|
||||||
0x52, 0x2c, 0x0a,
|
0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x2e, 0x46, 0x4f,
|
||||||
|
0x4f, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x43, 0x41, 0x4e, 0x56, 0x41, 0x53, 0x20,
|
||||||
|
0x6f, 0x72, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x2e, 0x46, 0x4f, 0x4f, 0x54,
|
||||||
|
0x45, 0x52, 0x2c, 0x0a,
|
||||||
|
0x09, 0x09, 0x09, 0x7d, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x2c, 0x0a,
|
||||||
0x09, 0x09, 0x7d, 0x0a,
|
0x09, 0x09, 0x7d, 0x0a,
|
||||||
0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
|
0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65,
|
||||||
0x63, 0x61, 0x74, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x2c, 0x20, 0x22, 0x5c,
|
0x73, 0x0a,
|
||||||
0x6e, 0x22, 0x29, 0x0a,
|
|
||||||
0x09, 0x65, 0x6e, 0x64, 0x0a,
|
0x09, 0x65, 0x6e, 0x64, 0x0a,
|
||||||
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73,
|
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73,
|
||||||
0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
|
0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
|
||||||
|
|||||||
Reference in New Issue
Block a user