mirror of
https://github.com/love2d/love-android.git
synced 2026-08-18 19:54:18 +02:00
updated from latest love-android (228a26ab99bb)
This commit is contained in:
@@ -98,11 +98,7 @@ bool Pool::isPlaying(Source *s)
|
||||
bool p = false;
|
||||
{
|
||||
thread::Lock lock(mutex);
|
||||
for (auto i = playing.begin(); i != playing.end(); i++)
|
||||
{
|
||||
if (i->first == s)
|
||||
p = true;
|
||||
}
|
||||
p = (playing.find(s) != playing.end());
|
||||
}
|
||||
return p;
|
||||
}
|
||||
@@ -181,11 +177,11 @@ bool Pool::play(Source *source, ALuint &out)
|
||||
void Pool::stop()
|
||||
{
|
||||
thread::Lock lock(mutex);
|
||||
for (auto i = playing.begin(); i != playing.end(); i++)
|
||||
for (const auto &i : playing)
|
||||
{
|
||||
i->first->stopAtomic();
|
||||
i->first->release();
|
||||
available.push(i->second);
|
||||
i.first->stopAtomic();
|
||||
i.first->release();
|
||||
available.push(i.second);
|
||||
}
|
||||
|
||||
playing.clear();
|
||||
@@ -200,8 +196,8 @@ void Pool::stop(Source *source)
|
||||
void Pool::pause()
|
||||
{
|
||||
thread::Lock lock(mutex);
|
||||
for (auto i = playing.begin(); i != playing.end(); i++)
|
||||
i->first->pauseAtomic();
|
||||
for (const auto &i : playing)
|
||||
i.first->pauseAtomic();
|
||||
}
|
||||
|
||||
void Pool::pause(Source *source)
|
||||
@@ -215,8 +211,8 @@ void Pool::pause(Source *source)
|
||||
void Pool::resume()
|
||||
{
|
||||
thread::Lock lock(mutex);
|
||||
for (auto i = playing.begin(); i != playing.end(); i++)
|
||||
i->first->resumeAtomic();
|
||||
for (const auto &i : playing)
|
||||
i.first->resumeAtomic();
|
||||
}
|
||||
|
||||
void Pool::resume(Source *source)
|
||||
@@ -230,8 +226,8 @@ void Pool::resume(Source *source)
|
||||
void Pool::rewind()
|
||||
{
|
||||
thread::Lock lock(mutex);
|
||||
for (auto i = playing.begin(); i != playing.end(); i++)
|
||||
i->first->rewindAtomic();
|
||||
for (const auto &i : playing)
|
||||
i.first->rewindAtomic();
|
||||
}
|
||||
|
||||
// For those times we don't need it backed.
|
||||
|
||||
@@ -62,6 +62,7 @@ Source::Source(Pool *pool, love::sound::SoundData *soundData)
|
||||
, cone()
|
||||
, offsetSamples(0)
|
||||
, offsetSeconds(0)
|
||||
, sampleRate(soundData->getSampleRate())
|
||||
, channels(soundData->getChannels())
|
||||
, decoder(nullptr)
|
||||
, toLoop(0)
|
||||
@@ -94,6 +95,7 @@ Source::Source(Pool *pool, love::sound::Decoder *decoder)
|
||||
, cone()
|
||||
, offsetSamples(0)
|
||||
, offsetSeconds(0)
|
||||
, sampleRate(decoder->getSampleRate())
|
||||
, channels(decoder->getChannels())
|
||||
, decoder(decoder)
|
||||
, toLoop(0)
|
||||
@@ -125,6 +127,7 @@ Source::Source(const Source &s)
|
||||
, cone(s.cone)
|
||||
, offsetSamples(0)
|
||||
, offsetSeconds(0)
|
||||
, sampleRate(s.sampleRate)
|
||||
, channels(s.channels)
|
||||
, decoder(nullptr)
|
||||
, toLoop(0)
|
||||
@@ -383,7 +386,7 @@ float Source::tellAtomic(void *unit) const
|
||||
default:
|
||||
{
|
||||
alGetSourcef(source, AL_SAMPLE_OFFSET, &offset);
|
||||
offset /= decoder->getSampleRate();
|
||||
offset /= sampleRate;
|
||||
if (type == TYPE_STREAM) offset += offsetSeconds;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -180,6 +180,7 @@ private:
|
||||
float offsetSamples;
|
||||
float offsetSeconds;
|
||||
|
||||
int sampleRate;
|
||||
int channels;
|
||||
|
||||
Object::StrongRef<love::sound::Decoder> decoder;
|
||||
|
||||
@@ -119,6 +119,16 @@ bool Graphics::getConstant(StackType in, const char *&out)
|
||||
return stackTypes.find(in, out);
|
||||
}
|
||||
|
||||
bool Graphics::getConstant(const char *in, StatType &out)
|
||||
{
|
||||
return statTypes.find(in, out);
|
||||
}
|
||||
|
||||
bool Graphics::getConstant(StatType in, const char *&out)
|
||||
{
|
||||
return statTypes.find(in, out);
|
||||
}
|
||||
|
||||
StringMap<Graphics::DrawMode, Graphics::DRAW_MAX_ENUM>::Entry Graphics::drawModeEntries[] =
|
||||
{
|
||||
{ "line", Graphics::DRAW_LINE },
|
||||
@@ -212,5 +222,17 @@ StringMap<Graphics::StackType, Graphics::STACK_MAX_ENUM>::Entry Graphics::stackT
|
||||
|
||||
StringMap<Graphics::StackType, Graphics::STACK_MAX_ENUM> Graphics::stackTypes(Graphics::stackTypeEntries, sizeof(Graphics::stackTypeEntries));
|
||||
|
||||
StringMap<Graphics::StatType, Graphics::STAT_MAX_ENUM>::Entry Graphics::statTypeEntries[] =
|
||||
{
|
||||
{"drawcalls", Graphics::STAT_DRAW_CALLS},
|
||||
{"canvasswitches", Graphics::STAT_CANVAS_SWITCHES},
|
||||
{"canvases", Graphics::STAT_CANVASES},
|
||||
{"images", Graphics::STAT_IMAGES},
|
||||
{"fonts", Graphics::STAT_FONTS},
|
||||
{"texturememory", Graphics::STAT_TEXTURE_MEMORY},
|
||||
};
|
||||
|
||||
StringMap<Graphics::StatType, Graphics::STAT_MAX_ENUM> Graphics::statTypes(Graphics::statTypeEntries, sizeof(Graphics::statTypeEntries));
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
@@ -128,6 +128,17 @@ public:
|
||||
STACK_MAX_ENUM
|
||||
};
|
||||
|
||||
enum StatType
|
||||
{
|
||||
STAT_DRAW_CALLS,
|
||||
STAT_CANVAS_SWITCHES,
|
||||
STAT_CANVASES,
|
||||
STAT_IMAGES,
|
||||
STAT_FONTS,
|
||||
STAT_TEXTURE_MEMORY,
|
||||
STAT_MAX_ENUM
|
||||
};
|
||||
|
||||
struct RendererInfo
|
||||
{
|
||||
std::string name;
|
||||
@@ -136,6 +147,16 @@ public:
|
||||
std::string device;
|
||||
};
|
||||
|
||||
struct Stats
|
||||
{
|
||||
int drawCalls;
|
||||
int canvasSwitches;
|
||||
int canvases;
|
||||
int images;
|
||||
int fonts;
|
||||
size_t textureMemory;
|
||||
};
|
||||
|
||||
virtual ~Graphics();
|
||||
|
||||
// Implements Module.
|
||||
@@ -200,6 +221,9 @@ public:
|
||||
static bool getConstant(const char *in, StackType &out);
|
||||
static bool getConstant(StackType in, const char *&out);
|
||||
|
||||
static bool getConstant(const char *in, StatType &out);
|
||||
static bool getConstant(StatType in, const char *&out);
|
||||
|
||||
private:
|
||||
|
||||
static StringMap<DrawMode, DRAW_MAX_ENUM>::Entry drawModeEntries[];
|
||||
@@ -229,6 +253,9 @@ private:
|
||||
static StringMap<StackType, STACK_MAX_ENUM>::Entry stackTypeEntries[];
|
||||
static StringMap<StackType, STACK_MAX_ENUM> stackTypes;
|
||||
|
||||
static StringMap<StatType, STAT_MAX_ENUM>::Entry statTypeEntries[];
|
||||
static StringMap<StatType, STAT_MAX_ENUM> statTypes;
|
||||
|
||||
}; // Graphics
|
||||
|
||||
} // graphics
|
||||
|
||||
@@ -43,26 +43,17 @@ Volatile::~Volatile()
|
||||
bool Volatile::loadAll()
|
||||
{
|
||||
bool success = true;
|
||||
std::list<Volatile *>::iterator i = all.begin();
|
||||
|
||||
while (i != all.end())
|
||||
{
|
||||
success = success && (*i)->loadVolatile();
|
||||
i++;
|
||||
}
|
||||
for (Volatile *v : all)
|
||||
success = success && v->loadVolatile();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void Volatile::unloadAll()
|
||||
{
|
||||
std::list<Volatile *>::iterator i = all.begin();
|
||||
|
||||
while (i != all.end())
|
||||
{
|
||||
(*i)->unloadVolatile();
|
||||
i++;
|
||||
}
|
||||
for (Volatile *v : all)
|
||||
v->unloadVolatile();
|
||||
}
|
||||
|
||||
} // graphics
|
||||
|
||||
@@ -185,6 +185,7 @@ struct FramebufferStrategyCore : public FramebufferStrategy
|
||||
virtual void bindFBO(GLuint framebuffer)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
++Canvas::switchCount;
|
||||
}
|
||||
|
||||
virtual void setAttachments()
|
||||
@@ -338,6 +339,7 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy
|
||||
virtual void bindFBO(GLuint framebuffer)
|
||||
{
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
|
||||
++Canvas::switchCount;
|
||||
}
|
||||
|
||||
virtual void setAttachments()
|
||||
@@ -433,6 +435,8 @@ FramebufferStrategyEXT strategyEXT;
|
||||
Canvas *Canvas::current = nullptr;
|
||||
OpenGL::Viewport Canvas::systemViewport = OpenGL::Viewport();
|
||||
bool Canvas::screenHasSRGB = false;
|
||||
int Canvas::switchCount = 0;
|
||||
int Canvas::canvasCount = 0;
|
||||
|
||||
static void getStrategy()
|
||||
{
|
||||
@@ -460,6 +464,7 @@ Canvas::Canvas(int width, int height, Format format, int msaa)
|
||||
, format(format)
|
||||
, msaa_samples(msaa)
|
||||
, msaa_dirty(false)
|
||||
, texture_memory(0)
|
||||
{
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
@@ -490,10 +495,14 @@ Canvas::Canvas(int width, int height, Format format, int msaa)
|
||||
getStrategy();
|
||||
|
||||
loadVolatile();
|
||||
|
||||
++canvasCount;
|
||||
}
|
||||
|
||||
Canvas::~Canvas()
|
||||
{
|
||||
--canvasCount;
|
||||
|
||||
// reset framebuffer if still using this one
|
||||
if (current == this)
|
||||
stopGrab();
|
||||
@@ -616,6 +625,14 @@ bool Canvas::loadVolatile()
|
||||
|
||||
msaa_dirty = (msaa_buffer != 0);
|
||||
|
||||
size_t prevmemsize = texture_memory;
|
||||
|
||||
texture_memory = (getFormatBitsPerPixel(format) * width * height) / 8;
|
||||
if (msaa_buffer != 0)
|
||||
texture_memory += (texture_memory * msaa_samples);
|
||||
|
||||
gl.updateTextureMemorySize(prevmemsize, texture_memory);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -630,6 +647,9 @@ void Canvas::unloadVolatile()
|
||||
resolve_fbo = msaa_buffer = 0;
|
||||
|
||||
attachedCanvases.clear();
|
||||
|
||||
gl.updateTextureMemorySize(texture_memory, 0);
|
||||
texture_memory = 0;
|
||||
}
|
||||
|
||||
void Canvas::drawv(const Matrix &t, const Vertex *v)
|
||||
@@ -647,7 +667,7 @@ void Canvas::drawv(const Matrix &t, const Vertex *v)
|
||||
gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, sizeof(Vertex), (GLvoid *) &v[0].x);
|
||||
gl.setVertexAttribArray(OpenGL::ATTRIB_TEXCOORD, 2, GL_FLOAT, sizeof(Vertex), (GLvoid *) &v[0].s);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
gl.drawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
|
||||
gl.disableVertexAttribArray(OpenGL::ATTRIB_TEXCOORD);
|
||||
@@ -1088,6 +1108,27 @@ void Canvas::convertFormat(Canvas::Format format, GLenum &internalformat, GLenum
|
||||
}
|
||||
}
|
||||
|
||||
size_t Canvas::getFormatBitsPerPixel(Format format)
|
||||
{
|
||||
switch (getSizedFormat(format))
|
||||
{
|
||||
case FORMAT_RGBA8:
|
||||
case FORMAT_RGB10A2:
|
||||
case FORMAT_RG11B10F:
|
||||
case FORMAT_SRGB:
|
||||
default:
|
||||
return 32;
|
||||
case FORMAT_RGBA4:
|
||||
case FORMAT_RGB5A1:
|
||||
case FORMAT_RGB565:
|
||||
return 16;
|
||||
case FORMAT_RGBA16F:
|
||||
return 64;
|
||||
case FORMAT_RGBA32F:
|
||||
return 128;
|
||||
}
|
||||
}
|
||||
|
||||
bool Canvas::isSupported()
|
||||
{
|
||||
getStrategy();
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "image/ImageData.h"
|
||||
#include "common/Matrix.h"
|
||||
#include "common/StringMap.h"
|
||||
#include "common/int.h"
|
||||
#include "Texture.h"
|
||||
#include "OpenGL.h"
|
||||
|
||||
@@ -127,6 +128,9 @@ public:
|
||||
// Whether the main screen should have linear -> sRGB conversions enabled.
|
||||
static bool screenHasSRGB;
|
||||
|
||||
static int switchCount;
|
||||
static int canvasCount;
|
||||
|
||||
static bool getConstant(const char *in, Format &out);
|
||||
static bool getConstant(Format in, const char *&out);
|
||||
|
||||
@@ -136,6 +140,7 @@ private:
|
||||
|
||||
static Format getSizedFormat(Format format);
|
||||
static void convertFormat(Format format, GLenum &internalformat, GLenum &externalformat, GLenum &type);
|
||||
static size_t getFormatBitsPerPixel(Format format);
|
||||
|
||||
GLuint fbo;
|
||||
GLuint resolve_fbo;
|
||||
@@ -153,6 +158,8 @@ private:
|
||||
int msaa_samples;
|
||||
bool msaa_dirty;
|
||||
|
||||
size_t texture_memory;
|
||||
|
||||
void setupGrab();
|
||||
void drawv(const Matrix &t, const Vertex *v);
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ namespace graphics
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
int Font::fontCount = 0;
|
||||
|
||||
const int Font::TEXTURE_WIDTHS[] = {128, 256, 256, 512, 512, 1024, 1024};
|
||||
const int Font::TEXTURE_HEIGHTS[] = {128, 128, 256, 256, 512, 512, 1024};
|
||||
|
||||
@@ -48,6 +50,7 @@ Font::Font(love::font::Rasterizer *r, const Texture::Filter &filter)
|
||||
, mSpacing(1)
|
||||
, filter(filter)
|
||||
, useSpacesAsTab(false)
|
||||
, textureMemorySize(0)
|
||||
{
|
||||
this->filter.mipmap = Texture::FILTER_NONE;
|
||||
|
||||
@@ -90,12 +93,16 @@ Font::Font(love::font::Rasterizer *r, const Texture::Filter &filter)
|
||||
}
|
||||
|
||||
delete gd;
|
||||
|
||||
++fontCount;
|
||||
}
|
||||
|
||||
Font::~Font()
|
||||
{
|
||||
delete indexBuffer;
|
||||
unloadVolatile();
|
||||
|
||||
--fontCount;
|
||||
}
|
||||
|
||||
bool Font::initializeTexture(GLenum format)
|
||||
@@ -173,6 +180,11 @@ void Font::createTexture()
|
||||
&emptyData[0]);
|
||||
|
||||
setFilter(filter);
|
||||
|
||||
size_t prevmemsize = textureMemorySize;
|
||||
|
||||
textureMemorySize += emptyData.size();
|
||||
gl.updateTextureMemorySize(prevmemsize, textureMemorySize);
|
||||
}
|
||||
|
||||
Font::Glyph *Font::addGlyph(uint32 glyph)
|
||||
@@ -414,14 +426,14 @@ void Font::print(const std::string &text, float x, float y, float extra_spacing,
|
||||
{
|
||||
// Optimization: setting a base vertex is faster than redoing the
|
||||
// setVertexAttribArray calls before each draw.
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, (it->vertexcount / 4) * 6, elemtype, elemoffset, it->startvertex);
|
||||
gl.drawElementsBaseVertex(GL_TRIANGLES, (it->vertexcount / 4) * 6, elemtype, elemoffset, it->startvertex);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, sizeof(GlyphVertex), &glyphverts[it->startvertex].x);
|
||||
gl.setVertexAttribArray(OpenGL::ATTRIB_TEXCOORD, 2, GL_FLOAT, sizeof(GlyphVertex), &glyphverts[it->startvertex].s);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, (it->vertexcount / 4) * 6, elemtype, elemoffset);
|
||||
gl.drawElements(GL_TRIANGLES, (it->vertexcount / 4) * 6, elemtype, elemoffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,6 +610,9 @@ void Font::unloadVolatile()
|
||||
iter++;
|
||||
}
|
||||
textures.clear();
|
||||
|
||||
gl.updateTextureMemorySize(textureMemorySize, 0);
|
||||
textureMemorySize = 0;
|
||||
}
|
||||
|
||||
int Font::getAscent() const
|
||||
|
||||
@@ -139,6 +139,8 @@ public:
|
||||
bool hasGlyph(uint32 glyph) const;
|
||||
bool hasGlyphs(const std::string &text) const;
|
||||
|
||||
static int fontCount;
|
||||
|
||||
private:
|
||||
|
||||
enum FontType
|
||||
@@ -210,6 +212,8 @@ private:
|
||||
|
||||
bool useSpacesAsTab;
|
||||
|
||||
size_t textureMemorySize;
|
||||
|
||||
static const int NUM_TEXTURE_SIZES = 7;
|
||||
static const int TEXTURE_WIDTHS[NUM_TEXTURE_SIZES];
|
||||
static const int TEXTURE_HEIGHTS[NUM_TEXTURE_SIZES];
|
||||
|
||||
@@ -442,6 +442,10 @@ void Graphics::present()
|
||||
|
||||
// Restore the currently active canvas, if there is one.
|
||||
setCanvas(canvases);
|
||||
|
||||
// Reset the per-frame stat counts.
|
||||
gl.stats.drawCalls = 0;
|
||||
Canvas::switchCount = 0;
|
||||
}
|
||||
|
||||
int Graphics::getWidth() const
|
||||
@@ -1049,7 +1053,7 @@ void Graphics::point(float x, float y)
|
||||
gl.enableVertexAttribArray(OpenGL::ATTRIB_POS);
|
||||
gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, 0, coord);
|
||||
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
gl.drawArrays(GL_POINTS, 0, 1);
|
||||
|
||||
gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
|
||||
}
|
||||
@@ -1170,7 +1174,7 @@ void Graphics::arc(DrawMode mode, float x, float y, float radius, float angle1,
|
||||
gl.enableVertexAttribArray(OpenGL::ATTRIB_POS);
|
||||
gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, 0, (GLvoid *) coords);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, points + 2);
|
||||
gl.drawArrays(GL_TRIANGLE_FAN, 0, points + 2);
|
||||
|
||||
gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
|
||||
}
|
||||
@@ -1198,7 +1202,7 @@ void Graphics::polygon(DrawMode mode, const float *coords, size_t count)
|
||||
gl.enableVertexAttribArray(OpenGL::ATTRIB_POS);
|
||||
gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, 0, (GLvoid *) coords);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, count / 2);
|
||||
gl.drawArrays(GL_TRIANGLE_FAN, 0, count / 2);
|
||||
|
||||
gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
|
||||
}
|
||||
@@ -1302,6 +1306,20 @@ Graphics::RendererInfo Graphics::getRendererInfo() const
|
||||
return info;
|
||||
}
|
||||
|
||||
Graphics::Stats Graphics::getStats() const
|
||||
{
|
||||
Stats stats;
|
||||
|
||||
stats.drawCalls = gl.stats.drawCalls;
|
||||
stats.canvasSwitches = Canvas::switchCount;
|
||||
stats.canvases = Canvas::canvasCount;
|
||||
stats.images = Image::imageCount;
|
||||
stats.fonts = Font::fontCount;
|
||||
stats.textureMemory = gl.stats.textureMemory;
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
double Graphics::getSystemLimit(SystemLimit limittype) const
|
||||
{
|
||||
double limit = 0.0;
|
||||
|
||||
@@ -415,11 +415,16 @@ public:
|
||||
|
||||
/**
|
||||
* Returns system-dependent renderer information.
|
||||
* Returned string s can vary greatly between systems! Do not rely on it for
|
||||
* Returned strings can vary greatly between systems! Do not rely on it for
|
||||
* anything!
|
||||
**/
|
||||
RendererInfo getRendererInfo() const;
|
||||
|
||||
/**
|
||||
* Returns performance-related statistics.
|
||||
**/
|
||||
Stats getStats() const;
|
||||
|
||||
/**
|
||||
* Gets the system-dependent numeric limit for the specified parameter.
|
||||
**/
|
||||
|
||||
@@ -31,6 +31,8 @@ namespace graphics
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
int Image::imageCount = 0;
|
||||
|
||||
float Image::maxMipmapSharpness = 0.0f;
|
||||
|
||||
Texture::FilterMode Image::defaultMipmapFilter = Texture::FILTER_NONE;
|
||||
@@ -47,10 +49,13 @@ Image::Image(love::image::ImageData *data, Format format)
|
||||
, compressed(false)
|
||||
, format(format)
|
||||
, usingDefaultTexture(false)
|
||||
, textureMemorySize(0)
|
||||
{
|
||||
width = data->getWidth();
|
||||
height = data->getHeight();
|
||||
preload();
|
||||
|
||||
++imageCount;
|
||||
}
|
||||
|
||||
Image::Image(love::image::CompressedData *cdata, Format format)
|
||||
@@ -64,15 +69,20 @@ Image::Image(love::image::CompressedData *cdata, Format format)
|
||||
, compressed(true)
|
||||
, format(format)
|
||||
, usingDefaultTexture(false)
|
||||
, textureMemorySize(0)
|
||||
{
|
||||
width = cdata->getWidth(0);
|
||||
height = cdata->getHeight(0);
|
||||
preload();
|
||||
|
||||
++imageCount;
|
||||
}
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
unload();
|
||||
|
||||
--imageCount;
|
||||
}
|
||||
|
||||
love::image::ImageData *Image::getImageData() const
|
||||
@@ -155,8 +165,11 @@ void Image::uploadCompressedMipmaps()
|
||||
"compressed image does not have all required levels.");
|
||||
}
|
||||
|
||||
size_t totalsize = cdata->getSize(0);
|
||||
|
||||
for (int i = 1; i < count; i++)
|
||||
{
|
||||
totalsize += cdata->getSize(i);
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D,
|
||||
i,
|
||||
getCompressedFormat(cdata->getFormat()),
|
||||
@@ -166,6 +179,10 @@ void Image::uploadCompressedMipmaps()
|
||||
GLsizei(cdata->getSize(i)),
|
||||
cdata->getData(i));
|
||||
}
|
||||
|
||||
size_t prevmemsize = textureMemorySize;
|
||||
textureMemorySize = totalsize;
|
||||
gl.updateTextureMemorySize(prevmemsize, textureMemorySize);
|
||||
}
|
||||
|
||||
void Image::createMipmaps()
|
||||
@@ -220,6 +237,10 @@ void Image::createMipmaps()
|
||||
data->getData());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
|
||||
}
|
||||
|
||||
size_t prevmemsize = textureMemorySize;
|
||||
textureMemorySize = paddedWidth * paddedHeight * 4 * 1.3333;
|
||||
gl.updateTextureMemorySize(prevmemsize, textureMemorySize);
|
||||
}
|
||||
|
||||
void Image::checkMipmapsCreated()
|
||||
@@ -403,6 +424,13 @@ bool Image::loadVolatile()
|
||||
if (glerr != GL_NO_ERROR)
|
||||
throw love::Exception("Cannot create image (error code 0x%x)", glerr);
|
||||
|
||||
if (isCompressed())
|
||||
textureMemorySize = cdata->getSize(0);
|
||||
else
|
||||
textureMemorySize = paddedWidth * paddedHeight * 4;
|
||||
|
||||
gl.updateTextureMemorySize(0, textureMemorySize);
|
||||
|
||||
usingDefaultTexture = false;
|
||||
mipmapsCreated = false;
|
||||
checkMipmapsCreated();
|
||||
@@ -478,6 +506,9 @@ void Image::unloadVolatile()
|
||||
{
|
||||
gl.deleteTexture(texture);
|
||||
texture = 0;
|
||||
|
||||
gl.updateTextureMemorySize(textureMemorySize, 0);
|
||||
textureMemorySize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -553,7 +584,7 @@ void Image::drawv(const Matrix &t, const Vertex *v)
|
||||
gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].x);
|
||||
gl.setVertexAttribArray(OpenGL::ATTRIB_TEXCOORD, 2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].s);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
gl.drawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
|
||||
gl.disableVertexAttribArray(OpenGL::ATTRIB_TEXCOORD);
|
||||
|
||||
@@ -147,6 +147,8 @@ public:
|
||||
static bool getConstant(const char *in, Format &out);
|
||||
static bool getConstant(Format in, const char *&out);
|
||||
|
||||
static int imageCount;
|
||||
|
||||
private:
|
||||
|
||||
void uploadDefaultTexture();
|
||||
@@ -183,6 +185,8 @@ private:
|
||||
// back to a default texture.
|
||||
bool usingDefaultTexture;
|
||||
|
||||
size_t textureMemorySize;
|
||||
|
||||
void preload();
|
||||
|
||||
void uploadTexturePadded();
|
||||
|
||||
@@ -375,7 +375,7 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
|
||||
GLenum type = element_data_type;
|
||||
const void *indices = ibo->getPointer(min * getGLDataTypeSize(type));
|
||||
|
||||
glDrawElements(mode, max - min + 1, type, indices);
|
||||
gl.drawElements(mode, max - min + 1, type, indices);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -388,7 +388,7 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
|
||||
min = std::min(range_min, max);
|
||||
|
||||
// Normal non-indexed drawing (no custom vertex map.)
|
||||
glDrawArrays(mode, min, max - min + 1);
|
||||
gl.drawArrays(mode, min, max - min + 1);
|
||||
}
|
||||
|
||||
gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
|
||||
|
||||
@@ -41,7 +41,8 @@ namespace opengl
|
||||
{
|
||||
|
||||
OpenGL::OpenGL()
|
||||
: contextInitialized(false)
|
||||
: stats()
|
||||
, contextInitialized(false)
|
||||
, maxAnisotropy(1.0f)
|
||||
, maxTextureSize(0)
|
||||
, maxRenderTargets(0)
|
||||
@@ -360,6 +361,24 @@ void OpenGL::prepareDraw()
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGL::drawArrays(GLenum mode, GLint first, GLsizei count)
|
||||
{
|
||||
glDrawArrays(mode, first, count);
|
||||
++stats.drawCalls;
|
||||
}
|
||||
|
||||
void OpenGL::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
|
||||
{
|
||||
glDrawElements(mode, count, type, indices);
|
||||
++stats.drawCalls;
|
||||
}
|
||||
|
||||
void OpenGL::drawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex)
|
||||
{
|
||||
glDrawElementsBaseVertex(mode, count, type, indices, basevertex);
|
||||
++stats.drawCalls;
|
||||
}
|
||||
|
||||
void OpenGL::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
|
||||
{
|
||||
Shader *shader = Shader::current;
|
||||
@@ -384,6 +403,8 @@ void OpenGL::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsize
|
||||
if (shaderHasID)
|
||||
state.lastPseudoInstanceID = primcount - 1;
|
||||
}
|
||||
|
||||
++stats.drawCalls;
|
||||
}
|
||||
|
||||
void OpenGL::drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount)
|
||||
@@ -410,6 +431,8 @@ void OpenGL::drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, cons
|
||||
if (shaderHasID)
|
||||
state.lastPseudoInstanceID = primcount - 1;
|
||||
}
|
||||
|
||||
++stats.drawCalls;
|
||||
}
|
||||
|
||||
void OpenGL::setColor(const Color &c)
|
||||
@@ -648,11 +671,10 @@ void OpenGL::deleteTexture(GLuint texture)
|
||||
{
|
||||
// glDeleteTextures binds texture 0 to all texture units the deleted texture
|
||||
// was bound to before deletion.
|
||||
std::vector<GLuint>::iterator it;
|
||||
for (it = state.textureUnits.begin(); it != state.textureUnits.end(); ++it)
|
||||
for (GLuint &texid : state.textureUnits)
|
||||
{
|
||||
if (*it == texture)
|
||||
*it = 0;
|
||||
if (texid == texture)
|
||||
texid = 0;
|
||||
}
|
||||
|
||||
glDeleteTextures(1, &texture);
|
||||
@@ -789,40 +811,6 @@ void OpenGL::setTextureWrap(const graphics::Texture::Wrap &w)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gt);
|
||||
}
|
||||
|
||||
Texture::Wrap OpenGL::getTextureWrap()
|
||||
{
|
||||
GLint gs, gt;
|
||||
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, &gs);
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, >);
|
||||
|
||||
Texture::Wrap w;
|
||||
|
||||
switch (gs)
|
||||
{
|
||||
case GL_CLAMP_TO_EDGE:
|
||||
w.s = Texture::WRAP_CLAMP;
|
||||
break;
|
||||
case GL_REPEAT:
|
||||
default:
|
||||
w.s = Texture::WRAP_REPEAT;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (gt)
|
||||
{
|
||||
case GL_CLAMP_TO_EDGE:
|
||||
w.t = Texture::WRAP_CLAMP;
|
||||
break;
|
||||
case GL_REPEAT:
|
||||
default:
|
||||
w.t = Texture::WRAP_REPEAT;
|
||||
break;
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
int OpenGL::getMaxTextureSize() const
|
||||
{
|
||||
return maxTextureSize;
|
||||
@@ -833,6 +821,12 @@ int OpenGL::getMaxRenderTargets() const
|
||||
return maxRenderTargets;
|
||||
}
|
||||
|
||||
void OpenGL::updateTextureMemorySize(size_t oldsize, size_t newsize)
|
||||
{
|
||||
int64 memsize = (int64) stats.textureMemory + ((int64 )newsize - (int64) oldsize);
|
||||
stats.textureMemory = (size_t) std::max(memsize, (int64) 0);
|
||||
}
|
||||
|
||||
OpenGL::Vendor OpenGL::getVendor() const
|
||||
{
|
||||
return vendor;
|
||||
|
||||
@@ -147,6 +147,12 @@ public:
|
||||
OpenGL ≷
|
||||
};
|
||||
|
||||
struct Stats
|
||||
{
|
||||
size_t textureMemory;
|
||||
int drawCalls;
|
||||
} stats;
|
||||
|
||||
OpenGL();
|
||||
virtual ~OpenGL() {}
|
||||
|
||||
@@ -174,13 +180,17 @@ public:
|
||||
void prepareDraw();
|
||||
|
||||
/**
|
||||
* glDrawArraysInstanced with a pseudo-instancing fallback.
|
||||
* glDraw* functions which increment the draw-call counter by themselves.
|
||||
**/
|
||||
void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
|
||||
void drawArrays(GLenum mode, GLint first, GLsizei count);
|
||||
void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
|
||||
void drawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex);
|
||||
|
||||
/**
|
||||
* glDrawElementsInstanced with a pseudo-instancing fallback.
|
||||
* glDrawArraysInstanced and glDrawElementsInstanced with pseudo-instancing
|
||||
* fallbacks. They also increment the draw-call counter (once per call).
|
||||
**/
|
||||
void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
|
||||
void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
|
||||
|
||||
/**
|
||||
@@ -318,11 +328,6 @@ public:
|
||||
**/
|
||||
void setTextureWrap(const graphics::Texture::Wrap &w);
|
||||
|
||||
/**
|
||||
* Returns the texture wrap mode for the currently bound texture.
|
||||
**/
|
||||
graphics::Texture::Wrap getTextureWrap();
|
||||
|
||||
/**
|
||||
* Returns the maximum supported width or height of a texture.
|
||||
**/
|
||||
@@ -333,6 +338,8 @@ public:
|
||||
**/
|
||||
int getMaxRenderTargets() const;
|
||||
|
||||
void updateTextureMemorySize(size_t oldsize, size_t newsize);
|
||||
|
||||
/**
|
||||
* Get the GPU vendor of this OpenGL context.
|
||||
**/
|
||||
|
||||
@@ -890,7 +890,7 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
|
||||
|
||||
{
|
||||
VertexBuffer::Bind ibo_bind(*ibo->getVertexBuffer());
|
||||
glDrawElements(GL_TRIANGLES, ibo->getIndexCount(pCount), ibo->getType(), ibo->getPointer(0));
|
||||
gl.drawElements(GL_TRIANGLES, ibo->getIndexCount(pCount), ibo->getType(), ibo->getPointer(0));
|
||||
}
|
||||
|
||||
gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
|
||||
|
||||
@@ -371,9 +371,9 @@ void Polyline::draw()
|
||||
gl.setVertexAttribArray(OpenGL::ATTRIB_POS, 2, GL_FLOAT, 0, vertices);
|
||||
|
||||
if (use_quad_indices)
|
||||
glDrawElements(draw_mode, (vertex_count / 4) * 6, GL_UNSIGNED_SHORT, indices);
|
||||
gl.drawElements(draw_mode, (vertex_count / 4) * 6, GL_UNSIGNED_SHORT, indices);
|
||||
else
|
||||
glDrawArrays(draw_mode, 0, vertex_count);
|
||||
gl.drawArrays(draw_mode, 0, vertex_count);
|
||||
|
||||
if (overdraw)
|
||||
{
|
||||
@@ -388,9 +388,9 @@ void Polyline::draw()
|
||||
gl.setVertexAttribArray(OpenGL::ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, 0, colors);
|
||||
|
||||
if (use_quad_indices)
|
||||
glDrawElements(draw_mode, (overdraw_vertex_count / 4) * 6, GL_UNSIGNED_SHORT, indices);
|
||||
gl.drawElements(draw_mode, (overdraw_vertex_count / 4) * 6, GL_UNSIGNED_SHORT, indices);
|
||||
else
|
||||
glDrawArrays(draw_mode, 0, overdraw_vertex_count);
|
||||
gl.drawArrays(draw_mode, 0, overdraw_vertex_count);
|
||||
|
||||
gl.disableVertexAttribArray(OpenGL::ATTRIB_COLOR);
|
||||
gl.setColor(c);
|
||||
|
||||
@@ -294,7 +294,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
|
||||
gl.setVertexAttribArray(OpenGL::ATTRIB_TEXCOORD, 2, GL_FLOAT, sizeof(Vertex), array_buf->getPointer(texel_offset));
|
||||
|
||||
gl.prepareDraw();
|
||||
glDrawElements(GL_TRIANGLES, element_buf->getIndexCount(next), element_buf->getType(), element_buf->getPointer(0));
|
||||
gl.drawElements(GL_TRIANGLES, element_buf->getIndexCount(next), element_buf->getType(), element_buf->getPointer(0));
|
||||
|
||||
gl.disableVertexAttribArray(OpenGL::ATTRIB_POS);
|
||||
gl.disableVertexAttribArray(OpenGL::ATTRIB_TEXCOORD);
|
||||
|
||||
@@ -1090,6 +1090,41 @@ int w_getRendererInfo(lua_State *L)
|
||||
return 4;
|
||||
}
|
||||
|
||||
int w_getStats(lua_State *L)
|
||||
{
|
||||
Graphics::Stats stats = instance()->getStats();
|
||||
|
||||
lua_createtable(L, 0, (int) Graphics::STAT_MAX_ENUM);
|
||||
|
||||
const char *sname = nullptr;
|
||||
|
||||
Graphics::getConstant(Graphics::STAT_DRAW_CALLS, sname);
|
||||
lua_pushinteger(L, stats.drawCalls);
|
||||
lua_setfield(L, -2, sname);
|
||||
|
||||
Graphics::getConstant(Graphics::STAT_CANVAS_SWITCHES, sname);
|
||||
lua_pushinteger(L, stats.canvasSwitches);
|
||||
lua_setfield(L, -2, sname);
|
||||
|
||||
Graphics::getConstant(Graphics::STAT_CANVASES, sname);
|
||||
lua_pushinteger(L, stats.canvases);
|
||||
lua_setfield(L, -2, sname);
|
||||
|
||||
Graphics::getConstant(Graphics::STAT_IMAGES, sname);
|
||||
lua_pushinteger(L, stats.images);
|
||||
lua_setfield(L, -2, sname);
|
||||
|
||||
Graphics::getConstant(Graphics::STAT_FONTS, sname);
|
||||
lua_pushinteger(L, stats.fonts);
|
||||
lua_setfield(L, -2, sname);
|
||||
|
||||
Graphics::getConstant(Graphics::STAT_TEXTURE_MEMORY, sname);
|
||||
lua_pushnumber(L, (lua_Number) stats.textureMemory);
|
||||
lua_setfield(L, -2, sname);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_getSystemLimit(lua_State *L)
|
||||
{
|
||||
const char *limitstr = luaL_checkstring(L, 1);
|
||||
@@ -1462,6 +1497,7 @@ static const luaL_Reg functions[] =
|
||||
{ "getCanvasFormats", w_getCanvasFormats },
|
||||
{ "getCompressedImageFormats", w_getCompressedImageFormats },
|
||||
{ "getRendererInfo", w_getRendererInfo },
|
||||
{ "getStats", w_getStats },
|
||||
{ "getSystemLimit", w_getSystemLimit },
|
||||
|
||||
{ "draw", w_draw },
|
||||
|
||||
@@ -98,6 +98,7 @@ int w_isSupported(lua_State *L);
|
||||
int w_getCanvasFormats(lua_State *L);
|
||||
int w_getCompressedImageFormats(lua_State *L);
|
||||
int w_getRendererInfo(lua_State *L);
|
||||
int w_getStats(lua_State *L);
|
||||
int w_getSystemLimit(lua_State *L);
|
||||
int w_draw(lua_State *L);
|
||||
int w_print(lua_State *L);
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
// C++
|
||||
#include <algorithm>
|
||||
|
||||
// C
|
||||
#include <cstdlib>
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace image
|
||||
@@ -46,39 +49,36 @@ static unsigned zlibDecompress(unsigned char **out, size_t *outsize, const unsig
|
||||
{
|
||||
int status = Z_OK;
|
||||
|
||||
uLongf outdataSize = insize;
|
||||
size_t sizeMultiplier = 0;
|
||||
uLongf outdatasize = insize;
|
||||
size_t sizemultiplier = 0;
|
||||
unsigned char *outdata = nullptr;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Enough size to hold the decompressed data, hopefully.
|
||||
outdataSize = insize << (++sizeMultiplier);
|
||||
outdatasize = insize << (++sizemultiplier);
|
||||
|
||||
try
|
||||
{
|
||||
outdata = new unsigned char[outdataSize];
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
// LodePNG uses malloc, realloc, and free.
|
||||
outdata = (unsigned char *) malloc(outdatasize);
|
||||
|
||||
if (!outdata)
|
||||
return 83; // "Memory allocation failed" error code for LodePNG.
|
||||
}
|
||||
|
||||
// Use zlib to decompress the PNG data.
|
||||
status = uncompress(outdata, &outdataSize, in, insize);
|
||||
status = uncompress(outdata, &outdatasize, in, insize);
|
||||
|
||||
// If the out buffer was big enough, break out of the loop.
|
||||
if (status != Z_BUF_ERROR)
|
||||
break;
|
||||
|
||||
// Otherwise delete the out buffer and try again with a larger size...
|
||||
delete[] outdata;
|
||||
free(outdata);
|
||||
outdata = nullptr;
|
||||
}
|
||||
|
||||
if (status != Z_OK)
|
||||
{
|
||||
delete[] outdata;
|
||||
free(outdata);
|
||||
return 10000; // "Unknown error code" for LodePNG.
|
||||
}
|
||||
|
||||
@@ -86,34 +86,30 @@ static unsigned zlibDecompress(unsigned char **out, size_t *outsize, const unsig
|
||||
*out = outdata;
|
||||
|
||||
if (outsize != nullptr)
|
||||
*outsize = outdataSize;
|
||||
*outsize = outdatasize;
|
||||
|
||||
return 0; // Success.
|
||||
}
|
||||
|
||||
// Custom PNG compression function for LodePNG, using zlib.
|
||||
static unsigned zlibCompress(unsigned char **out, size_t *outsize, const unsigned char *in,
|
||||
size_t insize, const LodePNGCompressSettings* /*settings*/)
|
||||
size_t insize, const LodePNGCompressSettings* /*settings*/)
|
||||
{
|
||||
// Get the maximum compressed size of the data.
|
||||
uLongf outdataSize = compressBound(insize);
|
||||
unsigned char *outdata = nullptr;
|
||||
uLongf outdatasize = compressBound(insize);
|
||||
|
||||
try
|
||||
{
|
||||
outdata = new unsigned char[outdataSize];
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
// LodePNG uses malloc, realloc, and free.
|
||||
unsigned char *outdata = (unsigned char *) malloc(outdatasize);
|
||||
|
||||
if (!outdata)
|
||||
return 83; // "Memory allocation failed" error code for LodePNG.
|
||||
}
|
||||
|
||||
// Use zlib to compress the PNG data.
|
||||
int status = compress(outdata, &outdataSize, in, insize);
|
||||
int status = compress(outdata, &outdatasize, in, insize);
|
||||
|
||||
if (status != Z_OK)
|
||||
{
|
||||
delete[] outdata;
|
||||
free(outdata);
|
||||
return 10000; // "Unknown error code" for LodePNG.
|
||||
}
|
||||
|
||||
@@ -121,7 +117,7 @@ static unsigned zlibCompress(unsigned char **out, size_t *outsize, const unsigne
|
||||
*out = outdata;
|
||||
|
||||
if (outsize != nullptr)
|
||||
*outsize = (size_t) outdataSize;
|
||||
*outsize = (size_t) outdatasize;
|
||||
|
||||
return 0; // Success.
|
||||
}
|
||||
|
||||
@@ -21,9 +21,6 @@
|
||||
// LOVE
|
||||
#include "ddsHandler.h"
|
||||
|
||||
// C++
|
||||
#include <algorithm>
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace image
|
||||
@@ -33,12 +30,6 @@ namespace magpie
|
||||
|
||||
bool DDSHandler::canParse(const filesystem::FileData *data)
|
||||
{
|
||||
std::string ext = data->getExtension();
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
||||
|
||||
if (ext.compare("dds") != 0)
|
||||
return false;
|
||||
|
||||
return dds::isCompressedDDS(data->getData(), data->getSize());
|
||||
}
|
||||
|
||||
|
||||
@@ -218,8 +218,8 @@ bool JoystickModule::setGamepadMapping(const std::string &guid, Joystick::Gamepa
|
||||
joyinputstream << "b" << joyinput.button;
|
||||
break;
|
||||
case Joystick::INPUT_TYPE_HAT:
|
||||
if (joyinput.hat.value >= 0 && Joystick::getConstant(joyinput.hat.value, sdlhat))
|
||||
joyinputstream << "h" << joyinput.hat.value << "." << int(sdlhat);
|
||||
if (joyinput.hat.index >= 0 && Joystick::getConstant(joyinput.hat.value, sdlhat))
|
||||
joyinputstream << "h" << joyinput.hat.index << "." << int(sdlhat);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -297,7 +297,7 @@ Joystick::JoystickInput JoystickModule::getGamepadMapping(const std::string &gui
|
||||
if (findpos == std::string::npos)
|
||||
return jinput;
|
||||
|
||||
size_t endpos = mapstr.find_first_of(',', findpos);
|
||||
size_t endpos = mapstr.find_first_of(',', findpos + 1);
|
||||
if (endpos == std::string::npos)
|
||||
{
|
||||
// Assume end-of-string if we can't find the next comma.
|
||||
@@ -364,19 +364,19 @@ Joystick::JoystickInput JoystickModule::JoystickInputFromString(const std::strin
|
||||
{
|
||||
case 'a':
|
||||
jinput.type = Joystick::INPUT_TYPE_AXIS;
|
||||
jinput.axis = atoi(bindvalues.c_str());
|
||||
jinput.axis = (int) strtol(bindvalues.c_str(), nullptr, 10);
|
||||
break;
|
||||
case 'b':
|
||||
jinput.type = Joystick::INPUT_TYPE_BUTTON;
|
||||
jinput.button = atoi(bindvalues.c_str());
|
||||
jinput.button = (int) strtol(bindvalues.c_str(), nullptr, 10);
|
||||
break;
|
||||
case 'h':
|
||||
// Hat string syntax is "index.value".
|
||||
if (bindvalues.length() < 3)
|
||||
break;
|
||||
jinput.type = Joystick::INPUT_TYPE_HAT;
|
||||
jinput.hat.index = atoi(bindvalues.substr(0, 1).c_str());
|
||||
sdlhat = (Uint8) atoi(bindvalues.substr(2, 1).c_str());
|
||||
jinput.hat.index = (int) strtol(bindvalues.substr(0, 1).c_str(), nullptr, 10);
|
||||
sdlhat = (Uint8) strtol(bindvalues.substr(2).c_str(), nullptr, 10);
|
||||
if (!Joystick::getConstant(sdlhat, jinput.hat.value))
|
||||
{
|
||||
// Return an invalid value if we can't find the hat constant.
|
||||
@@ -405,10 +405,14 @@ void JoystickModule::removeBindFromMapString(std::string &mapstr, const std::str
|
||||
if (joybindpos == std::string::npos)
|
||||
return;
|
||||
|
||||
// Find the start of the entire bind.
|
||||
// Find the start of the entire bind by looking for the separator between
|
||||
// the end of one section of the map string and the start of this section.
|
||||
size_t bindstart = mapstr.rfind(',', joybindpos);
|
||||
if (bindstart != std::string::npos && bindstart < mapstr.length() - 1)
|
||||
{
|
||||
// The start of the bind is directly after the separator.
|
||||
bindstart++;
|
||||
|
||||
size_t bindend = mapstr.find(',', bindstart + 1);
|
||||
if (bindend == std::string::npos)
|
||||
bindend = mapstr.length() - 1;
|
||||
|
||||
@@ -51,6 +51,7 @@ WindowSettings::WindowSettings()
|
||||
, display(0)
|
||||
, highdpi(false)
|
||||
, sRGB(false)
|
||||
, refreshrate(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -99,6 +100,7 @@ StringMap<Window::Setting, Window::SETTING_MAX_ENUM>::Entry Window::settingEntri
|
||||
{"display", SETTING_DISPLAY},
|
||||
{"highdpi", SETTING_HIGHDPI},
|
||||
{"srgb", SETTING_SRGB},
|
||||
{"refreshrate", SETTING_REFRESHRATE},
|
||||
};
|
||||
|
||||
StringMap<Window::Setting, Window::SETTING_MAX_ENUM> Window::settings(Window::settingEntries, sizeof(Window::settingEntries));
|
||||
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
SETTING_DISPLAY,
|
||||
SETTING_HIGHDPI,
|
||||
SETTING_SRGB,
|
||||
SETTING_REFRESHRATE,
|
||||
SETTING_MAX_ENUM
|
||||
};
|
||||
|
||||
@@ -200,6 +201,7 @@ struct WindowSettings
|
||||
int display; // = 0
|
||||
bool highdpi; // false
|
||||
bool sRGB; // false
|
||||
double refreshrate; // 0.0
|
||||
|
||||
}; // WindowSettings
|
||||
|
||||
|
||||
@@ -440,6 +440,12 @@ void Window::updateSettings(const WindowSettings &newsettings)
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
||||
|
||||
curMode.settings.sRGB = newsettings.sRGB;
|
||||
|
||||
SDL_DisplayMode dmode = {};
|
||||
SDL_GetCurrentDisplayMode(curMode.settings.display, &dmode);
|
||||
|
||||
// May be 0 if the refresh rate can't be determined.
|
||||
curMode.settings.refreshrate = (double) dmode.refresh_rate;
|
||||
}
|
||||
|
||||
void Window::getWindow(int &width, int &height, WindowSettings &settings)
|
||||
|
||||
@@ -105,17 +105,16 @@ int w_setMode(lua_State *L)
|
||||
settings.minheight = luax_intflag(L, 3, settingName(Window::SETTING_MIN_HEIGHT), 1);
|
||||
settings.borderless = luax_boolflag(L, 3, settingName(Window::SETTING_BORDERLESS), false);
|
||||
settings.centered = luax_boolflag(L, 3, settingName(Window::SETTING_CENTERED), true);
|
||||
settings.display = luax_intflag(L, 3, settingName(Window::SETTING_DISPLAY), 1);
|
||||
settings.display = luax_intflag(L, 3, settingName(Window::SETTING_DISPLAY), 1) - 1;
|
||||
settings.highdpi = luax_boolflag(L, 3, settingName(Window::SETTING_HIGHDPI), false);
|
||||
settings.sRGB = luax_boolflag(L, 3, settingName(Window::SETTING_SRGB), false);
|
||||
|
||||
// We don't explicitly set the refresh rate, it's "read-only".
|
||||
|
||||
// For backward-compatibility. TODO: remove!
|
||||
int fsaa = luax_intflag(L, 3, settingName(Window::SETTING_FSAA), 0);
|
||||
if (fsaa > settings.msaa) settings.msaa = fsaa;
|
||||
|
||||
// Display index is 1-based in Lua and 0-based internally.
|
||||
settings.display--;
|
||||
|
||||
luax_catchexcept(L,
|
||||
[&](){ luax_pushboolean(L, instance()->setWindow(w, h, &settings)); }
|
||||
);
|
||||
@@ -176,6 +175,9 @@ int w_getMode(lua_State *L)
|
||||
luax_pushboolean(L, settings.sRGB);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_SRGB));
|
||||
|
||||
lua_pushnumber(L, settings.refreshrate);
|
||||
lua_setfield(L, -2, settingName(Window::SETTING_REFRESHRATE));
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
@@ -1587,9 +1587,15 @@ function love.errhand(msg)
|
||||
end
|
||||
if love.audio then love.audio.stop() end
|
||||
love.graphics.reset()
|
||||
love.graphics.setBackgroundColor(89, 157, 220)
|
||||
local font = love.graphics.setNewFont(math.floor(14 * love.window.getPixelScale()))
|
||||
|
||||
local sRGB = select(3, love.window.getMode()).srgb
|
||||
if sRGB then
|
||||
love.graphics.setBackgroundColor(love.math.gammaToLinear(89, 157, 220))
|
||||
else
|
||||
love.graphics.setBackgroundColor(89, 157, 220)
|
||||
end
|
||||
|
||||
love.graphics.setColor(255, 255, 255, 255)
|
||||
|
||||
local trace = debug.traceback()
|
||||
|
||||
@@ -5340,14 +5340,25 @@ const unsigned char boot_lua[] =
|
||||
0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
|
||||
0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x72, 0x65, 0x73,
|
||||
0x65, 0x74, 0x28, 0x29, 0x0a,
|
||||
0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74,
|
||||
0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x38, 0x39,
|
||||
0x2c, 0x20, 0x31, 0x35, 0x37, 0x2c, 0x20, 0x32, 0x32, 0x30, 0x29, 0x0a,
|
||||
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65,
|
||||
0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x4e, 0x65, 0x77, 0x46, 0x6f,
|
||||
0x6e, 0x74, 0x28, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x31, 0x34, 0x20, 0x2a,
|
||||
0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x69,
|
||||
0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x29, 0x29, 0x29, 0x0a,
|
||||
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x52, 0x47, 0x42, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x65,
|
||||
0x63, 0x74, 0x28, 0x33, 0x2c, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e,
|
||||
0x67, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x29, 0x2e, 0x73, 0x72, 0x67, 0x62, 0x0a,
|
||||
0x09, 0x69, 0x66, 0x20, 0x73, 0x52, 0x47, 0x42, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
|
||||
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65,
|
||||
0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x6c,
|
||||
0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x54, 0x6f, 0x4c, 0x69,
|
||||
0x6e, 0x65, 0x61, 0x72, 0x28, 0x38, 0x39, 0x2c, 0x20, 0x31, 0x35, 0x37, 0x2c, 0x20, 0x32, 0x32, 0x30, 0x29,
|
||||
0x29, 0x0a,
|
||||
0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a,
|
||||
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65,
|
||||
0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x38,
|
||||
0x39, 0x2c, 0x20, 0x31, 0x35, 0x37, 0x2c, 0x20, 0x32, 0x32, 0x30, 0x29, 0x0a,
|
||||
0x09, 0x65, 0x6e, 0x64, 0x0a,
|
||||
0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74,
|
||||
0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35,
|
||||
0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x29, 0x0a,
|
||||
|
||||
@@ -1299,8 +1299,7 @@ do
|
||||
#define number float
|
||||
#define Image sampler2D
|
||||
#define extern uniform
|
||||
#define Texel texture2D
|
||||
#define love_Canvases gl_FragData]]
|
||||
#define Texel texture2D]]
|
||||
|
||||
GLSLES.SYNTAX = GLSL.SYNTAX
|
||||
|
||||
@@ -1383,12 +1382,14 @@ void main() {
|
||||
#define PIXEL
|
||||
|
||||
#define VaryingTexCoord gl_TexCoord[0]
|
||||
#define VaryingColor gl_Color]],
|
||||
#define VaryingColor gl_Color
|
||||
|
||||
#define love_Canvases gl_FragData]],
|
||||
|
||||
FOOTER = [[
|
||||
void main() {
|
||||
// fix crashing issue in OSX when _tex0_ is unused within effect()
|
||||
float dummy = texture2D(_tex0_, vec2(.5)).r;
|
||||
float dummy = Texel(_tex0_, vec2(.5)).r;
|
||||
|
||||
// See Shader::checkSetScreenParams in Shader.cpp.
|
||||
vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
|
||||
@@ -1399,7 +1400,7 @@ void main() {
|
||||
FOOTER_MULTI_CANVAS = [[
|
||||
void main() {
|
||||
// fix crashing issue in OSX when _tex0_ is unused within effect()
|
||||
float dummy = texture2D(_tex0_, vec2(.5)).r;
|
||||
float dummy = Texel(_tex0_, vec2(.5)).r;
|
||||
|
||||
// See Shader::checkSetScreenParams in Shader.cpp.
|
||||
vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
|
||||
@@ -1415,7 +1416,9 @@ void main() {
|
||||
precision mediump float;
|
||||
|
||||
varying mediump vec4 VaryingTexCoord;
|
||||
varying lowp vec4 VaryingColor;]],
|
||||
varying lowp vec4 VaryingColor;
|
||||
|
||||
#define love_Canvases gl_FragData;]],
|
||||
|
||||
FOOTER = GLSL.PIXEL.FOOTER,
|
||||
FOOTER_MULTI_CANVAS = GLSL.PIXEL.FOOTER_MULTI_CANVAS,
|
||||
|
||||
@@ -6278,9 +6278,7 @@ const unsigned char graphics_lua[] =
|
||||
0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x75, 0x6e, 0x69,
|
||||
0x66, 0x6f, 0x72, 0x6d, 0x0a,
|
||||
0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x65, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x78, 0x74,
|
||||
0x75, 0x72, 0x65, 0x32, 0x44, 0x0a,
|
||||
0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x43, 0x61, 0x6e, 0x76, 0x61,
|
||||
0x73, 0x65, 0x73, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5d, 0x5d, 0x0a,
|
||||
0x75, 0x72, 0x65, 0x32, 0x44, 0x5d, 0x5d, 0x0a,
|
||||
0x09, 0x47, 0x4c, 0x53, 0x4c, 0x45, 0x53, 0x2e, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x20, 0x3d, 0x20, 0x47,
|
||||
0x4c, 0x53, 0x4c, 0x2e, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x0a,
|
||||
0x09, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x20, 0x3d, 0x20, 0x5b,
|
||||
@@ -6417,16 +6415,18 @@ const unsigned char graphics_lua[] =
|
||||
0x43, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x67, 0x6c, 0x5f, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b,
|
||||
0x30, 0x5d, 0x0a,
|
||||
0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c,
|
||||
0x6f, 0x72, 0x20, 0x67, 0x6c, 0x5f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x5d, 0x5d, 0x2c, 0x0a,
|
||||
0x6f, 0x72, 0x20, 0x67, 0x6c, 0x5f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x0a,
|
||||
0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x43, 0x61, 0x6e, 0x76, 0x61,
|
||||
0x73, 0x65, 0x73, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5d, 0x5d, 0x2c, 0x0a,
|
||||
0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a,
|
||||
0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a,
|
||||
0x09, 0x2f, 0x2f, 0x20, 0x66, 0x69, 0x78, 0x20, 0x63, 0x72, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x69,
|
||||
0x73, 0x73, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x4f, 0x53, 0x58, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x5f,
|
||||
0x74, 0x65, 0x78, 0x30, 0x5f, 0x20, 0x69, 0x73, 0x20, 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x20, 0x77, 0x69,
|
||||
0x74, 0x68, 0x69, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x29, 0x0a,
|
||||
0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78,
|
||||
0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x76, 0x65, 0x63,
|
||||
0x32, 0x28, 0x2e, 0x35, 0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0a,
|
||||
0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x54, 0x65, 0x78,
|
||||
0x65, 0x6c, 0x28, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x2e, 0x35,
|
||||
0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0a,
|
||||
0x09, 0x2f, 0x2f, 0x20, 0x53, 0x65, 0x65, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x3a, 0x3a, 0x63, 0x68,
|
||||
0x65, 0x63, 0x6b, 0x53, 0x65, 0x74, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73,
|
||||
0x20, 0x69, 0x6e, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x63, 0x70, 0x70, 0x2e, 0x0a,
|
||||
@@ -6449,9 +6449,9 @@ const unsigned char graphics_lua[] =
|
||||
0x73, 0x73, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x4f, 0x53, 0x58, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x5f,
|
||||
0x74, 0x65, 0x78, 0x30, 0x5f, 0x20, 0x69, 0x73, 0x20, 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x20, 0x77, 0x69,
|
||||
0x74, 0x68, 0x69, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x29, 0x0a,
|
||||
0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78,
|
||||
0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x76, 0x65, 0x63,
|
||||
0x32, 0x28, 0x2e, 0x35, 0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0a,
|
||||
0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x54, 0x65, 0x78,
|
||||
0x65, 0x6c, 0x28, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x2e, 0x35,
|
||||
0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0a,
|
||||
0x09, 0x2f, 0x2f, 0x20, 0x53, 0x65, 0x65, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x3a, 0x3a, 0x63, 0x68,
|
||||
0x65, 0x63, 0x6b, 0x53, 0x65, 0x74, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73,
|
||||
0x20, 0x69, 0x6e, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x63, 0x70, 0x70, 0x2e, 0x0a,
|
||||
@@ -6476,7 +6476,10 @@ const unsigned char graphics_lua[] =
|
||||
0x63, 0x34, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64,
|
||||
0x3b, 0x0a,
|
||||
0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20,
|
||||
0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x5d, 0x5d, 0x2c, 0x0a,
|
||||
0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a,
|
||||
0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x43, 0x61, 0x6e, 0x76, 0x61,
|
||||
0x73, 0x65, 0x73, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x3b, 0x5d, 0x5d,
|
||||
0x2c, 0x0a,
|
||||
0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x50, 0x49,
|
||||
0x58, 0x45, 0x4c, 0x2e, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x2c, 0x0a,
|
||||
0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x43, 0x41, 0x4e,
|
||||
|
||||
Reference in New Issue
Block a user