diff --git a/platform/macosx/Info-Framework.plist b/platform/macosx/Info-Framework.plist
index 0493c71bb..fcc7ee4ce 100644
--- a/platform/macosx/Info-Framework.plist
+++ b/platform/macosx/Info-Framework.plist
@@ -13,13 +13,13 @@
CFBundleInfoDictionaryVersion
6.0
CFBundleName
- ${PRODUCT_NAME}
+ LÖVE
CFBundlePackageType
FMWK
CFBundleShortVersionString
0.8.0
CFBundleSignature
- ????
+ LoVe
CFBundleVersion
0.8.0
NSPrincipalClass
diff --git a/platform/macosx/love-framework.xcodeproj/project.pbxproj b/platform/macosx/love-framework.xcodeproj/project.pbxproj
index a1659a453..9cfa8eb62 100644
--- a/platform/macosx/love-framework.xcodeproj/project.pbxproj
+++ b/platform/macosx/love-framework.xcodeproj/project.pbxproj
@@ -685,7 +685,7 @@
FA577A8C16C71D3600860150 /* auto.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = auto.lua; sourceTree = ""; };
FA577A8D16C71D3600860150 /* boot.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = boot.lua; sourceTree = ""; };
FA577A8E16C71D3600860150 /* graphics.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = graphics.lua; sourceTree = ""; };
- FA577AAF16C7507900860150 /* love framework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = "love framework.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
+ FA577AAF16C7507900860150 /* love.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "love.framework"; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -959,7 +959,7 @@
2F654C0235EB60C744A22507 /* Products */ = {
isa = PBXGroup;
children = (
- FA577AAF16C7507900860150 /* love framework.framework */,
+ FA577AAF16C7507900860150 /* love.framework */,
);
name = Products;
sourceTree = "";
@@ -1578,9 +1578,9 @@
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
- FA577AAE16C7507900860150 /* love framework */ = {
+ FA577AAE16C7507900860150 /* Framework */ = {
isa = PBXNativeTarget;
- buildConfigurationList = FA577ABF16C7507900860150 /* Build configuration list for PBXNativeTarget "love framework" */;
+ buildConfigurationList = FA577ABF16C7507900860150 /* Build configuration list for PBXNativeTarget "Framework" */;
buildPhases = (
FA577AAA16C7507900860150 /* Sources */,
FA577AAB16C7507900860150 /* Frameworks */,
@@ -1591,9 +1591,9 @@
);
dependencies = (
);
- name = "love framework";
+ name = Framework;
productName = love;
- productReference = FA577AAF16C7507900860150 /* love framework.framework */;
+ productReference = FA577AAF16C7507900860150 /* love.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
@@ -1615,7 +1615,7 @@
projectDirPath = "";
projectRoot = "";
targets = (
- FA577AAE16C7507900860150 /* love framework */,
+ FA577AAE16C7507900860150 /* Framework */,
);
};
/* End PBXProject section */
@@ -1951,7 +1951,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
- FA577ABF16C7507900860150 /* Build configuration list for PBXNativeTarget "love framework" */ = {
+ FA577ABF16C7507900860150 /* Build configuration list for PBXNativeTarget "Framework" */ = {
isa = XCConfigurationList;
buildConfigurations = (
FA577AC016C7507900860150 /* Debug */,
diff --git a/platform/macosx/love.xcodeproj/project.pbxproj b/platform/macosx/love.xcodeproj/project.pbxproj
index fb1f78b9f..cce2ffc38 100644
--- a/platform/macosx/love.xcodeproj/project.pbxproj
+++ b/platform/macosx/love.xcodeproj/project.pbxproj
@@ -29,6 +29,16 @@
FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; };
/* End PBXBuildFile section */
+/* Begin PBXContainerItemProxy section */
+ FA08F6A616C77A4300F007B5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FA577A9316C7217800860150 /* love-framework.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = FA577AAF16C7507900860150;
+ remoteInfo = "love framework";
+ };
+/* End PBXContainerItemProxy section */
+
/* Begin PBXCopyFilesBuildPhase section */
A9255DDE1043185300BA1496 /* Copy Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
@@ -147,6 +157,14 @@
name = Resources;
sourceTree = "";
};
+ FA08F6A316C77A4300F007B5 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FA08F6A716C77A4300F007B5 /* love.framework */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
FA577A9D16C7262E00860150 /* Source */ = {
isa = PBXGroup;
children = (
@@ -200,6 +218,12 @@
);
mainGroup = 29B97314FDCFA39411CA2CEA /* love */;
projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = FA08F6A316C77A4300F007B5 /* Products */;
+ ProjectRef = FA577A9316C7217800860150 /* love-framework.xcodeproj */;
+ },
+ );
projectRoot = "";
targets = (
8D1107260486CEB800E47090 /* love */,
@@ -207,6 +231,17 @@
};
/* End PBXProject section */
+/* Begin PBXReferenceProxy section */
+ FA08F6A716C77A4300F007B5 /* love.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ name = "love.framework";
+ path = love.framework;
+ remoteRef = FA08F6A616C77A4300F007B5 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
/* Begin PBXResourcesBuildPhase section */
8D1107290486CEB800E47090 /* Resources */ = {
isa = PBXResourcesBuildPhase;
diff --git a/src/modules/graphics/opengl/SpriteBatch.cpp b/src/modules/graphics/opengl/SpriteBatch.cpp
index 8aa672c46..d17271309 100644
--- a/src/modules/graphics/opengl/SpriteBatch.cpp
+++ b/src/modules/graphics/opengl/SpriteBatch.cpp
@@ -97,9 +97,25 @@ SpriteBatch::~SpriteBatch()
int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/)
{
// Only do this if there's a free slot.
- if ((index == -1 && next >= size) || index < -1 || index >= size)
+ if ((index == -1 && next >= size && gaps.size() == 0) || index < -1 || index >= size)
return -1;
+ // Determine where in the vertex buffer to insert into, using the gap list
+ // if possible.
+ int realindex;
+ if (index == -1 && gaps.size() > 0)
+ {
+ realindex = gaps.front();
+ gaps.pop_front();
+ }
+ else
+ {
+ realindex = (index == -1) ? next : index;
+ std::deque::iterator it = std::find(gaps.begin(), gaps.end(), realindex);
+ if (it != gaps.end())
+ gaps.erase(it); // This index is no longer a gap.
+ }
+
// Needed for colors.
memcpy(sprite, image->getVertices(), sizeof(vertex)*4);
@@ -110,21 +126,39 @@ int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, fl
if (color)
setColorv(sprite, *color);
+
- addv(sprite, (index == -1 ? next : index));
+ addv(sprite, realindex);
// Increment counter.
- if (index == -1)
+ if (index == -1 && realindex == next)
return next++;
- return index;
+
+ return realindex;
}
int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/)
{
// Only do this if there's a free slot.
- if ((index == -1 && next >= size) || index < -1 || index >= next)
+ if ((index == -1 && next >= size && gaps.size() == 0) || index < -1 || index >= next)
return -1;
+ // Determine where in the vertex buffer to insert into, using the gap list
+ // if possible.
+ int realindex;
+ if (index == -1 && gaps.size() > 0)
+ {
+ realindex = gaps.front();
+ gaps.pop_front();
+ }
+ else
+ {
+ realindex = (index == -1) ? next : index;
+ std::deque::iterator it = std::find(gaps.begin(), gaps.end(), realindex);
+ if (it != gaps.end())
+ gaps.erase(it); // This index is no longer a gap.
+ }
+
// Needed for colors.
memcpy(sprite, quad->getVertices(), sizeof(vertex)*4);
@@ -136,18 +170,53 @@ int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy,
if (color)
setColorv(sprite, *color);
- addv(sprite, (index == -1 ? next : index));
+ addv(sprite, realindex);
// Increment counter.
- if (index == -1)
+ if (index == -1 && realindex == next)
return next++;
- return index;
+
+ return realindex;
+}
+
+void SpriteBatch::remove(int index)
+{
+ if (index < 0 || index >= next || next <= 0)
+ return;
+
+ // If this is the last index in the sprite list, decrease the total sprite
+ // count instead of adding a dummy sprite.
+ if (index == next - 1)
+ {
+ int spritecount = index;
+
+ // Remove all consecutive gaps at the end of the sprite list.
+ std::deque::iterator it;
+ while ((it = std::find(gaps.begin(), gaps.end(), --spritecount)) != gaps.end())
+ gaps.erase(it);
+
+ next = spritecount + 1;
+ return;
+ }
+ else if (std::find(gaps.begin(), gaps.end(), index) != gaps.end())
+ return; // Don't add the same index to the gap list twice.
+
+
+ // OpenGL won't render any primitive whose vertices are all identical.
+ for (int i = 0; i < 4; i++)
+ sprite[i].x = sprite[i].y = 0;
+
+ // Replace the existing sprite at this index with the dummy sprite.
+ addv(sprite, index);
+
+ gaps.push_back(index);
}
void SpriteBatch::clear()
{
// Reset the position of the next index.
next = 0;
+ gaps.clear();
}
void *SpriteBatch::lock()
diff --git a/src/modules/graphics/opengl/SpriteBatch.h b/src/modules/graphics/opengl/SpriteBatch.h
index e7c97a55f..baa7c0bda 100644
--- a/src/modules/graphics/opengl/SpriteBatch.h
+++ b/src/modules/graphics/opengl/SpriteBatch.h
@@ -23,6 +23,7 @@
// C
#include
+#include
// LOVE
#include "common/math.h"
@@ -64,6 +65,7 @@ public:
int add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1);
int addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1);
+ void remove(int index);
void clear();
void *lock();
@@ -126,6 +128,10 @@ private:
VertexBuffer *array_buf;
VertexIndex *element_buf;
+ // List of gaps in the SpriteBatch. Checked when adding sprites, and added
+ // to when removing them.
+ std::deque gaps;
+
}; // SpriteBatch
} // opengl
diff --git a/src/modules/graphics/opengl/wrap_SpriteBatch.cpp b/src/modules/graphics/opengl/wrap_SpriteBatch.cpp
index fdd9380a3..f29619991 100644
--- a/src/modules/graphics/opengl/wrap_SpriteBatch.cpp
+++ b/src/modules/graphics/opengl/wrap_SpriteBatch.cpp
@@ -101,6 +101,13 @@ int w_SpriteBatch_setq(lua_State *L)
return 0;
}
+int w_SpriteBatch_remove(lua_State *L)
+{
+ SpriteBatch *t = luax_checkspritebatch(L, 1);
+ int id = luaL_checkinteger(L, 2);
+ t->remove(id);
+ return 0;
+}
int w_SpriteBatch_clear(lua_State *L)
{
@@ -191,6 +198,7 @@ static const luaL_Reg functions[] =
{ "addq", w_SpriteBatch_addq },
{ "set", w_SpriteBatch_set },
{ "setq", w_SpriteBatch_setq },
+ { "remove", w_SpriteBatch_remove },
{ "clear", w_SpriteBatch_clear },
{ "bind", w_SpriteBatch_bind },
{ "unbind", w_SpriteBatch_unbind },
diff --git a/src/modules/graphics/opengl/wrap_SpriteBatch.h b/src/modules/graphics/opengl/wrap_SpriteBatch.h
index aa737dcc9..ca397d715 100644
--- a/src/modules/graphics/opengl/wrap_SpriteBatch.h
+++ b/src/modules/graphics/opengl/wrap_SpriteBatch.h
@@ -36,6 +36,7 @@ int w_SpriteBatch_add(lua_State *L);
int w_SpriteBatch_addq(lua_State *L);
int w_SpriteBatch_set(lua_State *L);
int w_SpriteBatch_setq(lua_State *L);
+int w_SpriteBatch_remove(lua_State *L);
int w_SpriteBatch_clear(lua_State *L);
int w_SpriteBatch_lock(lua_State *L);
int w_SpriteBatch_unlock(lua_State *L);