From 7948b11082c9a30967c59f6e4aeae219fb211299 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 21 Sep 2014 03:31:36 -0300 Subject: [PATCH 1/7] Updated love.physics.newPolygonShape and love.physics.newChainShape to accept a table of vertices, fixed a small memory leak if newChainShape errors, fixed the vertex order of newChainShape. --- src/modules/physics/box2d/Physics.cpp | 68 ++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index b62c17efe..393c93c7f 100644 --- a/src/modules/physics/box2d/Physics.cpp +++ b/src/modules/physics/box2d/Physics.cpp @@ -93,6 +93,12 @@ EdgeShape *Physics::newEdgeShape(float x1, float y1, float x2, float y2) int Physics::newPolygonShape(lua_State *L) { int argc = lua_gettop(L); + + bool istable = lua_istable(L, 1); + + if (istable) + argc = lua_objlen(L, 1); + if (argc % 2 != 0) return luaL_error(L, "Number of vertex components must be a multiple of two."); @@ -103,16 +109,31 @@ int Physics::newPolygonShape(lua_State *L) else if (vcount > b2_maxPolygonVertices) return luaL_error(L, "Expected a maximum of %d vertices, got %d.", b2_maxPolygonVertices, vcount); - b2PolygonShape *s = new b2PolygonShape(); - b2Vec2 vecs[b2_maxPolygonVertices]; - for (int i = 0; i < vcount; i++) + if (istable) { - float x = (float)luaL_checknumber(L, 1 + i * 2); - float y = (float)luaL_checknumber(L, 2 + i * 2); - vecs[i] = Physics::scaleDown(b2Vec2(x, y)); + for (int i = 0; i < vcount; i++) + { + lua_rawgeti(L, 1, 1 + i * 2); + lua_rawgeti(L, 1, 2 + i * 2); + float x = (float)luaL_checknumber(L, -2); + float y = (float)luaL_checknumber(L, -1); + vecs[i] = Physics::scaleDown(b2Vec2(x, y)); + lua_pop(L, 2); + } } + else + { + for (int i = 0; i < vcount; i++) + { + float x = (float)luaL_checknumber(L, 1 + i * 2); + float y = (float)luaL_checknumber(L, 2 + i * 2); + vecs[i] = Physics::scaleDown(b2Vec2(x, y)); + } + } + + b2PolygonShape *s = new b2PolygonShape(); try { @@ -133,22 +154,42 @@ int Physics::newPolygonShape(lua_State *L) int Physics::newChainShape(lua_State *L) { int argc = lua_gettop(L)-1; // first argument is looping + + bool istable = lua_istable(L, 2); + + if (istable) + argc = lua_objlen(L, 2); + if (argc % 2 != 0) return luaL_error(L, "Number of vertex components must be a multiple of two."); int vcount = (int)argc/2; - b2ChainShape *s = new b2ChainShape(); bool loop = luax_toboolean(L, 1); b2Vec2 *vecs = new b2Vec2[vcount]; - for (int i = 0; i Date: Sun, 21 Sep 2014 19:50:02 -0300 Subject: [PATCH 2/7] Cleaned up some code. --- platform/macosx/OSX.mm | 12 +++++------- src/modules/event/sdl/Event.cpp | 32 ++++++++++++------------------- src/modules/mouse/sdl/Mouse.cpp | 30 ++++++++++------------------- src/modules/window/Window.h | 5 +++++ src/modules/window/sdl/Window.cpp | 20 ++++--------------- 5 files changed, 36 insertions(+), 63 deletions(-) diff --git a/platform/macosx/OSX.mm b/platform/macosx/OSX.mm index 418de494f..bce0d6a43 100644 --- a/platform/macosx/OSX.mm +++ b/platform/macosx/OSX.mm @@ -34,13 +34,11 @@ std::string getLoveInResources() @autoreleasepool { - // check to see if there are any .love files in Resources - props to stevejohnson/diordna - NSArray *lovePaths = [[NSBundle mainBundle] pathsForResourcesOfType:@"love" inDirectory:nil]; - if ([lovePaths count] > 0) - { - NSString *firstLovePath = [lovePaths objectAtIndex:0]; - path = std::string([firstLovePath UTF8String]); - } + // Check to see if there are any .love files in Resources. + NSString *lovepath = [[NSBundle mainBundle] pathForResource:nil ofType:@"love"]; + + if (lovepath != nil) + path = [lovepath UTF8String]; } return path; diff --git a/src/modules/event/sdl/Event.cpp b/src/modules/event/sdl/Event.cpp index 8e0fe7365..f3537a6e9 100644 --- a/src/modules/event/sdl/Event.cpp +++ b/src/modules/event/sdl/Event.cpp @@ -42,17 +42,12 @@ namespace sdl // we want them in pixel coordinates (may be different with high-DPI enabled.) static void windowToPixelCoords(int *x, int *y) { - double scale = 1.0; - window::Window *window = Module::getInstance(Module::M_WINDOW); - if (window != nullptr) - scale = window->getPixelScale(); - if (x != nullptr) - *x = int(double(*x) * scale); - - if (y != nullptr) - *y = int(double(*y) * scale); + if (window && x) + *x = (int) window->toPixels(*x); + if (window && y) + *y = (int) window->toPixels(*y); } @@ -74,15 +69,11 @@ Event::~Event() void Event::pump() { - SDL_PumpEvents(); - - static SDL_Event e; - - Message *msg; + SDL_Event e; while (SDL_PollEvent(&e)) { - msg = convert(e); + Message *msg = convert(e); if (msg) { push(msg); @@ -93,16 +84,17 @@ void Event::pump() Message *Event::wait() { - static SDL_Event e; - bool ok = (SDL_WaitEvent(&e) == 1); - if (!ok) - return NULL; + SDL_Event e; + + if (SDL_WaitEvent(&e) != 1) + return nullptr; + return convert(e); } void Event::clear() { - static SDL_Event e; + SDL_Event e; while (SDL_PollEvent(&e)) { diff --git a/src/modules/mouse/sdl/Mouse.cpp b/src/modules/mouse/sdl/Mouse.cpp index cf1ccd0c9..ed97d4438 100644 --- a/src/modules/mouse/sdl/Mouse.cpp +++ b/src/modules/mouse/sdl/Mouse.cpp @@ -36,33 +36,23 @@ namespace sdl // we want them in pixel coordinates (may be different with high-DPI enabled.) static void windowToPixelCoords(int *x, int *y) { - double scale = 1.0; + window::Window *window = Module::getInstance(Module::M_WINDOW); - love::window::Window *window = love::window::sdl::Window::getSingleton(); - if (window != nullptr) - scale = window->getPixelScale(); - - if (x != nullptr) - *x = int(double(*x) * scale); - - if (y != nullptr) - *y = int(double(*y) * scale); + if (window && x) + *x = (int) window->toPixels(*x); + if (window && y) + *y = (int) window->toPixels(*y); } // And vice versa for setting mouse coordinates. static void pixelToWindowCoords(int *x, int *y) { - double scale = 1.0; + window::Window *window = Module::getInstance(Module::M_WINDOW); - love::window::Window *window = love::window::sdl::Window::getSingleton(); - if (window != nullptr) - scale = window->getPixelScale(); - - if (x != nullptr) - *x = int(double(*x) / scale); - - if (y != nullptr) - *y = int(double(*y) / scale); + if (window && x) + *x = (int) window->fromPixels(*x); + if (window && y) + *y = (int) window->fromPixels(*y); } const char *Mouse::getName() const diff --git a/src/modules/window/Window.h b/src/modules/window/Window.h index 4ada807c9..ecd7bd368 100644 --- a/src/modules/window/Window.h +++ b/src/modules/window/Window.h @@ -84,6 +84,11 @@ public: { int width; int height; + + bool operator == (const WindowSize &w) const + { + return w.width == width && w.height == height; + } }; struct MessageBoxData diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 5791c8fc7..89bb3a9c9 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -505,29 +505,17 @@ std::vector Window::getFullscreenSizes(int displayindex) const { std::vector sizes; - SDL_DisplayMode mode = {}; - std::vector::const_iterator it; for (int i = 0; i < SDL_GetNumDisplayModes(displayindex); i++) { + SDL_DisplayMode mode = {}; SDL_GetDisplayMode(displayindex, i, &mode); + WindowSize w = {mode.w, mode.h}; + // SDL2's display mode list has multiple entries for modes of the same // size with different bits per pixel, so we need to filter those out. - bool alreadyhassize = false; - for (it = sizes.begin(); it != sizes.end(); ++it) - { - if (it->width == mode.w && it->height == mode.h) - { - alreadyhassize = true; - break; - } - } - - if (!alreadyhassize) - { - WindowSize w = {mode.w, mode.h}; + if (std::find(sizes.begin(), sizes.end(), w) == sizes.end()) sizes.push_back(w); - } } return sizes; From b70f72acb3d0430be842f8235c529bad1e6e1bcd Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 27 Sep 2014 02:26:58 -0300 Subject: [PATCH 3/7] Fixed a couple potential memory leaks if love.graphics.newShader causes an error, and cleaned up some shader-related code. --- src/modules/graphics/opengl/Graphics.cpp | 4 +- src/modules/graphics/opengl/Graphics.h | 2 +- src/modules/graphics/opengl/Shader.cpp | 219 +++++++++--------- src/modules/graphics/opengl/Shader.h | 34 +-- src/modules/graphics/opengl/wrap_Graphics.cpp | 16 +- 5 files changed, 138 insertions(+), 137 deletions(-) diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index e98dec6a2..59c0b0226 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -576,9 +576,9 @@ Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int ms return nullptr; // never reached } -Shader *Graphics::newShader(const Shader::ShaderSources &sources) +Shader *Graphics::newShader(const Shader::ShaderSource &source) { - return new Shader(sources); + return new Shader(source); } Mesh *Graphics::newMesh(const std::vector &vertices, Mesh::DrawMode mode) diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 647c6ba98..811a76d4f 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -165,7 +165,7 @@ public: Canvas *newCanvas(int width, int height, Canvas::Format format = Canvas::FORMAT_NORMAL, int msaa = 0); - Shader *newShader(const Shader::ShaderSources &sources); + Shader *newShader(const Shader::ShaderSource &source); Mesh *newMesh(const std::vector &vertices, Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN); Mesh *newMesh(int vertexcount, Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN); diff --git a/src/modules/graphics/opengl/Shader.cpp b/src/modules/graphics/opengl/Shader.cpp index 698c58bd7..a5cb7239f 100644 --- a/src/modules/graphics/opengl/Shader.cpp +++ b/src/modules/graphics/opengl/Shader.cpp @@ -66,15 +66,15 @@ Shader *Shader::current = nullptr; GLint Shader::maxTexUnits = 0; std::vector Shader::textureCounters; -Shader::Shader(const ShaderSources &sources) - : shaderSources(sources) +Shader::Shader(const ShaderSource &source) + : shaderSource(source) , program(0) , builtinUniforms() - , vertexAttributes() + , builtinAttributes() , lastCanvas((Canvas *) -1) , lastViewport() { - if (shaderSources.empty()) + if (source.vertex.empty() && source.pixel.empty()) throw love::Exception("Cannot create shader: no source code!"); if (maxTexUnits <= 0) @@ -105,21 +105,21 @@ Shader::~Shader() unloadVolatile(); } -GLuint Shader::compileCode(ShaderType type, const std::string &code) +GLuint Shader::compileCode(ShaderStage stage, const std::string &code) { - GLenum glshadertype; + GLenum glstage; const char *typestr; - if (!typeNames.find(type, typestr)) + if (!stageNames.find(stage, typestr)) typestr = ""; - switch (type) + switch (stage) { - case TYPE_VERTEX: - glshadertype = GL_VERTEX_SHADER; + case STAGE_VERTEX: + glstage = GL_VERTEX_SHADER; break; - case TYPE_PIXEL: - glshadertype = GL_FRAGMENT_SHADER; + case STAGE_PIXEL: + glstage = GL_FRAGMENT_SHADER; break; default: throw love::Exception("Cannot create shader object: unknown shader type."); @@ -129,121 +129,75 @@ GLuint Shader::compileCode(ShaderType type, const std::string &code) // clear existing errors while (glGetError() != GL_NO_ERROR); - GLuint shaderid = glCreateShader(glshadertype); + GLuint shaderid = glCreateShader(glstage); - if (shaderid == 0) // oh no! + if (shaderid == 0) { - GLenum err = glGetError(); - - if (err == GL_INVALID_ENUM) + if (glGetError() == GL_INVALID_ENUM) throw love::Exception("Cannot create %s shader object: %s shaders not supported.", typestr, typestr); else throw love::Exception("Cannot create %s shader object.", typestr); } const char *src = code.c_str(); - size_t srclen = code.length(); - glShaderSource(shaderid, 1, (const GLchar **)&src, (GLint *)&srclen); + GLint srclen = (GLint) code.length(); + glShaderSource(shaderid, 1, (const GLchar **)&src, &srclen); glCompileShader(shaderid); - // Get any warnings the shader compiler may have produced. GLint infologlen; glGetShaderiv(shaderid, GL_INFO_LOG_LENGTH, &infologlen); - GLchar *infolog = new GLchar[infologlen + 1]; - glGetShaderInfoLog(shaderid, infologlen, nullptr, infolog); - - // Save any warnings for later querying. + // Get any warnings the shader compiler may have produced. if (infologlen > 0) - shaderWarnings[type] = infolog; + { + GLchar *infolog = new GLchar[infologlen]; + glGetShaderInfoLog(shaderid, infologlen, nullptr, infolog); - delete[] infolog; + // Save any warnings for later querying. + shaderWarnings[stage] = infolog; + + delete[] infolog; + } GLint status; glGetShaderiv(shaderid, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { + glDeleteShader(shaderid); throw love::Exception("Cannot compile %s shader code:\n%s", - typestr, shaderWarnings[type].c_str()); + typestr, shaderWarnings[stage].c_str()); } return shaderid; } -void Shader::createProgram(const std::vector &shaderids) -{ - program = glCreateProgram(); - if (program == 0) - throw love::Exception("Cannot create shader program object."); - - for (GLuint id : shaderids) - glAttachShader(program, id); - - // Bind generic vertex attribute indices to names in the shader. - for (int i = 0; i < int(OpenGL::ATTRIB_MAX_ENUM); i++) - { - OpenGL::VertexAttrib attrib = (OpenGL::VertexAttrib) i; - - // FIXME: We skip this both because pseudo-instancing is temporarily - // disabled (see graphics.lua), and because binding a non-existant - // attribute name to a location causes a shader linker warning. - if (attrib == OpenGL::ATTRIB_PSEUDO_INSTANCE_ID) - continue; - - const char *name = nullptr; - if (attribNames.find(attrib, name)) - glBindAttribLocation(program, i, (const GLchar *) name); - } - - glLinkProgram(program); - - // flag shaders for auto-deletion when the program object is deleted. - for (GLuint id : shaderids) - glDeleteShader(id); - - GLint status; - glGetProgramiv(program, GL_LINK_STATUS, &status); - - if (status == GL_FALSE) - { - std::string warnings = getProgramWarnings(); - glDeleteProgram(program); - program = 0; - - throw love::Exception("Cannot link shader program object:\n%s", warnings.c_str()); - } -} - void Shader::mapActiveUniforms() { + // Built-in uniform locations default to -1 (nonexistant.) + for (int i = 0; i < int(BUILTIN_MAX_ENUM); i++) + builtinUniforms[i] = -1; + uniforms.clear(); GLint numuniforms; glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numuniforms); - GLsizei bufsize; - glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, (GLint *) &bufsize); - - if (bufsize <= 0) - return; + GLchar cname[256]; + const GLint bufsize = (GLint) (sizeof(cname) / sizeof(GLchar)); for (int i = 0; i < numuniforms; i++) { - GLchar *cname = new GLchar[bufsize]; - GLsizei namelength; + GLsizei namelen = 0; + Uniform u = {}; - Uniform u; + glGetActiveUniform(program, (GLuint) i, bufsize, &namelen, &u.count, &u.type, cname); - glGetActiveUniform(program, (GLuint) i, bufsize, &namelength, &u.count, &u.type, cname); - - u.name = std::string(cname, (size_t) namelength); + u.name = std::string(cname, (size_t) namelen); u.location = glGetUniformLocation(program, u.name.c_str()); u.baseType = getUniformBaseType(u.type); - delete[] cname; - // glGetActiveUniform appends "[0]" to the end of array uniform names... if (u.name.length() > 3) { @@ -268,22 +222,70 @@ bool Shader::loadVolatile() activeTexUnits.clear(); activeTexUnits.insert(activeTexUnits.begin(), maxTexUnits, 0); - // Built-in uniform locations default to -1 (nonexistant.) - for (int i = 0; i < int(BUILTIN_MAX_ENUM); i++) - builtinUniforms[i] = -1; - std::vector shaderids; - for (const auto &source : shaderSources) + try { - GLuint shaderid = compileCode(source.first, source.second); - shaderids.push_back(shaderid); + if (!shaderSource.vertex.empty()) + shaderids.push_back(compileCode(STAGE_VERTEX, shaderSource.vertex)); + + if (!shaderSource.pixel.empty()) + shaderids.push_back(compileCode(STAGE_PIXEL, shaderSource.pixel)); + } + catch (love::Exception &) + { + for (GLuint id : shaderids) + glDeleteShader(id); + throw; } if (shaderids.empty()) throw love::Exception("Cannot create shader: no valid source code!"); - createProgram(shaderids); + program = glCreateProgram(); + + if (program == 0) + { + for (GLuint id : shaderids) + glDeleteShader(id); + throw love::Exception("Cannot create shader program object."); + } + + for (GLuint id : shaderids) + glAttachShader(program, id); + + // Bind generic vertex attribute indices to names in the shader. + for (int i = 0; i < int(OpenGL::ATTRIB_MAX_ENUM); i++) + { + OpenGL::VertexAttrib attrib = (OpenGL::VertexAttrib) i; + + // FIXME: We skip this both because pseudo-instancing is temporarily + // disabled (see graphics.lua), and because binding a non-existant + // attribute name to a location causes a shader linker warning. + if (attrib == OpenGL::ATTRIB_PSEUDO_INSTANCE_ID) + continue; + + const char *name = nullptr; + if (attribNames.find(attrib, name)) + glBindAttribLocation(program, i, (const GLchar *) name); + } + + glLinkProgram(program); + + // Flag shaders for auto-deletion when the program object is deleted. + for (GLuint id : shaderids) + glDeleteShader(id); + + GLint status; + glGetProgramiv(program, GL_LINK_STATUS, &status); + + if (status == GL_FALSE) + { + std::string warnings = getProgramWarnings(); + glDeleteProgram(program); + program = 0; + throw love::Exception("Cannot link shader program object:\n%s", warnings.c_str()); + } // Retreive all active uniform variables in this shader from OpenGL. mapActiveUniforms(); @@ -292,9 +294,9 @@ bool Shader::loadVolatile() { const char *name = nullptr; if (attribNames.find(OpenGL::VertexAttrib(i), name)) - vertexAttributes[i] = glGetAttribLocation(program, name); + builtinAttributes[i] = glGetAttribLocation(program, name); else - vertexAttributes[i] = -1; + builtinAttributes[i] = -1; } if (current == this) @@ -341,13 +343,16 @@ void Shader::unloadVolatile() std::string Shader::getProgramWarnings() const { - GLint strlen, nullpos; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &strlen); + GLint strsize, nullpos; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &strsize); - char *tempstr = new char[strlen+1]; + if (strsize == 0) + return ""; + + char *tempstr = new char[strsize]; // be extra sure that the error string will be 0-terminated - memset(tempstr, '\0', strlen+1); - glGetProgramInfoLog(program, strlen, &nullpos, tempstr); + memset(tempstr, '\0', strsize); + glGetProgramInfoLog(program, strsize, &nullpos, tempstr); tempstr[nullpos] = '\0'; std::string warnings(tempstr); @@ -359,13 +364,13 @@ std::string Shader::getProgramWarnings() const std::string Shader::getWarnings() const { std::string warnings; - const char *typestr; + const char *stagestr; // Get the individual shader stage warnings for (const auto &warning : shaderWarnings) { - if (typeNames.find(warning.first, typestr)) - warnings += std::string(typestr) + std::string(" shader:\n") + warning.second; + if (stageNames.find(warning.first, stagestr)) + warnings += std::string(stagestr) + std::string(" shader:\n") + warning.second; } warnings += getProgramWarnings(); @@ -671,7 +676,7 @@ Shader::UniformType Shader::getExternVariable(const std::string &name, int &comp bool Shader::hasVertexAttrib(OpenGL::VertexAttrib attrib) const { - return vertexAttributes[int(attrib)] != -1; + return builtinAttributes[int(attrib)] != -1; } bool Shader::hasBuiltinUniform(BuiltinUniform builtin) const @@ -785,13 +790,13 @@ bool Shader::getConstant(UniformType in, const char *&out) return uniformTypes.find(in, out); } -StringMap::Entry Shader::typeNameEntries[] = +StringMap::Entry Shader::stageNameEntries[] = { - {"vertex", Shader::TYPE_VERTEX}, - {"pixel", Shader::TYPE_PIXEL}, + {"vertex", Shader::STAGE_VERTEX}, + {"pixel", Shader::STAGE_PIXEL}, }; -StringMap Shader::typeNames(Shader::typeNameEntries, sizeof(Shader::typeNameEntries)); +StringMap Shader::stageNames(Shader::stageNameEntries, sizeof(Shader::stageNameEntries)); StringMap::Entry Shader::uniformTypeEntries[] = { diff --git a/src/modules/graphics/opengl/Shader.h b/src/modules/graphics/opengl/Shader.h index 38c70a137..2091e6f15 100644 --- a/src/modules/graphics/opengl/Shader.h +++ b/src/modules/graphics/opengl/Shader.h @@ -49,11 +49,11 @@ public: // Pointer to currently active Shader. static Shader *current; - enum ShaderType + enum ShaderStage { - TYPE_VERTEX, - TYPE_PIXEL, - TYPE_MAX_ENUM + STAGE_VERTEX, + STAGE_PIXEL, + STAGE_MAX_ENUM }; // Built-in uniform (extern) variables. @@ -74,14 +74,17 @@ public: UNIFORM_MAX_ENUM }; - // Type for a list of shader source codes in the form of sources[shadertype] = code - typedef std::map ShaderSources; + struct ShaderSource + { + std::string vertex; + std::string pixel; + }; /** * Creates a new Shader using a list of source codes. - * Sources must contain either vertex or pixel shader code, or both. + * Source must contain either vertex or pixel shader code, or both. **/ - Shader(const ShaderSources &sources); + Shader(const ShaderSource &source); virtual ~Shader(); @@ -196,8 +199,7 @@ private: UniformType getUniformBaseType(GLenum type) const; void checkSetUniformError(const Uniform &u, int size, int count, UniformType sendtype) const; - GLuint compileCode(ShaderType type, const std::string &code); - void createProgram(const std::vector &shaderids); + GLuint compileCode(ShaderStage stage, const std::string &code); int getTextureUnit(const std::string &name); @@ -206,11 +208,11 @@ private: // Get any warnings or errors generated only by the shader program object. std::string getProgramWarnings() const; - // List of all shader code attached to this Shader - ShaderSources shaderSources; + // Source code used for this Shader. + ShaderSource shaderSource; // Shader compiler warning strings for individual shader stages. - std::map shaderWarnings; + std::map shaderWarnings; // volatile GLuint program; @@ -219,7 +221,7 @@ private: GLint builtinUniforms[BUILTIN_MAX_ENUM]; // Location values for any generic vertex attribute variables. - GLint vertexAttributes[OpenGL::ATTRIB_MAX_ENUM]; + GLint builtinAttributes[OpenGL::ATTRIB_MAX_ENUM]; // Uniform location buffer map std::map uniforms; @@ -241,8 +243,8 @@ private: // Counts total number of textures bound to each texture unit in all shaders static std::vector textureCounters; - static StringMap::Entry typeNameEntries[]; - static StringMap typeNames; + static StringMap::Entry stageNameEntries[]; + static StringMap stageNames; static StringMap::Entry uniformTypeEntries[]; static StringMap uniformTypes; diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index 90f865d2a..a6416369d 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -436,27 +436,21 @@ int w_newShader(lua_State *L) if (lua_pcall(L, 2, 2, 0) != 0) return luaL_error(L, "%s", lua_tostring(L, -1)); - Shader::ShaderSources sources; + Shader::ShaderSource source; // vertex shader code if (lua_isstring(L, -2)) - { - std::string vertexcode(luaL_checkstring(L, -2)); - sources[Shader::TYPE_VERTEX] = vertexcode; - } + source.vertex = luax_checkstring(L, -2); else if (has_arg1 && has_arg2) return luaL_error(L, "Could not parse vertex shader code (missing 'position' function?)"); // pixel shader code if (lua_isstring(L, -1)) - { - std::string pixelcode(luaL_checkstring(L, -1)); - sources[Shader::TYPE_PIXEL] = pixelcode; - } + source.pixel = luax_checkstring(L, -1); else if (has_arg1 && has_arg2) return luaL_error(L, "Could not parse pixel shader code (missing 'effect' function?)"); - if (sources.empty()) + if (source.vertex.empty() && source.pixel.empty()) { // Original args had source code, but effectCodeToGLSL couldn't translate it for (int i = 1; i <= 2; i++) @@ -469,7 +463,7 @@ int w_newShader(lua_State *L) bool should_error = false; try { - Shader *shader = instance()->newShader(sources); + Shader *shader = instance()->newShader(source); luax_pushtype(L, "Shader", GRAPHICS_SHADER_T, shader); shader->release(); } From e2354acc65a228e5d37d2734f6b1727b8cfd2c72 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 27 Sep 2014 03:17:08 -0300 Subject: [PATCH 4/7] Updated the love key to SDL keycode mapping to be a static array instead of a std::map. --- src/modules/keyboard/Keyboard.h | 2 +- src/modules/keyboard/sdl/Keyboard.cpp | 13 ++++++------- src/modules/keyboard/sdl/Keyboard.h | 9 +++------ 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/modules/keyboard/Keyboard.h b/src/modules/keyboard/Keyboard.h index 2ca366d74..98a2177b3 100644 --- a/src/modules/keyboard/Keyboard.h +++ b/src/modules/keyboard/Keyboard.h @@ -241,7 +241,7 @@ public: KEY_EJECT, KEY_SLEEP, - KEY_MAX_ENUM = 512 + KEY_MAX_ENUM }; virtual ~Keyboard() {} diff --git a/src/modules/keyboard/sdl/Keyboard.cpp b/src/modules/keyboard/sdl/Keyboard.cpp index 00b6812f7..e50d176fe 100644 --- a/src/modules/keyboard/sdl/Keyboard.cpp +++ b/src/modules/keyboard/sdl/Keyboard.cpp @@ -18,8 +18,6 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#include "common/config.h" - #include "Keyboard.h" namespace love @@ -55,8 +53,8 @@ bool Keyboard::isDown(Key *keylist) const for (Key key = *keylist; key != KEY_MAX_ENUM; key = *(++keylist)) { - auto it = keys.find(key); - if (it != keys.end() && keystate[SDL_GetScancodeFromKey(it->second)]) + SDL_Scancode scancode = SDL_GetScancodeFromKey(keymap[key]); + if (keystate[scancode]) return true; } @@ -76,9 +74,10 @@ bool Keyboard::hasTextInput() const return SDL_IsTextInputActive(); } -std::map Keyboard::createKeyMap() +const SDL_Keycode *Keyboard::createKeyMap() { - std::map k; + // Array must be static so its lifetime continues once the function returns. + static SDL_Keycode k[Keyboard::KEY_MAX_ENUM] = {SDLK_UNKNOWN}; k[Keyboard::KEY_UNKNOWN] = SDLK_UNKNOWN; @@ -287,7 +286,7 @@ std::map Keyboard::createKeyMap() return k; } -std::map Keyboard::keys = Keyboard::createKeyMap(); +const SDL_Keycode *Keyboard::keymap = Keyboard::createKeyMap(); } // sdl } // keyboard diff --git a/src/modules/keyboard/sdl/Keyboard.h b/src/modules/keyboard/sdl/Keyboard.h index 9b7a5f2c4..5f5bea05b 100644 --- a/src/modules/keyboard/sdl/Keyboard.h +++ b/src/modules/keyboard/sdl/Keyboard.h @@ -26,10 +26,7 @@ #include "common/EnumMap.h" // SDL -#include - -// STL -#include +#include namespace love { @@ -60,8 +57,8 @@ private: // The real implementation is in love::event::sdl::Event::Convert. bool key_repeat; - static std::map createKeyMap(); - static std::map keys; + static const SDL_Keycode *createKeyMap(); + static const SDL_Keycode *keymap; }; // Keyboard From 808e533b025bbc65d6d716ff2b3846f9715bf9e0 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 28 Sep 2014 14:58:59 -0300 Subject: [PATCH 5/7] Tweaked streaming Sources to use fewer OpenAL buffers (and increased the amount of decoded data per buffer to compensate), and removed some unnecessary #include statements. --- src/modules/audio/openal/Audio.h | 1 - src/modules/audio/openal/Pool.h | 1 - src/modules/audio/openal/Source.h | 2 +- src/modules/audio/wrap_Audio.cpp | 3 +++ src/modules/event/sdl/Event.h | 2 +- src/modules/filesystem/physfs/Filesystem.h | 1 - src/modules/graphics/opengl/Graphics.cpp | 3 ++- src/modules/graphics/opengl/Graphics.h | 1 - src/modules/sound/Decoder.h | 2 +- 9 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/modules/audio/openal/Audio.h b/src/modules/audio/openal/Audio.h index 6e5f50696..35fe8afbb 100644 --- a/src/modules/audio/openal/Audio.h +++ b/src/modules/audio/openal/Audio.h @@ -24,7 +24,6 @@ // STD #include #include -#include #include // LOVE diff --git a/src/modules/audio/openal/Pool.h b/src/modules/audio/openal/Pool.h index f0896ea97..8ce7e0483 100644 --- a/src/modules/audio/openal/Pool.h +++ b/src/modules/audio/openal/Pool.h @@ -24,7 +24,6 @@ // STD #include #include -#include #include // LOVE diff --git a/src/modules/audio/openal/Source.h b/src/modules/audio/openal/Source.h index 6c923e3e3..8166e7336 100644 --- a/src/modules/audio/openal/Source.h +++ b/src/modules/audio/openal/Source.h @@ -145,7 +145,7 @@ private: ALuint source; bool valid; - static const unsigned int MAX_BUFFERS = 32; + static const unsigned int MAX_BUFFERS = 8; ALuint streamBuffers[MAX_BUFFERS]; Object::StrongRef staticBuffer; diff --git a/src/modules/audio/wrap_Audio.cpp b/src/modules/audio/wrap_Audio.cpp index c2be44f85..5d33373ec 100644 --- a/src/modules/audio/wrap_Audio.cpp +++ b/src/modules/audio/wrap_Audio.cpp @@ -26,6 +26,9 @@ #include "common/runtime.h" +// C++ +#include + namespace love { namespace audio diff --git a/src/modules/event/sdl/Event.h b/src/modules/event/sdl/Event.h index 1028a7211..e6274a9cc 100644 --- a/src/modules/event/sdl/Event.h +++ b/src/modules/event/sdl/Event.h @@ -27,7 +27,7 @@ #include "common/EnumMap.h" // SDL -#include +#include // STL #include diff --git a/src/modules/filesystem/physfs/Filesystem.h b/src/modules/filesystem/physfs/Filesystem.h index 8c2f96209..483033304 100644 --- a/src/modules/filesystem/physfs/Filesystem.h +++ b/src/modules/filesystem/physfs/Filesystem.h @@ -24,7 +24,6 @@ // STD #include #include -#include #include // LOVE diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 59c0b0226..a402fd638 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -35,6 +35,7 @@ // C #include +#include namespace love { @@ -259,7 +260,7 @@ bool Graphics::setMode(int width, int height, bool &sRGB) // Reload all volatile objects. if (!Volatile::loadAll()) - std::cerr << "Could not reload all volatile objects." << std::endl; + ::printf("Could not reload all volatile objects.\n"); // Restore the graphics state. restoreState(states.back()); diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 811a76d4f..4c1aadb1d 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -22,7 +22,6 @@ #define LOVE_GRAPHICS_OPENGL_GRAPHICS_H // STD -#include #include #include diff --git a/src/modules/sound/Decoder.h b/src/modules/sound/Decoder.h index 50c522c1b..eede6efcc 100644 --- a/src/modules/sound/Decoder.h +++ b/src/modules/sound/Decoder.h @@ -40,7 +40,7 @@ public: * Indicates how many bytes of raw data should be generated at each * call to Decode. **/ - static const int DEFAULT_BUFFER_SIZE = 2048; + static const int DEFAULT_BUFFER_SIZE = 16384; /** * Indicates the quality of the sound. From e8009bb4cbda9d2c32c1dd6f7b6da10f5ef467e2 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 28 Sep 2014 15:28:14 -0300 Subject: [PATCH 6/7] Reverted commit 14ca947 (love.math.setRandomSeed internally calling random() a few times.) The change can break existing 0.9.x games so it will be pushed back to the minor branch. --- src/modules/math/RandomGenerator.cpp | 5 ----- src/scripts/boot.lua | 1 + src/scripts/boot.lua.h | 3 +++ 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/modules/math/RandomGenerator.cpp b/src/modules/math/RandomGenerator.cpp index 6b14390f9..0f1b6bb37 100644 --- a/src/modules/math/RandomGenerator.cpp +++ b/src/modules/math/RandomGenerator.cpp @@ -81,11 +81,6 @@ void RandomGenerator::setSeed(RandomGenerator::Seed newseed) seed = newseed; rng_state = seed; - - // Xorshift's first couple results after seeding will be similar to results - // from very similar seeds, so we immediately discard them here. - for (int i = 0; i < 2; i++) - rand(); } RandomGenerator::Seed RandomGenerator::getSeed() const diff --git a/src/scripts/boot.lua b/src/scripts/boot.lua index c12dd58ed..ddf245f74 100644 --- a/src/scripts/boot.lua +++ b/src/scripts/boot.lua @@ -478,6 +478,7 @@ function love.run() if love.math then love.math.setRandomSeed(os.time()) + for i=1,3 do love.math.random() end end if love.event then diff --git a/src/scripts/boot.lua.h b/src/scripts/boot.lua.h index c00a0f40a..4d6a7b52b 100644 --- a/src/scripts/boot.lua.h +++ b/src/scripts/boot.lua.h @@ -859,6 +859,9 @@ const unsigned char boot_lua[] = 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x53, 0x65, 0x65, 0x64, 0x28, 0x6f, 0x73, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x29, 0x0a, + 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, 0x33, 0x20, 0x64, 0x6f, 0x20, 0x6c, 0x6f, 0x76, + 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, From d3e1993673a16638c757fb3704424cb05478f5f2 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 28 Sep 2014 15:37:56 -0300 Subject: [PATCH 7/7] Rearranged love.window.showMessageBox' arguments so the messagebox type is the second-last argument and defaults to "info" (resolves issue #937.) --- src/modules/window/Window.h | 2 +- src/modules/window/sdl/Window.cpp | 2 +- src/modules/window/sdl/Window.h | 2 +- src/modules/window/wrap_Window.cpp | 29 +++++++++++++++++------------ 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/modules/window/Window.h b/src/modules/window/Window.h index ecd7bd368..658974298 100644 --- a/src/modules/window/Window.h +++ b/src/modules/window/Window.h @@ -165,7 +165,7 @@ public: virtual const void *getHandle() const = 0; - virtual bool showMessageBox(MessageBoxType type, const std::string &title, const std::string &message, bool attachtowindow) = 0; + virtual bool showMessageBox(const std::string &title, const std::string &message, MessageBoxType type, bool attachtowindow) = 0; virtual int showMessageBox(const MessageBoxData &data) = 0; //virtual static Window *createSingleton() = 0; diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 89bb3a9c9..89cbab918 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -773,7 +773,7 @@ SDL_MessageBoxFlags Window::convertMessageBoxType(MessageBoxType type) const } } -bool Window::showMessageBox(MessageBoxType type, const std::string &title, const std::string &message, bool attachtowindow) +bool Window::showMessageBox(const std::string &title, const std::string &message, MessageBoxType type, bool attachtowindow) { SDL_MessageBoxFlags flags = convertMessageBoxType(type); SDL_Window *sdlwindow = attachtowindow ? window : nullptr; diff --git a/src/modules/window/sdl/Window.h b/src/modules/window/sdl/Window.h index 8f1416f14..7b30e3c9c 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -95,7 +95,7 @@ public: const void *getHandle() const; - bool showMessageBox(MessageBoxType type, const std::string &title, const std::string &message, bool attachtowindow); + bool showMessageBox(const std::string &title, const std::string &message, MessageBoxType type, bool attachtowindow); int showMessageBox(const MessageBoxData &data); static love::window::Window *createSingleton(); diff --git a/src/modules/window/wrap_Window.cpp b/src/modules/window/wrap_Window.cpp index b8418591b..94054be55 100644 --- a/src/modules/window/wrap_Window.cpp +++ b/src/modules/window/wrap_Window.cpp @@ -421,32 +421,29 @@ int w_minimize(lua_State* /*L*/) int w_showMessageBox(lua_State *L) { Window::MessageBoxData data = {}; + data.type = Window::MESSAGEBOX_INFO; - const char *typestr = luaL_checkstring(L, 1); - if (!Window::getConstant(typestr, data.type)) - return luaL_error(L, "Invalid messagebox type: %s", typestr); - - data.title = luaL_checkstring(L, 2); - data.message = luaL_checkstring(L, 3); + data.title = luaL_checkstring(L, 1); + data.message = luaL_checkstring(L, 2); // If we have a table argument, we assume a list of button names, which // means we should use the more complex message box API. - if (lua_istable(L, 4)) + if (lua_istable(L, 3)) { - size_t numbuttons = lua_objlen(L, 4); + size_t numbuttons = lua_objlen(L, 3); if (numbuttons == 0) return luaL_error(L, "Must have at least one messagebox button."); // Array of button names. for (size_t i = 0; i < numbuttons; i++) { - lua_rawgeti(L, 4, i + 1); + lua_rawgeti(L, 3, i + 1); data.buttons.push_back(luax_checkstring(L, -1)); lua_pop(L, 1); } // Optional table entry specifying the button to use when enter is pressed. - lua_getfield(L, 4, "enterbutton"); + lua_getfield(L, 3, "enterbutton"); if (!lua_isnoneornil(L, -1)) data.enterButtonIndex = luaL_checkint(L, -1) - 1; else @@ -454,13 +451,17 @@ int w_showMessageBox(lua_State *L) lua_pop(L, 1); // Optional table entry specifying the button to use when esc is pressed. - lua_getfield(L, 4, "escapebutton"); + lua_getfield(L, 3, "escapebutton"); if (!lua_isnoneornil(L, -1)) data.escapeButtonIndex = luaL_checkint(L, -1) - 1; else data.escapeButtonIndex = (int) data.buttons.size() - 1; lua_pop(L, 1); + const char *typestr = lua_isnoneornil(L, 4) ? nullptr : luaL_checkstring(L, 4); + if (typestr && !Window::getConstant(typestr, data.type)) + return luaL_error(L, "Invalid messagebox type: %s", typestr); + data.attachToWindow = luax_optboolean(L, 5, true); int pressedbutton = instance()->showMessageBox(data); @@ -468,10 +469,14 @@ int w_showMessageBox(lua_State *L) } else { + const char *typestr = lua_isnoneornil(L, 3) ? nullptr : luaL_checkstring(L, 3); + if (typestr && !Window::getConstant(typestr, data.type)) + return luaL_error(L, "Invalid messagebox type: %s", typestr); + data.attachToWindow = luax_optboolean(L, 4, true); // Display a simple message box. - bool success = instance()->showMessageBox(data.type, data.title, data.message, data.attachToWindow); + bool success = instance()->showMessageBox(data.title, data.message, data.type, data.attachToWindow); luax_pushboolean(L, success); }