Merged default into minor

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2014-06-16 03:09:04 -03:00
40 changed files with 376 additions and 117 deletions
+31
View File
@@ -1,3 +1,34 @@
LOVE 0.9.2 [Baby Inspector]
---------------------------
Released: N/A
* Added Shader:getExternVariable.
* Added several new canvas texture formats.
* Added love.graphics.hasCanvasFormat.
* Added an optional duration argument to Joystick:setVibration.
* Added love.joystick.loadGamepadMappings and love.joystick.saveGamepadMappings.
* Added Joint:setUserData and Joint:getUserData.
* Added Body:getWorld.
* Added love.window.getDisplayName.
* Fixed shader:getWarnings returning unnecessary information.
* Fixed love.filesystem.setIdentity breaking in some situations when called multiple times.
* 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.
* Fixed Image:refresh generating mipmaps multiple times if mipmap filtering is enabled.
* Fixed Mesh:setDrawRange when the Mesh has a vertex map set.
* Fixed internal detection of the 'position' and 'effect' shader functions.
* Renamed all cases of FSAA to MSAA. The FSAA names still exist for backward-compatibility.
* Updated error message when love.math.setRandomseed(0) is attempted.
* Updated love.physics.newChainShape to error if the number of arguments is invalid.
* Updated love-created threads to use names visible in external debuggers.
* 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.
LOVE 0.9.1 [Baby Inspector]
---------------------------
+1 -1
View File
@@ -184,7 +184,7 @@ StringMap<Graphics::SystemLimit, Graphics::LIMIT_MAX_ENUM>::Entry Graphics::syst
{"pointsize", Graphics::LIMIT_POINT_SIZE},
{"texturesize", Graphics::LIMIT_TEXTURE_SIZE},
{"multicanvas", Graphics::LIMIT_MULTI_CANVAS},
{"canvasfsaa", Graphics::LIMIT_CANVAS_FSAA},
{"canvasmsaa", Graphics::LIMIT_CANVAS_MSAA},
};
StringMap<Graphics::SystemLimit, Graphics::LIMIT_MAX_ENUM> Graphics::systemLimits(Graphics::systemLimitEntries, sizeof(Graphics::systemLimitEntries));
+1 -1
View File
@@ -102,7 +102,7 @@ public:
LIMIT_POINT_SIZE,
LIMIT_TEXTURE_SIZE,
LIMIT_MULTI_CANVAS,
LIMIT_CANVAS_FSAA,
LIMIT_CANVAS_MSAA,
LIMIT_MAX_ENUM
};
+37 -37
View File
@@ -417,15 +417,15 @@ static void getStrategy()
}
}
Canvas::Canvas(int width, int height, Format format, int fsaa)
Canvas::Canvas(int width, int height, Format format, int msaa)
: fbo(0)
, resolve_fbo(0)
, texture(0)
, fsaa_buffer(0)
, msaa_buffer(0)
, depth_stencil(0)
, format(format)
, fsaa_samples(fsaa)
, fsaa_dirty(false)
, msaa_samples(msaa)
, msaa_dirty(false)
{
this->width = width;
this->height = height;
@@ -467,7 +467,7 @@ Canvas::~Canvas()
unloadVolatile();
}
bool Canvas::createFSAAFBO(GLenum internalformat)
bool Canvas::createMSAAFBO(GLenum internalformat)
{
// Create our FBO without a texture.
status = strategy->createFBO(fbo, 0);
@@ -482,7 +482,7 @@ bool Canvas::createFSAAFBO(GLenum internalformat)
}
// Create and attach the MSAA buffer for our FBO.
if (strategy->createMSAABuffer(width, height, fsaa_samples, internalformat, fsaa_buffer))
if (strategy->createMSAABuffer(width, height, msaa_samples, internalformat, msaa_buffer))
status = GL_FRAMEBUFFER_COMPLETE;
else
status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
@@ -494,10 +494,10 @@ bool Canvas::createFSAAFBO(GLenum internalformat)
if (status != GL_FRAMEBUFFER_COMPLETE)
{
// Clean up.
strategy->deleteFBO(fbo, 0, fsaa_buffer);
strategy->deleteFBO(fbo, 0, msaa_buffer);
strategy->deleteFBO(resolve_fbo, 0, 0);
fbo = fsaa_buffer = resolve_fbo = 0;
fsaa_samples = 0;
fbo = msaa_buffer = resolve_fbo = 0;
msaa_samples = 0;
}
if (current != this)
@@ -509,7 +509,7 @@ bool Canvas::createFSAAFBO(GLenum internalformat)
bool Canvas::loadVolatile()
{
fbo = depth_stencil = texture = 0;
resolve_fbo = fsaa_buffer = 0;
resolve_fbo = msaa_buffer = 0;
status = GL_FRAMEBUFFER_COMPLETE;
// glTexImage2D is guaranteed to error in this case.
@@ -556,16 +556,16 @@ bool Canvas::loadVolatile()
glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
}
if (fsaa_samples > max_samples)
fsaa_samples = max_samples;
if (msaa_samples > max_samples)
msaa_samples = max_samples;
// Try to create a FSAA FBO if requested.
bool fsaasuccess = false;
if (fsaa_samples > 1)
fsaasuccess = createFSAAFBO(internalformat);
// Try to create a MSAA FBO if requested.
bool msaasuccess = false;
if (msaa_samples > 1)
msaasuccess = createMSAAFBO(internalformat);
// On failure (or no requested FSAA), fall back to a regular FBO.
if (!fsaasuccess)
// On failure (or no requested MSAA), fall back to a regular FBO.
if (!msaasuccess)
status = strategy->createFBO(fbo, texture);
if (status != GL_FRAMEBUFFER_COMPLETE)
@@ -573,20 +573,20 @@ bool Canvas::loadVolatile()
clear(Color(0, 0, 0, 0));
fsaa_dirty = (fsaa_buffer != 0);
msaa_dirty = (msaa_buffer != 0);
return true;
}
void Canvas::unloadVolatile()
{
strategy->deleteFBO(fbo, depth_stencil, fsaa_buffer);
strategy->deleteFBO(fbo, depth_stencil, msaa_buffer);
strategy->deleteFBO(resolve_fbo, 0, 0);
gl.deleteTexture(texture);
fbo = depth_stencil = texture = 0;
resolve_fbo = fsaa_buffer = 0;
resolve_fbo = msaa_buffer = 0;
for (size_t i = 0; i < attachedCanvases.size(); i++)
attachedCanvases[i]->release();
@@ -705,8 +705,8 @@ void Canvas::setupGrab()
else if (screenHasSRGB)
glDisable(GL_FRAMEBUFFER_SRGB);
if (fsaa_buffer != 0)
fsaa_dirty = true;
if (msaa_buffer != 0)
msaa_dirty = true;
}
void Canvas::startGrab(const std::vector<Canvas *> &canvases)
@@ -723,8 +723,8 @@ void Canvas::startGrab(const std::vector<Canvas *> &canvases)
if ((int) canvases.size() + 1 > gl.getMaxRenderTargets())
throw love::Exception("This system can't simultaniously render to %d canvases.", canvases.size()+1);
if (fsaa_samples != 0)
throw love::Exception("Multi-canvas rendering is not supported with FSAA.");
if (msaa_samples != 0)
throw love::Exception("Multi-canvas rendering is not supported with MSAA.");
}
for (size_t i = 0; i < canvases.size(); i++)
@@ -735,8 +735,8 @@ void Canvas::startGrab(const std::vector<Canvas *> &canvases)
if (canvases[i]->getTextureFormat() != format)
throw love::Exception("All canvas arguments must have the same texture format.");
if (canvases[i]->getFSAA() != 0)
throw love::Exception("Multi-canvas rendering is not supported with FSAA.");
if (canvases[i]->getMSAA() != 0)
throw love::Exception("Multi-canvas rendering is not supported with MSAA.");
if (!canvaseschanged && canvases[i] != attachedCanvases[i])
canvaseschanged = true;
@@ -857,8 +857,8 @@ void Canvas::clear(Color c)
if (current != this)
strategy->bindFBO(previous);
if (fsaa_buffer != 0)
fsaa_dirty = true;
if (msaa_buffer != 0)
msaa_dirty = true;
}
bool Canvas::checkCreateStencil()
@@ -870,7 +870,7 @@ bool Canvas::checkCreateStencil()
if (current != this)
strategy->bindFBO(fbo);
bool success = strategy->createStencil(width, height, fsaa_samples, depth_stencil);
bool success = strategy->createStencil(width, height, msaa_samples, depth_stencil);
if (current && current != this)
strategy->bindFBO(current->fbo);
@@ -889,9 +889,9 @@ love::image::ImageData *Canvas::getImageData(love::image::Image *image)
GLubyte *pixels = new GLubyte[size];
// Our texture is attached to 'resolve_fbo' when we use MSAA.
if (fsaa_samples > 1 && (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object))
if (msaa_samples > 1 && (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object))
glBindFramebuffer(GL_READ_FRAMEBUFFER, resolve_fbo);
else if (fsaa_samples > 1 && GLEE_EXT_framebuffer_multisample)
else if (msaa_samples > 1 && GLEE_EXT_framebuffer_multisample)
glBindFramebufferEXT(GL_READ_FRAMEBUFFER, resolve_fbo);
else
strategy->bindFBO(fbo);
@@ -913,9 +913,9 @@ void Canvas::getPixel(unsigned char* pixel_rgba, int x, int y)
resolveMSAA();
// Our texture is attached to 'resolve_fbo' when we use MSAA.
if (fsaa_samples > 1 && (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object))
if (msaa_samples > 1 && (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object))
glBindFramebuffer(GL_READ_FRAMEBUFFER, resolve_fbo);
else if (fsaa_samples > 1 && GLEE_EXT_framebuffer_multisample)
else if (msaa_samples > 1 && GLEE_EXT_framebuffer_multisample)
glBindFramebufferEXT(GL_READ_FRAMEBUFFER, resolve_fbo);
else if (current != this)
strategy->bindFBO(fbo);
@@ -930,10 +930,10 @@ void Canvas::getPixel(unsigned char* pixel_rgba, int x, int y)
bool Canvas::resolveMSAA()
{
if (resolve_fbo == 0 || fsaa_buffer == 0)
if (resolve_fbo == 0 || msaa_buffer == 0)
return false;
if (!fsaa_dirty)
if (!msaa_dirty)
return true;
GLuint previous = 0;
@@ -961,7 +961,7 @@ bool Canvas::resolveMSAA()
strategy->bindFBO(previous);
if (current != this)
fsaa_dirty = false;
msaa_dirty = false;
return true;
}
+7 -7
View File
@@ -57,7 +57,7 @@ public:
FORMAT_MAX_ENUM
};
Canvas(int width, int height, Format format = FORMAT_NORMAL, int fsaa = 0);
Canvas(int width, int height, Format format = FORMAT_NORMAL, int msaa = 0);
virtual ~Canvas();
// Implements Volatile.
@@ -108,9 +108,9 @@ public:
return format;
}
inline int getFSAA() const
inline int getMSAA() const
{
return fsaa_samples;
return msaa_samples;
}
bool resolveMSAA();
@@ -133,7 +133,7 @@ public:
private:
bool createFSAAFBO(GLenum internalformat);
bool createMSAAFBO(GLenum internalformat);
static Format getSizedFormat(Format format);
static void convertFormat(Format format, GLenum &internalformat, GLenum &externalformat, GLenum &type);
@@ -142,7 +142,7 @@ private:
GLuint resolve_fbo;
GLuint texture;
GLuint fsaa_buffer;
GLuint msaa_buffer;
GLuint depth_stencil;
Format format;
@@ -151,8 +151,8 @@ private:
std::vector<Canvas *> attachedCanvases;
int fsaa_samples;
bool fsaa_dirty;
int msaa_samples;
bool msaa_dirty;
void setupGrab();
void drawv(const Matrix &t, const Vertex *v);
+3 -3
View File
@@ -497,7 +497,7 @@ ParticleSystem *Graphics::newParticleSystem(Texture *texture, int size)
return new ParticleSystem(texture, size);
}
Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int fsaa)
Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int msaa)
{
if (!Canvas::isFormatSupported(format))
{
@@ -514,7 +514,7 @@ Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int fs
while (GL_NO_ERROR != glGetError())
/* clear opengl error flag */;
Canvas *canvas = new Canvas(width, height, format, fsaa);
Canvas *canvas = new Canvas(width, height, format, msaa);
GLenum err = canvas->getStatus();
// everything ok, return canvas (early out)
@@ -1097,7 +1097,7 @@ double Graphics::getSystemLimit(SystemLimit limittype) const
case Graphics::LIMIT_MULTI_CANVAS:
limit = (double) gl.getMaxRenderTargets();
break;
case Graphics::LIMIT_CANVAS_FSAA:
case Graphics::LIMIT_CANVAS_MSAA:
if (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object
|| GLEE_EXT_framebuffer_multisample)
{
+1 -1
View File
@@ -206,7 +206,7 @@ public:
ParticleSystem *newParticleSystem(Texture *texture, int size);
Canvas *newCanvas(int width, int height, Canvas::Format format = Canvas::FORMAT_NORMAL, int fsaa = 0);
Canvas *newCanvas(int width, int height, Canvas::Format format = Canvas::FORMAT_NORMAL, int msaa = 0);
Shader *newShader(const Shader::ShaderSources &sources);
@@ -146,12 +146,16 @@ ParticleSystem::ParticleSystem(const ParticleSystem &p)
, offsetX(p.offsetX)
, offsetY(p.offsetY)
, colors(p.colors)
, quads(p.quads)
, relativeRotation(p.relativeRotation)
{
setBufferSize(maxParticles);
if (texture != nullptr)
texture->retain();
for (Quad *quad : quads)
quad->retain();
}
ParticleSystem::~ParticleSystem()
@@ -159,6 +163,9 @@ ParticleSystem::~ParticleSystem()
if (texture != nullptr)
texture->release();
for (Quad *quad : quads)
quad->release();
deleteBuffers();
}
@@ -305,6 +312,8 @@ void ParticleSystem::initParticle(Particle *p, float t)
p->angle += atan2f(p->velocity.y, p->velocity.x);
p->color = colors[0];
p->quadIndex = 0;
}
void ParticleSystem::insertTop(Particle *p)
@@ -721,6 +730,30 @@ std::vector<Color> ParticleSystem::getColor() const
return ncolors;
}
void ParticleSystem::setQuads(const std::vector<Quad *> &newQuads)
{
for (Quad *quad : newQuads)
quad->retain();
for (Quad *quad : quads)
quad->release();
quads = newQuads;
}
void ParticleSystem::setQuads()
{
for (Quad *quad : quads)
quad->release();
quads.clear();
}
const std::vector<Quad *> &ParticleSystem::getQuads() const
{
return quads;
}
void ParticleSystem::setRelativeRotation(bool enable)
{
relativeRotation = enable;
@@ -820,9 +853,14 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
Vertex *pVerts = particleVerts;
Particle *p = pHead;
bool useQuads = !quads.empty();
// set the vertex data for each particle (transformation, texcoords, color)
while (p)
{
if (useQuads)
textureVerts = quads[p->quadIndex]->getVertices();
// particle vertices are image vertices transformed by particle information
t.setTransformation(p->position[0], p->position[1], p->angle, p->size, p->size, offsetX, offsetY, 0.0f, 0.0f);
t.transform(pVerts, textureVerts, 4);
@@ -948,6 +986,15 @@ void ParticleSystem::update(float dt)
s -= (float)i; // 0 <= s <= 1
p->color = colors[i] * (1.0f - s) + colors[k] * s;
// Update the quad index.
k = quads.size();
if (k > 0)
{
s = t * (float) k; // [0:numquads-1] (clamped below)
i = (s > 0.0f) ? (size_t) s : 0;
p->quadIndex = (i < k) ? i : k - 1;
}
// Next particle.
p = p->next;
}
@@ -27,6 +27,7 @@
#include "common/Vector.h"
#include "graphics/Drawable.h"
#include "graphics/Color.h"
#include "graphics/Quad.h"
#include "Texture.h"
// STL
@@ -421,6 +422,17 @@ public:
**/
std::vector<Color> getColor() const;
/**
* Sets a list of Quads to use for particles over their lifetime.
**/
void setQuads(const std::vector<Quad *> &newQuads);
void setQuads();
/**
* Gets the Quads used when drawing the particles.
**/
const std::vector<Quad *> &getQuads() const;
/**
* sets whether particle angles & rotations are relative to their velocities.
**/
@@ -531,6 +543,8 @@ protected:
float spinEnd;
Colorf color;
int quadIndex;
};
// Pointer to the beginning of the allocated memory.
@@ -625,6 +639,9 @@ protected:
// Color.
std::vector<Colorf> colors;
// Quads.
std::vector<Quad *> quads;
bool relativeRotation;
void createBuffers(size_t size);
+3 -3
View File
@@ -122,10 +122,10 @@ int w_Canvas_getFormat(lua_State *L)
return 1;
}
int w_Canvas_getFSAA(lua_State *L)
int w_Canvas_getMSAA(lua_State *L)
{
Canvas *canvas = luax_checkcanvas(L, 1);
lua_pushinteger(L, canvas->getFSAA());
lua_pushinteger(L, canvas->getMSAA());
return 1;
}
@@ -145,7 +145,7 @@ static const luaL_Reg functions[] =
{ "getPixel", w_Canvas_getPixel },
{ "clear", w_Canvas_clear },
{ "getFormat", w_Canvas_getFormat },
{ "getFSAA", w_Canvas_getFSAA },
{ "getMSAA", w_Canvas_getMSAA },
{ 0, 0 }
};
+1 -1
View File
@@ -40,7 +40,7 @@ int w_Canvas_getImageData(lua_State *L);
int w_Canvas_getPixel(lua_State * L);
int w_Canvas_clear(lua_State *L);
int w_Canvas_getFormat(lua_State *L);
int w_Canvas_getFSAA(lua_State *L);
int w_Canvas_getMSAA(lua_State *L);
extern "C" int luaopen_canvas(lua_State *L);
} // opengl
@@ -351,7 +351,7 @@ int w_newCanvas(lua_State *L)
int width = luaL_optint(L, 1, instance->getWidth());
int height = luaL_optint(L, 2, instance->getHeight());
const char *str = luaL_optstring(L, 3, "normal");
int fsaa = luaL_optint(L, 4, 0);
int msaa = luaL_optint(L, 4, 0);
Canvas::Format format;
if (!Canvas::getConstant(str, format))
@@ -359,7 +359,7 @@ int w_newCanvas(lua_State *L)
Canvas *canvas = nullptr;
luax_catchexcept(L,
[&](){ canvas = instance->newCanvas(width, height, format, fsaa); }
[&](){ canvas = instance->newCanvas(width, height, format, msaa); }
);
if (canvas == nullptr)
@@ -569,6 +569,53 @@ int w_ParticleSystem_getColors(lua_State *L)
return colors.size();
}
int w_ParticleSystem_setQuads(lua_State *L)
{
ParticleSystem *t = luax_checkparticlesystem(L, 1);
std::vector<Quad *> quads;
if (lua_istable(L, 2))
{
for (size_t i = 1; i <= lua_objlen(L, 2); i++)
{
lua_rawgeti(L, 2, i);
Quad *q = luax_checktype<Quad>(L, -1, "Quad", GRAPHICS_QUAD_T);
quads.push_back(q);
lua_pop(L, 1);
}
}
else
{
for (int i = 2; i <= lua_gettop(L); i++)
{
Quad *q = luax_checktype<Quad>(L, i, "Quad", GRAPHICS_QUAD_T);
quads.push_back(q);
}
}
t->setQuads(quads);
return 0;
}
int w_ParticleSystem_getQuads(lua_State *L)
{
ParticleSystem *t = luax_checkparticlesystem(L, 1);
const std::vector<Quad *> quads = t->getQuads();
lua_createtable(L, (int) quads.size(), 0);
for (size_t i = 0; i < quads.size(); i++)
{
quads[i]->retain();
luax_pushtype(L, "Quad", GRAPHICS_QUAD_T, quads[i]);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
int w_ParticleSystem_setRelativeRotation(lua_State *L)
{
ParticleSystem *t = luax_checkparticlesystem(L, 1);
@@ -699,6 +746,8 @@ static const luaL_Reg functions[] =
{ "getSpinVariation", w_ParticleSystem_getSpinVariation },
{ "setColors", w_ParticleSystem_setColors },
{ "getColors", w_ParticleSystem_getColors },
{ "setQuads", w_ParticleSystem_setQuads },
{ "getQuads", w_ParticleSystem_getQuads },
{ "setOffset", w_ParticleSystem_setOffset },
{ "getOffset", w_ParticleSystem_getOffset },
{ "setRelativeRotation", w_ParticleSystem_setRelativeRotation },
@@ -75,6 +75,8 @@ int w_ParticleSystem_setSpinVariation(lua_State *L);
int w_ParticleSystem_getSpinVariation(lua_State *L);
int w_ParticleSystem_setColors(lua_State *L);
int w_ParticleSystem_getColors(lua_State *L);
int w_ParticleSystem_setQuads(lua_State *L);
int w_ParticleSystem_getQuads(lua_State *L);
int w_ParticleSystem_setOffset(lua_State *L);
int w_ParticleSystem_getOffset(lua_State *L);
int w_ParticleSystem_setRelativeRotation(lua_State *L);
-26
View File
@@ -68,34 +68,8 @@ int w_setTextInput(lua_State *L)
return 0;
}
template <typename T>
static int throwExcept(lua_State *L, const T& func)
{
bool should_error = false;
try
{
func();
}
catch (love::Exception &e)
{
should_error = true;
lua_pushstring(L, e.what());
}
if (should_error)
return luaL_error(L, lua_tostring(L, -1));
return 0;
}
int w_hasTextInput(lua_State *L)
{
bool asdf = true;
throwExcept(L, [&](){ instance->setTextInput(asdf); });
// throwExcept(L, L);
luax_pushboolean(L, instance->hasTextInput());
return 1;
}
+39 -1
View File
@@ -41,20 +41,29 @@ namespace box2d
Joint::Joint(Body *body1)
: world(body1->world)
, udata(nullptr)
, body1(body1)
, body2(0)
, body2(nullptr)
{
udata = new jointudata();
udata->ref = nullptr;
}
Joint::Joint(Body *body1, Body *body2)
: world(body1->world)
, udata(nullptr)
, body1(body1)
, body2(body2)
{
udata = new jointudata();
udata->ref = nullptr;
}
Joint::~Joint()
{
if (udata != nullptr)
delete udata->ref;
delete udata;
}
Joint::Type Joint::getType() const
@@ -116,6 +125,7 @@ float Joint::getReactionTorque(float dt)
b2Joint *Joint::createJoint(b2JointDef *def)
{
def->userData = udata;
joint = world->world->CreateJoint(def);
Memoizer::add(joint, this);
// Box2D joint has a reference to this love Joint.
@@ -151,6 +161,34 @@ bool Joint::getCollideConnected() const
return joint->GetCollideConnected();
}
int Joint::setUserData(lua_State *L)
{
love::luax_assert_argc(L, 1, 1);
if (udata->ref != nullptr)
{
// We set the Reference's lua_State to this one before deleting it, so
// it unrefs using the current lua_State's stack. This is necessary
// if setUserData is called in a coroutine.
udata->ref->setL(L);
delete udata->ref;
}
udata->ref = new Reference(L);
return 0;
}
int Joint::getUserData(lua_State *L)
{
if (udata != nullptr && udata->ref != nullptr)
udata->ref->push(L);
else
lua_pushnil(L);
return 1;
}
} // box2d
} // physics
} // love
+23
View File
@@ -39,6 +39,16 @@ namespace box2d
class Body;
class World;
/**
* This struct is stored in a void pointer in the Box2D Joint class. For now, all
* we need is a Lua reference to arbitrary data, but we might need more later.
**/
struct jointudata
{
// Reference to arbitrary data.
Reference *ref;
};
/**
* A Joint acts as positioning constraints on Bodies.
* A Joint can be used to prevent Bodies from going to
@@ -95,6 +105,17 @@ public:
bool getCollideConnected() const;
/**
* This function stores an in-C reference to arbitrary Lua data in the Box2D
* Joint object.
**/
int setUserData(lua_State *L);
/**
* Gets the data set with setUserData. If no data is set, nil is returned.
**/
int getUserData(lua_State *L);
/**
* Joints require pointers to a Box2D joint objects at
* different polymorphic levels, which is why these function
@@ -117,6 +138,8 @@ protected:
World *world;
jointudata *udata;
private:
// A Joint must be destroyed *before* the bodies it acts upon,
+10
View File
@@ -522,6 +522,15 @@ int w_Body_isFixedRotation(lua_State *L)
return 1;
}
int w_Body_getWorld(lua_State *L)
{
Body *t = luax_checkbody(L, 1);
World *world = t->getWorld();
world->retain();
luax_pushtype(L, "World", PHYSICS_WORLD_T, world);
return 1;
}
int w_Body_getFixtureList(lua_State *L)
{
Body *t = luax_checkbody(L, 1);
@@ -604,6 +613,7 @@ static const luaL_Reg functions[] =
{ "setAwake", w_Body_setAwake },
{ "setFixedRotation", w_Body_setFixedRotation },
{ "isFixedRotation", w_Body_isFixedRotation },
{ "getWorld", w_Body_getWorld },
{ "getFixtureList", w_Body_getFixtureList },
{ "destroy", w_Body_destroy },
{ "setUserData", w_Body_setUserData },
+1
View File
@@ -83,6 +83,7 @@ int w_Body_setActive(lua_State *L);
int w_Body_setAwake(lua_State *L);
int w_Body_setFixedRotation(lua_State *L);
int w_Body_isFixedRotation(lua_State *L);
int w_Body_getWorld(lua_State *L);
int w_Body_getFixtureList(lua_State *L);
int w_Body_destroy(lua_State *L);
int w_Body_setUserData(lua_State *L);
@@ -94,6 +94,8 @@ static const luaL_Reg functions[] =
{ "getReactionForce", w_Joint_getReactionForce },
{ "getReactionTorque", w_Joint_getReactionTorque },
{ "getCollideConnected", w_Joint_getCollideConnected },
{ "setUserData", w_Joint_setUserData },
{ "getUserData", w_Joint_getUserData },
{ "destroy", w_Joint_destroy },
{ 0, 0 }
};
@@ -78,6 +78,8 @@ static const luaL_Reg functions[] =
{ "getReactionForce", w_Joint_getReactionForce },
{ "getReactionTorque", w_Joint_getReactionTorque },
{ "getCollideConnected", w_Joint_getCollideConnected },
{ "setUserData", w_Joint_setUserData },
{ "getUserData", w_Joint_getUserData },
{ "destroy", w_Joint_destroy },
{ 0, 0 }
};
@@ -61,6 +61,8 @@ static const luaL_Reg functions[] =
{ "getReactionForce", w_Joint_getReactionForce },
{ "getReactionTorque", w_Joint_getReactionTorque },
{ "getCollideConnected", w_Joint_getCollideConnected },
{ "setUserData", w_Joint_setUserData },
{ "getUserData", w_Joint_getUserData },
{ "destroy", w_Joint_destroy },
{ 0, 0 }
};
+16
View File
@@ -75,6 +75,20 @@ int w_Joint_getCollideConnected(lua_State *L)
return 1;
}
int w_Joint_setUserData(lua_State *L)
{
Joint *t = luax_checkjoint(L, 1);
lua_remove(L, 1);
return t->setUserData(L);
}
int w_Joint_getUserData(lua_State *L)
{
Joint *t = luax_checkjoint(L, 1);
lua_remove(L, 1);
return t->getUserData(L);
}
int w_Joint_destroy(lua_State *L)
{
Joint *t = luax_checkjoint(L, 1);
@@ -89,6 +103,8 @@ static const luaL_Reg functions[] =
{ "getReactionForce", w_Joint_getReactionForce },
{ "getReactionTorque", w_Joint_getReactionTorque },
{ "getCollideConnected", w_Joint_getCollideConnected },
{ "setUserData", w_Joint_setUserData },
{ "getUserData", w_Joint_getUserData },
{ "destroy", w_Joint_destroy },
{ 0, 0 }
};
+2
View File
@@ -38,6 +38,8 @@ int w_Joint_getAnchors(lua_State *L);
int w_Joint_getReactionForce(lua_State *L);
int w_Joint_getReactionTorque(lua_State *L);
int w_Joint_getCollideConnected(lua_State *L);
int w_Joint_setUserData(lua_State *L);
int w_Joint_getUserData(lua_State *L);
int w_Joint_destroy(lua_State *L);
extern "C" int luaopen_joint(lua_State *L);
@@ -128,6 +128,8 @@ static const luaL_Reg functions[] =
{ "getReactionForce", w_Joint_getReactionForce },
{ "getReactionTorque", w_Joint_getReactionTorque },
{ "getCollideConnected", w_Joint_getCollideConnected },
{ "setUserData", w_Joint_setUserData },
{ "getUserData", w_Joint_getUserData },
{ "destroy", w_Joint_destroy },
{ 0, 0 }
};
@@ -112,6 +112,8 @@ static const luaL_Reg functions[] =
{ "getReactionForce", w_Joint_getReactionForce },
{ "getReactionTorque", w_Joint_getReactionTorque },
{ "getCollideConnected", w_Joint_getCollideConnected },
{ "setUserData", w_Joint_setUserData },
{ "getUserData", w_Joint_getUserData },
{ "destroy", w_Joint_destroy },
{ 0, 0 }
};
@@ -189,6 +189,8 @@ static const luaL_Reg functions[] =
{ "getReactionForce", w_Joint_getReactionForce },
{ "getReactionTorque", w_Joint_getReactionTorque },
{ "getCollideConnected", w_Joint_getCollideConnected },
{ "setUserData", w_Joint_setUserData },
{ "getUserData", w_Joint_getUserData },
{ "destroy", w_Joint_destroy },
{ 0, 0 }
};
@@ -75,6 +75,8 @@ static const luaL_Reg functions[] =
{ "getReactionForce", w_Joint_getReactionForce },
{ "getReactionTorque", w_Joint_getReactionTorque },
{ "getCollideConnected", w_Joint_getCollideConnected },
{ "setUserData", w_Joint_setUserData },
{ "getUserData", w_Joint_getUserData },
{ "destroy", w_Joint_destroy },
{ 0, 0 }
};
@@ -189,6 +189,8 @@ static const luaL_Reg functions[] =
{ "getReactionForce", w_Joint_getReactionForce },
{ "getReactionTorque", w_Joint_getReactionTorque },
{ "getCollideConnected", w_Joint_getCollideConnected },
{ "setUserData", w_Joint_setUserData },
{ "getUserData", w_Joint_getUserData },
{ "destroy", w_Joint_destroy },
{ 0, 0 }
};
@@ -51,6 +51,8 @@ static const luaL_Reg functions[] =
{ "getReactionForce", w_Joint_getReactionForce },
{ "getReactionTorque", w_Joint_getReactionTorque },
{ "getCollideConnected", w_Joint_getCollideConnected },
{ "setUserData", w_Joint_setUserData },
{ "getUserData", w_Joint_getUserData },
{ "destroy", w_Joint_destroy },
{ 0, 0 }
};
@@ -77,6 +77,8 @@ static const luaL_Reg functions[] =
{ "getReactionForce", w_Joint_getReactionForce },
{ "getReactionTorque", w_Joint_getReactionTorque },
{ "getCollideConnected", w_Joint_getCollideConnected },
{ "setUserData", w_Joint_setUserData },
{ "getUserData", w_Joint_getUserData },
{ "destroy", w_Joint_destroy },
{ 0, 0 }
};
@@ -153,6 +153,8 @@ static const luaL_Reg functions[] =
{ "getReactionForce", w_Joint_getReactionForce },
{ "getReactionTorque", w_Joint_getReactionTorque },
{ "getCollideConnected", w_Joint_getCollideConnected },
{ "setUserData", w_Joint_setUserData },
{ "getUserData", w_Joint_getUserData },
{ "destroy", w_Joint_destroy },
{ 0, 0 }
};
+2 -2
View File
@@ -42,7 +42,7 @@ WindowSettings::WindowSettings()
: fullscreen(false)
, fstype(Window::FULLSCREEN_TYPE_NORMAL)
, vsync(true)
, fsaa(0)
, msaa(0)
, resizable(false)
, minwidth(1)
, minheight(1)
@@ -89,7 +89,7 @@ StringMap<Window::Setting, Window::SETTING_MAX_ENUM>::Entry Window::settingEntri
{"fullscreen", SETTING_FULLSCREEN},
{"fullscreentype", SETTING_FULLSCREEN_TYPE},
{"vsync", SETTING_VSYNC},
{"fsaa", SETTING_FSAA},
{"msaa", SETTING_MSAA},
{"resizable", SETTING_RESIZABLE},
{"minwidth", SETTING_MIN_WIDTH},
{"minheight", SETTING_MIN_HEIGHT},
+4 -2
View File
@@ -57,7 +57,7 @@ public:
SETTING_FULLSCREEN,
SETTING_FULLSCREEN_TYPE,
SETTING_VSYNC,
SETTING_FSAA,
SETTING_MSAA,
SETTING_RESIZABLE,
SETTING_MIN_WIDTH,
SETTING_MIN_HEIGHT,
@@ -94,6 +94,8 @@ public:
virtual int getDisplayCount() const = 0;
virtual const char *getDisplayName(int displayindex) const = 0;
virtual std::vector<WindowSize> getFullscreenSizes(int displayindex) const = 0;
virtual void getDesktopDimensions(int displayindex, int &width, int &height) const = 0;
@@ -163,7 +165,7 @@ struct WindowSettings
bool fullscreen; // = false
Window::FullscreenType fstype; // = FULLSCREEN_TYPE_NORMAL
bool vsync; // = true
int fsaa; // = 0
int msaa; // = 0
bool resizable; // = false
int minwidth; // = 1
int minheight; // = 1
+30 -20
View File
@@ -139,7 +139,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
wflags &= testflags;
if (sdlflags != wflags || width != curMode.width || height != curMode.height
|| f.display != curdisplay || f.fsaa != curMode.settings.fsaa)
|| f.display != curdisplay || f.msaa != curMode.settings.msaa)
{
SDL_DestroyWindow(window);
window = 0;
@@ -158,21 +158,21 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
created = false;
// In Windows and Linux, some GL attributes are set on window creation.
setWindowGLAttributes(f.fsaa, f.sRGB);
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);
if (!window && f.fsaa > 0)
if (!window && f.msaa > 0)
{
// FSAA might have caused the failure, disable it and try again.
// MSAA might have caused the failure, disable it and try again.
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags);
f.fsaa = 0;
f.msaa = 0;
}
// Make sure the window keeps any previously set icon.
@@ -194,7 +194,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
SDL_RaiseWindow(window);
if (!setContext(f.fsaa, f.vsync, f.sRGB))
if (!setContext(f.msaa, f.vsync, f.sRGB))
return false;
created = true;
@@ -231,9 +231,9 @@ bool Window::onWindowResize(int width, int height)
return true;
}
bool Window::setContext(int fsaa, bool vsync, bool sRGB)
bool Window::setContext(int msaa, bool vsync, bool sRGB)
{
// We would normally only need to recreate the context if FSAA changes or
// We would normally only need to recreate the context if MSAA changes or
// SDL_GL_MakeCurrent is unsuccessful, but in Windows MakeCurrent can
// sometimes claim success but the context will actually be trashed.
if (context)
@@ -243,13 +243,13 @@ bool Window::setContext(int fsaa, bool vsync, bool sRGB)
}
// Make sure the proper attributes are set.
setWindowGLAttributes(fsaa, sRGB);
setWindowGLAttributes(msaa, sRGB);
context = SDL_GL_CreateContext(window);
if (!context && fsaa > 0)
if (!context && msaa > 0)
{
// FSAA might have caused the failure, disable it and try again.
// MSAA might have caused the failure, disable it and try again.
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
context = SDL_GL_CreateContext(window);
@@ -276,26 +276,26 @@ bool Window::setContext(int fsaa, bool vsync, bool sRGB)
// Set vertical synchronization.
SDL_GL_SetSwapInterval(vsync ? 1 : 0);
// Verify FSAA setting.
// Verify MSAA setting.
int buffers;
int samples;
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers);
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &samples);
// Don't fail because of this, but issue a warning.
if ((!buffers && fsaa) || (samples != fsaa))
if ((!buffers && msaa) || (samples != msaa))
{
std::cerr << "Warning, FSAA setting failed! (Result: buffers: " << buffers << ", samples: " << samples << ")" << std::endl;
fsaa = (buffers > 0) ? samples : 0;
std::cerr << "Warning, MSAA setting failed! (Result: buffers: " << buffers << ", samples: " << samples << ")" << std::endl;
msaa = (buffers > 0) ? samples : 0;
}
curMode.settings.fsaa = fsaa;
curMode.settings.msaa = msaa;
curMode.settings.vsync = SDL_GL_GetSwapInterval() != 0;
return true;
}
void Window::setWindowGLAttributes(int fsaa, bool /* sRGB */) const
void Window::setWindowGLAttributes(int msaa, bool /* sRGB */) const
{
// Set GL window attributes.
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
@@ -306,9 +306,9 @@ void Window::setWindowGLAttributes(int fsaa, bool /* sRGB */) const
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
// FSAA.
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa > 0) ? 1 : 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0);
// MSAA.
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (msaa > 0) ? 1 : 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (msaa > 0) ? msaa : 0);
/* FIXME: Enable this code but make sure to try to re-create the window and
* context with this disabled, if creation fails with it enabled.
@@ -461,6 +461,16 @@ int Window::getDisplayCount() const
return SDL_GetNumVideoDisplays();
}
const char *Window::getDisplayName(int displayindex) const
{
const char *name = SDL_GetDisplayName(displayindex);
if (name == nullptr)
throw love::Exception("Invalid display index: %d", displayindex + 1);
return name;
}
typedef Window::WindowSize WindowSize;
std::vector<WindowSize> Window::getFullscreenSizes(int displayindex) const
+4 -2
View File
@@ -51,6 +51,8 @@ public:
int getDisplayCount() const;
const char *getDisplayName(int displayindex) const;
std::vector<WindowSize> getFullscreenSizes(int displayindex) const;
void getDesktopDimensions(int displayindex, int &width, int &height) const;
@@ -89,8 +91,8 @@ public:
private:
bool setContext(int fsaa, bool vsync, bool sRGB);
void setWindowGLAttributes(int fsaa, bool sRGB) const;
bool setContext(int msaa, bool vsync, bool sRGB);
void setWindowGLAttributes(int msaa, bool sRGB) const;
// Update the saved window settings based on the window's actual state.
void updateSettings(const WindowSettings &newsettings);
+15 -3
View File
@@ -34,6 +34,17 @@ int w_getDisplayCount(lua_State *L)
return 1;
}
int w_getDisplayName(lua_State *L)
{
int index = luaL_checkint(L, 1) - 1;
const char *name = nullptr;
luax_catchexcept(L, [&](){ name = instance->getDisplayName(index); });
lua_pushstring(L, name);
return 1;
}
static const char *settingName(Window::Setting setting)
{
const char *name = nullptr;
@@ -88,7 +99,7 @@ int w_setMode(lua_State *L)
settings.fullscreen = luax_boolflag(L, 3, settingName(Window::SETTING_FULLSCREEN), false);
settings.vsync = luax_boolflag(L, 3, settingName(Window::SETTING_VSYNC), true);
settings.fsaa = luax_intflag(L, 3, settingName(Window::SETTING_FSAA), 0);
settings.msaa = luax_intflag(L, 3, settingName(Window::SETTING_MSAA), 0);
settings.resizable = luax_boolflag(L, 3, settingName(Window::SETTING_RESIZABLE), false);
settings.minwidth = luax_intflag(L, 3, settingName(Window::SETTING_MIN_WIDTH), 1);
settings.minheight = luax_intflag(L, 3, settingName(Window::SETTING_MIN_HEIGHT), 1);
@@ -130,8 +141,8 @@ int w_getMode(lua_State *L)
luax_pushboolean(L, settings.vsync);
lua_setfield(L, -2, settingName(Window::SETTING_VSYNC));
lua_pushinteger(L, settings.fsaa);
lua_setfield(L, -2, settingName(Window::SETTING_FSAA));
lua_pushinteger(L, settings.msaa);
lua_setfield(L, -2, settingName(Window::SETTING_MSAA));
luax_pushboolean(L, settings.resizable);
lua_setfield(L, -2, settingName(Window::SETTING_RESIZABLE));
@@ -300,6 +311,7 @@ int w_getPixelScale(lua_State *L)
static const luaL_Reg functions[] =
{
{ "getDisplayCount", w_getDisplayCount },
{ "getDisplayName", w_getDisplayName },
{ "setMode", w_setMode },
{ "getMode", w_getMode },
{ "getFullscreenModes", w_getFullscreenModes },
+1
View File
@@ -30,6 +30,7 @@ namespace window
{
int w_getDisplayCount(lua_State *L);
int w_getDisplayName(lua_State *L);
int w_setMode(lua_State *L);
int w_getMode(lua_State *L);
int w_getFullscreenModes(lua_State *L);
+2 -2
View File
@@ -307,7 +307,7 @@ function love.init()
fullscreentype = "normal",
display = 1,
vsync = true,
fsaa = 0,
msaa = 0,
borderless = false,
resizable = false,
centered = true,
@@ -394,7 +394,7 @@ function love.init()
fullscreen = c.window.fullscreen,
fullscreentype = c.window.fullscreentype,
vsync = c.window.vsync,
fsaa = c.window.fsaa,
msaa = c.window.msaa,
resizable = c.window.resizable,
minwidth = c.window.minwidth,
minheight = c.window.minheight,
+3 -3
View File
@@ -559,7 +559,7 @@ const unsigned char boot_lua[] =
0x3d, 0x20, 0x22, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x22, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x66, 0x73, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x6d, 0x73, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x61,
0x6c, 0x73, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c,
@@ -686,8 +686,8 @@ const unsigned char boot_lua[] =
0x65, 0x65, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f,
0x77, 0x2e, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x66, 0x73, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77,
0x2e, 0x66, 0x73, 0x61, 0x61, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x6d, 0x73, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77,
0x2e, 0x6d, 0x73, 0x61, 0x61, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77,
0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69,