Merge branch 'love2d:12.0-development' into 12.0-development

This commit is contained in:
nikeinikei
2022-12-21 17:20:43 +01:00
committed by GitHub
51 changed files with 1335 additions and 523 deletions
+13 -8
View File
@@ -1160,6 +1160,19 @@ int Source::streamAtomic(ALuint buffer, love::sound::Decoder *d)
decoded = 0;
}
// This shouldn't run after toLoop is calculated in this streamAtomic call,
// otherwise it'll decrease too quickly.
// TODO: this code is hard to understand, can it be made more clear?
// It's meant to reset offsetSamples once OpenAL starts processing the first
// queued buffer after a loop.
if (toLoop > 0)
{
if (--toLoop == 0)
{
offsetSamples = 0;
}
}
if (decoder->isFinished() && isLooping())
{
int queued, processed;
@@ -1172,14 +1185,6 @@ int Source::streamAtomic(ALuint buffer, love::sound::Decoder *d)
d->rewind();
}
if (toLoop > 0)
{
if (--toLoop == 0)
{
offsetSamples = 0;
}
}
return decoded;
}
+60 -22
View File
@@ -32,6 +32,7 @@
#include "audio/Audio.h"
#include "common/config.h"
#include "timer/Timer.h"
#include "sensor/sdl/Sensor.h"
#include <cmath>
@@ -178,6 +179,7 @@ Message *Event::convert(const SDL_Event &e)
vargs.reserve(4);
love::filesystem::Filesystem *filesystem = nullptr;
love::sensor::Sensor *sensorInstance = nullptr;
love::keyboard::Keyboard::Key key = love::keyboard::Keyboard::KEY_UNKNOWN;
love::keyboard::Keyboard::Scancode scancode = love::keyboard::Keyboard::SCANCODE_UNKNOWN;
@@ -191,10 +193,6 @@ Message *Event::convert(const SDL_Event &e)
love::touch::Touch::TouchInfo touchinfo;
#endif
#ifdef LOVE_LINUX
static bool touchNormalizationBug = false;
#endif
switch (e.type)
{
case SDL_KEYDOWN:
@@ -313,22 +311,9 @@ Message *Event::convert(const SDL_Event &e)
touchinfo.dy = e.tfinger.dy;
touchinfo.pressure = e.tfinger.pressure;
#ifdef LOVE_LINUX
// FIXME: hacky workaround for SDL not normalizing touch coordinates in
// its X11 backend: https://bugzilla.libsdl.org/show_bug.cgi?id=2307
if (touchNormalizationBug || fabs(touchinfo.x) >= 1.5 || fabs(touchinfo.y) >= 1.5 || fabs(touchinfo.dx) >= 1.5 || fabs(touchinfo.dy) >= 1.5)
{
touchNormalizationBug = true;
windowToDPICoords(&touchinfo.x, &touchinfo.y);
windowToDPICoords(&touchinfo.dx, &touchinfo.dy);
}
else
#endif
{
// SDL's coords are normalized to [0, 1], but we want screen coords.
normalizedToDPICoords(&touchinfo.x, &touchinfo.y);
normalizedToDPICoords(&touchinfo.dx, &touchinfo.dy);
}
// SDL's coords are normalized to [0, 1], but we want screen coords.
normalizedToDPICoords(&touchinfo.x, &touchinfo.y);
normalizedToDPICoords(&touchinfo.dx, &touchinfo.dy);
// We need to update the love.touch.sdl internal state from here.
touchmodule = (touch::sdl::Touch *) Module::getInstance("love.touch.sdl");
@@ -366,12 +351,14 @@ Message *Event::convert(const SDL_Event &e)
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
case SDL_CONTROLLERAXISMOTION:
#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR)
case SDL_CONTROLLERSENSORUPDATE:
#endif
msg = convertJoystickEvent(e);
break;
case SDL_WINDOWEVENT:
msg = convertWindowEvent(e);
break;
#if SDL_VERSION_ATLEAST(2, 0, 9)
case SDL_DISPLAYEVENT:
if (e.display.event == SDL_DISPLAYEVENT_ORIENTATION)
{
@@ -405,7 +392,6 @@ Message *Event::convert(const SDL_Event &e)
msg = new Message("displayrotated", vargs);
}
break;
#endif
case SDL_DROPFILE:
filesystem = Module::getInstance<filesystem::Filesystem>(Module::M_FILESYSTEM);
if (filesystem != nullptr)
@@ -446,6 +432,37 @@ Message *Event::convert(const SDL_Event &e)
msg = new Message("localechanged");
break;
#endif
case SDL_SENSORUPDATE:
sensorInstance = Module::getInstance<sensor::Sensor>(M_SENSOR);
if (sensorInstance)
{
std::vector<void*> sensors = sensorInstance->getHandles();
for (void *s: sensors)
{
SDL_Sensor *sensor = (SDL_Sensor *) s;
SDL_SensorID id = SDL_SensorGetInstanceID(sensor);
if (e.sensor.which == id)
{
// Found sensor
const char *sensorType;
if (!sensor::Sensor::getConstant(sensor::sdl::Sensor::convert(SDL_SensorGetType(sensor)), sensorType))
sensorType = "unknown";
vargs.emplace_back(sensorType, strlen(sensorType));
// Both accelerometer and gyroscope only pass up to 3 values.
// https://github.com/libsdl-org/SDL/blob/SDL2/include/SDL_sensor.h#L81-L127
vargs.emplace_back(e.sensor.data[0]);
vargs.emplace_back(e.sensor.data[1]);
vargs.emplace_back(e.sensor.data[2]);
msg = new Message("sensorupdated", vargs);
break;
}
}
}
break;
default:
break;
}
@@ -564,6 +581,27 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
msg = new Message("joystickremoved", vargs);
}
break;
#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR)
case SDL_CONTROLLERSENSORUPDATE:
stick = joymodule->getJoystickFromID(e.csensor.which);
if (stick)
{
using Sensor = love::sensor::Sensor;
const char *sensorName;
Sensor::SensorType sensorType = love::sensor::sdl::Sensor::convert((SDL_SensorType) e.csensor.sensor);
if (!Sensor::getConstant(sensorType, sensorName))
sensorName = "unknown";
vargs.emplace_back(joysticktype, stick);
vargs.emplace_back(sensorName, strlen(sensorName));
vargs.emplace_back(e.csensor.data[0]);
vargs.emplace_back(e.csensor.data[1]);
vargs.emplace_back(e.csensor.data[2]);
msg = new Message("joysticksensorupdated", vargs);
}
break;
#endif // SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR)
default:
break;
}
+3 -3
View File
@@ -30,7 +30,7 @@
#include "ParticleSystem.h"
#include "Font.h"
#include "Video.h"
#include "Text.h"
#include "TextBatch.h"
#include "common/deprecation.h"
#include "common/config.h"
@@ -439,9 +439,9 @@ Mesh *Graphics::newMesh(const std::vector<Mesh::BufferAttribute> &attributes, Pr
return new Mesh(attributes, drawmode);
}
love::graphics::Text *Graphics::newText(graphics::Font *font, const std::vector<Font::ColoredString> &text)
love::graphics::TextBatch *Graphics::newTextBatch(graphics::Font *font, const std::vector<Font::ColoredString> &text)
{
return new Text(font, text);
return new TextBatch(font, text);
}
love::data::ByteData *Graphics::readbackBuffer(Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset)
+2 -2
View File
@@ -58,7 +58,7 @@ namespace graphics
class SpriteBatch;
class ParticleSystem;
class Text;
class TextBatch;
class Video;
class Buffer;
@@ -460,7 +460,7 @@ public:
Mesh *newMesh(const std::vector<Buffer::DataDeclaration> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, BufferDataUsage usage);
Mesh *newMesh(const std::vector<Mesh::BufferAttribute> &attributes, PrimitiveType drawmode);
Text *newText(Font *font, const std::vector<Font::ColoredString> &text = {});
TextBatch *newTextBatch(Font *font, const std::vector<Font::ColoredString> &text = {});
data::ByteData *readbackBuffer(Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset);
GraphicsReadback *readbackBufferAsync(Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset);
+8 -3
View File
@@ -140,7 +140,7 @@ void Mesh::setupAttachedAttributes()
if (getAttachedAttributeIndex(name) != -1)
throw love::Exception("Duplicate vertex attribute name: %s", name.c_str());
attachedAttributes.push_back({name, vertexBuffer, nullptr, (int) i, STEP_PER_VERTEX, true});
attachedAttributes.push_back({name, vertexBuffer, nullptr, (int) i, 0, STEP_PER_VERTEX, true});
}
}
@@ -208,7 +208,7 @@ bool Mesh::isAttributeEnabled(const std::string &name) const
return attachedAttributes[index].enabled;
}
void Mesh::attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh, const std::string &attachname, AttributeStep step)
void Mesh::attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh, const std::string &attachname, int startindex, AttributeStep step)
{
if ((buffer->getUsageFlags() & BUFFERUSAGEFLAG_VERTEX) == 0)
throw love::Exception("Buffer must be created with vertex buffer support to be used as a Mesh vertex attribute.");
@@ -217,6 +217,9 @@ void Mesh::attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh,
if (step == STEP_PER_INSTANCE && !gfx->getCapabilities().features[Graphics::FEATURE_INSTANCING])
throw love::Exception("Vertex attribute instancing is not supported on this system.");
if (startindex < 0 || startindex >= (int) buffer->getArrayLength())
throw love::Exception("Invalid start array index %d.", startindex + 1);
BufferAttribute oldattrib = {};
BufferAttribute newattrib = {};
@@ -231,6 +234,7 @@ void Mesh::attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh,
newattrib.mesh = mesh;
newattrib.enabled = oldattrib.buffer.get() ? oldattrib.enabled : true;
newattrib.indexInBuffer = buffer->getDataMemberIndex(attachname);
newattrib.startArrayIndex = startindex;
newattrib.step = step;
if (newattrib.indexInBuffer < 0)
@@ -578,12 +582,13 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount)
uint16 offset = (uint16) member.offset;
uint16 stride = (uint16) buffer->getArrayStride();
size_t bufferoffset = (size_t) stride * attrib.startArrayIndex;
attributes.set(attributeindex, member.decl.format, offset, activebuffers);
attributes.setBufferLayout(activebuffers, stride, attrib.step);
// TODO: Ideally we want to reuse buffers with the same stride+step.
buffers.set(activebuffers, buffer, 0);
buffers.set(activebuffers, buffer, bufferoffset);
activebuffers++;
}
}
+2 -1
View File
@@ -57,6 +57,7 @@ public:
StrongRef<Buffer> buffer;
StrongRef<Mesh> mesh;
int indexInBuffer;
int startArrayIndex;
AttributeStep step;
bool enabled;
};
@@ -109,7 +110,7 @@ public:
* to make sure this Mesh knows to flush the passed in Mesh's data to its
* buffer when drawing.
**/
void attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh, const std::string &attachname, AttributeStep step = STEP_PER_VERTEX);
void attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh, const std::string &attachname, int startindex = 0, AttributeStep step = STEP_PER_VERTEX);
bool detachAttribute(const std::string &name);
const std::vector<BufferAttribute> &getAttachedAttributes() const;
@@ -18,7 +18,7 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Text.h"
#include "TextBatch.h"
#include "Graphics.h"
#include <algorithm>
@@ -28,9 +28,9 @@ namespace love
namespace graphics
{
love::Type Text::type("Text", &Drawable::type);
love::Type TextBatch::type("TextBatch", &Drawable::type);
Text::Text(Font *font, const std::vector<Font::ColoredString> &text)
TextBatch::TextBatch(Font *font, const std::vector<Font::ColoredString> &text)
: font(font)
, vertexAttributes(Font::vertexFormat, 0)
, vertexData(nullptr)
@@ -41,13 +41,13 @@ Text::Text(Font *font, const std::vector<Font::ColoredString> &text)
set(text);
}
Text::~Text()
TextBatch::~TextBatch()
{
if (vertexData != nullptr)
free(vertexData);
}
void Text::uploadVertices(const std::vector<Font::GlyphVertex> &vertices, size_t vertoffset)
void TextBatch::uploadVertices(const std::vector<Font::GlyphVertex> &vertices, size_t vertoffset)
{
size_t offset = vertoffset * sizeof(Font::GlyphVertex);
size_t datasize = vertices.size() * sizeof(Font::GlyphVertex);
@@ -90,7 +90,7 @@ void Text::uploadVertices(const std::vector<Font::GlyphVertex> &vertices, size_t
}
}
void Text::regenerateVertices()
void TextBatch::regenerateVertices()
{
// If the font's texture cache was invalidated then we need to recreate the
// text's vertices, since glyph texcoords might have changed.
@@ -107,7 +107,7 @@ void Text::regenerateVertices()
}
}
void Text::addTextData(const TextData &t)
void TextBatch::addTextData(const TextData &t)
{
std::vector<Font::GlyphVertex> vertices;
std::vector<Font::DrawCommand> newcommands;
@@ -172,12 +172,12 @@ void Text::addTextData(const TextData &t)
regenerateVertices();
}
void Text::set(const std::vector<Font::ColoredString> &text)
void TextBatch::set(const std::vector<Font::ColoredString> &text)
{
return set(text, -1.0f, Font::ALIGN_MAX_ENUM);
}
void Text::set(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align)
void TextBatch::set(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align)
{
if (text.empty() || (text.size() == 1 && text[0].str.empty()))
return clear();
@@ -188,12 +188,12 @@ void Text::set(const std::vector<Font::ColoredString> &text, float wrap, Font::A
addTextData({codepoints, wrap, align, {}, false, false, Matrix4()});
}
int Text::add(const std::vector<Font::ColoredString> &text, const Matrix4 &m)
int TextBatch::add(const std::vector<Font::ColoredString> &text, const Matrix4 &m)
{
return addf(text, -1.0f, Font::ALIGN_MAX_ENUM, m);
}
int Text::addf(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align, const Matrix4 &m)
int TextBatch::addf(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align, const Matrix4 &m)
{
Font::ColoredCodepoints codepoints;
Font::getCodepointsFromString(text, codepoints);
@@ -203,7 +203,7 @@ int Text::addf(const std::vector<Font::ColoredString> &text, float wrap, Font::A
return (int) textData.size() - 1;
}
void Text::clear()
void TextBatch::clear()
{
textData.clear();
drawCommands.clear();
@@ -211,7 +211,7 @@ void Text::clear()
vertOffset = 0;
}
void Text::setFont(Font *f)
void TextBatch::setFont(Font *f)
{
font.set(f);
@@ -221,12 +221,12 @@ void Text::setFont(Font *f)
regenerateVertices();
}
Font *Text::getFont() const
Font *TextBatch::getFont() const
{
return font.get();
}
int Text::getWidth(int index) const
int TextBatch::getWidth(int index) const
{
if (index < 0)
index = std::max((int) textData.size() - 1, 0);
@@ -237,7 +237,7 @@ int Text::getWidth(int index) const
return textData[index].textInfo.width;
}
int Text::getHeight(int index) const
int TextBatch::getHeight(int index) const
{
if (index < 0)
index = std::max((int) textData.size() - 1, 0);
@@ -248,7 +248,7 @@ int Text::getHeight(int index) const
return textData[index].textInfo.height;
}
void Text::draw(Graphics *gfx, const Matrix4 &m)
void TextBatch::draw(Graphics *gfx, const Matrix4 &m)
{
if (vertexBuffer == nullptr || vertexData == nullptr || drawCommands.empty())
return;
@@ -34,14 +34,14 @@ namespace graphics
class Graphics;
class Text : public Drawable
class TextBatch : public Drawable
{
public:
static love::Type type;
Text(Font *font, const std::vector<Font::ColoredString> &text = {});
virtual ~Text();
TextBatch(Font *font, const std::vector<Font::ColoredString> &text = {});
virtual ~TextBatch();
void set(const std::vector<Font::ColoredString> &text);
void set(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align);
+19 -19
View File
@@ -28,7 +28,7 @@
#include "Shader.h"
#include "Vulkan.h"
#include "SDL_vulkan.h"
#include <SDL_vulkan.h>
#include <algorithm>
#include <vector>
@@ -468,7 +468,8 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh
this->pixelWidth = pixelwidth;
this->pixelHeight = pixelheight;
resetProjection();
if (!isRenderTargetActive())
resetProjection();
}
bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa)
@@ -476,6 +477,9 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
requestedMsaa = msaa;
windowHasStencil = windowhasstencil;
// Must be called before the swapchain is created.
setViewportSize(width, height, pixelwidth, pixelheight);
cleanUpFunctions.clear();
cleanUpFunctions.resize(MAX_FRAMES_IN_FLIGHT);
@@ -529,8 +533,6 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
restoreState(states.back());
setViewportSize(width, height, pixelwidth, pixelheight);
Vulkan::resetShaderSwitches();
frameCounter = 0;
@@ -1783,16 +1785,20 @@ VkPresentModeKHR Graphics::chooseSwapPresentMode(const std::vector<VkPresentMode
else
return VK_PRESENT_MODE_FIFO_KHR;
case 0:
if (std::find(begin, end, VK_PRESENT_MODE_MAILBOX_KHR) != end)
// Mailbox mode might be better than immediate mode for a lot of people.
// But on at least some systems it acts as if vsync is enabled
// https://github.com/love2d/love/issues/1852
// TODO: is that a bug in love's code or the graphics driver / compositor?
// Should love expose mailbox mode in an API to users in some manner,
// instead of trying to guess what to do?
if (std::find(begin, end, VK_PRESENT_MODE_IMMEDIATE_KHR) != end)
return VK_PRESENT_MODE_IMMEDIATE_KHR;
else if (std::find(begin, end, VK_PRESENT_MODE_MAILBOX_KHR) != end)
return VK_PRESENT_MODE_MAILBOX_KHR;
else
{
if (std::find(begin, end, VK_PRESENT_MODE_IMMEDIATE_KHR) != end)
return VK_PRESENT_MODE_IMMEDIATE_KHR;
else
return VK_PRESENT_MODE_FIFO_KHR;
}
return VK_PRESENT_MODE_FIFO_KHR;
default:
// TODO: support for swap interval = 2, etc?
return VK_PRESENT_MODE_FIFO_KHR;
}
}
@@ -1814,15 +1820,9 @@ VkExtent2D Graphics::chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabiliti
return capabilities.currentExtent;
else
{
auto window = Module::getInstance<love::window::Window>(M_WINDOW);
const void *handle = window->getHandle();
int width, height;
SDL_Vulkan_GetDrawableSize((SDL_Window*)handle, &width, &height);
VkExtent2D actualExtent = {
static_cast<uint32_t>(width),
static_cast<uint32_t>(height)
static_cast<uint32_t>(pixelWidth),
static_cast<uint32_t>(pixelHeight)
};
actualExtent.width = clampuint32_t(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
+13 -6
View File
@@ -2101,21 +2101,21 @@ int w_newMesh(lua_State *L)
return 1;
}
int w_newText(lua_State *L)
int w_newTextBatch(lua_State *L)
{
luax_checkgraphicscreated(L);
graphics::Font *font = luax_checkfont(L, 1);
Text *t = nullptr;
TextBatch *t = nullptr;
if (lua_isnoneornil(L, 2))
luax_catchexcept(L, [&](){ t = instance()->newText(font); });
luax_catchexcept(L, [&](){ t = instance()->newTextBatch(font); });
else
{
std::vector<Font::ColoredString> text;
luax_checkcoloredstring(L, 2, text);
luax_catchexcept(L, [&](){ t = instance()->newText(font, text); });
luax_catchexcept(L, [&](){ t = instance()->newTextBatch(font, text); });
}
luax_pushtype(L, t);
@@ -2123,6 +2123,12 @@ int w_newText(lua_State *L)
return 1;
}
int w_newText(lua_State *L)
{
luax_markdeprecated(L, 1, "love.graphics.newText", API_FUNCTION, DEPRECATED_RENAMED, "love.graphics.newTextBatch");
return w_newTextBatch(L);
}
int w_newVideo(lua_State *L)
{
luax_checkgraphicscreated(L);
@@ -3769,7 +3775,7 @@ static const luaL_Reg functions[] =
{ "newVertexBuffer", w_newVertexBuffer },
{ "newIndexBuffer", w_newIndexBuffer },
{ "newMesh", w_newMesh },
{ "newText", w_newText },
{ "newTextBatch", w_newTextBatch },
{ "_newVideo", w_newVideo },
{ "readbackBuffer", w_readbackBuffer },
@@ -3895,6 +3901,7 @@ static const luaL_Reg functions[] =
{ "newArrayImage", w_newArrayImage },
{ "newVolumeImage", w_newVolumeImage },
{ "newCubeImage", w_newCubeImage },
{ "newText", w_newText },
{ "getCanvasFormats", w_getCanvasFormats },
{ "getImageFormats", w_getImageFormats },
@@ -3919,7 +3926,7 @@ static const lua_CFunction types[] =
luaopen_particlesystem,
luaopen_shader,
luaopen_mesh,
luaopen_text,
luaopen_textbatch,
luaopen_video,
0
};
+1 -1
View File
@@ -29,7 +29,7 @@
#include "wrap_ParticleSystem.h"
#include "wrap_Shader.h"
#include "wrap_Mesh.h"
#include "wrap_Text.h"
#include "wrap_TextBatch.h"
#include "wrap_Video.h"
#include "wrap_Buffer.h"
#include "wrap_GraphicsReadback.h"
+6 -2
View File
@@ -314,8 +314,9 @@ int w_Mesh_attachAttribute(lua_State *L)
return luax_enumerror(L, "vertex attribute step", getConstants(step), stepstr);
const char *attachname = luaL_optstring(L, 5, name);
int startindex = (int) luaL_optinteger(L, 6, 1) - 1;
luax_catchexcept(L, [&](){ t->attachAttribute(name, buffer, mesh, attachname, step); });
luax_catchexcept(L, [&](){ t->attachAttribute(name, buffer, mesh, attachname, startindex, step); });
return 0;
}
@@ -340,7 +341,7 @@ int w_Mesh_getAttachedAttributes(lua_State *L)
{
const auto &attrib = attributes[i];
lua_createtable(L, 4, 0);
lua_createtable(L, 5, 0);
luax_pushstring(L, attrib.name);
lua_rawseti(L, -1, 1);
@@ -358,6 +359,9 @@ int w_Mesh_getAttachedAttributes(lua_State *L)
luax_pushstring(L, member.decl.name);
lua_rawseti(L, -1, 4);
lua_pushinteger(L, attrib.startArrayIndex + 1);
lua_rawseti(L, -1, 5);
lua_rawseti(L, -1, i + 1);
}
@@ -18,7 +18,7 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "wrap_Text.h"
#include "wrap_TextBatch.h"
#include "wrap_Font.h"
#include "math/wrap_Transform.h"
@@ -27,14 +27,14 @@ namespace love
namespace graphics
{
Text *luax_checktext(lua_State *L, int idx)
TextBatch *luax_checktextbatch(lua_State *L, int idx)
{
return luax_checktype<Text>(L, idx);
return luax_checktype<TextBatch>(L, idx);
}
int w_Text_set(lua_State *L)
int w_TextBatch_set(lua_State *L)
{
Text *t = luax_checktext(L, 1);
TextBatch *t = luax_checktextbatch(L, 1);
std::vector<Font::ColoredString> newtext;
luax_checkcoloredstring(L, 2, newtext);
@@ -43,9 +43,9 @@ int w_Text_set(lua_State *L)
return 0;
}
int w_Text_setf(lua_State *L)
int w_TextBatch_setf(lua_State *L)
{
Text *t = luax_checktext(L, 1);
TextBatch *t = luax_checktextbatch(L, 1);
float wraplimit = (float) luaL_checknumber(L, 3);
@@ -62,9 +62,9 @@ int w_Text_setf(lua_State *L)
return 0;
}
int w_Text_add(lua_State *L)
int w_TextBatch_add(lua_State *L)
{
Text *t = luax_checktext(L, 1);
TextBatch *t = luax_checktextbatch(L, 1);
int index = 0;
@@ -96,9 +96,9 @@ int w_Text_add(lua_State *L)
return 1;
}
int w_Text_addf(lua_State *L)
int w_TextBatch_addf(lua_State *L)
{
Text *t = luax_checktext(L, 1);
TextBatch *t = luax_checktextbatch(L, 1);
int index = 0;
@@ -138,72 +138,72 @@ int w_Text_addf(lua_State *L)
return 1;
}
int w_Text_clear(lua_State *L)
int w_TextBatch_clear(lua_State *L)
{
Text *t = luax_checktext(L, 1);
TextBatch *t = luax_checktextbatch(L, 1);
luax_catchexcept(L, [&](){ t->clear(); });
return 0;
}
int w_Text_setFont(lua_State *L)
int w_TextBatch_setFont(lua_State *L)
{
Text *t = luax_checktext(L, 1);
TextBatch *t = luax_checktextbatch(L, 1);
Font *f = luax_checktype<Font>(L, 2);
luax_catchexcept(L, [&](){ t->setFont(f); });
return 0;
}
int w_Text_getFont(lua_State *L)
int w_TextBatch_getFont(lua_State *L)
{
Text *t = luax_checktext(L, 1);
TextBatch *t = luax_checktextbatch(L, 1);
Font *f = t->getFont();
luax_pushtype(L, f);
return 1;
}
int w_Text_getWidth(lua_State *L)
int w_TextBatch_getWidth(lua_State *L)
{
Text *t = luax_checktext(L, 1);
TextBatch *t = luax_checktextbatch(L, 1);
int index = (int) luaL_optinteger(L, 2, 0) - 1;
lua_pushnumber(L, t->getWidth(index));
return 1;
}
int w_Text_getHeight(lua_State *L)
int w_TextBatch_getHeight(lua_State *L)
{
Text *t = luax_checktext(L, 1);
TextBatch *t = luax_checktextbatch(L, 1);
int index = (int) luaL_optinteger(L, 2, 0) - 1;
lua_pushnumber(L, t->getHeight(index));
return 1;
}
int w_Text_getDimensions(lua_State *L)
int w_TextBatch_getDimensions(lua_State *L)
{
Text *t = luax_checktext(L, 1);
TextBatch *t = luax_checktextbatch(L, 1);
int index = (int) luaL_optinteger(L, 2, 0) - 1;
lua_pushnumber(L, t->getWidth(index));
lua_pushnumber(L, t->getHeight(index));
return 2;
}
static const luaL_Reg w_Text_functions[] =
static const luaL_Reg w_TextBatch_functions[] =
{
{ "set", w_Text_set },
{ "setf", w_Text_setf },
{ "add", w_Text_add },
{ "addf", w_Text_addf },
{ "clear", w_Text_clear },
{ "setFont", w_Text_setFont },
{ "getFont", w_Text_getFont },
{ "getWidth", w_Text_getWidth },
{ "getHeight", w_Text_getHeight },
{ "getDimensions", w_Text_getDimensions },
{ "set", w_TextBatch_set },
{ "setf", w_TextBatch_setf },
{ "add", w_TextBatch_add },
{ "addf", w_TextBatch_addf },
{ "clear", w_TextBatch_clear },
{ "setFont", w_TextBatch_setFont },
{ "getFont", w_TextBatch_getFont },
{ "getWidth", w_TextBatch_getWidth },
{ "getHeight", w_TextBatch_getHeight },
{ "getDimensions", w_TextBatch_getDimensions },
{ 0, 0 }
};
extern "C" int luaopen_text(lua_State *L)
extern "C" int luaopen_textbatch(lua_State *L)
{
return luax_register_type(L, &Text::type, w_Text_functions, nullptr);
return luax_register_type(L, &TextBatch::type, w_TextBatch_functions, nullptr);
}
} // graphics
@@ -20,7 +20,7 @@
#pragma once
#include "Text.h"
#include "TextBatch.h"
#include "common/runtime.h"
namespace love
@@ -28,8 +28,8 @@ namespace love
namespace graphics
{
Text *luax_checktext(lua_State *L, int idx);
extern "C" int luaopen_text(lua_State *L);
TextBatch *luax_checktextbatch(lua_State *L, int idx);
extern "C" int luaopen_textbatch(lua_State *L);
} // graphics
} // love
+1 -1
View File
@@ -242,7 +242,7 @@ int w_Texture_setWrap(lua_State *L)
return luax_enumerror(L, "wrap mode", SamplerState::getConstants(s.wrapW), rstr);
luax_catchexcept(L, [&](){ t->setSamplerState(s); });
return 1;
return 0;
}
int w_Texture_getWrap(lua_State *L)
+8
View File
@@ -24,6 +24,7 @@
// LOVE
#include "common/Object.h"
#include "common/StringMap.h"
#include "sensor/Sensor.h"
// stdlib
#include <vector>
@@ -38,6 +39,8 @@ class Joystick : public Object
{
public:
using Sensor = love::sensor::Sensor;
static love::Type type;
// Joystick hat values.
@@ -198,6 +201,11 @@ public:
virtual bool setVibration() = 0;
virtual void getVibration(float &left, float &right) = 0;
virtual bool hasSensor(Sensor::SensorType type) const = 0;
virtual bool isSensorEnabled(Sensor::SensorType type) const = 0;
virtual void setSensorEnabled(Sensor::SensorType type, bool enabled) = 0;
virtual std::vector<float> getSensorData(Sensor::SensorType type) const = 0;
STRINGMAP_CLASS_DECLARE(Hat);
STRINGMAP_CLASS_DECLARE(GamepadType);
STRINGMAP_CLASS_DECLARE(GamepadAxis);
+84 -6
View File
@@ -22,6 +22,10 @@
#include "common/config.h"
#include "Joystick.h"
#include "common/int.h"
#include "sensor/sdl/Sensor.h"
// SDL
#include <SDL_version.h>
// C++
#include <algorithm>
@@ -409,7 +413,6 @@ int Joystick::getID() const
void Joystick::getDeviceInfo(int &vendorID, int &productID, int &productVersion) const
{
#if SDL_VERSION_ATLEAST(2, 0, 6)
if (joyhandle != nullptr)
{
vendorID = SDL_JoystickGetVendor(joyhandle);
@@ -417,7 +420,6 @@ void Joystick::getDeviceInfo(int &vendorID, int &productID, int &productVersion)
productVersion = SDL_JoystickGetProductVersion(joyhandle);
}
else
#endif
{
vendorID = 0;
productID = 0;
@@ -521,10 +523,8 @@ 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;
@@ -606,10 +606,8 @@ bool Joystick::setVibration()
{
bool success = false;
#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);
@@ -643,6 +641,86 @@ void Joystick::getVibration(float &left, float &right)
right = vibration.right;
}
bool Joystick::hasSensor(Sensor::SensorType type) const
{
#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR)
using SDLSensor = love::sensor::sdl::Sensor;
if (!isGamepad())
return false;
return SDL_GameControllerHasSensor(controller, SDLSensor::convert(type)) == SDL_TRUE;
#else
return false;
#endif
}
bool Joystick::isSensorEnabled(Sensor::SensorType type) const
{
#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR)
using SDLSensor = love::sensor::sdl::Sensor;
if (!isGamepad())
return false;
return SDL_GameControllerIsSensorEnabled(controller, SDLSensor::convert(type)) == SDL_TRUE;
#else
return false;
#endif
}
void Joystick::setSensorEnabled(Sensor::SensorType type, bool enabled)
{
#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR)
using SDLSensor = love::sensor::sdl::Sensor;
if (!isGamepad())
throw love::Exception("Sensor is only supported on gamepad");
if (SDL_GameControllerSetSensorEnabled(controller, SDLSensor::convert(type), enabled ? SDL_TRUE : SDL_FALSE) != 0)
{
const char *name = nullptr;
SDLSensor::getConstant(type, name);
throw love::Exception("Could not open \"%s\" SDL gamepad sensor (%s)", name, SDL_GetError());
}
#else
throw love::Exception("Compiled version of SDL or LOVE does not support gamepad sensor");
#endif
}
std::vector<float> Joystick::getSensorData(Sensor::SensorType type) const
{
#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR)
using SDLSensor = love::sensor::sdl::Sensor;
if (!isGamepad())
throw love::Exception("Sensor is only supported on gamepad");
std::vector<float> data(3);
if (!isSensorEnabled(type))
{
const char *name = nullptr;
SDLSensor::getConstant(type, name);
throw love::Exception("\"%s\" gamepad sensor is not enabled", name);
}
if (SDL_GameControllerGetSensorData(controller, SDLSensor::convert(type), data.data(), (int) data.size()) != 0)
{
const char *name = nullptr;
SDLSensor::getConstant(type, name);
throw love::Exception("Could not get \"%s\" SDL gamepad sensor data (%s)", name, SDL_GetError());
}
return data;
#else
throw love::Exception("Compiled version of SDL or LOVE does not support gamepad sensor");
#endif
}
bool Joystick::getConstant(Uint8 in, Joystick::Hat &out)
{
return hats.find(in, out);
+5
View File
@@ -88,6 +88,11 @@ public:
bool setVibration() override;
void getVibration(float &left, float &right) override;
bool hasSensor(Sensor::SensorType type) const override;
bool isSensorEnabled(Sensor::SensorType type) const override;
void setSensorEnabled(Sensor::SensorType type, bool enabled) override;
std::vector<float> getSensorData(Sensor::SensorType type) const override;
static bool getConstant(Hat in, Uint8 &out);
static bool getConstant(Uint8 in, Hat &out);
+80
View File
@@ -21,6 +21,7 @@
// LOVE
#include "wrap_Joystick.h"
#include "wrap_JoystickModule.h"
#include "sensor/Sensor.h"
#include <vector>
@@ -367,6 +368,78 @@ int w_Joystick_getVibration(lua_State *L)
return 2;
}
#ifdef LOVE_ENABLE_SENSOR
int w_Joystick_hasSensor(lua_State *L)
{
using namespace love::sensor;
Joystick *j = luax_checkjoystick(L, 1);
const char *sensorType = luaL_checkstring(L, 2);
Sensor::SensorType type;
if (!Sensor::getConstant(sensorType, type))
luax_enumerror(L, "sensor type", Sensor::getConstants(type), sensorType);
luax_pushboolean(L, j->hasSensor(type));
return 1;
}
int w_Joystick_isSensorEnabled(lua_State *L)
{
using namespace love::sensor;
Joystick *j = luax_checkjoystick(L, 1);
const char *sensorType = luaL_checkstring(L, 2);
Sensor::SensorType type;
if (!Sensor::getConstant(sensorType, type))
luax_enumerror(L, "sensor type", Sensor::getConstants(type), sensorType);
luax_pushboolean(L, j->isSensorEnabled(type));
return 1;
}
int w_Joystick_setSensorEnabled(lua_State *L)
{
using namespace love::sensor;
Joystick *j = luax_checkjoystick(L, 1);
const char *sensorType = luaL_checkstring(L, 2);
Sensor::SensorType type;
if (!Sensor::getConstant(sensorType, type))
luax_enumerror(L, "sensor type", Sensor::getConstants(type), sensorType);
bool enabled = luax_checkboolean(L, 3);
luax_catchexcept(L, [&]() { j->setSensorEnabled(type, enabled); });
return 0;
}
int w_Joystick_getSensorData(lua_State *L)
{
using namespace love::sensor;
Joystick *j = luax_checkjoystick(L, 1);
const char *sensorType = luaL_checkstring(L, 2);
Sensor::SensorType type;
if (!Sensor::getConstant(sensorType, type))
luax_enumerror(L, "sensor type", Sensor::getConstants(type), sensorType);
std::vector<float> data;
luax_catchexcept(L, [&]() { data = j->getSensorData(type); });
for (float f: data)
lua_pushnumber(L, f);
return (int) data.size();
}
#endif // LOVE_ENABLE_SENSOR
// List of functions to wrap.
static const luaL_Reg w_Joystick_functions[] =
{
@@ -396,6 +469,13 @@ static const luaL_Reg w_Joystick_functions[] =
{ "setVibration", w_Joystick_setVibration },
{ "getVibration", w_Joystick_getVibration },
#ifdef LOVE_ENABLE_SENSOR
{ "hasSensor", w_Joystick_hasSensor },
{ "isSensorEnabled", w_Joystick_isSensorEnabled },
{ "setSensorEnabled", w_Joystick_setSensorEnabled },
{ "getSensorData", w_Joystick_setSensorEnabled },
#endif
// From wrap_JoystickModule.
{ "getConnectedIndex", w_getIndex },
+3 -1
View File
@@ -189,6 +189,7 @@ function love.init()
audio = true,
math = true,
physics = true,
sensor = true,
sound = true,
system = true,
font = true,
@@ -204,7 +205,7 @@ function love.init()
identity = false,
appendidentity = false,
externalstorage = false, -- Only relevant for Android.
accelerometerjoystick = true, -- Only relevant for Android / iOS.
accelerometerjoystick = nil, -- Only relevant for Android / iOS, deprecated.
gammacorrect = false,
highdpi = false,
renderers = nil,
@@ -311,6 +312,7 @@ function love.init()
"touch",
"sound",
"system",
"sensor",
"audio",
"image",
"video",
+8 -1
View File
@@ -88,6 +88,9 @@ function love.createhandlers()
joystickremoved = function (j)
if love.joystickremoved then return love.joystickremoved(j) end
end,
joysticksensorupdated = function (j, sensorType, x, y, z)
if love.joysticksensorupdated then return love.joysticksensorupdated(j, sensorType, x, y, z) end
end,
focus = function (f)
if love.focus then return love.focus(f) end
end,
@@ -134,6 +137,9 @@ function love.createhandlers()
love.audio.setPlaybackDevice()
end
end,
sensorupdated = function (sensorType, x, y, z)
if love.sensorupdated then return love.sensorupdated(sensorType, x, y, z) end
end,
}, {
__index = function(self, name)
error("Unknown event: " .. name)
@@ -232,7 +238,8 @@ function love.errhand(msg)
if love.audio then love.audio.stop() end
love.graphics.reset()
local font = love.graphics.setNewFont(14)
local font = love.graphics.newFont(14)
love.graphics.setFont(font)
love.graphics.setColor(1, 1, 1)
+10
View File
@@ -152,6 +152,9 @@ extern "C"
#if defined(LOVE_ENABLE_PHYSICS)
extern int luaopen_love_physics(lua_State*);
#endif
#if defined(LOVE_ENABLE_SENSOR)
extern int luaopen_love_sensor(lua_State*);
#endif
#if defined(LOVE_ENABLE_SOUND)
extern int luaopen_love_sound(lua_State*);
#endif
@@ -221,6 +224,9 @@ static const luaL_Reg modules[] = {
#if defined(LOVE_ENABLE_PHYSICS)
{ "love.physics", luaopen_love_physics },
#endif
#if defined(LOVE_ENABLE_SENSOR)
{ "love.sensor", luaopen_love_sensor },
#endif
#if defined(LOVE_ENABLE_SOUND)
{ "love.sound", luaopen_love_sound },
#endif
@@ -778,6 +784,10 @@ int w__setAccelerometerAsJoystick(lua_State *L)
{
bool enable = (bool) lua_toboolean(L, 1);
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, enable ? "1" : "0");
if (enable)
love::luax_markdeprecated(L, 1, "accelerometerjoystick", love::API_FIELD, love::DEPRECATED_REPLACED, "love.sensor module");
return 0;
}
#endif // LOVE_LEGENDARY_ACCELEROMETER_AS_JOYSTICK_HACK
@@ -56,34 +56,6 @@ float DistanceJoint::getLength() const
return Physics::scaleUp(joint->GetLength());
}
void DistanceJoint::setFrequency(float hz)
{
float stiffness, damping;
b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB());
joint->SetStiffness(stiffness);
}
float DistanceJoint::getFrequency() const
{
float frequency, ratio;
Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB());
return frequency;
}
void DistanceJoint::setDampingRatio(float ratio)
{
float stiffness, damping;
b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB());
joint->SetDamping(damping);
}
float DistanceJoint::getDampingRatio() const
{
float frequency, ratio;
Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB());
return ratio;
}
void DistanceJoint::setStiffness(float k)
{
joint->SetStiffness(k);
-20
View File
@@ -56,26 +56,6 @@ public:
**/
float getLength() const;
/**
* Sets the response speed. Independent of mass
**/
void setFrequency(float hz);
/**
* Gets the response speed. Independent of mass
**/
float getFrequency() const;
/**
* Set the spring damping ratio. Independent of mass
**/
void setDampingRatio(float ratio);
/**
* Get the spring damping ratio. Independent of mass
**/
float getDampingRatio() const;
/**
* Sets the response speed. Dependent of mass
**/
+1 -34
View File
@@ -49,6 +49,7 @@ MouseJoint::MouseJoint(Body *body1, float x, float y)
def.bodyB = body1->body;
def.maxForce = 1000.0f * body1->body->GetMass();
def.target = Physics::scaleDown(b2Vec2(x,y));
Physics::computeLinearStiffness(def.stiffness, def.damping, 5.0, 0.7, def.bodyA, def.bodyB);
joint = (b2MouseJoint *)createJoint(&def);
}
@@ -78,40 +79,6 @@ float MouseJoint::getMaxForce() const
return Physics::scaleUp(joint->GetMaxForce());
}
void MouseJoint::setFrequency(float hz)
{
// This is kind of a crappy check. The Stiffness is used in an internal
// box2d calculation whose result must be > FLT_EPSILON, but other variables
// go into that calculation...
if (hz <= FLT_EPSILON * 2)
throw love::Exception("MouseJoint Stiffness must be a positive number.");
float stiffness, damping;
b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB());
joint->SetStiffness(stiffness);
}
float MouseJoint::getFrequency() const
{
float frequency, ratio;
Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB());
return frequency;
}
void MouseJoint::setDampingRatio(float ratio)
{
float stiffness, damping;
b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB());
joint->SetDamping(damping);
}
float MouseJoint::getDampingRatio() const
{
float frequency, ratio;
Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB());
return ratio;
}
void MouseJoint::setStiffness(float k)
{
// This is kind of a crappy check. The Stiffness is used in an internal
+12 -2
View File
@@ -405,7 +405,12 @@ b2AABB Physics::scaleUp(const b2AABB &aabb)
return t;
}
void Physics::b2LinearFrequency(float& frequency, float& ratio, float stiffness, float damping, b2Body* bodyA, b2Body* bodyB)
void Physics::computeLinearStiffness(float &stiffness, float &damping, float frequency, float dampingRatio, b2Body *bodyA, b2Body *bodyB)
{
b2LinearStiffness(stiffness, damping, frequency, dampingRatio, bodyA, bodyB);
}
void Physics::computeLinearFrequency(float &frequency, float &ratio, float stiffness, float damping, b2Body *bodyA, b2Body *bodyB)
{
float massA = bodyA->GetMass();
float massB = bodyB->GetMass();
@@ -435,7 +440,12 @@ void Physics::b2LinearFrequency(float& frequency, float& ratio, float stiffness,
ratio = damping / (mass * 2.0f * omega);
}
void Physics::b2AngularFrequency(float& frequency, float& ratio, float stiffness, float damping, b2Body* bodyA, b2Body* bodyB)
void Physics::computeAngularStiffness(float &stiffness, float &damping, float frequency, float dampingRatio, b2Body *bodyA, b2Body *bodyB)
{
b2AngularStiffness(stiffness, damping, frequency, dampingRatio, bodyA, bodyB);
}
void Physics::computeAngularFrequency(float &frequency, float &ratio, float stiffness, float damping, b2Body *bodyA, b2Body *bodyB)
{
float IA = bodyA->GetInertia();
float IB = bodyB->GetInertia();
+30 -8
View File
@@ -360,18 +360,18 @@ public:
static b2AABB scaleUp(const b2AABB& aabb);
/**
* Calculates linear frequency and damping radio from stiffness and damping
* @param frequency The output frequency
* @param ratio The output damping ratio
* @param stiffness The joint stiffness
* @param damping The joint damping
* Calculates the stiffness and damping, given the linear frequency, and damping ratio.
* @param stiffness The output stiffness
* @param damping The output damping
* @param frequency The joint linear frequency
* @param dampingRatio The joint damping ratio
* @param bodyA The bodyA of the joint
* @param bodyB The bodyB of the joint
**/
static void b2LinearFrequency(float& frequency, float& ratio, float stiffness, float damping, b2Body* bodyA, b2Body* bodyB);
static void computeLinearStiffness(float& stiffness, float& damping, float frequency, float dampingRatio, b2Body* bodyA, b2Body* bodyB);
/**
* Calculates angular frequency and damping radio from stiffness and damping
* Calculates linear frequency and damping ratio from stiffness and damping
* @param frequency The output frequency
* @param ratio The output damping ratio
* @param stiffness The joint stiffness
@@ -379,7 +379,29 @@ public:
* @param bodyA The bodyA of the joint
* @param bodyB The bodyB of the joint
**/
static void b2AngularFrequency(float& frequency, float& ratio, float stiffness, float damping, b2Body* bodyA, b2Body* bodyB);
static void computeLinearFrequency(float &frequency, float &ratio, float stiffness, float damping, b2Body *bodyA, b2Body *bodyB);
/**
* Calculates the stiffness and damping, given the angular frequency, and damping ratio.
* @param stiffness The output stiffness
* @param damping The output damping
* @param frequency The joint angular frequency
* @param dampingRatio The joint damping ratio
* @param bodyA The bodyA of the joint
* @param bodyB The bodyB of the joint
**/
static void computeAngularStiffness(float &stiffness, float &damping, float frequency, float dampingRatio, b2Body *bodyA, b2Body *bodyB);
/**
* Calculates angular frequency and damping ratio from stiffness and damping
* @param frequency The output frequency
* @param ratio The output damping ratio
* @param stiffness The joint stiffness
* @param damping The joint damping
* @param bodyA The bodyA of the joint
* @param bodyB The bodyB of the joint
**/
static void computeAngularFrequency(float &frequency, float &ratio, float stiffness, float damping, b2Body *bodyA, b2Body *bodyB);
private:
-28
View File
@@ -66,34 +66,6 @@ void WeldJoint::init(b2WeldJointDef &def, Body *body1, Body *body2, float xA, fl
def.collideConnected = collideConnected;
}
void WeldJoint::setFrequency(float hz)
{
float stiffness, damping;
b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB());
joint->SetStiffness(stiffness);
}
float WeldJoint::getFrequency() const
{
float frequency, ratio;
Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB());
return frequency;
}
void WeldJoint::setDampingRatio(float ratio)
{
float stiffness, damping;
b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB());
joint->SetDamping(damping);
}
float WeldJoint::getDampingRatio() const
{
float frequency, ratio;
Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB());
return ratio;
}
void WeldJoint::setStiffness(float k)
{
joint->SetStiffness(k);
-20
View File
@@ -49,26 +49,6 @@ public:
virtual ~WeldJoint();
/**
* Sets the response speed. Independent of mass
**/
void setFrequency(float hz);
/**
* Gets the response speed. Independent of mass
**/
float getFrequency() const;
/**
* Set the spring damping ratio. Independent of mass
**/
void setDampingRatio(float ratio);
/**
* Get the spring damping ratio. Independent of mass
**/
float getDampingRatio() const;
/**
* Sets the response speed. Dependent of mass
**/
-28
View File
@@ -95,34 +95,6 @@ float WheelJoint::getMotorTorque(float inv_dt) const
return Physics::scaleUp(Physics::scaleUp(joint->GetMotorTorque(inv_dt)));
}
void WheelJoint::setFrequency(float hz)
{
float stiffness, damping;
b2AngularStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB());
joint->SetStiffness(stiffness);
}
float WheelJoint::getFrequency() const
{
float frequency, ratio;
Physics::b2AngularFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB());
return frequency;
}
void WheelJoint::setDampingRatio(float ratio)
{
float stiffness, damping;
b2AngularStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB());
joint->SetDamping(damping);
}
float WheelJoint::getDampingRatio() const
{
float frequency, ratio;
Physics::b2AngularFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB());
return ratio;
}
void WheelJoint::setStiffness(float k)
{
joint->SetStiffness(k);
-20
View File
@@ -95,26 +95,6 @@ public:
**/
float getMotorTorque(float inv_dt) const;
/**
* Sets the response speed. Independent of mass
**/
void setFrequency(float hz);
/**
* Gets the response speed. Independent of mass
**/
float getFrequency() const;
/**
* Set the spring damping ratio. Independent of mass
**/
void setDampingRatio(float ratio);
/**
* Get the spring damping ratio. Independent of mass
**/
float getDampingRatio() const;
/**
* Sets the response speed. Dependent of mass
**/
@@ -50,36 +50,6 @@ int w_DistanceJoint_getLength(lua_State *L)
return 1;
}
int w_DistanceJoint_setFrequency(lua_State *L)
{
DistanceJoint *t = luax_checkdistancejoint(L, 1);
float arg1 = (float)luaL_checknumber(L, 2);
t->setFrequency(arg1);
return 0;
}
int w_DistanceJoint_getFrequency(lua_State *L)
{
DistanceJoint *t = luax_checkdistancejoint(L, 1);
lua_pushnumber(L, t->getFrequency());
return 1;
}
int w_DistanceJoint_setDampingRatio(lua_State *L)
{
DistanceJoint *t = luax_checkdistancejoint(L, 1);
float arg1 = (float)luaL_checknumber(L, 2);
t->setDampingRatio(arg1);
return 0;
}
int w_DistanceJoint_getDampingRatio(lua_State *L)
{
DistanceJoint *t = luax_checkdistancejoint(L, 1);
lua_pushnumber(L, t->getDampingRatio());
return 1;
}
int w_DistanceJoint_setStiffness(lua_State *L)
{
DistanceJoint *t = luax_checkdistancejoint(L, 1);
@@ -114,10 +84,6 @@ static const luaL_Reg w_DistanceJoint_functions[] =
{
{ "setLength", w_DistanceJoint_setLength },
{ "getLength", w_DistanceJoint_getLength },
{ "setFrequency", w_DistanceJoint_setFrequency },
{ "getFrequency", w_DistanceJoint_getFrequency },
{ "setDampingRatio", w_DistanceJoint_setDampingRatio },
{ "getDampingRatio", w_DistanceJoint_getDampingRatio },
{ "setStiffness", w_DistanceJoint_setStiffness },
{ "getStiffness", w_DistanceJoint_getStiffness },
{ "setDamping", w_DistanceJoint_setDamping },
@@ -66,36 +66,6 @@ int w_MouseJoint_getMaxForce(lua_State *L)
return 1;
}
int w_MouseJoint_setFrequency(lua_State *L)
{
MouseJoint *t = luax_checkmousejoint(L, 1);
float arg1 = (float)luaL_checknumber(L, 2);
luax_catchexcept(L, [&]() { t->setFrequency(arg1); });
return 0;
}
int w_MouseJoint_getFrequency(lua_State *L)
{
MouseJoint *t = luax_checkmousejoint(L, 1);
lua_pushnumber(L, t->getFrequency());
return 1;
}
int w_MouseJoint_setDampingRatio(lua_State *L)
{
MouseJoint *t = luax_checkmousejoint(L, 1);
float arg1 = (float)luaL_checknumber(L, 2);
t->setDampingRatio(arg1);
return 0;
}
int w_MouseJoint_getDampingRatio(lua_State *L)
{
MouseJoint *t = luax_checkmousejoint(L, 1);
lua_pushnumber(L, t->getDampingRatio());
return 1;
}
int w_MouseJoint_setStiffness(lua_State *L)
{
MouseJoint *t = luax_checkmousejoint(L, 1);
@@ -132,10 +102,6 @@ static const luaL_Reg w_MouseJoint_functions[] =
{ "getTarget", w_MouseJoint_getTarget },
{ "setMaxForce", w_MouseJoint_setMaxForce },
{ "getMaxForce", w_MouseJoint_getMaxForce },
{ "setFrequency", w_MouseJoint_setFrequency },
{ "getFrequency", w_MouseJoint_getFrequency },
{ "setDampingRatio", w_MouseJoint_setDampingRatio },
{ "getDampingRatio", w_MouseJoint_getDampingRatio },
{ "setStiffness", w_MouseJoint_setStiffness },
{ "getStiffness", w_MouseJoint_getStiffness },
{ "setDamping", w_MouseJoint_setDamping },
@@ -477,12 +477,97 @@ int w_setMeter(lua_State *L)
return 0;
}
int w_getMeter(lua_State *L)
{
lua_pushinteger(L, Physics::getMeter());
return 1;
}
int w_computeLinearStiffness(lua_State *L)
{
float frequency = (float)luaL_checknumber(L, 1);
float dampingRatio = (float)luaL_checknumber(L, 2);
Body *body1 = luax_checkbody(L, 3);
b2Body *other = 0;
if (lua_isnoneornil(L, 4))
other = body1->getWorld()->getGroundBody();
else
other = luax_checkbody(L, 4)->body;
float stiffness, damping;
Physics::computeLinearStiffness(stiffness, damping, frequency, dampingRatio, body1->body, other);
lua_pushnumber(L, stiffness);
lua_pushnumber(L, damping);
return 2;
}
int w_computeLinearFrequency(lua_State *L)
{
float stiffness = (float)luaL_checknumber(L, 1);
float damping = (float)luaL_checknumber(L, 2);
Body *body1 = luax_checkbody(L, 3);
b2Body *other = 0;
if (lua_isnoneornil(L, 4))
other = body1->getWorld()->getGroundBody();
else
other = luax_checkbody(L, 4)->body;
float frequency, dampingRatio;
Physics::computeLinearFrequency(frequency, dampingRatio, stiffness, damping, body1->body, other);
lua_pushnumber(L, frequency);
lua_pushnumber(L, dampingRatio);
return 2;
}
int w_computeAngularStiffness(lua_State *L)
{
float frequency = (float)luaL_checknumber(L, 1);
float dampingRatio = (float)luaL_checknumber(L, 2);
Body *body1 = luax_checkbody(L, 3);
b2Body *other = 0;
if (lua_isnoneornil(L, 4))
other = body1->getWorld()->getGroundBody();
else
other = luax_checkbody(L, 4)->body;
float stiffness, damping;
Physics::computeAngularStiffness(stiffness, damping, frequency, dampingRatio, body1->body, other);
lua_pushnumber(L, stiffness);
lua_pushnumber(L, damping);
return 2;
}
int w_computeAngularFrequency(lua_State *L)
{
float stiffness = (float)luaL_checknumber(L, 1);
float damping = (float)luaL_checknumber(L, 2);
Body *body1 = luax_checkbody(L, 3);
b2Body *other = 0;
if (lua_isnoneornil(L, 4))
other = body1->getWorld()->getGroundBody();
else
other = luax_checkbody(L, 4)->body;
float frequency, dampingRatio;
Physics::computeAngularFrequency(frequency, dampingRatio, stiffness, damping, body1->body, other);
lua_pushnumber(L, frequency);
lua_pushnumber(L, dampingRatio);
return 2;
}
// List of functions to wrap.
static const luaL_Reg functions[] =
{
@@ -508,6 +593,10 @@ static const luaL_Reg functions[] =
{ "getDistance", w_getDistance },
{ "getMeter", w_getMeter },
{ "setMeter", w_setMeter },
{ "computeLinearStiffness", w_computeLinearStiffness },
{ "computeLinearFrequency", w_computeLinearFrequency },
{ "computeAngularStiffness", w_computeAngularStiffness },
{ "computeAngularFrequency", w_computeAngularFrequency },
{ 0, 0 },
};
@@ -35,36 +35,6 @@ WeldJoint *luax_checkweldjoint(lua_State *L, int idx)
return j;
}
int w_WeldJoint_setFrequency(lua_State *L)
{
WeldJoint *t = luax_checkweldjoint(L, 1);
float arg1 = (float)luaL_checknumber(L, 2);
t->setFrequency(arg1);
return 0;
}
int w_WeldJoint_getFrequency(lua_State *L)
{
WeldJoint *t = luax_checkweldjoint(L, 1);
lua_pushnumber(L, t->getFrequency());
return 1;
}
int w_WeldJoint_setDampingRatio(lua_State *L)
{
WeldJoint *t = luax_checkweldjoint(L, 1);
float arg1 = (float)luaL_checknumber(L, 2);
t->setDampingRatio(arg1);
return 0;
}
int w_WeldJoint_getDampingRatio(lua_State *L)
{
WeldJoint *t = luax_checkweldjoint(L, 1);
lua_pushnumber(L, t->getDampingRatio());
return 1;
}
int w_WeldJoint_setStiffness(lua_State *L)
{
WeldJoint *t = luax_checkweldjoint(L, 1);
@@ -104,10 +74,6 @@ int w_WeldJoint_getReferenceAngle(lua_State *L)
static const luaL_Reg w_WeldJoint_functions[] =
{
{ "setFrequency", w_WeldJoint_setFrequency },
{ "getFrequency", w_WeldJoint_getFrequency },
{ "setDampingRatio", w_WeldJoint_setDampingRatio },
{ "getDampingRatio", w_WeldJoint_getDampingRatio },
{ "setStiffness", w_WeldJoint_setStiffness },
{ "getStiffness", w_WeldJoint_getStiffness },
{ "setDamping", w_WeldJoint_setDamping },
@@ -102,36 +102,6 @@ int w_WheelJoint_getMotorTorque(lua_State *L)
return 1;
}
int w_WheelJoint_setFrequency(lua_State *L)
{
WheelJoint *t = luax_checkwheeljoint(L, 1);
float arg1 = (float)luaL_checknumber(L, 2);
t->setFrequency(arg1);
return 0;
}
int w_WheelJoint_getFrequency(lua_State *L)
{
WheelJoint *t = luax_checkwheeljoint(L, 1);
lua_pushnumber(L, t->getFrequency());
return 1;
}
int w_WheelJoint_setDampingRatio(lua_State *L)
{
WheelJoint *t = luax_checkwheeljoint(L, 1);
float arg1 = (float)luaL_checknumber(L, 2);
t->setDampingRatio(arg1);
return 0;
}
int w_WheelJoint_getDampingRatio(lua_State *L)
{
WheelJoint *t = luax_checkwheeljoint(L, 1);
lua_pushnumber(L, t->getDampingRatio());
return 1;
}
int w_WheelJoint_setStiffness(lua_State *L)
{
WheelJoint *t = luax_checkwheeljoint(L, 1);
@@ -180,18 +150,10 @@ static const luaL_Reg w_WheelJoint_functions[] =
{ "setMaxMotorTorque", w_WheelJoint_setMaxMotorTorque },
{ "getMaxMotorTorque", w_WheelJoint_getMaxMotorTorque },
{ "getMotorTorque", w_WheelJoint_getMotorTorque },
{ "setSpringFrequency", w_WheelJoint_setFrequency },
{ "getSpringFrequency", w_WheelJoint_getFrequency },
{ "setSpringDampingRatio", w_WheelJoint_setDampingRatio },
{ "getSpringDampingRatio", w_WheelJoint_getDampingRatio },
{ "setSpringStiffness", w_WheelJoint_setStiffness },
{ "getSpringStiffness", w_WheelJoint_getStiffness },
{ "setSpringDamping", w_WheelJoint_setDamping },
{ "getSpringDamping", w_WheelJoint_getDamping },
{ "setFrequency", w_WheelJoint_setFrequency },
{ "getFrequency", w_WheelJoint_getFrequency },
{ "setDampingRatio", w_WheelJoint_setDampingRatio },
{ "getDampingRatio", w_WheelJoint_getDampingRatio },
{ "setStiffness", w_WheelJoint_setStiffness },
{ "getStiffness", w_WheelJoint_getStiffness },
{ "setDamping", w_WheelJoint_setDamping },
+37
View File
@@ -0,0 +1,37 @@
/**
* Copyright (c) 2006-2022 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.
**/
// LOVE
#include "Sensor.h"
namespace love
{
namespace sensor
{
STRINGMAP_CLASS_BEGIN(Sensor, Sensor::SensorType, Sensor::SENSOR_MAX_ENUM, sensorType)
{
{ "accelerometer", Sensor::SENSOR_ACCELEROMETER },
{ "gyroscope", Sensor::SENSOR_GYROSCOPE },
}
STRINGMAP_CLASS_END(Sensor, Sensor::SensorType, Sensor::SENSOR_MAX_ENUM, sensorType)
} // sensor
} // love
+83
View File
@@ -0,0 +1,83 @@
/**
* Copyright (c) 2006-2022 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.
**/
#ifndef LOVE_SENSOR_H
#define LOVE_SENSOR_H
// LOVE
#include "common/Module.h"
#include "common/StringMap.h"
namespace love
{
namespace sensor
{
class Sensor: public Module
{
public:
enum SensorType
{
SENSOR_ACCELEROMETER,
SENSOR_GYROSCOPE,
SENSOR_MAX_ENUM
};
virtual ~Sensor() {}
// Implements Module.
ModuleType getModuleType() const override { return M_SENSOR; }
/**
* Check the availability of the sensor.
**/
virtual bool hasSensor(SensorType type) = 0;
/**
* Check if the sensor is enabled.
**/
virtual bool isEnabled(SensorType type) = 0;
/**
* Enable or disable a sensor.
**/
virtual void setEnabled(SensorType type, bool enabled) = 0;
/**
* Get data from sensor.
**/
virtual std::vector<float> getData(SensorType type) = 0;
/**
* Get backend-dependent handle of sensor.
**/
virtual std::vector<void *> getHandles() = 0;
virtual const char *getSensorName(SensorType type) = 0;
STRINGMAP_CLASS_DECLARE(SensorType);
}; // Sensor
} // sensor
} // love
#endif
+174
View File
@@ -0,0 +1,174 @@
/**
* Copyright (c) 2006-2022 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.
**/
// LOVE
#include "Sensor.h"
// SDL
#include <SDL.h>
#include <SDL_sensor.h>
namespace love
{
namespace sensor
{
namespace sdl
{
Sensor::Sensor()
: sensors()
{
if (SDL_InitSubSystem(SDL_INIT_SENSOR) < 0)
throw love::Exception("Could not initialize SDL sensor subsystem (%s)", SDL_GetError());
}
Sensor::~Sensor()
{
SDL_QuitSubSystem(SDL_INIT_SENSOR);
}
const char *Sensor::getName() const
{
return "love.sensor.sdl";
}
bool Sensor::hasSensor(SensorType type)
{
for (int i = 0; i < SDL_NumSensors(); i++)
{
if (convert(SDL_SensorGetDeviceType(i)) == type)
return true;
}
return false;
}
bool Sensor::isEnabled(SensorType type)
{
return sensors[type]; // nullptr is default
}
void Sensor::setEnabled(SensorType type, bool enable)
{
if (sensors[type] && !enable)
{
SDL_SensorClose(sensors[type]);
sensors[type] = nullptr;
}
else if (sensors[type] == nullptr && enable)
{
for (int i = 0; i < SDL_NumSensors(); i++)
{
if (convert(SDL_SensorGetDeviceType(i)) == type)
{
SDL_Sensor *sensorHandle = SDL_SensorOpen(i);
if (sensorHandle == nullptr)
{
const char *name = nullptr;
getConstant(type, name);
throw love::Exception("Could not open \"%s\" SDL sensor (%s)", name, SDL_GetError());
}
sensors[type] = sensorHandle;
}
}
}
}
std::vector<float> Sensor::getData(SensorType type)
{
if (sensors[type] == nullptr)
{
const char *name = nullptr;
getConstant(type, name);
throw love::Exception("\"%s\" sensor is not enabled", name);
}
std::vector<float> values(3);
if (SDL_SensorGetData(sensors[type], values.data(), (int) values.size()) != 0)
{
const char *name = nullptr;
getConstant(type, name);
throw love::Exception("Could not get \"%s\" SDL sensor data (%s)", name, SDL_GetError());
}
return values;
}
std::vector<void*> Sensor::getHandles()
{
std::vector<void*> nativeSensor;
for (const std::pair<SensorType, SDL_Sensor*> &data: sensors)
{
if (data.second)
nativeSensor.push_back(data.second);
}
return nativeSensor;
}
const char *Sensor::getSensorName(SensorType type)
{
if (sensors[type] == nullptr)
{
const char *name = nullptr;
getConstant(type, name);
throw love::Exception("\"%s\" sensor is not enabled", name);
}
return SDL_SensorGetName(sensors[type]);
}
Sensor::SensorType Sensor::convert(SDL_SensorType type)
{
switch (type)
{
case SDL_SENSOR_ACCEL:
return SENSOR_ACCELEROMETER;
case SDL_SENSOR_GYRO:
return SENSOR_GYROSCOPE;
default:
return SENSOR_MAX_ENUM;
}
}
SDL_SensorType Sensor::convert(Sensor::SensorType type)
{
switch (type)
{
case SENSOR_ACCELEROMETER:
return SDL_SENSOR_ACCEL;
case SENSOR_GYROSCOPE:
return SDL_SENSOR_GYRO;
default:
return SDL_SENSOR_UNKNOWN;
}
}
}
}
}
+68
View File
@@ -0,0 +1,68 @@
/**
* Copyright (c) 2006-2022 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.
**/
#ifndef LOVE_SENSOR_SDL_SENSOR_H
#define LOVE_SENSOR_SDL_SENSOR_H
// LOVE
#include "sensor/Sensor.h"
// SDL
#include <SDL_sensor.h>
// std
#include <map>
namespace love
{
namespace sensor
{
namespace sdl
{
class Sensor : public love::sensor::Sensor
{
public:
Sensor();
~Sensor() override;
// Implements Module.
const char *getName() const override;
bool hasSensor(SensorType type) override;
bool isEnabled(SensorType type) override;
void setEnabled(SensorType type, bool enable) override;
std::vector<float> getData(SensorType type) override;
std::vector<void*> getHandles() override;
const char *getSensorName(SensorType type) override;
static SensorType convert(SDL_SensorType type);
static SDL_SensorType convert(SensorType type);
private:
std::map<SensorType, SDL_Sensor*> sensors;
}; // Sensor
} // sdl
} // sensor
} // love
#endif
+120
View File
@@ -0,0 +1,120 @@
/**
* Copyright (c) 2006-2022 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.
**/
// LOVE
#include "wrap_Sensor.h"
#include "sdl/Sensor.h"
namespace love
{
namespace sensor
{
#define instance() (Module::getInstance<Sensor>(Module::M_SENSOR))
inline Sensor::SensorType luax_checksensortype(lua_State *L, int i)
{
const char *sensorType = luaL_checkstring(L, i);
Sensor::SensorType type = Sensor::SENSOR_MAX_ENUM;
if (!Sensor::getConstant(sensorType, type))
luax_enumerror(L, "sensor mode", Sensor::getConstants(type), sensorType);
return type;
}
static int w_hasSensor(lua_State *L)
{
Sensor::SensorType type = luax_checksensortype(L, 1);
lua_pushboolean(L, instance()->hasSensor(type));
return 1;
}
static int w_isEnabled(lua_State *L)
{
Sensor::SensorType type = luax_checksensortype(L, 1);
lua_pushboolean(L, instance()->isEnabled(type));
return 1;
}
static int w_setEnabled(lua_State *L)
{
Sensor::SensorType type = luax_checksensortype(L, 1);
bool enabled = luax_checkboolean(L, 2);
luax_catchexcept(L, [&](){ instance()->setEnabled(type, enabled); });
return 0;
}
static int w_getData(lua_State *L)
{
Sensor::SensorType type = luax_checksensortype(L, 1);
std::vector<float> data;
luax_catchexcept(L, [&](){ data = instance()->getData(type); });
for (float f: data)
lua_pushnumber(L, f);
return (int) data.size();
}
static int w_getName(lua_State *L)
{
Sensor::SensorType type = luax_checksensortype(L, 1);
const char *name = nullptr;
luax_catchexcept(L, [&](){ name = instance()->getSensorName(type); });
lua_pushstring(L, name);
return 1;
}
static const luaL_Reg functions[] =
{
{ "hasSensor", w_hasSensor },
{ "isEnabled", w_isEnabled },
{ "setEnabled", w_setEnabled },
{ "getData", w_getData },
{ "getName", w_getName },
{ nullptr, nullptr }
};
extern "C" int luaopen_love_sensor(lua_State * L)
{
Sensor *instance = instance();
if (instance == nullptr)
luax_catchexcept(L, [&]() { instance = new love::sensor::sdl::Sensor(); });
else
instance->retain();
WrappedModule w;
w.module = instance;
w.name = "sensor";
w.type = &Module::type;
w.functions = functions;
w.types = nullptr;
return luax_register_module(L, w);
}
} // sensor
} // love
+37
View File
@@ -0,0 +1,37 @@
/**
* Copyright (c) 2006-2022 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.
**/
#ifndef LOVE_WRAP_SENSOR_H
#define LOVE_WRAP_SENSOR_H
// LOVE
#include "common/runtime.h"
namespace love
{
namespace sensor
{
extern "C" LOVE_EXPORT int luaopen_love_sensor(lua_State *L);
} // sensor
} // love
#endif
+20 -33
View File
@@ -46,6 +46,10 @@
// SDL
#include <SDL_syswm.h>
#ifdef LOVE_GRAPHICS_VULKAN
#include <SDL_vulkan.h>
#endif
#if defined(LOVE_WINDOWS)
#include <windows.h>
#include <dwmapi.h>
@@ -91,7 +95,6 @@ Window::Window()
, metalView(nullptr)
#endif
, displayedWindowError(false)
, hasSDL203orEarlier(false)
, contextAttribs()
{
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
@@ -99,10 +102,6 @@ Window::Window()
// Make sure the screensaver doesn't activate by default.
setDisplaySleepEnabled(false);
SDL_version version = {};
SDL_GetVersion(&version);
hasSDL203orEarlier = (version.major == 2 && version.minor == 0 && version.patch <= 3);
}
Window::~Window()
@@ -140,16 +139,6 @@ void Window::setGLFramebufferAttributes(bool sRGB)
SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, sRGB ? 1 : 0);
const char *driver = SDL_GetCurrentVideoDriver();
if (driver && strstr(driver, "x11") == driver)
{
// Always disable the sRGB flag when GLX is used with older SDL versions,
// because of this bug: https://bugzilla.libsdl.org/show_bug.cgi?id=2897
// In practice GLX will always give an sRGB-capable framebuffer anyway.
if (hasSDL203orEarlier)
SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 0);
}
#if defined(LOVE_WINDOWS)
// Avoid the Microsoft OpenGL 1.1 software renderer on Windows. Apparently
// older Intel drivers like to use it as a fallback when requesting some
@@ -250,14 +239,6 @@ std::vector<Window::ContextAttribs> Window::getContextAttribsList() const
if (curdriver && strstr(curdriver, glesdriver) == curdriver)
{
preferGLES = true;
// Prior to SDL 2.0.4, backends that use OpenGL ES didn't properly
// ask for a sRGB framebuffer when requested by SDL_GL_SetAttribute.
// This doesn't account for windowing backends that sometimes use
// EGL, e.g. the X11 and windows SDL backends.
if (hasSDL203orEarlier)
graphics::setGammaCorrect(false);
break;
}
}
@@ -588,12 +569,8 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
if (!f.fullscreen)
SDL_SetWindowSize(window, width, height);
// On linux systems 2.0.5+ might not be available...
// TODO: require at least 2.0.5?
#if SDL_VERSION_ATLEAST(2, 0, 5)
if (this->settings.resizable != f.resizable)
SDL_SetWindowResizable(window, f.resizable ? SDL_TRUE : SDL_FALSE);
#endif
if (this->settings.borderless != f.borderless)
SDL_SetWindowBordered(window, f.borderless ? SDL_FALSE : SDL_TRUE);
@@ -688,11 +665,16 @@ bool Window::onSizeChanged(int width, int height)
windowWidth = width;
windowHeight = height;
// TODO: Use SDL_GetWindowSizeInPixels here when supported.
if (glcontext != nullptr)
SDL_GL_GetDrawableSize(window, &pixelWidth, &pixelHeight);
#ifdef LOVE_GRAPHICS_METAL
else if (metalView != nullptr)
SDL_Metal_GetDrawableSize(window, &pixelWidth, &pixelHeight);
#endif
#ifdef LOVE_GRAPHICS_VULKAN
else if (windowRenderer == graphics::RENDERER_VULKAN)
SDL_Vulkan_GetDrawableSize(window, &pixelWidth, &pixelHeight);
#endif
else
{
@@ -720,12 +702,17 @@ void Window::updateSettings(const WindowSettings &newsettings, bool updateGraphi
pixelWidth = windowWidth;
pixelHeight = windowHeight;
// TODO: Use SDL_GetWindowSizeInPixels here when supported.
if ((wflags & SDL_WINDOW_OPENGL) != 0)
SDL_GL_GetDrawableSize(window, &pixelWidth, &pixelHeight);
#ifdef LOVE_GRAPHICS_METAL
else if ((wflags & SDL_WINDOW_METAL) != 0)
SDL_Metal_GetDrawableSize(window, &pixelWidth, &pixelHeight);
#endif
#ifdef LOVE_GRAPHICS_VULKAN
else if ((wflags & SDL_WINDOW_VULKAN) != 0)
SDL_Vulkan_GetDrawableSize(window, &pixelWidth, &pixelHeight);
#endif
if ((wflags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)
{
@@ -909,9 +896,6 @@ const char *Window::getDisplayName(int displayindex) const
Window::DisplayOrientation Window::getDisplayOrientation(int displayindex) const
{
// TODO: We can expose this everywhere, we just need to watch out for the
// SDL binary being older than the headers on Linux.
#if SDL_VERSION_ATLEAST(2, 0, 9) && (defined(LOVE_ANDROID) || !defined(LOVE_LINUX))
switch (SDL_GetDisplayOrientation(displayindex))
{
case SDL_ORIENTATION_UNKNOWN: return ORIENTATION_UNKNOWN;
@@ -920,9 +904,6 @@ Window::DisplayOrientation Window::getDisplayOrientation(int displayindex) const
case SDL_ORIENTATION_PORTRAIT: return ORIENTATION_PORTRAIT;
case SDL_ORIENTATION_PORTRAIT_FLIPPED: return ORIENTATION_PORTRAIT_FLIPPED;
}
#else
LOVE_UNUSED(displayindex);
#endif
return ORIENTATION_UNKNOWN;
}
@@ -1119,6 +1100,7 @@ void Window::setVSync(int vsync)
}
#ifdef LOVE_GRAPHICS_VULKAN
// TODO: this doesn't update the swap-chain, but it should.
love::graphics::vulkan::Vulkan::setVsync(vsync);
#endif
@@ -1148,6 +1130,11 @@ int Window::getVSync() const
}
#endif
#ifdef LOVE_GRAPHICS_VULKAN
if (windowRenderer == love::graphics::RENDERER_VULKAN)
return love::graphics::vulkan::Vulkan::getVsync();
#endif
return 0;
}
-1
View File
@@ -175,7 +175,6 @@ private:
graphics::Renderer windowRenderer = graphics::RENDERER_NONE;
bool displayedWindowError;
bool hasSDL203orEarlier;
ContextAttribs contextAttribs;
StrongRef<graphics::Graphics> graphics;