mirror of
https://github.com/love2d/love-android.git
synced 2026-08-17 11:11:23 +02:00
Updated LÖVE to changeset c303c1f52ea6
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
repo: d362ae6ab7f5005b8dbc7cba9ce592637de60f99
|
||||
node: a2e84c9fdb8ca18d073d0e782d68205b9aa9ec96
|
||||
node: c303c1f52ea638c96660d0c3bf35b10818a2e3f4
|
||||
branch: default
|
||||
latesttag: 0.10.2
|
||||
latesttagdistance: 381
|
||||
changessincelatesttag: 550
|
||||
latesttagdistance: 395
|
||||
changessincelatesttag: 564
|
||||
|
||||
@@ -93,7 +93,7 @@ Released: N/A
|
||||
* Renamed all get[Object]List functions to get[Object]s.
|
||||
|
||||
* 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 love.graphics.getCompressedImageFormats, use love.graphics.getImageFormats instead.
|
||||
* Removed the 'void effects(...)' pixel shader entry point. Use the new 'void effect()' instead.
|
||||
|
||||
+1144
-1194
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,8 @@ Run `platform/unix/automagic` from the repository root, then run ./configure and
|
||||
$ ./configure
|
||||
$ make
|
||||
|
||||
When using a source release, automagic has already been run, and the first step can be skipped.
|
||||
|
||||
###Mac OS X
|
||||
Download the required frameworks from [here][dependencies] and place them in `/Library/Frameworks/`.
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$
|
||||
**/
|
||||
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[2] = (char) (len > 1 ? cb64[(int)(((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6))] : '=');
|
||||
out[3] = (char) (len > 2 ? cb64[(int)(in[2] & 0x3f)] : '=');
|
||||
|
||||
@@ -31,7 +31,7 @@ static const int VERSION_MINOR = 11;
|
||||
static const int VERSION_REV = 0;
|
||||
static const char *VERSION = LOVE_VERSION_STRING;
|
||||
static const char *VERSION_COMPATIBILITY[] = { VERSION, 0 };
|
||||
static const char *VERSION_CODENAME = "";
|
||||
static const char *VERSION_CODENAME = "Mysterious Mysteries";
|
||||
|
||||
} // love
|
||||
|
||||
|
||||
@@ -408,7 +408,7 @@ const std::vector<love::audio::RecordingDevice*> &Audio::getRecordingDevices()
|
||||
if (defaultname.length() == 0)
|
||||
{
|
||||
//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)
|
||||
{
|
||||
defaultname = alcGetString(defaultdevice, ALC_CAPTURE_DEVICE_SPECIFIER);
|
||||
|
||||
@@ -610,36 +610,36 @@ double Source::getDuration(Unit unit)
|
||||
|
||||
switch (sourceType)
|
||||
{
|
||||
case TYPE_STATIC:
|
||||
{
|
||||
ALsizei size = staticBuffer->getSize();
|
||||
ALsizei samples = (size / channels) / (bitDepth / 8);
|
||||
case TYPE_STATIC:
|
||||
{
|
||||
ALsizei size = staticBuffer->getSize();
|
||||
ALsizei samples = (size / channels) / (bitDepth / 8);
|
||||
|
||||
if (unit == UNIT_SAMPLES)
|
||||
return (double) samples;
|
||||
else
|
||||
return (double) samples / (double) sampleRate;
|
||||
}
|
||||
case TYPE_STREAM:
|
||||
{
|
||||
double seconds = decoder->getDuration();
|
||||
if (unit == UNIT_SAMPLES)
|
||||
return (double) samples;
|
||||
else
|
||||
return (double) samples / (double) sampleRate;
|
||||
}
|
||||
case TYPE_STREAM:
|
||||
{
|
||||
double seconds = decoder->getDuration();
|
||||
|
||||
if (unit == UNIT_SECONDS)
|
||||
return seconds;
|
||||
else
|
||||
return seconds * decoder->getSampleRate();
|
||||
}
|
||||
case TYPE_QUEUE:
|
||||
{
|
||||
ALsizei samples = (bufferedBytes / channels) / (bitDepth / 8);
|
||||
if (unit == UNIT_SECONDS)
|
||||
return seconds;
|
||||
else
|
||||
return seconds * decoder->getSampleRate();
|
||||
}
|
||||
case TYPE_QUEUE:
|
||||
{
|
||||
ALsizei samples = (bufferedBytes / channels) / (bitDepth / 8);
|
||||
|
||||
if (unit == UNIT_SAMPLES)
|
||||
return (double)samples;
|
||||
else
|
||||
return (double)samples / (double)sampleRate;
|
||||
}
|
||||
case TYPE_MAX_ENUM:
|
||||
return 0.0;
|
||||
if (unit == UNIT_SAMPLES)
|
||||
return (double)samples;
|
||||
else
|
||||
return (double)samples / (double)sampleRate;
|
||||
}
|
||||
case TYPE_MAX_ENUM:
|
||||
return 0.0;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
@@ -813,14 +813,14 @@ int Source::getFreeBufferCount() const
|
||||
{
|
||||
switch (sourceType) //why not :^)
|
||||
{
|
||||
case TYPE_STATIC:
|
||||
return 0;
|
||||
case TYPE_STREAM:
|
||||
return unusedBuffers.size();
|
||||
case TYPE_QUEUE:
|
||||
return unusedBuffers.size();
|
||||
case TYPE_MAX_ENUM:
|
||||
return 0;
|
||||
case TYPE_STATIC:
|
||||
return 0;
|
||||
case TYPE_STREAM:
|
||||
return unusedBuffers.size();
|
||||
case TYPE_QUEUE:
|
||||
return unusedBuffers.size();
|
||||
case TYPE_MAX_ENUM:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -834,34 +834,34 @@ void Source::prepareAtomic()
|
||||
|
||||
switch (sourceType)
|
||||
{
|
||||
case TYPE_STATIC:
|
||||
alSourcei(source, AL_BUFFER, staticBuffer->getBuffer());
|
||||
break;
|
||||
case TYPE_STREAM:
|
||||
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:
|
||||
case TYPE_STATIC:
|
||||
alSourcei(source, AL_BUFFER, staticBuffer->getBuffer());
|
||||
break;
|
||||
case TYPE_STREAM:
|
||||
while (!unusedBuffers.empty())
|
||||
{
|
||||
while (!streamBuffers.empty())
|
||||
{
|
||||
alSourceQueueBuffers(source, 1, &streamBuffers.front());
|
||||
streamBuffers.pop();
|
||||
}
|
||||
break;
|
||||
auto b = unusedBuffers.top();
|
||||
if (streamAtomic(b, decoder.get()) == 0)
|
||||
break;
|
||||
|
||||
alSourceQueueBuffers(source, 1, &b);
|
||||
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)
|
||||
{
|
||||
case TYPE_STATIC:
|
||||
break;
|
||||
case TYPE_STREAM:
|
||||
{
|
||||
ALint queued;
|
||||
ALuint buffer;
|
||||
case TYPE_STATIC:
|
||||
break;
|
||||
case TYPE_STREAM:
|
||||
{
|
||||
ALint queued;
|
||||
ALuint buffer;
|
||||
|
||||
decoder->seek(0);
|
||||
// drain buffers
|
||||
//since we only unqueue 1 buffer, it's OK to use singular variable pointer instead of array
|
||||
alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
|
||||
for (unsigned int i = 0; i < (unsigned int)queued; i++)
|
||||
{
|
||||
alSourceUnqueueBuffers(source, 1, &buffer);
|
||||
unusedBuffers.push(buffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_QUEUE:
|
||||
decoder->seek(0);
|
||||
// drain buffers
|
||||
//since we only unqueue 1 buffer, it's OK to use singular variable pointer instead of array
|
||||
alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
|
||||
for (unsigned int i = 0; i < (unsigned int)queued; i++)
|
||||
{
|
||||
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;
|
||||
alSourceUnqueueBuffers(source, 1, &buffer);
|
||||
unusedBuffers.push(buffer);
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -198,6 +198,8 @@ private:
|
||||
int windowbits = 15;
|
||||
if (format == FORMAT_GZIP)
|
||||
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);
|
||||
|
||||
@@ -217,7 +219,7 @@ private:
|
||||
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 = {};
|
||||
|
||||
@@ -230,6 +232,9 @@ private:
|
||||
// 15 is the default. Adding 32 makes zlib auto-detect the header type.
|
||||
int windowbits = 15 + 32;
|
||||
|
||||
if (format == FORMAT_DEFLATE)
|
||||
windowbits = -15;
|
||||
|
||||
int err = inflateInit2(&stream, windowbits);
|
||||
|
||||
if (err != Z_OK)
|
||||
@@ -324,7 +329,7 @@ public:
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -348,7 +353,7 @@ public:
|
||||
|
||||
bool isSupported(Format format) const override
|
||||
{
|
||||
return format == FORMAT_ZLIB || format == FORMAT_GZIP;
|
||||
return format == FORMAT_ZLIB || format == FORMAT_GZIP || format == FORMAT_DEFLATE;
|
||||
}
|
||||
|
||||
}; // zlibCompressor
|
||||
@@ -386,9 +391,10 @@ std::vector<std::string> Compressor::getConstants(Format)
|
||||
|
||||
StringMap<Compressor::Format, Compressor::FORMAT_MAX_ENUM>::Entry Compressor::formatEntries[] =
|
||||
{
|
||||
{ "lz4", FORMAT_LZ4 },
|
||||
{ "zlib", FORMAT_ZLIB },
|
||||
{ "gzip", FORMAT_GZIP },
|
||||
{ "lz4", FORMAT_LZ4 },
|
||||
{ "zlib", FORMAT_ZLIB },
|
||||
{ "gzip", FORMAT_GZIP },
|
||||
{ "deflate", FORMAT_DEFLATE },
|
||||
};
|
||||
|
||||
StringMap<Compressor::Format, Compressor::FORMAT_MAX_ENUM> Compressor::formatNames(Compressor::formatEntries, sizeof(Compressor::formatEntries));
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
FORMAT_LZ4,
|
||||
FORMAT_ZLIB,
|
||||
FORMAT_GZIP,
|
||||
FORMAT_DEFLATE,
|
||||
FORMAT_MAX_ENUM
|
||||
};
|
||||
|
||||
|
||||
@@ -130,6 +130,11 @@ bool Filesystem::getConstant(FileType in, const char *&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[] =
|
||||
{
|
||||
{ "file", FILETYPE_FILE },
|
||||
|
||||
@@ -265,6 +265,7 @@ public:
|
||||
|
||||
static bool getConstant(const char *in, FileType &out);
|
||||
static bool getConstant(FileType in, const char *&out);
|
||||
static std::vector<std::string> getConstants(FileType);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -267,6 +267,8 @@ int w_File_lines_i(lua_State *L)
|
||||
const char *start = buffer+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
|
||||
// found another line or EOF
|
||||
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
|
||||
int64 pos = file->tell();
|
||||
int64 userpos = -1;
|
||||
if (!lua_isnoneornil(L, lua_upvalueindex(4)))
|
||||
if (seekBack)
|
||||
{
|
||||
userpos = pos;
|
||||
pos = (int64) lua_tonumber(L, lua_upvalueindex(4));
|
||||
if (userpos != pos)
|
||||
file->seek(pos);
|
||||
else
|
||||
userpos = -1;
|
||||
}
|
||||
|
||||
// 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
|
||||
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);
|
||||
}
|
||||
|
||||
// We've now got a new buffer, replace the old one
|
||||
luaL_pushresult(&storage);
|
||||
@@ -319,7 +324,7 @@ int w_File_lines_i(lua_State *L)
|
||||
end = reinterpret_cast<const char*>(memchr(start, '\n', len));
|
||||
}
|
||||
|
||||
if (!end && file->isEOF())
|
||||
if (!end)
|
||||
end = buffer+len-1;
|
||||
|
||||
// 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_pushnumber(L, 0); // buffer offset
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -395,14 +395,31 @@ int w_getInfo(lua_State *L)
|
||||
const char *filepath = luaL_checkstring(L, 1);
|
||||
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 (filtertype != Filesystem::FILETYPE_MAX_ENUM && info.type != filtertype)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *typestr = nullptr;
|
||||
if (!Filesystem::getConstant(info.type, typestr))
|
||||
return luaL_error(L, "Unknown file type.");
|
||||
|
||||
if (lua_istable(L, 2))
|
||||
lua_pushvalue(L, 2);
|
||||
if (lua_istable(L, startidx))
|
||||
lua_pushvalue(L, startidx);
|
||||
else
|
||||
lua_createtable(L, 0, 3);
|
||||
|
||||
|
||||
@@ -27,6 +27,14 @@
|
||||
#include <cmath>
|
||||
#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
|
||||
|
||||
@@ -366,7 +366,7 @@ static void pushRenderTarget(lua_State *L, const Graphics::RenderTarget &rt)
|
||||
lua_pushnumber(L, rt.slice + 1);
|
||||
lua_setfield(L, -2, "layer");
|
||||
}
|
||||
else if (type == TEXTURE_VOLUME)
|
||||
else if (type == TEXTURE_CUBE)
|
||||
{
|
||||
lua_pushnumber(L, rt.slice + 1);
|
||||
lua_setfield(L, -2, "face");
|
||||
|
||||
@@ -199,8 +199,18 @@ bool JoystickModule::setGamepadMapping(const std::string &guid, Joystick::Gamepa
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use a generic name if we have to create a new mapping string.
|
||||
mapstr = guid + ",Controller,";
|
||||
std::string name = "Controller";
|
||||
|
||||
for (love::joystick::Joystick *stick : joysticks)
|
||||
{
|
||||
if (stick->getGUID() == guid)
|
||||
{
|
||||
name = stick->getName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mapstr = guid + "," + name + ",";
|
||||
}
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user