mirror of
https://github.com/love2d/love.git
synced 2026-08-12 00:20:52 +02:00
Merge branch 'main' into 12.0-development
This commit is contained in:
+19
-26
@@ -9,37 +9,30 @@ jobs:
|
||||
run: sudo apt-get update
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get install --assume-yes build-essential autotools-dev automake libtool pkg-config \
|
||||
libfreetype6-dev libluajit-5.1-dev libsdl2-dev libopenal-dev \
|
||||
libogg-dev libvorbis-dev libmodplug-dev libmpg123-dev libtheora-dev
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Pre-Configure
|
||||
run: $PWD/platform/unix/automagic
|
||||
- name: Configure
|
||||
run: mkdir build && cd build && ../configure
|
||||
- name: Build
|
||||
run: cd build && make -j2
|
||||
- name: Prepare appimagetool
|
||||
run: |
|
||||
cd build &&
|
||||
wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O appimagetool &&
|
||||
chmod +x appimagetool &&
|
||||
sudo apt install -y appstream
|
||||
- name: Clone love-appimages
|
||||
sudo apt-get install --assume-yes build-essential git make cmake autoconf automake \
|
||||
libtool pkg-config libasound2-dev libpulse-dev libaudio-dev \
|
||||
libjack-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev \
|
||||
libxfixes-dev libxi-dev libxinerama-dev libxxf86vm-dev libxss-dev \
|
||||
libgl1-mesa-dev libdbus-1-dev libudev-dev libgles2-mesa-dev \
|
||||
libegl1-mesa-dev libibus-1.0-dev fcitx-libs-dev libsamplerate0-dev \
|
||||
libsndio-dev libwayland-dev libxkbcommon-dev libdrm-dev libgbm-dev
|
||||
- name: Checkout love-appimage-source
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: build/love-appimages
|
||||
repository: pfirsich/love-appimages
|
||||
repository: MikuAuahDark/love-appimage-source
|
||||
- name: Checkout LÖVE
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: love2d-${{ github.sha }}
|
||||
- name: Build AppImage
|
||||
run: |
|
||||
cd build &&
|
||||
python3 love-appimages/build.py .. AppDir --builddir build --appimage love.AppImage
|
||||
run: make LOVE_BRANCH=${{ github.sha }}
|
||||
- name: Print LuaJIT branch
|
||||
run: git -C LuaJIT-v2.1 branch -v
|
||||
- name: Artifact
|
||||
uses: actions/upload-artifact@v2-preview
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: love.AppImage
|
||||
path: build/love.AppImage
|
||||
name: love-x86_64.AppImage
|
||||
path: love-${{ github.sha }}.AppImage
|
||||
windows-os:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
|
||||
@@ -38,12 +38,14 @@ LOVE 11.4 [Mysterious Mysteries]
|
||||
|
||||
Released: N/A
|
||||
|
||||
* Added native arm64 support on macOS.
|
||||
* Added Body:getLocalPoints.
|
||||
* Added Font:getKerning.
|
||||
* Added support for r16, rg16, and rgba16 pixel formats in Canvases.
|
||||
* Added Shader:send(name, matrixlayout, data, ...) variant, whose argument order is more consistent than Shader:send(name, data, matrixlayout, ...).
|
||||
|
||||
* Changed love.timer.getTime to start at 0 when the module is first loaded.
|
||||
* Changed certain out-of-Lua-memory situations to show a message box instead of instantly crashing.
|
||||
|
||||
* Fixed build-time compatibility with Lua 5.4.
|
||||
* Fixed code compatibility with math.mod and string.gfind when LuaJIT 2.1 is used.
|
||||
@@ -54,21 +56,28 @@ Released: N/A
|
||||
* Fixed support for > 2GB dropped files on desktops.
|
||||
* Fixed love.physics meter scale value persisting after love.event.quit("restart").
|
||||
* Fixed audio to resume properly after interruption on iOS.
|
||||
* Fixed love.graphics.newVideo to error instead of crash when an invalid video file is given.
|
||||
* Fixed initial window creation to set the window's title during creation instead of after.
|
||||
* Fixed the window's screen position when exiting fullscreen via love.window.setFullscreen.
|
||||
* Fixed love.displayrotated being given a boolean instead of an enum string.
|
||||
* Fixed memory corruption and a crash when drawing smooth lines.
|
||||
* Fixed a crash in Canvas:newImageData when the pixel format's pixel byte size multiplied by its width isn't a multiple of 4.
|
||||
* Fixed love.graphics.newVolumeImage when explicit mipmaps are provided.
|
||||
* Fixed freezes and crashes in automatic batching when an AMD GPU is used.
|
||||
* Fixed love.graphics.print and Image:replacePixels on more AMD/ATI GPUs.
|
||||
* Fixed Font:setFallbacks to account for different DPI scales in each fallback font.
|
||||
* Fixed Font:getWrap to not remove trailing newlines.
|
||||
* Fixed Text:getWidth when the Text's string only contains spaces.
|
||||
* Fixed a crash with some Intel graphics drivers on Linux.
|
||||
* Fixed a hang with some Intel graphics drivers on Windows, by preventing gamma correct rendering on affected systems.
|
||||
* Fixed a crash with some Intel graphics drivers on Windows when mipmapped Canvases are used.
|
||||
* Fixed texture memory reported by love.graphics.getStats when a volume or array Canvas is created.
|
||||
* Fixed DXT1 textures which use 1 bit alpha-cutout.
|
||||
* Fixed rare issues where textures were not sent to shaders correctly.
|
||||
* Fixed Shader:send(name, data, matrixlayout, ...).
|
||||
* Fixed quad offsets in ParticleSystems when ParticleSystem:setOffset is not used.
|
||||
* Fixed rounded rectangles breaking if the rx or ry parameters are negative.
|
||||
* Fixed rounded rectangle automatic points calculation when rx or ry are more than half the rectangle's size.
|
||||
* Fixed source code compilation on Xcode 12+.
|
||||
* Fixed source code compilation on Linux systems that don't provide posix_spawn APIs.
|
||||
|
||||
|
||||
@@ -1769,6 +1769,7 @@
|
||||
FA620A301AA2F8DB005DB4C2 /* wrap_Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Texture.cpp; sourceTree = "<group>"; };
|
||||
FA620A311AA2F8DB005DB4C2 /* wrap_Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Texture.h; sourceTree = "<group>"; };
|
||||
FA620A391AA305F6005DB4C2 /* types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = types.cpp; sourceTree = "<group>"; };
|
||||
FA69B918273828DD00CDC2E7 /* jitsetup.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = jitsetup.lua; sourceTree = "<group>"; };
|
||||
FA6A2B641F5F7B6B0074C308 /* wrap_Data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Data.h; sourceTree = "<group>"; };
|
||||
FA6A2B651F5F7B6B0074C308 /* wrap_Data.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Data.cpp; sourceTree = "<group>"; };
|
||||
FA6A2B681F5F7F560074C308 /* DataView.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DataView.cpp; sourceTree = "<group>"; };
|
||||
@@ -2850,6 +2851,7 @@
|
||||
FA1E95B4271F932B0044CF08 /* arg.lua */,
|
||||
FA577A8D16C71D3600860150 /* boot.lua */,
|
||||
FA1E95B5271F932B0044CF08 /* callbacks.lua */,
|
||||
FA69B918273828DD00CDC2E7 /* jitsetup.lua */,
|
||||
FA0B7BFE1A95902C000E1D17 /* love.cpp */,
|
||||
FA0B7BFF1A95902C000E1D17 /* love.h */,
|
||||
);
|
||||
@@ -4208,7 +4210,7 @@
|
||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1250;
|
||||
LastUpgradeCheck = 1310;
|
||||
TargetAttributes = {
|
||||
FA0B78DC1A958B90000E1D17 = {
|
||||
CreatedOnToolsVersion = 6.1.1;
|
||||
|
||||
@@ -324,7 +324,7 @@
|
||||
29B97313FDCFA39411CA2CEA /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1250;
|
||||
LastUpgradeCheck = 1310;
|
||||
TargetAttributes = {
|
||||
FA0B7F051A95AAF3000E1D17 = {
|
||||
CreatedOnToolsVersion = 6.1.1;
|
||||
|
||||
@@ -83,16 +83,16 @@ Dependencies
|
||||
- Vorbisfile
|
||||
- Theora
|
||||
|
||||
[site]: http://love2d.org
|
||||
[wiki]: http://love2d.org/wiki
|
||||
[forums]: http://love2d.org/forums
|
||||
[site]: https://love2d.org
|
||||
[wiki]: https://love2d.org/wiki
|
||||
[forums]: https://love2d.org/forums
|
||||
[discord]: https://discord.gg/rhUets9
|
||||
[irc]: irc://irc.oftc.net/love
|
||||
[dependencies-macos]: https://github.com/slime73/love-apple-dependencies
|
||||
[dependencies-ios]: https://github.com/love2d/love/releases
|
||||
[megasource]: https://github.com/love2d/megasource
|
||||
[unstableppa]: https://launchpad.net/~bartbes/+archive/love-unstable
|
||||
[aur]: http://aur.archlinux.org/packages/love-git
|
||||
[aur]: https://aur.archlinux.org/packages/love-git
|
||||
[love-experiments]: https://github.com/slime73/love-experiments
|
||||
[codestyle]: https://love2d.org/wiki/Code_Style
|
||||
[android-repository]: https://github.com/love2d/love-android
|
||||
|
||||
+154
-55
@@ -333,24 +333,59 @@ void showRecordingPermissionMissingDialog()
|
||||
env->DeleteLocalRef(activity);
|
||||
}
|
||||
|
||||
/* A container for AssetManager Java object */
|
||||
class AssetManagerObject
|
||||
{
|
||||
public:
|
||||
AssetManagerObject()
|
||||
{
|
||||
JNIEnv *env = (JNIEnv *) SDL_AndroidGetJNIEnv();
|
||||
jobject am = getLocalAssetManager(env);
|
||||
|
||||
assetManager = env->NewGlobalRef(am);
|
||||
env->DeleteLocalRef(am);
|
||||
}
|
||||
|
||||
~AssetManagerObject()
|
||||
{
|
||||
JNIEnv *env = (JNIEnv *) SDL_AndroidGetJNIEnv();
|
||||
env->DeleteGlobalRef(assetManager);
|
||||
}
|
||||
|
||||
static jobject getLocalAssetManager(JNIEnv *env) {
|
||||
jobject self = (jobject) SDL_AndroidGetActivity();
|
||||
jclass activity = env->GetObjectClass(self);
|
||||
jmethodID method = env->GetMethodID(activity, "getAssets", "()Landroid/content/res/AssetManager;");
|
||||
jobject am = env->CallObjectMethod(self, method);
|
||||
|
||||
env->DeleteLocalRef(self);
|
||||
env->DeleteLocalRef(activity);
|
||||
return am;
|
||||
}
|
||||
|
||||
explicit operator jobject()
|
||||
{
|
||||
return assetManager;
|
||||
};
|
||||
private:
|
||||
jobject assetManager;
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper functions to aid new fusing method
|
||||
*/
|
||||
|
||||
// This returns *global* reference, no need to free it.
|
||||
static jobject getJavaAssetManager()
|
||||
{
|
||||
static AssetManagerObject assetManager;
|
||||
return (jobject) assetManager;
|
||||
}
|
||||
|
||||
static AAssetManager *getAssetManager()
|
||||
{
|
||||
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
|
||||
jobject self = (jobject) SDL_AndroidGetActivity();
|
||||
jclass activity = env->GetObjectClass(self);
|
||||
jmethodID method = env->GetMethodID(activity, "getAssetManager", "()Landroid/content/res/AssetManager;");
|
||||
|
||||
jobject assetManager = env->CallObjectMethod(self, method);
|
||||
AAssetManager *assetManagerObject = AAssetManager_fromJava(env, assetManager);
|
||||
|
||||
env->DeleteLocalRef(assetManager);
|
||||
env->DeleteLocalRef(activity);
|
||||
env->DeleteLocalRef(self);
|
||||
|
||||
return assetManagerObject;
|
||||
return AAssetManager_fromJava(env, (jobject) getJavaAssetManager());
|
||||
}
|
||||
|
||||
namespace aasset
|
||||
@@ -368,35 +403,6 @@ struct AssetInfo
|
||||
|
||||
static std::unordered_map<std::string, PHYSFS_FileType> fileTree;
|
||||
|
||||
// Workaround AAsset can't detect whetever something is a directory or doesn't exist
|
||||
static void buildFileLookup(
|
||||
AAssetManager *assetManager,
|
||||
std::unordered_map<std::string, PHYSFS_FileType> &out,
|
||||
const std::string &path = ""
|
||||
)
|
||||
{
|
||||
if (!path.empty())
|
||||
{
|
||||
AAsset *test = AAssetManager_open(assetManager, path.c_str(), AASSET_MODE_STREAMING);
|
||||
if (test)
|
||||
{
|
||||
AAsset_close(test);
|
||||
out[path] = PHYSFS_FILETYPE_REGULAR;
|
||||
return;
|
||||
}
|
||||
|
||||
out[path] = PHYSFS_FILETYPE_DIRECTORY;
|
||||
}
|
||||
|
||||
AAssetDir *dir = AAssetManager_openDir(assetManager, path.c_str());
|
||||
const char *file;
|
||||
|
||||
while ((file = AAssetDir_getNextFileName(dir)) != nullptr)
|
||||
buildFileLookup(assetManager, out, file);
|
||||
|
||||
AAssetDir_close(dir);
|
||||
}
|
||||
|
||||
PHYSFS_sint64 read(PHYSFS_Io *io, void *buf, PHYSFS_uint64 len)
|
||||
{
|
||||
AAsset *asset = ((AssetInfo *) io->opaque)->asset;
|
||||
@@ -505,7 +511,31 @@ void *openArchive(PHYSFS_Io *io, const char *name, int forWrite, int *claimed)
|
||||
AAssetManager *assetManager = getAssetManager();
|
||||
|
||||
if (io::fileTree.empty())
|
||||
io::buildFileLookup(assetManager, io::fileTree);
|
||||
{
|
||||
// AAssetDir_getNextFileName intentionally excludes directories, so
|
||||
// we have to use JNI that calls AssetManager.list() recursively.
|
||||
JNIEnv *env = (JNIEnv *) SDL_AndroidGetJNIEnv();
|
||||
jobject activity = (jobject) SDL_AndroidGetActivity();
|
||||
jclass clazz = env->GetObjectClass(activity);
|
||||
|
||||
jmethodID method = env->GetMethodID(clazz, "buildFileTree", "()[Ljava/lang/String;");
|
||||
jobjectArray list = (jobjectArray) env->CallObjectMethod(activity, method);
|
||||
|
||||
for (jsize i = 0; i < env->GetArrayLength(list); i++)
|
||||
{
|
||||
jstring jstr = (jstring) env->GetObjectArrayElement(list, i);
|
||||
const char *str = env->GetStringUTFChars(jstr, nullptr);
|
||||
|
||||
io::fileTree[str + 1] = str[0] == 'd' ? PHYSFS_FILETYPE_DIRECTORY : PHYSFS_FILETYPE_REGULAR;
|
||||
|
||||
env->ReleaseStringUTFChars(jstr, str);
|
||||
env->DeleteLocalRef(jstr);
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(list);
|
||||
env->DeleteLocalRef(clazz);
|
||||
env->DeleteLocalRef(activity);
|
||||
}
|
||||
|
||||
return assetManager;
|
||||
}
|
||||
@@ -518,33 +548,60 @@ PHYSFS_EnumerateCallbackResult enumerate(
|
||||
void *callbackdata
|
||||
)
|
||||
{
|
||||
using FileTreeIterator = std::unordered_map<std::string, PHYSFS_FileType>::iterator;
|
||||
LOVE_UNUSED(opaque);
|
||||
|
||||
const char *path = dirname;
|
||||
if (path == nullptr || (path[0] == '/' && path[1] == 0))
|
||||
path = "";
|
||||
|
||||
AAssetManager *assetManager = (AAssetManager *) opaque;
|
||||
AAssetDir *dir = AAssetManager_openDir(assetManager, path);
|
||||
|
||||
if (dir == nullptr)
|
||||
if (path[0] != 0)
|
||||
{
|
||||
PHYSFS_setErrorCode(PHYSFS_ERR_NOT_FOUND);
|
||||
return PHYSFS_ENUM_ERROR;
|
||||
FileTreeIterator result = io::fileTree.find(path);
|
||||
|
||||
if (result == io::fileTree.end() || result->second != PHYSFS_FILETYPE_DIRECTORY)
|
||||
{
|
||||
PHYSFS_setErrorCode(PHYSFS_ERR_NOT_FOUND);
|
||||
return PHYSFS_ENUM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEnv *env = (JNIEnv *) SDL_AndroidGetJNIEnv();
|
||||
jobject assetManager = getJavaAssetManager();
|
||||
jclass clazz = env->GetObjectClass(assetManager);
|
||||
jmethodID method = env->GetMethodID(clazz, "list", "(Ljava/lang/String;)[Ljava/lang/String;");
|
||||
|
||||
jstring jstringDir = env->NewStringUTF(path);
|
||||
jobjectArray dir = (jobjectArray) env->CallObjectMethod(assetManager, method, jstringDir);
|
||||
|
||||
PHYSFS_EnumerateCallbackResult ret = PHYSFS_ENUM_OK;
|
||||
|
||||
while (ret == PHYSFS_ENUM_OK)
|
||||
if (env->ExceptionCheck())
|
||||
{
|
||||
const char *name = AAssetDir_getNextFileName(dir);
|
||||
// IOException occured
|
||||
ret = PHYSFS_ENUM_ERROR;
|
||||
env->ExceptionClear();
|
||||
}
|
||||
else
|
||||
{
|
||||
jsize i = 0;
|
||||
jsize len = env->GetArrayLength(dir);
|
||||
|
||||
// No more files?
|
||||
if (name == nullptr)
|
||||
break;
|
||||
while (ret == PHYSFS_ENUM_OK && i < len) {
|
||||
jstring jstr = (jstring) env->GetObjectArrayElement(dir, i++);
|
||||
const char *name = env->GetStringUTFChars(jstr, nullptr);
|
||||
|
||||
ret = cb(callbackdata, origdir, name);
|
||||
ret = cb(callbackdata, origdir, name);
|
||||
|
||||
env->ReleaseStringUTFChars(jstr, name);
|
||||
env->DeleteLocalRef(jstr);
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(dir);
|
||||
}
|
||||
|
||||
AAssetDir_close(dir);
|
||||
env->DeleteLocalRef(jstringDir);
|
||||
env->DeleteLocalRef(clazz);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -724,6 +781,48 @@ bool checkFusedGame(void **physfsIO_Out)
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *getCRequirePath()
|
||||
{
|
||||
static bool initialized = false;
|
||||
static const char *path = nullptr;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
|
||||
jobject activity = (jobject) SDL_AndroidGetActivity();
|
||||
|
||||
jclass clazz(env->GetObjectClass(activity));
|
||||
jmethodID method_id = env->GetMethodID(clazz, "getCRequirePath", "()Ljava/lang/String;");
|
||||
|
||||
path = "";
|
||||
initialized = true;
|
||||
|
||||
if (method_id)
|
||||
{
|
||||
jstring cpath = (jstring) env->CallObjectMethod(activity, method_id);
|
||||
const char *utf = env->GetStringUTFChars(cpath, nullptr);
|
||||
if (utf)
|
||||
{
|
||||
path = SDL_strdup(utf);
|
||||
env->ReleaseStringUTFChars(cpath, utf);
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(cpath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NoSuchMethodException is thrown in case methodID is null
|
||||
env->ExceptionClear();
|
||||
return "";
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(activity);
|
||||
env->DeleteLocalRef(clazz);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
} // android
|
||||
} // love
|
||||
|
||||
|
||||
@@ -101,6 +101,8 @@ void deinitializeVirtualArchive();
|
||||
*/
|
||||
bool checkFusedGame(void **physfsIO_Out);
|
||||
|
||||
const char *getCRequirePath();
|
||||
|
||||
} // android
|
||||
} // love
|
||||
|
||||
|
||||
@@ -1156,7 +1156,9 @@ void luax_runwrapper(lua_State *L, const char *filedata, size_t datalen, const c
|
||||
// functions struct pointer as arguments.
|
||||
if (lua_istable(L, -1))
|
||||
{
|
||||
luaL_loadbuffer(L, filedata, datalen, filename);
|
||||
std::string chunkname = std::string("=[love \"") + std::string(filename) + std::string("\"]");
|
||||
|
||||
luaL_loadbuffer(L, filedata, datalen, chunkname.c_str());
|
||||
lua_pushvalue(L, -2);
|
||||
if (ffifuncs != nullptr)
|
||||
luax_pushpointerasstring(L, ffifuncs);
|
||||
@@ -1179,8 +1181,10 @@ int luax_resume(lua_State *L, int nargs, int* nres)
|
||||
#if LUA_VERSION_NUM >= 504
|
||||
return lua_resume(L, nullptr, nargs, nres);
|
||||
#elif LUA_VERSION_NUM >= 502
|
||||
LOVE_UNUSED(nres);
|
||||
return lua_resume(L, nullptr, nargs);
|
||||
#else
|
||||
LOVE_UNUSED(nres);
|
||||
return lua_resume(L, nargs);
|
||||
#endif
|
||||
}
|
||||
|
||||
+40
-14
@@ -118,11 +118,30 @@ static size_t find_peer_index(lua_State *l, ENetHost *enet_host, ENetPeer *peer)
|
||||
#define ENET_ALIGNOF(x) alignof(x)
|
||||
#endif
|
||||
|
||||
// For use with the enet_peers registry.
|
||||
// Using the pointer directly via lightuserdata would be ideal, but LuaJIT
|
||||
// cannot use lightuserdata with more than 47 bits whereas some newer arm64
|
||||
// architectures allow pointers which use more than that.
|
||||
static lua_Number compute_peer_key(lua_State *L, ENetPeer *peer)
|
||||
static bool supports_full_lightuserdata(lua_State *L)
|
||||
{
|
||||
static bool checked = false;
|
||||
static bool supported = false;
|
||||
|
||||
if (!checked)
|
||||
{
|
||||
lua_pushcclosure(L, [](lua_State* L) -> int
|
||||
{
|
||||
// Try to push pointer with all bits set.
|
||||
lua_pushlightuserdata(L, (void*)(~((size_t)0)));
|
||||
return 1;
|
||||
}, 0);
|
||||
|
||||
supported = lua_pcall(L, 0, 1, 0) == 0;
|
||||
checked = true;
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
static uintptr_t compute_peer_key(lua_State *L, ENetPeer *peer)
|
||||
{
|
||||
// ENet peers are be allocated on the heap in an array. Lua numbers
|
||||
// (doubles) can store all possible integers up to 2^53. We can store
|
||||
@@ -140,21 +159,28 @@ static lua_Number compute_peer_key(lua_State *L, ENetPeer *peer)
|
||||
|
||||
static const size_t shift = (size_t) log2((double) minalign);
|
||||
|
||||
key >>= shift;
|
||||
return key >> shift;
|
||||
}
|
||||
|
||||
// Make sure our key isn't larger than 2^53.
|
||||
if (key > 0x20000000000000ULL)
|
||||
luaL_error(L, "Cannot push enet peer to Lua: pointer value %p is too large", peer);
|
||||
|
||||
return (lua_Number) key;
|
||||
static void push_peer_key(lua_State *L, uintptr_t key)
|
||||
{
|
||||
// If full 64-bit lightuserdata is supported, always use that. Otherwise,
|
||||
// if the key is smaller than 2^53 (which is integer precision for double
|
||||
// datatype), then push number. Otherwise, throw error.
|
||||
if (supports_full_lightuserdata(L))
|
||||
lua_pushlightuserdata(L, (void*) key);
|
||||
else if (key > 0x20000000000000ULL) // 2^53
|
||||
luaL_error(L, "Cannot push enet peer to Lua: pointer value %p is too large", key);
|
||||
else
|
||||
lua_pushnumber(L, (lua_Number) key);
|
||||
}
|
||||
|
||||
static void push_peer(lua_State *l, ENetPeer *peer) {
|
||||
lua_Number key = compute_peer_key(l, peer);
|
||||
uintptr_t key = compute_peer_key(l, peer);
|
||||
|
||||
// try to find in peer table
|
||||
lua_getfield(l, LUA_REGISTRYINDEX, "enet_peers");
|
||||
lua_pushnumber(l, key);
|
||||
push_peer_key(l, key);
|
||||
lua_gettable(l, -2);
|
||||
|
||||
if (lua_isnil(l, -1)) {
|
||||
@@ -165,7 +191,7 @@ static void push_peer(lua_State *l, ENetPeer *peer) {
|
||||
luaL_getmetatable(l, "enet_peer");
|
||||
lua_setmetatable(l, -2);
|
||||
|
||||
lua_pushnumber(l, key);
|
||||
push_peer_key(l, key);
|
||||
lua_pushvalue(l, -2);
|
||||
|
||||
lua_settable(l, -4);
|
||||
|
||||
@@ -540,5 +540,5 @@ static const unsigned char B1[]={
|
||||
|
||||
};
|
||||
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"ftp.lua")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"=[socket \"ftp.lua\"]")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
}
|
||||
|
||||
@@ -192,5 +192,5 @@ static const unsigned char B1[]={
|
||||
108,101,114, 34, 44, 10,125, 10, 10,114,101,116,117,114,110, 32, 95, 77,
|
||||
};
|
||||
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"headers.lua")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"=[socket \"headers.lua\"]")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
}
|
||||
|
||||
@@ -668,5 +668,5 @@ static const unsigned char B1[]={
|
||||
101,110,100, 41, 10, 10,114,101,116,117,114,110, 32, 95, 77, 10,
|
||||
};
|
||||
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"http.lua")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"=[socket \"http.lua\"]")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
}
|
||||
|
||||
@@ -442,5 +442,5 @@ static const unsigned char B1[]={
|
||||
110,100, 10,101,110,100, 10, 10,114,101,116,117,114,110, 32, 95, 77, 10,
|
||||
};
|
||||
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"ltn12.lua")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"=[socket \"ltn12.lua\"]")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
}
|
||||
|
||||
@@ -140,5 +140,5 @@ static const unsigned char B1[]={
|
||||
110,100, 10, 10,114,101,116,117,114,110, 32, 95, 77, 10,
|
||||
};
|
||||
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"mbox.lua")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"=[socket \"mbox.lua\"]")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
}
|
||||
|
||||
@@ -132,5 +132,5 @@ static const unsigned char B1[]={
|
||||
116,117,114,110, 32, 95, 77,
|
||||
};
|
||||
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"mime.lua")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"=[socket \"mime.lua\"]")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
}
|
||||
|
||||
@@ -411,5 +411,5 @@ static const unsigned char B1[]={
|
||||
110,100, 41, 10, 10,114,101,116,117,114,110, 32, 95, 77,
|
||||
};
|
||||
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"smtp.lua")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"=[socket \"smtp.lua\"]")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
}
|
||||
|
||||
@@ -230,5 +230,5 @@ static const unsigned char B1[]={
|
||||
116,117,114,110, 32, 95, 77, 10,
|
||||
};
|
||||
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"socket.lua")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"=[socket \"socket.lua\"]")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
}
|
||||
|
||||
@@ -196,5 +196,5 @@ static const unsigned char B1[]={
|
||||
114,110, 32, 95, 77, 10,
|
||||
};
|
||||
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"tp.lua")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"=[socket \"tp.lua\"]")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
}
|
||||
|
||||
@@ -563,5 +563,5 @@ static const unsigned char B1[]={
|
||||
110, 32, 95, 77, 10,
|
||||
};
|
||||
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"url.lua")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"=[socket \"url.lua\"]")==0) lua_call(L, 0, LUA_MULTRET);
|
||||
}
|
||||
|
||||
+16
-8
@@ -143,14 +143,6 @@ enum DoneAction
|
||||
|
||||
static DoneAction runlove(int argc, char **argv, int &retval, love::Variant &restartvalue)
|
||||
{
|
||||
#ifdef LOVE_LEGENDARY_APP_ARGV_HACK
|
||||
int hack_argc = 0;
|
||||
char **hack_argv = 0;
|
||||
get_app_arguments(argc, argv, hack_argc, hack_argv);
|
||||
argc = hack_argc;
|
||||
argv = hack_argv;
|
||||
#endif // LOVE_LEGENDARY_APP_ARGV_HACK
|
||||
|
||||
// Oh, you just want the version? Okay!
|
||||
if (argc > 1 && strcmp(argv[1], "--version") == 0)
|
||||
{
|
||||
@@ -167,6 +159,22 @@ static DoneAction runlove(int argc, char **argv, int &retval, love::Variant &res
|
||||
lua_State *L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
|
||||
// LuaJIT-specific setup needs to be done as early as possible - before
|
||||
// get_app_arguments because that loads external library code. This is also
|
||||
// loaded inside require("love"). Note that it doesn't use the love table.
|
||||
love_preload(L, luaopen_love_jitsetup, "love.jitsetup");
|
||||
lua_getglobal(L, "require");
|
||||
lua_pushstring(L, "love.jitsetup");
|
||||
lua_call(L, 1, 0);
|
||||
|
||||
#ifdef LOVE_LEGENDARY_APP_ARGV_HACK
|
||||
int hack_argc = 0;
|
||||
char **hack_argv = nullptr;
|
||||
get_app_arguments(argc, argv, hack_argc, hack_argv);
|
||||
argc = hack_argc;
|
||||
argv = hack_argv;
|
||||
#endif // LOVE_LEGENDARY_APP_ARGV_HACK
|
||||
|
||||
// Add love to package.preload for easy requiring.
|
||||
love_preload(L, luaopen_love, "love");
|
||||
|
||||
|
||||
@@ -31,8 +31,19 @@ ByteData *luax_checkbytedata(lua_State *L, int idx)
|
||||
return luax_checktype<ByteData>(L, idx);
|
||||
}
|
||||
|
||||
int w_ByteData_clone(lua_State *L)
|
||||
{
|
||||
ByteData *t = luax_checkbytedata(L, 1);
|
||||
ByteData *c = nullptr;
|
||||
luax_catchexcept(L, [&](){ c = t->clone(); });
|
||||
luax_pushtype(L, c);
|
||||
c->release();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg w_ByteData_functions[] =
|
||||
{
|
||||
{ "clone", w_ByteData_clone },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -26,13 +26,24 @@ namespace love
|
||||
namespace data
|
||||
{
|
||||
|
||||
DataView *luax_checkdataView(lua_State *L, int idx)
|
||||
DataView *luax_checkdataview(lua_State *L, int idx)
|
||||
{
|
||||
return luax_checktype<DataView>(L, idx);
|
||||
}
|
||||
|
||||
int w_DataView_clone(lua_State *L)
|
||||
{
|
||||
DataView *t = luax_checkdataview(L, 1);
|
||||
DataView *c = nullptr;
|
||||
luax_catchexcept(L, [&](){ c = t->clone(); });
|
||||
luax_pushtype(L, c);
|
||||
c->release();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg w_DataView_functions[] =
|
||||
{
|
||||
{ "clone", w_DataView_clone },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ extern "C" int luaopen_love_event(lua_State *L)
|
||||
|
||||
int ret = luax_register_module(L, w);
|
||||
|
||||
if (luaL_loadbuffer(L, (const char *)event_lua, sizeof(event_lua), "wrap_Event.lua") == 0)
|
||||
if (luaL_loadbuffer(L, (const char *)event_lua, sizeof(event_lua), "=[love \"wrap_Event.lua\"]") == 0)
|
||||
lua_call(L, 0, 0);
|
||||
else
|
||||
lua_error(L);
|
||||
|
||||
@@ -240,15 +240,13 @@ bool Filesystem::setSource(const char *source)
|
||||
|
||||
PHYSFS_Io *gameLoveIO;
|
||||
bool hasFusedGame = love::android::checkFusedGame((void **) &gameLoveIO);
|
||||
bool isAAssetMounted = false;
|
||||
|
||||
if (hasFusedGame)
|
||||
{
|
||||
if (gameLoveIO)
|
||||
{
|
||||
// Actually we should just be able to mount gameLoveIO, but that's experimental.
|
||||
gameLoveIO->destroy(gameLoveIO);
|
||||
goto oldschool;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!love::android::initializeVirtualArchive())
|
||||
@@ -256,11 +254,15 @@ bool Filesystem::setSource(const char *source)
|
||||
SDL_Log("Unable to mount AAsset: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
return false;
|
||||
}
|
||||
|
||||
// See love::android::initializeVirtualArchive()
|
||||
new_search_path = "ASET.AASSET";
|
||||
isAAssetMounted = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (!isAAssetMounted)
|
||||
{
|
||||
oldschool:
|
||||
new_search_path = love::android::getSelectedGameFile();
|
||||
|
||||
// try mounting first, if that fails, load to memory and mount
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
|
||||
#include "physfs/Filesystem.h"
|
||||
|
||||
#ifdef LOVE_ANDROID
|
||||
#include "common/android.h"
|
||||
#endif
|
||||
|
||||
// SDL
|
||||
#include <SDL_loadso.h>
|
||||
|
||||
@@ -380,11 +384,22 @@ int w_newFileData(lua_State *L)
|
||||
}
|
||||
|
||||
size_t length = 0;
|
||||
const char *str = luaL_checklstring(L, 1, &length);
|
||||
const void *ptr = nullptr;
|
||||
if (luax_istype(L, 1, Data::type))
|
||||
{
|
||||
Data *data = data::luax_checkdata(L, 1);
|
||||
ptr = data->getData();
|
||||
length = data->getSize();
|
||||
}
|
||||
else if (lua_isstring(L, 1))
|
||||
ptr = luaL_checklstring(L, 1, &length);
|
||||
else
|
||||
return luaL_argerror(L, 1, "string or Data expected");
|
||||
|
||||
const char *filename = luaL_checkstring(L, 2);
|
||||
|
||||
FileData *t = nullptr;
|
||||
luax_catchexcept(L, [&](){ t = instance()->newFileData(str, length, filename); });
|
||||
luax_catchexcept(L, [&](){ t = instance()->newFileData(ptr, length, filename); });
|
||||
|
||||
luax_pushtype(L, t);
|
||||
t->release();
|
||||
@@ -849,6 +864,23 @@ int extloader(lua_State *L)
|
||||
void *handle = nullptr;
|
||||
auto *inst = instance();
|
||||
|
||||
#ifdef LOVE_ANDROID
|
||||
// Specifically Android, look the library path based on getCRequirePath first
|
||||
std::string androidPath(love::android::getCRequirePath());
|
||||
|
||||
if (!androidPath.empty())
|
||||
{
|
||||
// Replace ? with just the dotted filename (not tokenized_name)
|
||||
replaceAll(androidPath, "?", filename);
|
||||
|
||||
// Load directly, don't check for existence.
|
||||
handle = SDL_LoadObject(androidPath.c_str());
|
||||
}
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
#endif // LOVE_ANDROID
|
||||
|
||||
for (const std::string &el : inst->getCRequirePath())
|
||||
{
|
||||
for (const char *ext : library_extensions)
|
||||
@@ -878,6 +910,10 @@ int extloader(lua_State *L)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef LOVE_ANDROID
|
||||
} // if (!handle)
|
||||
#endif
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
lua_pushfstring(L, "\n\tno file '%s' in LOVE paths.", tokenized_name.c_str());
|
||||
|
||||
@@ -901,14 +901,11 @@ void Font::getWrap(const ColoredCodepoints &codepoints, float wraplimit, std::ve
|
||||
}
|
||||
|
||||
// Push the last line.
|
||||
if (!wline.cps.empty())
|
||||
{
|
||||
lines.push_back(wline);
|
||||
lines.push_back(wline);
|
||||
|
||||
// Ignore the width of any trailing spaces, for individual lines.
|
||||
if (linewidths)
|
||||
linewidths->push_back(width - widthoftrailingspace);
|
||||
}
|
||||
// Ignore the width of any trailing spaces, for individual lines.
|
||||
if (linewidths)
|
||||
linewidths->push_back(width - widthoftrailingspace);
|
||||
}
|
||||
|
||||
void Font::getWrap(const std::vector<ColoredString> &text, float wraplimit, std::vector<std::string> &lines, std::vector<int> *linewidths)
|
||||
|
||||
@@ -177,7 +177,7 @@ void ParticleSystem::resetOffset()
|
||||
else
|
||||
{
|
||||
Quad::Viewport v = quads[0]->getViewport();
|
||||
offset = love::Vector2(v.x*0.5f, v.y*0.5f);
|
||||
offset = love::Vector2(v.w*0.5f, v.h*0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3648,7 +3648,7 @@ extern "C" int luaopen_love_graphics(lua_State *L)
|
||||
|
||||
int n = luax_register_module(L, w);
|
||||
|
||||
if (luaL_loadbuffer(L, (const char *)graphics_lua, sizeof(graphics_lua), "wrap_Graphics.lua") == 0)
|
||||
if (luaL_loadbuffer(L, (const char *)graphics_lua, sizeof(graphics_lua), "=[love \"wrap_Graphics.lua\"]") == 0)
|
||||
lua_call(L, 0, 0);
|
||||
else
|
||||
lua_error(L);
|
||||
|
||||
@@ -168,7 +168,7 @@ int luaopen_video(lua_State *L)
|
||||
{
|
||||
int ret = luax_register_type(L, &Video::type, functions, nullptr);
|
||||
|
||||
luaL_loadbuffer(L, video_lua, sizeof(video_lua), "Video.lua");
|
||||
luaL_loadbuffer(L, video_lua, sizeof(video_lua), "=[love \"Video.lua\"]");
|
||||
luax_gettypemetatable(L, Video::type);
|
||||
lua_call(L, 1, 0);
|
||||
|
||||
|
||||
@@ -440,6 +440,11 @@ bool Joystick::checkCreateHaptic()
|
||||
|
||||
bool Joystick::isVibrationSupported()
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 18)
|
||||
if (isConnected() && SDL_JoystickHasRumble(joyhandle) == SDL_TRUE)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
if (!checkCreateHaptic())
|
||||
return false;
|
||||
|
||||
@@ -490,8 +495,12 @@ bool Joystick::setVibration(float left, float right, float duration)
|
||||
if (left == 0.0f && right == 0.0f)
|
||||
return setVibration();
|
||||
|
||||
if (!checkCreateHaptic())
|
||||
if (!isConnected())
|
||||
{
|
||||
vibration.left = vibration.right = 0.0f;
|
||||
vibration.endtime = SDL_HAPTIC_INFINITY;
|
||||
return false;
|
||||
}
|
||||
|
||||
Uint32 length = SDL_HAPTIC_INFINITY;
|
||||
if (duration >= 0.0f)
|
||||
@@ -501,10 +510,19 @@ bool Joystick::setVibration(float left, float right, float duration)
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
if (SDL_JoystickRumble(joyhandle, (Uint16)(left * LOVE_UINT16_MAX), (Uint16)(right * LOVE_UINT16_MAX), length) == 0)
|
||||
success = true;
|
||||
#endif
|
||||
|
||||
if (!success && !checkCreateHaptic())
|
||||
return false;
|
||||
|
||||
unsigned int features = SDL_HapticQuery(haptic);
|
||||
int axes = SDL_HapticNumAxes(haptic);
|
||||
|
||||
if ((features & SDL_HAPTIC_LEFTRIGHT) != 0)
|
||||
if (!success && (features & SDL_HAPTIC_LEFTRIGHT) != 0)
|
||||
{
|
||||
memset(&vibration.effect, 0, sizeof(SDL_HapticEffect));
|
||||
vibration.effect.type = SDL_HAPTIC_LEFTRIGHT;
|
||||
@@ -576,9 +594,14 @@ bool Joystick::setVibration(float left, float right, float duration)
|
||||
|
||||
bool Joystick::setVibration()
|
||||
{
|
||||
bool success = true;
|
||||
bool success = false;
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_HAPTIC) && haptic && SDL_HapticIndex(haptic) != -1)
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
if (!success)
|
||||
success = isConnected() && SDL_JoystickRumble(joyhandle, 0, 0, 0) == 0;
|
||||
#endif
|
||||
|
||||
if (!success && SDL_WasInit(SDL_INIT_HAPTIC) && haptic && SDL_HapticIndex(haptic) != -1)
|
||||
success = (SDL_HapticStopEffect(haptic, vibration.id) == 0);
|
||||
|
||||
if (success)
|
||||
|
||||
@@ -256,6 +256,7 @@ function love.errhand(msg)
|
||||
p = p:gsub("%[string \"(.-)\"%]", "%1")
|
||||
|
||||
local function draw()
|
||||
if not love.graphics.isActive() then return end
|
||||
local pos = 70
|
||||
love.graphics.clear(89/255, 157/255, 220/255)
|
||||
love.graphics.printf(p, pos, pos, love.graphics.getWidth() - pos)
|
||||
@@ -267,7 +268,6 @@ function love.errhand(msg)
|
||||
if not love.system then return end
|
||||
love.system.setClipboardText(fullErrorText)
|
||||
p = p .. "\nCopied to clipboard!"
|
||||
draw()
|
||||
end
|
||||
|
||||
if love.system then
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
R"luastring"--(
|
||||
-- DO NOT REMOVE THE ABOVE LINE. It is used to load this file as a C++ string.
|
||||
-- There is a matching delimiter at the bottom of the file.
|
||||
|
||||
--[[
|
||||
Copyright (c) 2006-2021 LOVE Development Team
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
--]]
|
||||
|
||||
if type(jit) ~= "table" or not jit.status() then
|
||||
return
|
||||
end
|
||||
|
||||
-- Double the defaults.
|
||||
jit.opt.start("maxtrace=2000", "maxrecord=8000")
|
||||
|
||||
-- Somewhat arbitrary value. Needs to be higher than the combined sizes below,
|
||||
-- and higher than the default (512) because that's already too low.
|
||||
jit.opt.start("maxmcode=16384")
|
||||
|
||||
if jit.arch == "arm64" then
|
||||
-- https://github.com/LuaJIT/LuaJIT/issues/285
|
||||
-- LuaJIT 2.1 on arm64 currently (as of commit b4b2dce) can only use memory
|
||||
-- for JIT compilation within a certain short range. Other libraries such as
|
||||
-- SDL can take all the usable space in that range and cause attempts at JIT
|
||||
-- compilation to both fail and take a long time.
|
||||
-- This is a very hacky attempt at a workaround. LuaJIT allocates executable
|
||||
-- code in pools. We'll try "reserving" pools before any external code is
|
||||
-- executed, by causing JIT compilation via a small loop. We can't easily
|
||||
-- tell if JIT compilation succeeded, so we do several successively smaller
|
||||
-- pool allocations in case previous ones fail.
|
||||
-- This is a really hacky hack and by no means foolproof - there are a lot of
|
||||
-- potential situations (especially when threads are used) where previously
|
||||
-- executed external code will still take up space that LuaJIT needed for itself.
|
||||
|
||||
jit.opt.start("sizemcode=2048")
|
||||
for i=1, 100 do end
|
||||
|
||||
jit.opt.start("sizemcode=1024")
|
||||
for i=1, 100 do end
|
||||
|
||||
jit.opt.start("sizemcode=512")
|
||||
for i=1, 100 do end
|
||||
|
||||
jit.opt.start("sizemcode=256")
|
||||
for i=1, 100 do end
|
||||
|
||||
jit.opt.start("sizemcode=128")
|
||||
for i=1, 100 do end
|
||||
else
|
||||
-- Somewhat arbitrary value (>= the default).
|
||||
jit.opt.start("sizemcode=128")
|
||||
end
|
||||
|
||||
-- DO NOT REMOVE THE NEXT LINE. It is used to load this file as a C++ string.
|
||||
--)luastring"--"
|
||||
@@ -102,6 +102,10 @@ static const char boot_lua[] =
|
||||
#include "boot.lua"
|
||||
;
|
||||
|
||||
static const char jit_setup_lua[] =
|
||||
#include "jitsetup.lua"
|
||||
;
|
||||
|
||||
// All modules define a c-accessible luaopen
|
||||
// so let's make use of those, instead
|
||||
// of addressing implementations directly.
|
||||
@@ -165,6 +169,7 @@ extern "C"
|
||||
extern int luaopen_love_window(lua_State*);
|
||||
#endif
|
||||
extern int luaopen_love_nogame(lua_State*);
|
||||
extern int luaopen_love_jitsetup(lua_State*);
|
||||
extern int luaopen_love_arg(lua_State*);
|
||||
extern int luaopen_love_callbacks(lua_State*);
|
||||
extern int luaopen_love_boot(lua_State*);
|
||||
@@ -229,6 +234,7 @@ static const luaL_Reg modules[] = {
|
||||
{ "love.window", luaopen_love_window },
|
||||
#endif
|
||||
{ "love.nogame", luaopen_love_nogame },
|
||||
{ "love.jitsetup", luaopen_love_jitsetup },
|
||||
{ "love.arg", luaopen_love_arg },
|
||||
{ "love.callbacks", luaopen_love_callbacks },
|
||||
{ "love.boot", luaopen_love_boot },
|
||||
@@ -440,6 +446,15 @@ static void luax_addcompatibilityalias(lua_State *L, const char *module, const c
|
||||
|
||||
int luaopen_love(lua_State *L)
|
||||
{
|
||||
// Preload module loaders.
|
||||
for (int i = 0; modules[i].name != nullptr; i++)
|
||||
love::luax_preload(L, modules[i].func, modules[i].name);
|
||||
|
||||
// jitsetup is also loaded in the love executable runlove function. It's
|
||||
// needed here too for threads. Note that it doesn't use the love table.
|
||||
love::luax_require(L, "love.jitsetup");
|
||||
lua_pop(L, 1);
|
||||
|
||||
love::luax_insistpinnedthread(L);
|
||||
|
||||
love::luax_insistglobal(L, "love");
|
||||
@@ -543,10 +558,6 @@ int luaopen_love(lua_State *L)
|
||||
lua_setfield(L, -2, "hasDeprecationOutput");
|
||||
}
|
||||
|
||||
// Preload module loaders.
|
||||
for (int i = 0; modules[i].name != nullptr; i++)
|
||||
love::luax_preload(L, modules[i].func, modules[i].name);
|
||||
|
||||
// Necessary for Data-creating methods to work properly in Data subclasses.
|
||||
love::luax_require(L, "love.data");
|
||||
lua_pop(L, 1);
|
||||
@@ -693,7 +704,15 @@ int w__setAccelerometerAsJoystick(lua_State *L)
|
||||
|
||||
int luaopen_love_nogame(lua_State *L)
|
||||
{
|
||||
if (luaL_loadbuffer(L, (const char *)love::nogame_lua, sizeof(love::nogame_lua), "nogame.lua") == 0)
|
||||
if (luaL_loadbuffer(L, (const char *)love::nogame_lua, sizeof(love::nogame_lua), "=[love \"nogame.lua\"]") == 0)
|
||||
lua_call(L, 0, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int luaopen_love_jitsetup(lua_State *L)
|
||||
{
|
||||
if (luaL_loadbuffer(L, jit_setup_lua, sizeof(jit_setup_lua), "=[love \"jitsetup.lua\"]") == 0)
|
||||
lua_call(L, 0, 1);
|
||||
|
||||
return 1;
|
||||
@@ -701,7 +720,7 @@ int luaopen_love_nogame(lua_State *L)
|
||||
|
||||
int luaopen_love_arg(lua_State *L)
|
||||
{
|
||||
if (luaL_loadbuffer(L, arg_lua, sizeof(arg_lua), "arg.lua") == 0)
|
||||
if (luaL_loadbuffer(L, arg_lua, sizeof(arg_lua), "=[love \"arg.lua\"]") == 0)
|
||||
lua_call(L, 0, 1);
|
||||
|
||||
return 1;
|
||||
@@ -709,7 +728,7 @@ int luaopen_love_arg(lua_State *L)
|
||||
|
||||
int luaopen_love_callbacks(lua_State *L)
|
||||
{
|
||||
if (luaL_loadbuffer(L, callbacks_lua, sizeof(callbacks_lua), "callbacks.lua") == 0)
|
||||
if (luaL_loadbuffer(L, callbacks_lua, sizeof(callbacks_lua), "=[love \"callbacks.lua\"]") == 0)
|
||||
lua_call(L, 0, 1);
|
||||
|
||||
return 1;
|
||||
@@ -717,7 +736,7 @@ int luaopen_love_callbacks(lua_State *L)
|
||||
|
||||
int luaopen_love_boot(lua_State *L)
|
||||
{
|
||||
if (luaL_loadbuffer(L, boot_lua, sizeof(boot_lua), "boot.lua") == 0)
|
||||
if (luaL_loadbuffer(L, boot_lua, sizeof(boot_lua), "=[love \"boot.lua\"]") == 0)
|
||||
lua_call(L, 0, 1);
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -36,6 +36,9 @@ LOVE_EXPORT const char *love_version();
|
||||
LOVE_EXPORT const char *love_codename();
|
||||
LOVE_EXPORT int luaopen_love(lua_State *L);
|
||||
LOVE_EXPORT int luaopen_love_nogame(lua_State *L);
|
||||
LOVE_EXPORT int luaopen_love_jitsetup(lua_State *L);
|
||||
LOVE_EXPORT int luaopen_love_arg(lua_State *L);
|
||||
LOVE_EXPORT int luaopen_love_callbacks(lua_State *L);
|
||||
LOVE_EXPORT int luaopen_love_boot(lua_State *L);
|
||||
|
||||
#ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK
|
||||
|
||||
@@ -415,7 +415,7 @@ extern "C" int luaopen_love_math(lua_State *L)
|
||||
int n = luax_register_module(L, w);
|
||||
|
||||
// Execute wrap_Math.lua, sending the math table and ffifuncs pointer as args.
|
||||
luaL_loadbuffer(L, math_lua, sizeof(math_lua), "wrap_Math.lua");
|
||||
luaL_loadbuffer(L, math_lua, sizeof(math_lua), "=[love \"wrap_Math.lua\"]");
|
||||
lua_pushvalue(L, -2);
|
||||
luax_pushpointerasstring(L, &ffifuncs);
|
||||
lua_call(L, 2, 0);
|
||||
|
||||
@@ -43,7 +43,7 @@ OggDemuxer::~OggDemuxer()
|
||||
ogg_sync_clear(&sync);
|
||||
}
|
||||
|
||||
void OggDemuxer::readPage()
|
||||
bool OggDemuxer::readPage(bool erroreof)
|
||||
{
|
||||
char *syncBuffer = nullptr;
|
||||
while (ogg_sync_pageout(&sync, &page) != 1)
|
||||
@@ -53,8 +53,13 @@ void OggDemuxer::readPage()
|
||||
|
||||
syncBuffer = ogg_sync_buffer(&sync, 8192);
|
||||
size_t read = file->read(syncBuffer, 8192);
|
||||
if (read == 0 && erroreof)
|
||||
return false;
|
||||
|
||||
ogg_sync_wrote(&sync, read);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OggDemuxer::readPacket(ogg_packet &packet, bool mustSucceed)
|
||||
@@ -118,22 +123,25 @@ OggDemuxer::StreamType OggDemuxer::findStream()
|
||||
if (streamInited)
|
||||
{
|
||||
eos = false;
|
||||
streamInited = false;
|
||||
file->seek(0);
|
||||
ogg_stream_clear(&stream);
|
||||
ogg_sync_reset(&sync);
|
||||
}
|
||||
|
||||
streamInited = true;
|
||||
while (true)
|
||||
{
|
||||
if (!readPage(true))
|
||||
return TYPE_UNKNOWN;
|
||||
|
||||
// If this page isn't at the start of a stream, we've seen all streams
|
||||
readPage();
|
||||
if (!ogg_page_bos(&page))
|
||||
break;
|
||||
|
||||
videoSerial = ogg_page_serialno(&page);
|
||||
ogg_stream_init(&stream, videoSerial);
|
||||
ogg_stream_pagein(&stream, &page);
|
||||
streamInited = true;
|
||||
|
||||
StreamType type = determineType();
|
||||
switch(type)
|
||||
@@ -145,10 +153,15 @@ OggDemuxer::StreamType OggDemuxer::findStream()
|
||||
}
|
||||
|
||||
ogg_stream_clear(&stream);
|
||||
streamInited = false;
|
||||
}
|
||||
|
||||
if (streamInited)
|
||||
{
|
||||
streamInited = false;
|
||||
ogg_stream_clear(&stream);
|
||||
}
|
||||
|
||||
streamInited = false;
|
||||
ogg_stream_clear(&stream);
|
||||
ogg_sync_reset(&sync);
|
||||
|
||||
return TYPE_UNKNOWN;
|
||||
|
||||
@@ -67,7 +67,7 @@ private:
|
||||
int videoSerial;
|
||||
bool eos;
|
||||
|
||||
void readPage();
|
||||
bool readPage(bool erroreof = false);
|
||||
StreamType determineType();
|
||||
}; // OggDemuxer
|
||||
|
||||
|
||||
Reference in New Issue
Block a user