diff --git a/changes.txt b/changes.txt index 7b188a8bc..41704b360 100644 --- a/changes.txt +++ b/changes.txt @@ -8,6 +8,7 @@ LOVE 0.9.2 [Baby Inspector] * Added love.graphics.getCanvasFormats. * Added love.graphics.getCompressedImageFormats. * Added ParticleSystem:setQuads. + * Added ParticleSystem:setLinearDamping. * Added SpriteBatch:flush. * Added love.graphics.getStats. * Added optional duration argument to Joystick:setVibration. @@ -18,8 +19,10 @@ LOVE 0.9.2 [Baby Inspector] * Added love.window.getDisplayName. * Added love.window.minimize. * Added love.window.showMessageBox. - * Added love.filesystem.isSymlink, love.filesystem.setSymlinksEnabled, and love.filesystem.areSymlinksEnabled. * Added 'refreshrate' field to the table returned by love.window.getMode. + * Added love.window.toPixels and love.window.fromPixels. + * Added love.window.setPosition and love.window.getPosition, and 'x' and 'y' fields to love.window.setMode and t.window in love.conf. + * Added love.filesystem.isSymlink, love.filesystem.setSymlinksEnabled, and love.filesystem.areSymlinksEnabled. * Deprecated SpriteBatch:bind and SpriteBatch:unbind. * Deprecated all uses of the name 'FSAA' in favor of 'MSAA'. @@ -27,8 +30,11 @@ LOVE 0.9.2 [Baby Inspector] * Deprecated the 'dxt' and 'bc5' graphics feature enums in favor of getCompressedImageFormats. * Fixed love.filesystem.setIdentity breaking in some situations when called multiple times. + * Fixed the default love.filesystem identity when in Fused mode in Windows. * Fixed love.system.openURL sometimes blocking indefinitely on Linux. + * Fixed love.joystick.setGamepadMapping. * Fixed shader:getWarnings returning unnecessary information. + * Fixed some cases of noncompliant shader code not properly erroring on some nvidia drivers. * Fixed a potential crash when Shader objects are garbage collected. * Fixed love.graphics.newMesh(vertexcount, ...) causing the Mesh to do instanced rendering. * Fixed Mesh:getVertexMap. @@ -38,6 +44,7 @@ LOVE 0.9.2 [Baby Inspector] * Fixed Texture memory leak when Meshes are garbage collected. * Fixed the default line join mode to be 'miter' instead of an undefined value. * Fixed the default error handler text size when highdpi mode is enabled on a Retina monitor. + * Fixed the default error handler background color when sRGB mode is enabled for the window. * Fixed love.window.setMode to fall back to the largest available mode if a width or height greater than the largest supported is specified and fullscreen=true. * Fixed the state of wireframe mode when love.window.setMode is called. * Fixed Canvas:getPixel to error if the coordinates are not within the Canvas' size. @@ -47,6 +54,7 @@ LOVE 0.9.2 [Baby Inspector] * Updated the Lua wrapper code for modules to avoid crashes when the module's instance is created, deleted, and recreated. * Updated internal code for handling garbage collection of love objects to be more efficient. + * Updated love's initialization code to trigger a Lua error if love.conf has an error in it. * Updated the paths returned by love.filesystem.getSaveDirectory and friends to strip double-slashes from the string. * Updated the error message when love.filesystem.write or File:open fails because the directory doesn't exist. * Updated the error message when love.math.setRandomseed(0) is attempted. @@ -55,6 +63,8 @@ LOVE 0.9.2 [Baby Inspector] * Updated SpriteBatch:unbind to use less VRAM if the SpriteBatch has the static usage hint. * Updated love.graphics.newImage, love.image.newImageData, etc. to leave less Lua-owned memory around. * Updated love.graphics.push to accept different stack types to push. Current types are "transform" and "all". + * Updated love shaders to accept GLSL ES precision qualifiers on variables, although they do nothing. + * Updated the error message for love.graphics.newShader to be less cryptic if an invalid filename is given. LOVE 0.9.1 [Baby Inspector] --------------------------- diff --git a/src/common/Matrix.cpp b/src/common/Matrix.cpp index d403e8b02..8a603a3f6 100644 --- a/src/common/Matrix.cpp +++ b/src/common/Matrix.cpp @@ -37,6 +37,11 @@ Matrix::Matrix() setIdentity(); } +Matrix::Matrix(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) +{ + setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); +} + Matrix::~Matrix() { } diff --git a/src/common/Matrix.h b/src/common/Matrix.h index 0e33b37d9..cac6c747a 100644 --- a/src/common/Matrix.h +++ b/src/common/Matrix.h @@ -41,6 +41,11 @@ public: **/ Matrix(); + /** + * Creates a new matrix set to a transformation. + **/ + Matrix(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky); + /** * Destructor. **/ diff --git a/src/modules/graphics/opengl/ParticleSystem.cpp b/src/modules/graphics/opengl/ParticleSystem.cpp index e64fbb1dd..5989ad3f6 100644 --- a/src/modules/graphics/opengl/ParticleSystem.cpp +++ b/src/modules/graphics/opengl/ParticleSystem.cpp @@ -86,6 +86,8 @@ ParticleSystem::ParticleSystem(Texture *texture, uint32 size) , radialAccelerationMax(0) , tangentialAccelerationMin(0) , tangentialAccelerationMax(0) + , linearDampingMin(0.0f) + , linearDampingMax(0.0f) , sizeVariation(0) , rotationMin(0) , rotationMax(0) @@ -135,6 +137,8 @@ ParticleSystem::ParticleSystem(const ParticleSystem &p) , radialAccelerationMax(p.radialAccelerationMax) , tangentialAccelerationMin(p.tangentialAccelerationMin) , tangentialAccelerationMax(p.tangentialAccelerationMax) + , linearDampingMin(p.linearDampingMin) + , linearDampingMax(p.linearDampingMax) , sizes(p.sizes) , sizeVariation(p.sizeVariation) , rotationMin(p.rotationMin) @@ -284,6 +288,10 @@ void ParticleSystem::initParticle(Particle *p, float t) max = tangentialAccelerationMax; p->tangentialAcceleration = (float) rng.random(min, max); + min = linearDampingMin; + max = linearDampingMax; + p->linearDamping = (float) rng.random(min, max); + p->sizeOffset = (float) rng.random(sizeVariation); // time offset for size change p->sizeIntervalSize = (1.0f - (float) rng.random(sizeVariation)) - p->sizeOffset; p->size = sizes[(size_t)(p->sizeOffset - .5f) * (sizes.size() - 1)]; @@ -460,12 +468,10 @@ void ParticleSystem::setParticleLifetime(float min, float max) particleLifeMax = max; } -void ParticleSystem::getParticleLifetime(float *min, float *max) const +void ParticleSystem::getParticleLifetime(float &min, float &max) const { - if (min) - *min = particleLifeMin; - if (max) - *max = particleLifeMax; + min = particleLifeMin; + max = particleLifeMax; } void ParticleSystem::setPosition(float x, float y) @@ -531,12 +537,10 @@ void ParticleSystem::setSpeed(float min, float max) speedMax = max; } -void ParticleSystem::getSpeed(float *min, float *max) const +void ParticleSystem::getSpeed(float &min, float &max) const { - if (min) - *min = speedMin; - if (max) - *max = speedMax; + min = speedMin; + max = speedMax; } void ParticleSystem::setLinearAcceleration(float x, float y) @@ -551,12 +555,10 @@ void ParticleSystem::setLinearAcceleration(float xmin, float ymin, float xmax, f linearAccelerationMax = love::Vector(xmax, ymax); } -void ParticleSystem::getLinearAcceleration(love::Vector *min, love::Vector *max) const +void ParticleSystem::getLinearAcceleration(love::Vector &min, love::Vector &max) const { - if (min) - *min = linearAccelerationMin; - if (max) - *max = linearAccelerationMax; + min = linearAccelerationMin; + max = linearAccelerationMax; } void ParticleSystem::setRadialAcceleration(float acceleration) @@ -570,12 +572,10 @@ void ParticleSystem::setRadialAcceleration(float min, float max) radialAccelerationMax = max; } -void ParticleSystem::getRadialAcceleration(float *min, float *max) const +void ParticleSystem::getRadialAcceleration(float &min, float &max) const { - if (min) - *min = radialAccelerationMin; - if (max) - *max = radialAccelerationMax; + min = radialAccelerationMin; + max = radialAccelerationMax; } void ParticleSystem::setTangentialAcceleration(float acceleration) @@ -589,12 +589,22 @@ void ParticleSystem::setTangentialAcceleration(float min, float max) tangentialAccelerationMax = max; } -void ParticleSystem::getTangentialAcceleration(float *min, float *max) const +void ParticleSystem::getTangentialAcceleration(float &min, float &max) const { - if (min) - *min = tangentialAccelerationMin; - if (max) - *max = tangentialAccelerationMax; + min = tangentialAccelerationMin; + max = tangentialAccelerationMax; +} + +void ParticleSystem::setLinearDamping(float min, float max) +{ + linearDampingMin = min; + linearDampingMax = max; +} + +void ParticleSystem::getLinearDamping(float &min, float &max) const +{ + min = linearDampingMin; + max = linearDampingMax; } void ParticleSystem::setSize(float size) @@ -634,12 +644,10 @@ void ParticleSystem::setRotation(float min, float max) rotationMax = max; } -void ParticleSystem::getRotation(float *min, float *max) const +void ParticleSystem::getRotation(float &min, float &max) const { - if (min) - *min = rotationMin; - if (max) - *max = rotationMax; + min = rotationMin; + max = rotationMax; } void ParticleSystem::setSpin(float spin) @@ -654,12 +662,10 @@ void ParticleSystem::setSpin(float start, float end) spinEnd = end; } -void ParticleSystem::getSpin(float *start, float *end) const +void ParticleSystem::getSpin(float &start, float &end) const { - if (start) - *start = spinStart; - if (end) - *end = spinEnd; + start = spinStart; + end = spinEnd; } void ParticleSystem::setSpinVariation(float variation) @@ -931,6 +937,9 @@ void ParticleSystem::update(float dt) // Update velocity. p->velocity += (radial + tangential + p->linearAcceleration) * dt; + // Apply damping. + p->velocity *= 1.0f / (1.0f + p->linearDamping * dt); + // Modify position. ppos += p->velocity * dt; diff --git a/src/modules/graphics/opengl/ParticleSystem.h b/src/modules/graphics/opengl/ParticleSystem.h index 64b7b6244..4dfe7003d 100644 --- a/src/modules/graphics/opengl/ParticleSystem.h +++ b/src/modules/graphics/opengl/ParticleSystem.h @@ -162,7 +162,7 @@ public: * @param[out] min The minimum life. * @param[out] max The maximum life. **/ - void getParticleLifetime(float *min, float *max) const; + void getParticleLifetime(float &min, float &max) const; /** * Sets the position of the center of the emitter. @@ -249,7 +249,7 @@ public: * @param[out] min The minimum speed. * @param[out] max The maximum speed. **/ - void getSpeed(float *min, float *max) const; + void getSpeed(float &min, float &max) const; /** * Sets the linear acceleration (the acceleration along the x and y axes). @@ -272,7 +272,7 @@ public: * @param[out] min The minimum acceleration. * @param[out] max The maximum acceleration. **/ - void getLinearAcceleration(love::Vector *min, love::Vector *max) const; + void getLinearAcceleration(love::Vector &min, love::Vector &max) const; /** * Sets the radial acceleration (the acceleration towards the particle emitter). @@ -292,7 +292,7 @@ public: * @param[out] min The minimum amount of radial acceleration. * @param[out] max The maximum amount of radial acceleration. **/ - void getRadialAcceleration(float *min, float *max) const; + void getRadialAcceleration(float &min, float &max) const; /** * Sets the tangential acceleration (the acceleration perpendicular to the particle's direction). @@ -312,7 +312,18 @@ public: * @param[out] min The minimum tangential acceleration. * @param[out] max The maximum tangential acceleration. **/ - void getTangentialAcceleration(float *min, float *max) const; + void getTangentialAcceleration(float &min, float &max) const; + + /** + * Sets the amount of linear damping. Damping reduces the velocity of + * particles over time. A value of 0 corresponds to no damping. + **/ + void setLinearDamping(float min, float max); + + /** + * Gets the current amount of linear damping. + **/ + void getLinearDamping(float &min, float &max) const; /** * Sets the size of the sprite (1.0 being the default size). @@ -360,7 +371,7 @@ public: * @param[out] min The minimum initial rotation. * @param[out] max The maximum initial rotation. **/ - void getRotation(float *min, float *max) const; + void getRotation(float &min, float &max) const; /** * Sets the spin of the sprite. @@ -380,7 +391,7 @@ public: * @param[out] start The initial spin, in radians / s. * @param[out] end The final spin, in radians / s. **/ - void getSpin(float *start, float *end) const; + void getSpin(float &start, float &end) const; /** * Sets the variation of the start spin (0 being no variation and 1 being a random spin between start and end). @@ -533,6 +544,8 @@ protected: float radialAcceleration; float tangentialAcceleration; + float linearDamping; + float size; float sizeOffset; float sizeIntervalSize; @@ -619,6 +632,9 @@ protected: float tangentialAccelerationMin; float tangentialAccelerationMax; + float linearDampingMin; + float linearDampingMax; + // Size. std::vector sizes; float sizeVariation; diff --git a/src/modules/graphics/opengl/SpriteBatch.cpp b/src/modules/graphics/opengl/SpriteBatch.cpp index 327dece67..7a6dedd83 100644 --- a/src/modules/graphics/opengl/SpriteBatch.cpp +++ b/src/modules/graphics/opengl/SpriteBatch.cpp @@ -47,7 +47,7 @@ SpriteBatch::SpriteBatch(Texture *texture, int size, int usage) , next(0) , color(0) , array_buf(nullptr) - , element_buf(nullptr) + , element_buf(size) , buffer_used_offset(0) , buffer_used_size(0) { @@ -74,18 +74,15 @@ SpriteBatch::SpriteBatch(Texture *texture, int size, int usage) try { array_buf = VertexBuffer::Create(vertex_size, GL_ARRAY_BUFFER, gl_usage); - element_buf = new VertexIndex(size); } catch (love::Exception &) { delete array_buf; - delete element_buf; throw; } catch (std::bad_alloc &) { delete array_buf; - delete element_buf; throw love::Exception("Out of memory."); } } @@ -94,7 +91,6 @@ SpriteBatch::~SpriteBatch() { delete color; delete array_buf; - delete element_buf; } int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/) @@ -103,20 +99,9 @@ int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, fl if ((index == -1 && next >= size) || index < -1 || index >= size) return -1; - Vertex sprite[4]; + Matrix t(x, y, a, sx, sy, ox, oy, kx, ky); - // Needed for colors. - memcpy(sprite, texture->getVertices(), sizeof(Vertex) * 4); - - // Transform. - Matrix t; - t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky); - t.transform(sprite, sprite, 4); - - if (color) - setColorv(sprite, *color); - - addv(sprite, (index == -1) ? next : index); + addv(texture->getVertices(), t, (index == -1) ? next : index); // Increment counter. if (index == -1) @@ -131,19 +116,9 @@ int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy, if ((index == -1 && next >= size) || index < -1 || index >= next) return -1; - Vertex sprite[4]; + Matrix t(x, y, a, sx, sy, ox, oy, kx, ky); - // Needed for colors. - memcpy(sprite, quad->getVertices(), sizeof(Vertex) * 4); - - Matrix t; - t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky); - t.transform(sprite, sprite, 4); - - if (color) - setColorv(sprite, *color); - - addv(sprite, (index == -1) ? next : index); + addv(quad->getVertices(), t, (index == -1) ? next : index); // Increment counter. if (index == -1) @@ -171,7 +146,7 @@ void SpriteBatch::setTexture(Texture *newtexture) texture.set(newtexture); } -Texture *SpriteBatch::getTexture() +Texture *SpriteBatch::getTexture() const { return texture.get(); } @@ -216,40 +191,32 @@ void SpriteBatch::setBufferSize(int newsize) } size_t vertex_size = sizeof(Vertex) * 4 * newsize; - VertexBuffer *new_array_buf = nullptr; - VertexIndex *new_element_buf = nullptr; try { new_array_buf = VertexBuffer::Create(vertex_size, array_buf->getTarget(), array_buf->getUsage()); - new_element_buf = new VertexIndex(newsize); + + // Copy as much of the old data into the new VertexBuffer as can fit. + VertexBuffer::Bind bind(*new_array_buf); + void *new_data = new_array_buf->map(); + memcpy(new_data, old_data, sizeof(Vertex) * 4 * std::min(newsize, size)); + + element_buf = VertexIndex(newsize); } catch (love::Exception &) { delete new_array_buf; - delete new_element_buf; throw; } - // Copy as much of the old data into the new VertexBuffer as can fit. - { - VertexBuffer::Bind bind(*new_array_buf); - new_array_buf->fill(0, sizeof(Vertex) * 4 * std::min(newsize, size), old_data); - } - // We don't need to unmap the old VertexBuffer since we're deleting it. delete array_buf; - delete element_buf; array_buf = new_array_buf; - element_buf = new_element_buf; size = newsize; next = std::min(next, newsize); - - // The new VertexBuffer isn't mapped, so we should reset these variables. - buffer_used_offset = buffer_used_size = 0; } int SpriteBatch::getBufferSize() const @@ -266,8 +233,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float if (next == 0) return; - static Matrix t; - t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); + Matrix t(x, y, angle, sx, sy, ox, oy, kx, ky); OpenGL::TempTransform transform(gl); transform.get() *= t; @@ -275,7 +241,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float texture->predraw(); VertexBuffer::Bind array_bind(*array_buf); - VertexBuffer::Bind element_bind(*element_buf->getVertexBuffer()); + VertexBuffer::Bind element_bind(*element_buf.getVertexBuffer()); // Make sure the VBO isn't mapped when we draw (sends data to GPU if needed.) array_buf->unmap(buffer_used_offset, buffer_used_size); @@ -297,7 +263,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), array_buf->getPointer(texel_offset)); gl.prepareDraw(); - gl.drawElements(GL_TRIANGLES, element_buf->getIndexCount(next), element_buf->getType(), element_buf->getPointer(0)); + gl.drawElements(GL_TRIANGLES, element_buf.getIndexCount(next), element_buf.getType(), element_buf.getPointer(0)); glDisableVertexAttribArray(ATTRIB_TEXCOORD); glDisableVertexAttribArray(ATTRIB_POS); @@ -311,9 +277,16 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float texture->postdraw(); } -void SpriteBatch::addv(const Vertex *v, int index) +void SpriteBatch::addv(const Vertex *v, const Matrix &m, int index) { - static const size_t sprite_size = 4 * sizeof(Vertex); // bytecount + // Needed for colors. + Vertex sprite[4] = {v[0], v[1], v[2], v[3]}; + const size_t sprite_size = 4 * sizeof(Vertex); // bytecount + + m.transform(sprite, sprite, 4); + + if (color) + setColorv(sprite, *color); VertexBuffer::Bind bind(*array_buf); @@ -321,7 +294,7 @@ void SpriteBatch::addv(const Vertex *v, int index) // on draw.) array_buf->map(); - array_buf->fill(index * sprite_size, sprite_size, v); + array_buf->fill(index * sprite_size, sprite_size, sprite); buffer_used_offset = std::min(buffer_used_offset, index * sprite_size); buffer_used_size = std::max(buffer_used_size, (index + 1) * sprite_size - buffer_used_offset); diff --git a/src/modules/graphics/opengl/SpriteBatch.h b/src/modules/graphics/opengl/SpriteBatch.h index 55a736929..dd9e5bfe7 100644 --- a/src/modules/graphics/opengl/SpriteBatch.h +++ b/src/modules/graphics/opengl/SpriteBatch.h @@ -26,13 +26,13 @@ // LOVE #include "common/math.h" -#include "common/Object.h" #include "common/Matrix.h" #include "common/StringMap.h" #include "graphics/Drawable.h" #include "graphics/Volatile.h" #include "graphics/Color.h" #include "graphics/Quad.h" +#include "VertexBuffer.h" namespace love { @@ -43,8 +43,6 @@ namespace opengl // Forward declarations. class Texture; -class VertexBuffer; -class VertexIndex; class SpriteBatch : public Drawable { @@ -68,7 +66,7 @@ public: void flush(); void setTexture(Texture *newtexture); - Texture *getTexture(); + Texture *getTexture() const; /** * Set the current color for this SpriteBatch. The sprites added @@ -115,7 +113,7 @@ public: private: - void addv(const Vertex *v, int index); + void addv(const Vertex *v, const Matrix &m, int index); /** * Set the color for vertices. @@ -139,7 +137,7 @@ private: Color *color; VertexBuffer *array_buf; - VertexIndex *element_buf; + VertexIndex element_buf; // The portion of the vertex buffer that's been modified while mapped. size_t buffer_used_offset; diff --git a/src/modules/graphics/opengl/VertexBuffer.cpp b/src/modules/graphics/opengl/VertexBuffer.cpp index ee712d5c9..6b8d185aa 100644 --- a/src/modules/graphics/opengl/VertexBuffer.cpp +++ b/src/modules/graphics/opengl/VertexBuffer.cpp @@ -50,7 +50,7 @@ VertexBuffer::VertexBuffer(size_t size, GLenum target, GLenum usage, MemoryBacki , backing(backing) , vbo(0) , memory_map(nullptr) - , is_dirty(true) + , is_dirty(false) { if (getMemoryBacking() == BACKING_FULL) memory_map = (char *) malloc(getSize()); @@ -249,6 +249,20 @@ VertexIndex::VertexIndex(size_t size) addSize(size); } +VertexIndex::VertexIndex(const VertexIndex &other) + : size(other.size) +{ + addSize(size); +} + +VertexIndex &VertexIndex::operator = (const VertexIndex &other) +{ + addSize(other.size); + removeSize(size); + size = other.size; + return *this; +} + VertexIndex::~VertexIndex() { removeSize(size); diff --git a/src/modules/graphics/opengl/VertexBuffer.h b/src/modules/graphics/opengl/VertexBuffer.h index 68eb10456..97a4c0523 100644 --- a/src/modules/graphics/opengl/VertexBuffer.h +++ b/src/modules/graphics/opengl/VertexBuffer.h @@ -344,6 +344,9 @@ public: */ VertexIndex(size_t size); + VertexIndex(const VertexIndex &other); + VertexIndex &operator = (const VertexIndex &other); + /** * Removes an entry from the list of sizes and resizes the VertexBuffer * if needed. diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index ee82661f0..fab2bf271 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -28,6 +28,7 @@ #include "scripts/graphics.lua.h" #include +#include namespace love { @@ -412,6 +413,19 @@ int w_newShader(lua_State *L) lua_call(L, 1, 1); lua_replace(L, i); } + else + { + // Check if the argument looks like a filepath - we want a nicer + // error for misspelled filepath arguments. + size_t slen = 0; + const char *str = lua_tolstring(L, i, &slen); + if (slen > 0 && slen < 256 && !strchr(str, '\n')) + { + const char *ext = strchr(str, '.'); + if (ext != nullptr && !strchr(ext, ';') && !strchr(ext, ' ')) + return luaL_error(L, "Could not open file %s. Does not exist.", str); + } + } } bool has_arg1 = lua_isstring(L, 1); diff --git a/src/modules/graphics/opengl/wrap_ParticleSystem.cpp b/src/modules/graphics/opengl/wrap_ParticleSystem.cpp index a786f2860..212dde062 100644 --- a/src/modules/graphics/opengl/wrap_ParticleSystem.cpp +++ b/src/modules/graphics/opengl/wrap_ParticleSystem.cpp @@ -164,7 +164,7 @@ int w_ParticleSystem_getParticleLifetime(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); float min, max; - t->getParticleLifetime(&min, &max); + t->getParticleLifetime(min, max); lua_pushnumber(L, min); lua_pushnumber(L, max); return 2; @@ -278,7 +278,7 @@ int w_ParticleSystem_getSpeed(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); float min, max; - t->getSpeed(&min, &max); + t->getSpeed(min, max); lua_pushnumber(L, min); lua_pushnumber(L, max); return 2; @@ -299,7 +299,7 @@ int w_ParticleSystem_getLinearAcceleration(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); love::Vector min, max; - t->getLinearAcceleration(&min, &max); + t->getLinearAcceleration(min, max); lua_pushnumber(L, min.x); lua_pushnumber(L, min.y); lua_pushnumber(L, max.x); @@ -320,7 +320,7 @@ int w_ParticleSystem_getRadialAcceleration(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); float min, max; - t->getRadialAcceleration(&min, &max); + t->getRadialAcceleration(min, max); lua_pushnumber(L, min); lua_pushnumber(L, max); return 2; @@ -339,7 +339,26 @@ int w_ParticleSystem_getTangentialAcceleration(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); float min, max; - t->getTangentialAcceleration(&min, &max); + t->getTangentialAcceleration(min, max); + lua_pushnumber(L, min); + lua_pushnumber(L, max); + return 2; +} + +int w_ParticleSystem_setLinearDamping(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + float arg2 = (float)luaL_optnumber(L, 3, arg1); + t->setLinearDamping(arg1, arg2); + return 0; +} + +int w_ParticleSystem_getLinearDamping(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + float min, max; + t->getLinearDamping(min, max); lua_pushnumber(L, min); lua_pushnumber(L, max); return 2; @@ -411,7 +430,7 @@ int w_ParticleSystem_getRotation(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); float min, max; - t->getRotation(&min, &max); + t->getRotation(min, max); lua_pushnumber(L, min); lua_pushnumber(L, max); return 2; @@ -430,7 +449,7 @@ int w_ParticleSystem_getSpin(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); float start, end; - t->getSpin(&start, &end); + t->getSpin(start, end); lua_pushnumber(L, start); lua_pushnumber(L, end); return 2; @@ -730,6 +749,8 @@ static const luaL_Reg functions[] = { "getRadialAcceleration", w_ParticleSystem_getRadialAcceleration }, { "setTangentialAcceleration", w_ParticleSystem_setTangentialAcceleration }, { "getTangentialAcceleration", w_ParticleSystem_getTangentialAcceleration }, + { "setLinearDamping", w_ParticleSystem_setLinearDamping }, + { "getLinearDamping", w_ParticleSystem_getLinearDamping }, { "setSizes", w_ParticleSystem_setSizes }, { "getSizes", w_ParticleSystem_getSizes }, { "setSizeVariation", w_ParticleSystem_setSizeVariation }, diff --git a/src/modules/graphics/opengl/wrap_ParticleSystem.h b/src/modules/graphics/opengl/wrap_ParticleSystem.h index f1f788388..3fdc62c1d 100644 --- a/src/modules/graphics/opengl/wrap_ParticleSystem.h +++ b/src/modules/graphics/opengl/wrap_ParticleSystem.h @@ -63,6 +63,8 @@ int w_ParticleSystem_setRadialAcceleration(lua_State *L); int w_ParticleSystem_getRadialAcceleration(lua_State *L); int w_ParticleSystem_setTangentialAcceleration(lua_State *L); int w_ParticleSystem_getTangentialAcceleration(lua_State *L); +int w_ParticleSystem_setLinearDamping(lua_State *L); +int w_ParticleSystem_getLinearDamping(lua_State *L); int w_ParticleSystem_setSizes(lua_State *L); int w_ParticleSystem_getSizes(lua_State *L); int w_ParticleSystem_setSizeVariation(lua_State *L); diff --git a/src/modules/window/Window.cpp b/src/modules/window/Window.cpp index 68dc0c602..89edccca0 100644 --- a/src/modules/window/Window.cpp +++ b/src/modules/window/Window.cpp @@ -83,6 +83,8 @@ StringMap::Entry Window::settingEntri {"highdpi", SETTING_HIGHDPI}, {"srgb", SETTING_SRGB}, {"refreshrate", SETTING_REFRESHRATE}, + {"x", SETTING_X}, + {"y", SETTING_Y}, }; StringMap Window::settings(Window::settingEntries, sizeof(Window::settingEntries)); diff --git a/src/modules/window/Window.h b/src/modules/window/Window.h index 070912876..3595895d7 100644 --- a/src/modules/window/Window.h +++ b/src/modules/window/Window.h @@ -59,6 +59,8 @@ public: SETTING_HIGHDPI, SETTING_SRGB, SETTING_REFRESHRATE, + SETTING_X, + SETTING_Y, SETTING_MAX_ENUM }; @@ -118,6 +120,9 @@ public: virtual void getDesktopDimensions(int displayindex, int &width, int &height) const = 0; + virtual void setPosition(int x, int y, int displayindex) = 0; + virtual void getPosition(int &x, int &y, int &displayindex) = 0; + virtual bool isCreated() const = 0; virtual void setWindowTitle(const std::string &title) = 0; @@ -199,6 +204,9 @@ struct WindowSettings bool highdpi = false; bool sRGB = false; double refreshrate = 0.0; + bool useposition = false; + int x = 0; + int y = 0; }; } // window diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index c7d15bfd7..db852fb6d 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -116,6 +116,25 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI; #endif + int x = f.x; + int y = f.y; + + if (f.useposition && !f.fullscreen) + { + // The position needs to be in the global coordinate space. + SDL_Rect displaybounds = {}; + SDL_GetDisplayBounds(f.display, &displaybounds); + x += displaybounds.x; + y += displaybounds.y; + } + else + { + if (f.centered) + x = y = SDL_WINDOWPOS_CENTERED_DISPLAY(f.display); + else + x = y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display); + } + graphics::Graphics *gfx = Module::getInstance(Module::M_GRAPHICS); if (gfx != nullptr) gfx->unSetMode(); @@ -148,9 +167,6 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) } } - int centeredpos = SDL_WINDOWPOS_CENTERED_DISPLAY(f.display); - int uncenteredpos = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display); - if (!window) { created = false; @@ -159,9 +175,8 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) setWindowGLAttributes(f.msaa, f.sRGB); const char *title = windowTitle.c_str(); - int pos = f.centered ? centeredpos : uncenteredpos; - window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags); + window = SDL_CreateWindow(title, x, y, width, height, sdlflags); if (!window && f.msaa > 0) { @@ -169,7 +184,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); - window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags); + window = SDL_CreateWindow(title, x, y, width, height, sdlflags); f.msaa = 0; } @@ -187,8 +202,8 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) // Enforce minimum window dimensions. SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight); - if (f.centered && !f.fullscreen) - SDL_SetWindowPosition(window, centeredpos, centeredpos); + if ((f.useposition || f.centered) && !f.fullscreen) + SDL_SetWindowPosition(window, x, y); SDL_RaiseWindow(window); @@ -366,7 +381,8 @@ void Window::updateSettings(const WindowSettings &newsettings) curMode.settings.resizable = (wflags & SDL_WINDOW_RESIZABLE) != 0; curMode.settings.borderless = (wflags & SDL_WINDOW_BORDERLESS) != 0; curMode.settings.centered = newsettings.centered; - curMode.settings.display = std::max(SDL_GetWindowDisplayIndex(window), 0); + + getPosition(curMode.settings.x, curMode.settings.y, curMode.settings.display); #if SDL_VERSION_ATLEAST(2,0,1) curMode.settings.highdpi = (wflags & SDL_WINDOW_ALLOW_HIGHDPI) != 0; @@ -525,6 +541,50 @@ void Window::getDesktopDimensions(int displayindex, int &width, int &height) con } } +void Window::setPosition(int x, int y, int displayindex) +{ + if (!window) + return; + + displayindex = std::min(std::max(displayindex, 0), getDisplayCount() - 1); + + SDL_Rect displaybounds = {}; + SDL_GetDisplayBounds(displayindex, &displaybounds); + + // The position needs to be in the global coordinate space. + x += displaybounds.x; + y += displaybounds.y; + + SDL_SetWindowPosition(window, x, y); + + curMode.settings.useposition = true; +} + +void Window::getPosition(int &x, int &y, int &displayindex) +{ + if (!window) + { + x = y = 0; + displayindex = 0; + return; + } + + displayindex = std::max(SDL_GetWindowDisplayIndex(window), 0); + + SDL_GetWindowPosition(window, &x, &y); + + // SDL always reports 0, 0 for fullscreen windows. + if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN)) + { + SDL_Rect displaybounds = {}; + SDL_GetDisplayBounds(displayindex, &displaybounds); + + // The position needs to be in the monitor's coordinate space. + x -= displaybounds.x; + y -= displaybounds.y; + } +} + bool Window::isCreated() const { return created; diff --git a/src/modules/window/sdl/Window.h b/src/modules/window/sdl/Window.h index 723272b8c..83f277f7f 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -57,6 +57,9 @@ public: void getDesktopDimensions(int displayindex, int &width, int &height) const; + void setPosition(int x, int y, int displayindex); + void getPosition(int &x, int &y, int &displayindex); + bool isCreated() const; void setWindowTitle(const std::string &title); diff --git a/src/modules/window/wrap_Window.cpp b/src/modules/window/wrap_Window.cpp index e59b49e01..297362445 100644 --- a/src/modules/window/wrap_Window.cpp +++ b/src/modules/window/wrap_Window.cpp @@ -109,6 +109,16 @@ int w_setMode(lua_State *L) settings.highdpi = luax_boolflag(L, 3, settingName(Window::SETTING_HIGHDPI), false); settings.sRGB = luax_boolflag(L, 3, settingName(Window::SETTING_SRGB), false); + lua_getfield(L, 3, settingName(Window::SETTING_X)); + lua_getfield(L, 3, settingName(Window::SETTING_Y)); + settings.useposition = !(lua_isnoneornil(L, -2) && lua_isnoneornil(L, -1)); + if (settings.useposition) + { + settings.x = luaL_optint(L, -2, 0); + settings.y = luaL_optint(L, -1, 0); + } + lua_pop(L, 2); + // We don't explicitly set the refresh rate, it's "read-only". luax_catchexcept(L, @@ -171,6 +181,12 @@ int w_getMode(lua_State *L) lua_pushnumber(L, settings.refreshrate); lua_setfield(L, -2, settingName(Window::SETTING_REFRESHRATE)); + lua_pushinteger(L, settings.x); + lua_setfield(L, -2, settingName(Window::SETTING_X)); + + lua_pushinteger(L, settings.y); + lua_setfield(L, -2, settingName(Window::SETTING_Y)); + return 3; } @@ -253,6 +269,27 @@ int w_getDesktopDimensions(lua_State *L) return 2; } +int w_setPosition(lua_State *L) +{ + int x = luaL_checkint(L, 1); + int y = luaL_checkint(L, 2); + int displayindex = luaL_optint(L, 3, 1) - 1; + instance()->setPosition(x, y, displayindex); + return 0; +} + +int w_getPosition(lua_State *L) +{ + int x = 0; + int y = 0; + int displayindex = 0; + instance()->getPosition(x, y, displayindex); + lua_pushinteger(L, x); + lua_pushinteger(L, y); + lua_pushinteger(L, displayindex + 1); + return 3; +} + int w_setIcon(lua_State *L) { image::ImageData *i = luax_checktype(L, 1, "ImageData", IMAGE_IMAGE_DATA_T); @@ -426,6 +463,8 @@ static const luaL_Reg functions[] = { "getFullscreen", w_getFullscreen }, { "isCreated", w_isCreated }, { "getDesktopDimensions", w_getDesktopDimensions }, + { "setPosition", w_setPosition }, + { "getPosition", w_getPosition }, { "setIcon", w_setIcon }, { "getIcon", w_getIcon }, { "setTitle", w_setTitle }, diff --git a/src/modules/window/wrap_Window.h b/src/modules/window/wrap_Window.h index 8df92bcdc..14d6c042f 100644 --- a/src/modules/window/wrap_Window.h +++ b/src/modules/window/wrap_Window.h @@ -38,6 +38,8 @@ int w_setFullscreen(lua_State *L); int w_getFullscreen(lua_State *L); int w_isCreated(lua_State *L); int w_getDesktopDimensions(lua_State *L); +int w_setPosition(lua_State *L); +int w_getPosition(lua_State *L); int w_setIcon(lua_State *L); int w_getIcon(lua_State *L); int w_setTitle(lua_State *L); diff --git a/src/scripts/boot.lua b/src/scripts/boot.lua index e3145aaa4..bd0c942dc 100644 --- a/src/scripts/boot.lua +++ b/src/scripts/boot.lua @@ -303,6 +303,8 @@ function love.init() window = { width = 800, height = 600, + x = nil, + y = nil, minwidth = 1, minheight = 1, fullscreen = false, @@ -408,6 +410,8 @@ function love.init() display = c.window.display, highdpi = c.window.highdpi, srgb = c.window.srgb, + x = c.window.x, + y = c.window.y, }), "Could not set window mode") love.window.setTitle(c.window.title or c.title) if c.window.icon then diff --git a/src/scripts/boot.lua.h b/src/scripts/boot.lua.h index 5ad41af98..3db477a06 100644 --- a/src/scripts/boot.lua.h +++ b/src/scripts/boot.lua.h @@ -553,6 +553,8 @@ const unsigned char boot_lua[] = 0x09, 0x09, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x38, 0x30, 0x30, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x36, 0x30, 0x30, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x78, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x79, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x61, @@ -716,6 +718,8 @@ const unsigned char boot_lua[] = 0x64, 0x6f, 0x77, 0x2e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x73, 0x72, 0x67, 0x62, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x72, 0x67, 0x62, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x78, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x78, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x79, 0x2c, 0x0a, 0x09, 0x09, 0x7d, 0x29, 0x2c, 0x20, 0x22, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x65, 0x74, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54,