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/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 3be26e7da..a723b9b8b 100644 --- a/src/modules/audio/openal/Source.h +++ b/src/modules/audio/openal/Source.h @@ -144,7 +144,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.cpp b/src/modules/event/sdl/Event.cpp index 938b5bae8..bae71cfc7 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/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 ba4d9b810..3a13a1f57 100644 --- a/src/modules/filesystem/physfs/Filesystem.h +++ b/src/modules/filesystem/physfs/Filesystem.h @@ -24,7 +24,6 @@ // STD #include #include -#include #include #include diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index b00ea8436..9b135b271 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -35,6 +35,7 @@ // C #include +#include namespace love { @@ -223,7 +224,7 @@ bool Graphics::setMode(int width, int height, bool &sRGB) message += "\nThe program may crash or have graphical issues."; ::printf("%s\n%s\n", title.c_str(), message.c_str()); - currentWindow->showMessageBox(type, title, message, true); + currentWindow->showMessageBox(title, message, type, true); // We should only show the message once, instead of after every setMode. displayedMinReqWarning = true; @@ -283,7 +284,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()); @@ -650,9 +651,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 39d4288be..b2b4a623d 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 @@ -154,7 +153,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 fb8592404..71d5bff43 100644 --- a/src/modules/graphics/opengl/Shader.cpp +++ b/src/modules/graphics/opengl/Shader.cpp @@ -64,20 +64,20 @@ namespace Shader *Shader::current = nullptr; Shader *Shader::defaultShader = nullptr; -Shader::ShaderSources Shader::defaultCode[1]; // TODO: RENDERER_MAX_ENUM +Shader::ShaderSource Shader::defaultCode[1]; // TODO: RENDERER_MAX_ENUM 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) @@ -108,21 +108,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."); @@ -132,128 +132,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."); - - try - { - for (GLuint id : shaderids) - glAttachShader(program, id); - } - catch (love::Exception &) - { - glDeleteProgram(program); - throw; - } - - // Bind love's vertex attribute indices to names in the shader. - for (int i = 0; i < int(ATTRIB_MAX_ENUM); i++) - { - VertexAttribID attrib = (VertexAttribID) 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 can cause a shader linker warning. - if (attrib == ATTRIB_PSEUDO_INSTANCE_ID) - continue; - - const char *name = nullptr; - if (attribNames.find(attrib, name)) - glBindAttribLocation(program, i, (const GLchar *) name); - } - - glLinkProgram(program); - - 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()); - } - - // flag shaders for auto-deletion when the program object is deleted. - for (GLuint id : shaderids) - glDeleteShader(id); -} - 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) { @@ -278,35 +225,18 @@ 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) - { - GLuint shaderid = compileCode(source.first, source.second); - shaderids.push_back(shaderid); - } - // The shader program must have both vertex and pixel shader stages. - ShaderSources &defaults = defaultCode[0]; + const ShaderSource &defaults = defaultCode[0]; - ShaderSources::const_iterator source = shaderSources.find(TYPE_VERTEX); - if (source == shaderSources.end()) - shaderids.push_back(compileCode(TYPE_VERTEX, defaults[TYPE_VERTEX])); - - source = shaderSources.find(TYPE_PIXEL); - if (source == shaderSources.end()) - shaderids.push_back(compileCode(TYPE_PIXEL, defaults[TYPE_PIXEL])); - - if (shaderids.empty()) - throw love::Exception("Cannot create shader: no valid source code!"); + const std::string &vertexcode = shaderSource.vertex.empty() ? defaults.vertex : shaderSource.vertex; + const std::string &pixelcode = shaderSource.pixel.empty() ? defaults.pixel : shaderSource.pixel; try { - createProgram(shaderids); + shaderids.push_back(compileCode(STAGE_VERTEX, vertexcode)); + shaderids.push_back(compileCode(STAGE_PIXEL, pixelcode)); } catch (love::Exception &) { @@ -315,6 +245,51 @@ bool Shader::loadVolatile() throw; } + 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(ATTRIB_MAX_ENUM); i++) + { + VertexAttribID attrib = (VertexAttribID) 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 == 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(); @@ -322,9 +297,9 @@ bool Shader::loadVolatile() { const char *name = nullptr; if (attribNames.find(VertexAttribID(i), name)) - vertexAttributes[i] = glGetAttribLocation(program, name); + builtinAttributes[i] = glGetAttribLocation(program, name); else - vertexAttributes[i] = -1; + builtinAttributes[i] = -1; } if (current == this) @@ -371,13 +346,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); @@ -389,13 +367,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(); @@ -644,7 +622,7 @@ Shader::UniformType Shader::getExternVariable(const std::string &name, int &comp bool Shader::hasVertexAttrib(VertexAttribID attrib) const { - return vertexAttributes[int(attrib)] != -1; + return builtinAttributes[int(attrib)] != -1; } bool Shader::hasBuiltinUniform(BuiltinUniform builtin) const @@ -816,13 +794,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 019fd91ca..f09478f49 100644 --- a/src/modules/graphics/opengl/Shader.h +++ b/src/modules/graphics/opengl/Shader.h @@ -46,11 +46,11 @@ class Shader : public Object, public Volatile { public: - enum ShaderType + enum ShaderStage { - TYPE_VERTEX, - TYPE_PIXEL, - TYPE_MAX_ENUM + STAGE_VERTEX, + STAGE_PIXEL, + STAGE_MAX_ENUM }; // Built-in uniform (extern) variables. @@ -71,8 +71,11 @@ 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; + }; // Pointer to currently active Shader. static Shader *current; @@ -81,13 +84,13 @@ public: static Shader *defaultShader; // Default shader code (a shader is always required internally.) - static ShaderSources defaultCode[1]; // TODO: RENDERER_MAX_ENUM + static ShaderSource defaultCode[1]; // TODO: RENDERER_MAX_ENUM /** * 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(); @@ -202,8 +205,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); @@ -212,11 +214,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; @@ -225,7 +227,7 @@ private: GLint builtinUniforms[BUILTIN_MAX_ENUM]; // Location values for any generic vertex attribute variables. - GLint vertexAttributes[ATTRIB_MAX_ENUM]; + GLint builtinAttributes[ATTRIB_MAX_ENUM]; // Uniform location buffer map std::map uniforms; @@ -247,8 +249,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 fab2bf271..cc0094846 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -445,27 +445,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++) @@ -478,7 +472,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(); } @@ -982,9 +976,9 @@ int w_setDefaultShaderCode(lua_State *L) lua_rawgeti(L, -1, 1); lua_rawgeti(L, -2, 2); - Shader::ShaderSources openglcode; - openglcode[Shader::TYPE_VERTEX] = luax_checkstring(L, -2); - openglcode[Shader::TYPE_PIXEL] = luax_checkstring(L, -1); + Shader::ShaderSource openglcode; + openglcode.vertex = luax_checkstring(L, -2); + openglcode.pixel = luax_checkstring(L, -1); lua_pop(L, 3); 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 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/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/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 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; @@ -767,7 +755,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 83f277f7f..43f007c2d 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -92,7 +92,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 297362445..fe408dc59 100644 --- a/src/modules/window/wrap_Window.cpp +++ b/src/modules/window/wrap_Window.cpp @@ -395,32 +395,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 @@ -428,13 +425,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); @@ -442,10 +443,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); } diff --git a/src/scripts/boot.lua b/src/scripts/boot.lua index bd0c942dc..5e4645f01 100644 --- a/src/scripts/boot.lua +++ b/src/scripts/boot.lua @@ -479,6 +479,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 3db477a06..e59131b39 100644 --- a/src/scripts/boot.lua.h +++ b/src/scripts/boot.lua.h @@ -858,6 +858,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,