Merge branch 'main' into 12.0-development

This commit is contained in:
Alex Szpakowski
2021-12-24 11:35:35 -04:00
37 changed files with 488 additions and 159 deletions
+11
View File
@@ -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 }
};
+12 -1
View File
@@ -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 }
};
+1 -1
View File
@@ -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);
+7 -5
View File
@@ -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
+38 -2
View File
@@ -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());
+4 -7
View File
@@ -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)
+1 -1
View File
@@ -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);
}
}
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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);
+27 -4
View File
@@ -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)
+1 -1
View File
@@ -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
+71
View File
@@ -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"--"
+27 -8
View File
@@ -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;
+3
View File
@@ -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
+1 -1
View File
@@ -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);
+18 -5
View File
@@ -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;
+1 -1
View File
@@ -67,7 +67,7 @@ private:
int videoSerial;
bool eos;
void readPage();
bool readPage(bool erroreof = false);
StreamType determineType();
}; // OggDemuxer