Updated LÖVE to changeset c303c1f52ea6

This commit is contained in:
Martin Felis
2018-03-30 21:42:03 +02:00
parent 4d8f4f70ce
commit f8241c1b65
17 changed files with 1317 additions and 1310 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
repo: d362ae6ab7f5005b8dbc7cba9ce592637de60f99 repo: d362ae6ab7f5005b8dbc7cba9ce592637de60f99
node: a2e84c9fdb8ca18d073d0e782d68205b9aa9ec96 node: c303c1f52ea638c96660d0c3bf35b10818a2e3f4
branch: default branch: default
latesttag: 0.10.2 latesttag: 0.10.2
latesttagdistance: 381 latesttagdistance: 395
changessincelatesttag: 550 changessincelatesttag: 564
+1 -1
View File
@@ -93,7 +93,7 @@ Released: N/A
* Renamed all get[Object]List functions to get[Object]s. * Renamed all get[Object]List functions to get[Object]s.
* Removed the default source type for love.audio.newSource. * Removed the default source type for love.audio.newSource.
* Removed variant of love.filesystem.newFileData which takes base64 data, use love.math.decode instead. * Removed variant of love.filesystem.newFileData which takes base64 data, use love.data.decode instead.
* Removed the no-argument variant of Text:set, use Text:clear instead. * Removed the no-argument variant of Text:set, use Text:clear instead.
* Removed love.graphics.getCompressedImageFormats, use love.graphics.getImageFormats instead. * Removed love.graphics.getCompressedImageFormats, use love.graphics.getImageFormats instead.
* Removed the 'void effects(...)' pixel shader entry point. Use the new 'void effect()' instead. * Removed the 'void effects(...)' pixel shader entry point. Use the new 'void effect()' instead.
+1144 -1194
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -21,6 +21,8 @@ Run `platform/unix/automagic` from the repository root, then run ./configure and
$ ./configure $ ./configure
$ make $ make
When using a source release, automagic has already been run, and the first step can be skipped.
###Mac OS X ###Mac OS X
Download the required frameworks from [here][dependencies] and place them in `/Library/Frameworks/`. Download the required frameworks from [here][dependencies] and place them in `/Library/Frameworks/`.
+1 -1
View File
@@ -38,7 +38,7 @@ static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$
**/ **/
static void b64_encode_block(char in[3], char out[4], int len) static void b64_encode_block(char in[3], char out[4], int len)
{ {
out[0] = (char) cb64[(int)(in[0] >> 2)]; out[0] = (char) cb64[(int)((in[0] & 0xfc) >> 2)];
out[1] = (char) cb64[(int)(((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4))]; out[1] = (char) cb64[(int)(((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4))];
out[2] = (char) (len > 1 ? cb64[(int)(((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6))] : '='); out[2] = (char) (len > 1 ? cb64[(int)(((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6))] : '=');
out[3] = (char) (len > 2 ? cb64[(int)(in[2] & 0x3f)] : '='); out[3] = (char) (len > 2 ? cb64[(int)(in[2] & 0x3f)] : '=');
+1 -1
View File
@@ -31,7 +31,7 @@ static const int VERSION_MINOR = 11;
static const int VERSION_REV = 0; static const int VERSION_REV = 0;
static const char *VERSION = LOVE_VERSION_STRING; static const char *VERSION = LOVE_VERSION_STRING;
static const char *VERSION_COMPATIBILITY[] = { VERSION, 0 }; static const char *VERSION_COMPATIBILITY[] = { VERSION, 0 };
static const char *VERSION_CODENAME = ""; static const char *VERSION_CODENAME = "Mysterious Mysteries";
} // love } // love
@@ -408,7 +408,7 @@ const std::vector<love::audio::RecordingDevice*> &Audio::getRecordingDevices()
if (defaultname.length() == 0) if (defaultname.length() == 0)
{ {
//use some safe basic parameters - 8 kHz, 8 bits, 1 channel //use some safe basic parameters - 8 kHz, 8 bits, 1 channel
ALCdevice *defaultdevice = alcCaptureOpenDevice(NULL, 8000, 8, 1); ALCdevice *defaultdevice = alcCaptureOpenDevice(NULL, 8000, AL_FORMAT_MONO8, 1024);
if (alGetError() == AL_NO_ERROR) if (alGetError() == AL_NO_ERROR)
{ {
defaultname = alcGetString(defaultdevice, ALC_CAPTURE_DEVICE_SPECIFIER); defaultname = alcGetString(defaultdevice, ALC_CAPTURE_DEVICE_SPECIFIER);
@@ -610,36 +610,36 @@ double Source::getDuration(Unit unit)
switch (sourceType) switch (sourceType)
{ {
case TYPE_STATIC: case TYPE_STATIC:
{ {
ALsizei size = staticBuffer->getSize(); ALsizei size = staticBuffer->getSize();
ALsizei samples = (size / channels) / (bitDepth / 8); ALsizei samples = (size / channels) / (bitDepth / 8);
if (unit == UNIT_SAMPLES) if (unit == UNIT_SAMPLES)
return (double) samples; return (double) samples;
else else
return (double) samples / (double) sampleRate; return (double) samples / (double) sampleRate;
} }
case TYPE_STREAM: case TYPE_STREAM:
{ {
double seconds = decoder->getDuration(); double seconds = decoder->getDuration();
if (unit == UNIT_SECONDS) if (unit == UNIT_SECONDS)
return seconds; return seconds;
else else
return seconds * decoder->getSampleRate(); return seconds * decoder->getSampleRate();
} }
case TYPE_QUEUE: case TYPE_QUEUE:
{ {
ALsizei samples = (bufferedBytes / channels) / (bitDepth / 8); ALsizei samples = (bufferedBytes / channels) / (bitDepth / 8);
if (unit == UNIT_SAMPLES) if (unit == UNIT_SAMPLES)
return (double)samples; return (double)samples;
else else
return (double)samples / (double)sampleRate; return (double)samples / (double)sampleRate;
} }
case TYPE_MAX_ENUM: case TYPE_MAX_ENUM:
return 0.0; return 0.0;
} }
return 0.0; return 0.0;
} }
@@ -813,14 +813,14 @@ int Source::getFreeBufferCount() const
{ {
switch (sourceType) //why not :^) switch (sourceType) //why not :^)
{ {
case TYPE_STATIC: case TYPE_STATIC:
return 0; return 0;
case TYPE_STREAM: case TYPE_STREAM:
return unusedBuffers.size(); return unusedBuffers.size();
case TYPE_QUEUE: case TYPE_QUEUE:
return unusedBuffers.size(); return unusedBuffers.size();
case TYPE_MAX_ENUM: case TYPE_MAX_ENUM:
return 0; return 0;
} }
return 0; return 0;
} }
@@ -834,34 +834,34 @@ void Source::prepareAtomic()
switch (sourceType) switch (sourceType)
{ {
case TYPE_STATIC: case TYPE_STATIC:
alSourcei(source, AL_BUFFER, staticBuffer->getBuffer()); alSourcei(source, AL_BUFFER, staticBuffer->getBuffer());
break; break;
case TYPE_STREAM: case TYPE_STREAM:
while (!unusedBuffers.empty()) while (!unusedBuffers.empty())
{
auto b = unusedBuffers.top();
if (streamAtomic(b, decoder.get()) == 0)
break;
alSourceQueueBuffers(source, 1, &b);
unusedBuffers.pop();
if (decoder->isFinished())
break;
}
break;
case TYPE_QUEUE:
{ {
while (!streamBuffers.empty()) auto b = unusedBuffers.top();
{ if (streamAtomic(b, decoder.get()) == 0)
alSourceQueueBuffers(source, 1, &streamBuffers.front()); break;
streamBuffers.pop();
} alSourceQueueBuffers(source, 1, &b);
break; unusedBuffers.pop();
if (decoder->isFinished())
break;
} }
case TYPE_MAX_ENUM: break;
break; case TYPE_QUEUE:
{
while (!streamBuffers.empty())
{
alSourceQueueBuffers(source, 1, &streamBuffers.front());
streamBuffers.pop();
}
break;
}
case TYPE_MAX_ENUM:
break;
} }
} }
@@ -869,39 +869,39 @@ void Source::teardownAtomic()
{ {
switch (sourceType) switch (sourceType)
{ {
case TYPE_STATIC: case TYPE_STATIC:
break; break;
case TYPE_STREAM: case TYPE_STREAM:
{ {
ALint queued; ALint queued;
ALuint buffer; ALuint buffer;
decoder->seek(0); decoder->seek(0);
// drain buffers // drain buffers
//since we only unqueue 1 buffer, it's OK to use singular variable pointer instead of array //since we only unqueue 1 buffer, it's OK to use singular variable pointer instead of array
alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
for (unsigned int i = 0; i < (unsigned int)queued; i++) for (unsigned int i = 0; i < (unsigned int)queued; i++)
{
alSourceUnqueueBuffers(source, 1, &buffer);
unusedBuffers.push(buffer);
}
break;
}
case TYPE_QUEUE:
{ {
ALint queued; alSourceUnqueueBuffers(source, 1, &buffer);
ALuint buffer; unusedBuffers.push(buffer);
alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
for (unsigned int i = (unsigned int)queued; i > 0; i--)
{
alSourceUnqueueBuffers(source, 1, &buffer);
unusedBuffers.push(buffer);
}
break;
} }
case TYPE_MAX_ENUM: break;
break; }
case TYPE_QUEUE:
{
ALint queued;
ALuint buffer;
alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
for (unsigned int i = (unsigned int)queued; i > 0; i--)
{
alSourceUnqueueBuffers(source, 1, &buffer);
unusedBuffers.push(buffer);
}
break;
}
case TYPE_MAX_ENUM:
break;
} }
alSourcei(source, AL_BUFFER, AL_NONE); alSourcei(source, AL_BUFFER, AL_NONE);
@@ -198,6 +198,8 @@ private:
int windowbits = 15; int windowbits = 15;
if (format == FORMAT_GZIP) if (format == FORMAT_GZIP)
windowbits += 16; // This tells zlib to use a gzip header. windowbits += 16; // This tells zlib to use a gzip header.
else if (format == FORMAT_DEFLATE)
windowbits = -windowbits;
int err = deflateInit2(&stream, level, Z_DEFLATED, windowbits, 8, Z_DEFAULT_STRATEGY); int err = deflateInit2(&stream, level, Z_DEFLATED, windowbits, 8, Z_DEFAULT_STRATEGY);
@@ -217,7 +219,7 @@ private:
return deflateEnd(&stream); return deflateEnd(&stream);
} }
int zlibDecompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen) int zlibDecompress(Format format, Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
{ {
z_stream stream = {}; z_stream stream = {};
@@ -230,6 +232,9 @@ private:
// 15 is the default. Adding 32 makes zlib auto-detect the header type. // 15 is the default. Adding 32 makes zlib auto-detect the header type.
int windowbits = 15 + 32; int windowbits = 15 + 32;
if (format == FORMAT_DEFLATE)
windowbits = -15;
int err = inflateInit2(&stream, windowbits); int err = inflateInit2(&stream, windowbits);
if (err != Z_OK) if (err != Z_OK)
@@ -324,7 +329,7 @@ public:
} }
uLongf destLen = (uLongf) rawsize; uLongf destLen = (uLongf) rawsize;
int status = zlibDecompress((Bytef *) rawbytes, &destLen, (const Bytef *) data, (uLong) dataSize); int status = zlibDecompress(format, (Bytef *) rawbytes, &destLen, (const Bytef *) data, (uLong) dataSize);
if (status == Z_OK) if (status == Z_OK)
{ {
@@ -348,7 +353,7 @@ public:
bool isSupported(Format format) const override bool isSupported(Format format) const override
{ {
return format == FORMAT_ZLIB || format == FORMAT_GZIP; return format == FORMAT_ZLIB || format == FORMAT_GZIP || format == FORMAT_DEFLATE;
} }
}; // zlibCompressor }; // zlibCompressor
@@ -386,9 +391,10 @@ std::vector<std::string> Compressor::getConstants(Format)
StringMap<Compressor::Format, Compressor::FORMAT_MAX_ENUM>::Entry Compressor::formatEntries[] = StringMap<Compressor::Format, Compressor::FORMAT_MAX_ENUM>::Entry Compressor::formatEntries[] =
{ {
{ "lz4", FORMAT_LZ4 }, { "lz4", FORMAT_LZ4 },
{ "zlib", FORMAT_ZLIB }, { "zlib", FORMAT_ZLIB },
{ "gzip", FORMAT_GZIP }, { "gzip", FORMAT_GZIP },
{ "deflate", FORMAT_DEFLATE },
}; };
StringMap<Compressor::Format, Compressor::FORMAT_MAX_ENUM> Compressor::formatNames(Compressor::formatEntries, sizeof(Compressor::formatEntries)); StringMap<Compressor::Format, Compressor::FORMAT_MAX_ENUM> Compressor::formatNames(Compressor::formatEntries, sizeof(Compressor::formatEntries));
@@ -40,6 +40,7 @@ public:
FORMAT_LZ4, FORMAT_LZ4,
FORMAT_ZLIB, FORMAT_ZLIB,
FORMAT_GZIP, FORMAT_GZIP,
FORMAT_DEFLATE,
FORMAT_MAX_ENUM FORMAT_MAX_ENUM
}; };
@@ -130,6 +130,11 @@ bool Filesystem::getConstant(FileType in, const char *&out)
return fileTypes.find(in, out); return fileTypes.find(in, out);
} }
std::vector<std::string> Filesystem::getConstants(FileType)
{
return fileTypes.getNames();
}
StringMap<Filesystem::FileType, Filesystem::FILETYPE_MAX_ENUM>::Entry Filesystem::fileTypeEntries[] = StringMap<Filesystem::FileType, Filesystem::FILETYPE_MAX_ENUM>::Entry Filesystem::fileTypeEntries[] =
{ {
{ "file", FILETYPE_FILE }, { "file", FILETYPE_FILE },
@@ -265,6 +265,7 @@ public:
static bool getConstant(const char *in, FileType &out); static bool getConstant(const char *in, FileType &out);
static bool getConstant(FileType in, const char *&out); static bool getConstant(FileType in, const char *&out);
static std::vector<std::string> getConstants(FileType);
private: private:
@@ -267,6 +267,8 @@ int w_File_lines_i(lua_State *L)
const char *start = buffer+offset; const char *start = buffer+offset;
const char *end = reinterpret_cast<const char*>(memchr(start, '\n', len-offset)); const char *end = reinterpret_cast<const char*>(memchr(start, '\n', len-offset));
bool seekBack = luax_toboolean(L, lua_upvalueindex(5));
// If there are no more lines in the buffer, keep adding more data until we // If there are no more lines in the buffer, keep adding more data until we
// found another line or EOF // found another line or EOF
if (!end && !file->isEOF()) if (!end && !file->isEOF())
@@ -282,14 +284,12 @@ int w_File_lines_i(lua_State *L)
// If the user has changed the position, we need to seek back first // If the user has changed the position, we need to seek back first
int64 pos = file->tell(); int64 pos = file->tell();
int64 userpos = -1; int64 userpos = -1;
if (!lua_isnoneornil(L, lua_upvalueindex(4))) if (seekBack)
{ {
userpos = pos; userpos = pos;
pos = (int64) lua_tonumber(L, lua_upvalueindex(4)); pos = (int64) lua_tonumber(L, lua_upvalueindex(4));
if (userpos != pos) if (userpos != pos)
file->seek(pos); file->seek(pos);
else
userpos = -1;
} }
// Keep reading until newline or EOF // Keep reading until newline or EOF
@@ -307,8 +307,13 @@ int w_File_lines_i(lua_State *L)
} }
// Possibly seek back to the user position // Possibly seek back to the user position
if (userpos >= 0 && luax_toboolean(L, lua_upvalueindex(5))) // But make sure to save our target position too
if (seekBack)
{
lua_pushnumber(L, file->tell());
lua_replace(L, lua_upvalueindex(4));
file->seek(userpos); file->seek(userpos);
}
// We've now got a new buffer, replace the old one // We've now got a new buffer, replace the old one
luaL_pushresult(&storage); luaL_pushresult(&storage);
@@ -319,7 +324,7 @@ int w_File_lines_i(lua_State *L)
end = reinterpret_cast<const char*>(memchr(start, '\n', len)); end = reinterpret_cast<const char*>(memchr(start, '\n', len));
} }
if (!end && file->isEOF()) if (!end)
end = buffer+len-1; end = buffer+len-1;
// We've found the next line, update our offset upvalue and return // We've found the next line, update our offset upvalue and return
@@ -353,7 +358,7 @@ int w_File_lines(lua_State *L)
lua_pushstring(L, ""); // buffer lua_pushstring(L, ""); // buffer
lua_pushnumber(L, 0); // buffer offset lua_pushnumber(L, 0); // buffer offset
lua_pushnumber(L, 0); // File position. lua_pushnumber(L, 0); // File position.
luax_pushboolean(L, file->getMode() != File::MODE_CLOSED); // Save current file mode. luax_pushboolean(L, file->getMode() != File::MODE_CLOSED); // Save current file position.
if (file->getMode() != File::MODE_READ) if (file->getMode() != File::MODE_READ)
{ {
@@ -395,14 +395,31 @@ int w_getInfo(lua_State *L)
const char *filepath = luaL_checkstring(L, 1); const char *filepath = luaL_checkstring(L, 1);
Filesystem::Info info = {}; Filesystem::Info info = {};
int startidx = 2;
Filesystem::FileType filtertype = Filesystem::FILETYPE_MAX_ENUM;
if (lua_isstring(L, startidx))
{
const char *typestr = luaL_checkstring(L, startidx);
if (!Filesystem::getConstant(typestr, filtertype))
return luax_enumerror(L, "file type", Filesystem::getConstants(filtertype), typestr);
startidx++;
}
if (instance()->getInfo(filepath, info)) if (instance()->getInfo(filepath, info))
{ {
if (filtertype != Filesystem::FILETYPE_MAX_ENUM && info.type != filtertype)
{
lua_pushnil(L);
return 1;
}
const char *typestr = nullptr; const char *typestr = nullptr;
if (!Filesystem::getConstant(info.type, typestr)) if (!Filesystem::getConstant(info.type, typestr))
return luaL_error(L, "Unknown file type."); return luaL_error(L, "Unknown file type.");
if (lua_istable(L, 2)) if (lua_istable(L, startidx))
lua_pushvalue(L, 2); lua_pushvalue(L, startidx);
else else
lua_createtable(L, 0, 3); lua_createtable(L, 0, 3);
@@ -27,6 +27,14 @@
#include <cmath> #include <cmath>
#include <algorithm> #include <algorithm>
#ifdef LOVE_ANDROID
// log2 is not declared in the math.h shipped with the Android NDK
static inline double log2(double n)
{
// log(n)/log(2) is log2.
return std::log(n) / std::log(2);
}
#endif
namespace love namespace love
@@ -366,7 +366,7 @@ static void pushRenderTarget(lua_State *L, const Graphics::RenderTarget &rt)
lua_pushnumber(L, rt.slice + 1); lua_pushnumber(L, rt.slice + 1);
lua_setfield(L, -2, "layer"); lua_setfield(L, -2, "layer");
} }
else if (type == TEXTURE_VOLUME) else if (type == TEXTURE_CUBE)
{ {
lua_pushnumber(L, rt.slice + 1); lua_pushnumber(L, rt.slice + 1);
lua_setfield(L, -2, "face"); lua_setfield(L, -2, "face");
@@ -199,8 +199,18 @@ bool JoystickModule::setGamepadMapping(const std::string &guid, Joystick::Gamepa
} }
else else
{ {
// Use a generic name if we have to create a new mapping string. std::string name = "Controller";
mapstr = guid + ",Controller,";
for (love::joystick::Joystick *stick : joysticks)
{
if (stick->getGUID() == guid)
{
name = stick->getName();
break;
}
}
mapstr = guid + "," + name + ",";
} }
std::stringstream joyinputstream; std::stringstream joyinputstream;
@@ -432,7 +442,9 @@ void JoystickModule::loadGamepadMappings(const std::string &mappings)
} }
} }
if (!success) // Don't error when an empty string is given, since saveGamepadMappings can
// produce an empty string if there are no recently seen gamepads to save.
if (!success && !mappings.empty())
throw love::Exception("Invalid gamepad mappings."); throw love::Exception("Invalid gamepad mappings.");
} }