imported Löve GLES branch (changeset 1ba9037e558b)

This commit is contained in:
Martin Felis
2013-12-05 18:05:13 +01:00
parent 41b2db04a7
commit 2644d1ee18
615 changed files with 150300 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
/**
* Copyright (c) 2006-2013 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_DATA_H
#define LOVE_DATA_H
// LOVE
#include "config.h"
#include "Object.h"
namespace love
{
/**
* This class is a simple abstraction over all objects which contain data.
**/
class Data : public Object
{
public:
/**
* Destructor.
**/
virtual ~Data() {};
/**
* Gets a pointer to the data. This pointer will obviously not
* be valid if the Data object is destroyed.
**/
virtual void *getData() const = 0 ;
/**
* Gets the size of the Data in bytes.
**/
virtual int getSize() const = 0;
}; // Data
} // love
#endif // LOVE_DATA_H
+100
View File
@@ -0,0 +1,100 @@
/**
* Copyright (c) 2006-2013 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_ENUM_MAP_H
#define LOVE_ENUM_MAP_H
#include "Exception.h"
namespace love
{
template<typename T, typename U, unsigned PEAK>
class EnumMap
{
public:
struct Entry
{
T t;
U u;
};
EnumMap(Entry *entries, unsigned size)
{
unsigned n = size/sizeof(Entry);
for (unsigned i = 0; i<n; ++i)
{
unsigned e_t = (unsigned)entries[i].t;
unsigned e_u = (unsigned)entries[i].u;
if (e_t < PEAK)
{
values_u[e_t].v = e_u;
values_u[e_t].set = true;
}
if (e_u < PEAK)
{
values_t[e_u].v = e_t;
values_t[e_u].set = true;
}
}
}
bool find(T t, U &u)
{
if ((unsigned)t < PEAK && values_u[(unsigned)t].set)
{
u = (U)values_u[(unsigned)t].v;
return true;
}
return false;
}
bool find(U u, T &t)
{
if ((unsigned)u < PEAK && values_t[(unsigned)u].set)
{
t = (T)values_t[(unsigned)u].v;
return true;
}
return false;
}
private:
struct Value
{
unsigned v;
bool set;
Value() : set(false) {}
};
Value values_t[PEAK];
Value values_u[PEAK];
}; // EnumMap
} // love
#endif // LOVE_ENUM_MAP_H
+63
View File
@@ -0,0 +1,63 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "Exception.h"
#include "common/config.h"
#include <iostream>
namespace love
{
Exception::Exception(const char *fmt, ...)
{
va_list args;
int size_buffer = 256, size_out;
char *buffer;
while (true)
{
buffer = new char[size_buffer];
memset(buffer, 0, size_buffer);
va_start(args, fmt);
size_out = vsnprintf(buffer, size_buffer, fmt, args);
va_end(args);
// see http://perfec.to/vsnprintf/pasprintf.c
// if size_out ...
// == -1 --> output was truncated
// == size_buffer --> output was truncated
// == size_buffer-1 --> ambiguous, /may/ have been truncated
// > size_buffer --> output was truncated, and size_out
// bytes would have been written
if (size_out == size_buffer || size_out == -1 || size_out == size_buffer-1)
size_buffer *= 2;
else if (size_out > size_buffer)
size_buffer = size_out + 2; // to avoid the ambiguous case
else
break;
delete[] buffer;
}
message = std::string(buffer);
delete[] buffer;
}
}
+67
View File
@@ -0,0 +1,67 @@
/**
* Copyright (c) 2006-2013 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_EXCEPTION_H
#define LOVE_EXCEPTION_H
#include <exception>
#include <cstdarg> // vararg
#include <cstdio> // vsnprintf
#include <cstring> // strncpy
#include <string>
namespace love
{
/**
* A convenient vararg-enabled exception class.
**/
class Exception : public std::exception
{
public:
/**
* Creates a new Exception according to printf-rules.
*
* See: http://www.cplusplus.com/reference/clibrary/cstdio/printf/
*
* @param fmt The format string (see printf).
**/
Exception(const char *fmt, ...);
virtual ~Exception() throw() {}
/**
* Returns a string containing reason for the exception.
* @return A description of the exception.
**/
inline virtual const char *what() const throw()
{
return message.c_str();
}
private:
std::string message;
}; // Exception
} // love
#endif // LOVE_EXCEPTION_H
+212
View File
@@ -0,0 +1,212 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "Matrix.h"
// STD
#include <cstring> // memcpy
#include <cmath>
namespace love
{
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
Matrix::Matrix()
{
setIdentity();
}
Matrix::~Matrix()
{
}
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
Matrix Matrix::operator * (const Matrix &m) const
{
Matrix t;
t.e[0] = (e[0]*m.e[0]) + (e[4]*m.e[1]) + (e[8]*m.e[2]) + (e[12]*m.e[3]);
t.e[4] = (e[0]*m.e[4]) + (e[4]*m.e[5]) + (e[8]*m.e[6]) + (e[12]*m.e[7]);
t.e[8] = (e[0]*m.e[8]) + (e[4]*m.e[9]) + (e[8]*m.e[10]) + (e[12]*m.e[11]);
t.e[12] = (e[0]*m.e[12]) + (e[4]*m.e[13]) + (e[8]*m.e[14]) + (e[12]*m.e[15]);
t.e[1] = (e[1]*m.e[0]) + (e[5]*m.e[1]) + (e[9]*m.e[2]) + (e[13]*m.e[3]);
t.e[5] = (e[1]*m.e[4]) + (e[5]*m.e[5]) + (e[9]*m.e[6]) + (e[13]*m.e[7]);
t.e[9] = (e[1]*m.e[8]) + (e[5]*m.e[9]) + (e[9]*m.e[10]) + (e[13]*m.e[11]);
t.e[13] = (e[1]*m.e[12]) + (e[5]*m.e[13]) + (e[9]*m.e[14]) + (e[13]*m.e[15]);
t.e[2] = (e[2]*m.e[0]) + (e[6]*m.e[1]) + (e[10]*m.e[2]) + (e[14]*m.e[3]);
t.e[6] = (e[2]*m.e[4]) + (e[6]*m.e[5]) + (e[10]*m.e[6]) + (e[14]*m.e[7]);
t.e[10] = (e[2]*m.e[8]) + (e[6]*m.e[9]) + (e[10]*m.e[10]) + (e[14]*m.e[11]);
t.e[14] = (e[2]*m.e[12]) + (e[6]*m.e[13]) + (e[10]*m.e[14]) + (e[14]*m.e[15]);
t.e[3] = (e[3]*m.e[0]) + (e[7]*m.e[1]) + (e[11]*m.e[2]) + (e[15]*m.e[3]);
t.e[7] = (e[3]*m.e[4]) + (e[7]*m.e[5]) + (e[11]*m.e[6]) + (e[15]*m.e[7]);
t.e[11] = (e[3]*m.e[8]) + (e[7]*m.e[9]) + (e[11]*m.e[10]) + (e[15]*m.e[11]);
t.e[15] = (e[3]*m.e[12]) + (e[7]*m.e[13]) + (e[11]*m.e[14]) + (e[15]*m.e[15]);
return t;
}
void Matrix::operator *= (const Matrix &m)
{
Matrix t = (*this) * m;
memcpy((void *)this->e, (void *)t.e, sizeof(float)*16);
}
const float *Matrix::getElements() const
{
return e;
}
void Matrix::setIdentity()
{
memset(e, 0, sizeof(float)*16);
e[0] = e[5] = e[10] = e[15] = 1;
}
void Matrix::setTranslation(float x, float y)
{
setIdentity();
e[12] = x;
e[13] = y;
}
void Matrix::setRotation(float rad)
{
setIdentity();
float c = cosf(rad), s = sinf(rad);
e[0] = c;
e[4] = -s;
e[1] = s;
e[5] = c;
}
void Matrix::setScale(float sx, float sy)
{
setIdentity();
e[0] = sx;
e[5] = sy;
}
void Matrix::setShear(float kx, float ky)
{
setIdentity();
e[1] = ky;
e[4] = kx;
}
void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
{
memset(e, 0, sizeof(float)*16); // zero out matrix
float c = cosf(angle), s = sinf(angle);
// matrix multiplication carried out on paper:
// |1 x| |c -s | |sx | | 1 ky | |1 -ox|
// | 1 y| |s c | | sy | |kx 1 | | 1 -oy|
// | 1 | | 1 | | 1 | | 1 | | 1 |
// | 1| | 1| | 1| | 1| | 1 |
// move rotate scale skew origin
e[10] = e[15] = 1.0f;
e[0] = c * sx - ky * s * sy; // = a
e[1] = s * sx + ky * c * sy; // = b
e[4] = kx * c * sx - s * sy; // = c
e[5] = kx * s * sx + c * sy; // = d
e[12] = x - ox * e[0] - oy * e[4];
e[13] = y - ox * e[1] - oy * e[5];
}
void Matrix::translate(float x, float y)
{
Matrix t;
t.setTranslation(x, y);
this->operator *=(t);
}
void Matrix::rotate(float rad)
{
Matrix t;
t.setRotation(rad);
this->operator *=(t);
}
void Matrix::scale(float sx, float sy)
{
Matrix t;
t.setScale(sx, sy);
this->operator *=(t);
}
void Matrix::shear(float kx, float ky)
{
Matrix t;
t.setShear(kx,ky);
this->operator *=(t);
}
// | x |
// | y |
// | 0 |
// | 1 |
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
void Matrix::transform(Vertex *dst, const Vertex *src, int size) const
{
for (int i = 0; i<size; i++)
{
// Store in temp variables in case src = dst
float x = (e[0]*src[i].x) + (e[4]*src[i].y) + (0) + (e[12]);
float y = (e[1]*src[i].x) + (e[5]*src[i].y) + (0) + (e[13]);
dst[i].x = x;
dst[i].y = y;
}
}
Matrix Matrix::ortho(float left, float right, float bottom, float top)
{
Matrix m;
m.e[0] = 2.0f / (right - left);
m.e[5] = 2.0f / (top - bottom);
m.e[10] = -1.0;
m.e[12] = -(right + left) / (right - left);
m.e[13] = -(top + bottom) / (top - bottom);
return m;
}
} // love
+173
View File
@@ -0,0 +1,173 @@
/**
* Copyright (c) 2006-2013 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_MATRIX_H
#define LOVE_MATRIX_H
// LOVE
#include "math.h"
namespace love
{
/**
* This class is the basis for all transformations in LOVE. Althought not
* really needed for 2D, it contains 4x4 elements to be compatible with
* OpenGL without conversions.
**/
class Matrix
{
public:
/**
* Creates a new identity matrix.
**/
Matrix();
/**
* Destructor.
**/
~Matrix();
/**
* Multiplies this Matrix with another Matrix, changing neither.
* @param m The Matrix to multiply with this Matrix.
* @return The combined matrix.
**/
Matrix operator * (const Matrix &m) const;
/**
* Multiplies a Matrix into this Matrix.
* @param m The Matrix to combine into this Matrix.
**/
void operator *= (const Matrix &m);
/**
* Gets a pointer to the 16 array elements.
* @return The array elements.
**/
const float *getElements() const;
/**
* Resets this Matrix to the identity matrix.
**/
void setIdentity();
/**
* Resets this Matrix to a translation.
* @param x Translation along x-axis.
* @param y Translation along y-axis.
**/
void setTranslation(float x, float y);
/**
* Resets this Matrix to a rotation.
* @param r The angle in radians.
**/
void setRotation(float r);
/**
* Resets this Matrix to a scale transformation.
* @param sx Scale factor along the x-axis.
* @param sy Scale factor along the y-axis.
**/
void setScale(float sx, float sy);
/**
* Resets this Matrix to a shear transformation.
* @param kx Shear along x-axis.
* @param ky Shear along y-axis.
**/
void setShear(float kx, float ky);
/**
* Creates a transformation with a certain position, orientation, scale
* and offset. Perfect for Drawables -- what a coincidence!
*
* @param x The translation along the x-axis.
* @param y The translation along the y-axis.
* @param angle The rotation (rad) around the center with offset (ox,oy).
* @param sx Scale along x-axis.
* @param sy Scale along y-axis.
* @param ox The offset for rotation along the x-axis.
* @param oy The offset for rotation along the y-axis.
* @param kx Shear along x-axis
* @param ky Shear along y-axis
**/
void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
/**
* Multiplies this Matrix with a translation.
* @param x Translation along x-axis.
* @param y Translation along y-axis.
**/
void translate(float x, float y);
/**
* Multiplies this Matrix with a rotation.
* @param r Angle in radians.
**/
void rotate(float r);
/**
* Multiplies this Matrix with a scale transformation.
* @param sx Scale factor along the x-axis.
* @param sy Scale factor along the y-axis.
**/
void scale(float sx, float sy);
/**
* Multiplies this Matrix with a shear transformation.
* @param kx Shear along the x-axis.
* @param ky Shear along the y-axis.
**/
void shear(float kx, float ky);
/**
* Transforms an array of vertices by this Matrix. The sources and
* destination arrays may be the same.
*
* @param dst Storage for the transformed vertices.
* @param src The source vertices.
* @param size The number of vertices.
**/
void transform(Vertex *dst, const Vertex *src, int size) const;
/**
* Creates a new orthographic projection matrix with depth in the range of
* [-1, 1].
**/
static Matrix ortho(float left, float right, float bottom, float top);
private:
/**
* | e0 e4 e8 e12 |
* | e1 e5 e9 e13 |
* | e2 e6 e10 e14 |
* | e3 e7 e11 e15 |
**/
float e[16];
}; // Matrix
} //love
#endif// LOVE_MATRIX_H
+45
View File
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "Memoizer.h"
#include <cstddef>
namespace love
{
std::map<void *, void *> Memoizer::objectMap;
void Memoizer::add(void *key, void *val)
{
objectMap[key] = val;
}
void Memoizer::remove(void *key)
{
objectMap.erase(key);
}
void *Memoizer::find(void *key)
{
if (objectMap.count(key)) return objectMap[key];
return NULL;
}
} // love
+46
View File
@@ -0,0 +1,46 @@
/**
* Copyright (c) 2006-2013 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_MEMOIZER_H
#define LOVE_MEMOIZER_H
#include <map>
namespace love
{
class Memoizer
{
public:
static void add(void *key, void *val);
static void remove(void *key);
static void *find(void *key);
private:
static std::map<void *, void *> objectMap;
}; // Memoizer
} // love
#endif // LOVE_MEMOIZER_H
+124
View File
@@ -0,0 +1,124 @@
/**
* Copyright (c) 2006-2013 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 "Module.h"
#include "Exception.h"
// std
#include <map>
#include <utility>
#include <string>
namespace
{
typedef std::map<std::string, love::Module*> ModuleRegistry;
// The registry must be dynamically managed, because some modules
// (the math module) are static globals that are not guaranteed to
// be destroyed before other static globals.
ModuleRegistry *registry = nullptr;
ModuleRegistry &registryInstance()
{
if (!registry)
registry = new ModuleRegistry;
return *registry;
}
void freeEmptyRegistry()
{
if (registry && registry->empty())
{
delete registry;
registry = nullptr;
}
}
} // anonymous namespace
namespace love
{
Module::~Module()
{
ModuleRegistry &registry = registryInstance();
// We can't use the overridden Module::getName() in this destructor.
for (auto it = registry.begin(); it != registry.end(); ++it)
{
if (it->second == this)
{
registry.erase(it);
break;
}
}
freeEmptyRegistry();
}
void Module::registerInstance(Module *instance)
{
if (instance == nullptr)
throw Exception("Module instance is NULL");
std::string name(instance->getName());
ModuleRegistry &registry = registryInstance();
auto it = registry.find(name);
if (it != registry.end())
{
if (it->second == instance)
return;
throw Exception("Module %s already registered!", instance->getName());
}
registry.insert(make_pair(name, instance));
}
Module *Module::getInstance(const std::string &name)
{
ModuleRegistry &registry = registryInstance();
auto it = registry.find(name);
if (registry.end() == it)
return nullptr;
return it->second;
}
Module *Module::findInstance(const std::string &name)
{
ModuleRegistry &registry = registryInstance();
for (auto it = registry.begin(); it != registry.end(); ++it)
{
if (it->first.find(name) == 0)
return it->second;
}
return nullptr;
}
} // love
+79
View File
@@ -0,0 +1,79 @@
/**
* Copyright (c) 2006-2013 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_MODULE_H
#define LOVE_MODULE_H
// LOVE
#include "runtime.h"
#include "Exception.h"
#include "Object.h"
namespace love
{
/**
* Abstract superclass for all modules.
**/
class Module : public Object
{
public:
/**
* Destructor.
**/
virtual ~Module();
/**
* Gets the name of the module. This is used in case of errors
* and other messages.
*
* @return The full name of the module, eg. love.graphics.opengl.
**/
virtual const char *getName() const = 0;
/**
* Add module to internal registry. To be used /only/ in
* runtime.cpp:luax_register_module()
* @param instance The module instance.
*/
static void registerInstance(Module *instance);
/**
* Retrieve module instance from internal registry. May return NULL
* if module not registered.
* @param name The full name of the module.
* @return Module instance or NULL if the module is not registered.
*/
static Module *getInstance(const std::string &name);
/**
* Find the first module instance from the internal registry whose name
* starts with the supplied name. May return NULL if module is not
* registered or the supplied name is not part of any module name.
* @param name The partial name of the module.
* @return Module instance or NULL if the module is not registered.
**/
static Module *findInstance(const std::string &name);
}; // Module
} // love
#endif // LOVE_MODULE_H
+52
View File
@@ -0,0 +1,52 @@
/**
* Copyright (c) 2006-2013 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 "Object.h"
namespace love
{
Object::Object()
: count(1)
{
}
Object::~Object()
{
}
int Object::getReferenceCount() const
{
return count;
}
void Object::retain()
{
++count;
}
void Object::release()
{
if (--count <= 0)
delete this;
}
} // love
+102
View File
@@ -0,0 +1,102 @@
/**
* Copyright (c) 2006-2013 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_OBJECT_H
#define LOVE_OBJECT_H
namespace love
{
/**
* Superclass for all object that should be able to cross the Lua/C border
* (this pertains to most objects).
*
* This class is an alternative to using smart pointers; it contains retain/release
* methods, and will delete itself with the reference count hits zero. The wrapper
* code assumes that all userdata inherits from this class.
**/
class Object
{
public:
/**
* Constructor. Sets reference count to one.
**/
Object();
/**
* Destructor.
**/
virtual ~Object() = 0;
/**
* Gets the reference count of this Object.
* @returns The reference count.
**/
int getReferenceCount() const;
/**
* Retains the Object, i.e. increases the
* reference count by one.
**/
virtual void retain();
/**
* Releases one reference to the Object, i.e. decrements the
* reference count by one, and potentially deletes the Object
* if there are no more references.
**/
virtual void release();
/**
* Meant to be used as a temporary object. Facilitates safer and cleaner
* code to release objects by doing so when the AutoRelease object is
* destroyed (e.g. goes out of scope.)
**/
class AutoRelease
{
public:
AutoRelease(Object *obj)
: object(obj)
{
}
~AutoRelease()
{
if (object)
object->release();
}
private:
AutoRelease() {}
Object *object;
}; // AutoRelease
private:
// The reference count.
int count;
}; // Object
} // love
#endif // LOVE_OBJECT_H
+84
View File
@@ -0,0 +1,84 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "Reference.h"
namespace love
{
const char REFERENCE_TABLE_NAME[] = "love-references";
Reference::Reference()
: L(0)
, idx(LUA_REFNIL)
{
}
Reference::Reference(lua_State *L)
: L(L)
, idx(LUA_REFNIL)
{
ref(L);
}
Reference::~Reference()
{
unref();
}
void Reference::ref(lua_State *L)
{
unref(); // Just to be safe.
this->L = L;
luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
lua_insert(L, -2); // Move reference table behind value.
idx = luaL_ref(L, -2);
lua_pop(L, 1);
}
void Reference::unref()
{
if (idx != LUA_REFNIL)
{
luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
luaL_unref(L, -1, idx);
lua_pop(L, 1);
idx = LUA_REFNIL;
}
}
void Reference::push()
{
if (idx != LUA_REFNIL)
{
luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
lua_rawgeti(L, -1, idx);
lua_remove(L, -2);
}
else
lua_pushnil(L);
}
lua_State *Reference::getL()
{
return L;
}
} // love
+88
View File
@@ -0,0 +1,88 @@
/**
* Copyright (c) 2006-2013 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_REFERENCE_H
#define LOVE_REFERENCE_H
// LOVE
#include "runtime.h"
namespace love
{
/**
* This class wraps the reference functionality built into
* Lua, which allows C++ code to refer to Lua variables.
**/
class Reference
{
public:
/**
* Creates the reference object, but does not create
* the actual reference.
**/
Reference();
/**
* Creates the object and a reference to the value
* on the top of the stack.
**/
Reference(lua_State *L);
/**
* Deletes the reference, if any.
**/
virtual ~Reference();
/**
* Creates a reference to the value on the
* top of the stack.
**/
void ref(lua_State *L);
/**
* Unrefs the reference, if any.
**/
void unref();
/**
* Pushes the referred value onto the stack.
**/
void push();
/**
* Gets the Lua state associated with this
* reference.
**/
lua_State *getL();
private:
// The Lua state in which the reference resides.
lua_State *L;
// Index to the Lua reference.
int idx;
};
} // love
#endif // LOVE_REFERENCE_H
+168
View File
@@ -0,0 +1,168 @@
/**
* Copyright (c) 2006-2013 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_STRING_MAP_H
#define LOVE_STRING_MAP_H
#include "Exception.h"
namespace love
{
template<typename T, unsigned SIZE>
class StringMap
{
public:
struct Entry
{
const char *key;
T value;
};
StringMap(Entry *entries, unsigned num)
{
for (unsigned i = 0; i < SIZE; ++i)
reverse[i] = 0;
unsigned n = num/sizeof(Entry);
for (unsigned i = 0; i < n; ++i)
{
add(entries[i].key, entries[i].value);
}
}
bool streq(const char *a, const char *b)
{
while (*a != 0 && *b != 0)
{
if (*a != *b)
return false;
++a;
++b;
}
return (*a == 0 && *b == 0);
}
bool find(const char *key, T &t)
{
unsigned str_hash = djb2(key);
for (unsigned i = 0; i < MAX; ++i)
{
unsigned str_i = (str_hash + i) % MAX;
if (!records[str_i].set)
return false;
if (streq(records[str_i].key, key))
{
t = records[str_i].value;
return true;
}
}
return false;
}
bool find(T key, const char *&str)
{
unsigned index = (unsigned)key;
if (index >= SIZE)
return false;
if (reverse[index] != 0)
{
str = reverse[index];
return true;
}
else
{
return false;
}
}
bool add(const char *key, T value)
{
unsigned str_hash = djb2(key);
bool inserted = false;
for (unsigned i = 0; i < MAX; ++i)
{
unsigned str_i = (str_hash + i) % MAX;
if (!records[str_i].set)
{
inserted = true;
records[str_i].set = true;
records[str_i].key = key;
records[str_i].value = value;
break;
}
}
unsigned index = (unsigned)value;
if (index >= SIZE)
{
printf("\nConstant %s out of bounds with %i!\n", key, index);
return false;
}
reverse[index] = key;
return inserted;
}
unsigned djb2(const char *key)
{
unsigned hash = 5381;
int c;
while ((c = *key++))
hash = ((hash << 5) + hash) + c;
return hash;
}
private:
struct Record
{
const char *key;
T value;
bool set;
Record() : set(false) {}
};
const static unsigned MAX = SIZE*2;
Record records[MAX];
const char *reverse[SIZE];
}; // StringMap
} // love
#endif // LOVE_STRING_MAP_H
+255
View File
@@ -0,0 +1,255 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "Variant.h"
#include "common/StringMap.h"
namespace love
{
extern StringMap<Type, TYPE_MAX_ENUM> types;
static love::Type extractudatatype(lua_State *L, int idx)
{
Type t = INVALID_ID;
if (!lua_isuserdata(L, idx))
return t;
if (luaL_getmetafield(L, idx, "__tostring") == 0)
return t;
lua_pushvalue(L, idx);
int result = lua_pcall(L, 1, 1, 0);
if (result == 0)
types.find(lua_tostring(L, -1), t);
if (result == 0 || result == LUA_ERRRUN)
lua_pop(L, 1);
return t;
}
static inline void delete_table(std::vector<std::pair<Variant*, Variant*> > *table)
{
while (!table->empty())
{
std::pair<Variant*, Variant*> &kv = table->back();
kv.first->release();
kv.second->release();
table->pop_back();
}
delete table;
}
Variant::Variant()
: type(NIL)
, data()
{
}
Variant::Variant(bool boolean)
: type(BOOLEAN)
{
data.boolean = boolean;
}
Variant::Variant(double number)
: type(NUMBER)
{
data.number = number;
}
Variant::Variant(const char *string, size_t len)
: type(STRING)
{
char *buf = new char[len+1];
memset(buf, 0, len+1);
memcpy(buf, string, len);
data.string.str = buf;
data.string.len = len;
}
Variant::Variant(char c)
: type(CHARACTER)
{
data.character = c;
}
Variant::Variant(void *userdata)
: type(LUSERDATA)
{
data.userdata = userdata;
}
Variant::Variant(love::Type udatatype, void *userdata)
: type(FUSERDATA)
, udatatype(udatatype)
{
if (udatatype != INVALID_ID)
{
Proxy *p = (Proxy *) userdata;
flags = p->flags;
data.userdata = p->data;
((love::Object *) data.userdata)->retain();
}
else
data.userdata = userdata;
}
// Variant gets ownership of the vector.
Variant::Variant(std::vector<std::pair<Variant*, Variant*> > *table)
: type(TABLE)
{
data.table = table;
}
Variant::~Variant()
{
switch (type)
{
case STRING:
delete[] data.string.str;
break;
case FUSERDATA:
((love::Object *) data.userdata)->release();
break;
case TABLE:
delete_table(data.table);
default:
break;
}
}
Variant *Variant::fromLua(lua_State *L, int n, bool allowTables)
{
Variant *v = NULL;
size_t len;
const char *str;
if (n < 0) // Fix the stack position, we might modify it later
n += lua_gettop(L) + 1;
switch (lua_type(L, n))
{
case LUA_TBOOLEAN:
v = new Variant(luax_toboolean(L, n));
break;
case LUA_TNUMBER:
v = new Variant(lua_tonumber(L, n));
break;
case LUA_TSTRING:
str = lua_tolstring(L, n, &len);
v = new Variant(str, len);
break;
case LUA_TLIGHTUSERDATA:
v = new Variant(lua_touserdata(L, n));
break;
case LUA_TUSERDATA:
v = new Variant(extractudatatype(L, n), lua_touserdata(L, n));
break;
case LUA_TNIL:
v = new Variant();
break;
case LUA_TTABLE:
if (allowTables)
{
bool success = true;
std::vector<std::pair<Variant*, Variant*> > *table = new std::vector<std::pair<Variant*, Variant*> >();
lua_pushnil(L);
while (lua_next(L, n))
{
Variant *key = fromLua(L, -2, false);
if (!key)
{
success = false;
lua_pop(L, 2);
break;
}
Variant *value = fromLua(L, -1, false);
if (!value)
{
delete key;
success = false;
lua_pop(L, 2);
break;
}
table->push_back(std::make_pair(key, value));
lua_pop(L, 1);
}
if (success)
v = new Variant(table);
else
delete_table(table);
}
break;
}
return v;
}
void Variant::toLua(lua_State *L)
{
switch (type)
{
case BOOLEAN:
lua_pushboolean(L, data.boolean);
break;
case CHARACTER:
lua_pushlstring(L, &data.character, 1);
break;
case NUMBER:
lua_pushnumber(L, data.number);
break;
case STRING:
lua_pushlstring(L, data.string.str, data.string.len);
break;
case LUSERDATA:
lua_pushlightuserdata(L, data.userdata);
break;
case FUSERDATA:
if (udatatype != INVALID_ID)
{
const char *name = NULL;
love::types.find(udatatype, name);
((love::Object *) data.userdata)->retain();
luax_pushtype(L, name, flags, (love::Object *) data.userdata);
}
else
lua_pushlightuserdata(L, data.userdata);
// I know this is not the same
// sadly, however, it's the most
// I can do (at the moment).
break;
case TABLE:
lua_newtable(L);
for (size_t i = 0; i < data.table->size(); ++i)
{
std::pair<Variant*, Variant*> &kv = data.table->at(i);
kv.first->toLua(L);
kv.second->toLua(L);
lua_settable(L, -3);
}
break;
case NIL:
default:
lua_pushnil(L);
break;
}
}
} // love
+83
View File
@@ -0,0 +1,83 @@
/**
* Copyright (c) 2006-2013 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_VARIANT_H
#define LOVE_VARIANT_H
#include "common/runtime.h"
#include "common/Object.h"
#include <cstring>
#include <vector>
#include <utility>
namespace love
{
class Variant : public love::Object
{
public:
Variant();
Variant(bool boolean);
Variant(double number);
Variant(const char *string, size_t len);
Variant(char c);
Variant(void *userdata);
Variant(love::Type udatatype, void *userdata);
Variant(std::vector<std::pair<Variant*, Variant*> > *table);
virtual ~Variant();
static Variant *fromLua(lua_State *L, int n, bool allowTables = true);
void toLua(lua_State *L);
private:
enum Type
{
UNKNOWN = 0,
BOOLEAN,
NUMBER,
CHARACTER,
STRING,
LUSERDATA,
FUSERDATA,
NIL,
TABLE
} type;
union
{
bool boolean;
char character;
double number;
struct
{
const char *str;
size_t len;
} string;
void *userdata;
std::vector<std::pair<Variant*, Variant*> > *table;
} data;
love::Type udatatype;
bits flags;
}; // Variant
} // love
#endif // LOVE_VARIANT_H
+26
View File
@@ -0,0 +1,26 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "Vector.h"
namespace love
{
// Implementation in header.
}
+325
View File
@@ -0,0 +1,325 @@
/**
* Copyright (c) 2006-2013 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_VECTOR_H
#define LOVE_VECTOR_H
// STD
#include <cmath>
// LOVE
#include "Matrix.h"
namespace love
{
/**
* 2D Vector class.
*
* @author Anders Ruud
* @date 2006-05-13
**/
class Vector
{
public:
// The components.
float x, y;
/**
* Creates a new (1,1) Vector.
**/
Vector();
/**
* Creates a new Vector.
* @param x The x position/dimension.
* @param y The y position/dimension.
**/
Vector(float x, float y);
/**
* Gets the length of the Vector.
* @return The length of the Vector.
*
* This method requires sqrtf() and should be used
* carefully.
**/
float getLength() const;
/**
* Normalizes the Vector.
* @param length Desired length of the vector.
* @return The old length of the Vector.
**/
float normalize(float length = 1.0);
/**
* Gets a vector perpendicular to the Vector.
* To get the true (normalized) normal, use v.getNormal(1.0f / v.getLength())
* @return A normal to the Vector.
**/
Vector getNormal() const;
/**
* Gets a vector perpendicular to the Vector.
* To get the true (normalized) normal, use v.getNormal(1.0f / v.getLength())
* @param scale factor to apply.
* @return A normal to the Vector.
**/
Vector getNormal(float scale) const;
/**
* Adds a Vector to this Vector.
* @param v The Vector we want to add to this Vector.
* @return The resulting Vector.
**/
Vector operator + (const Vector &v) const;
/**
* Substracts a Vector to this Vector.
* @param v The Vector we want to subtract to this Vector.
* @return The resulting Vector.
**/
Vector operator - (const Vector &v) const;
/**
* Resizes a Vector by a scalar.
* @param s The scalar with which to resize the Vector.
* @return The resulting Vector.
**/
Vector operator * (float s) const;
/**
* Resizes a Vector by a scalar.
* @param s The scalar with which to resize the Vector.
* @return The resulting Vector.
**/
Vector operator / (float s) const;
/**
* Reverses the Vector.
* @return The reversed Vector.
**/
Vector operator - () const;
/**
* Adds a Vector to this Vector, and also saves changes in the first Vector.
* @param v The Vector we want to add to this Vector.
**/
void operator += (const Vector &v);
/**
* Subtracts a Vector to this Vector, and also saves changes in the first Vector.
* @param v The Vector we want to subtract to this Vector.
**/
void operator -= (const Vector &v);
/**
* Resizes the Vector, and also saves changes in the first Vector.
* @param s The scalar by which we want to resize the Vector.
**/
void operator *= (float s);
/**
* Resizes the Vector, and also saves changes in the first Vector.
* @param s The scalar by which we want to resize the Vector.
**/
void operator /= (float s);
/**
* Calculates the dot product of two Vectors.
* @return The dot product of the two Vectors.
**/
float operator * (const Vector &v) const;
/**
* Calculates the cross product of two Vectors.
* @return The cross product of the two Vectors.
**/
float operator ^ (const Vector &v) const;
bool operator == (const Vector &v) const;
bool operator < (const Vector &v) const;
/**
* Gets the x value of the Vector.
* @return The x value of the Vector.
**/
float getX() const;
/**
* Gets the x value of the Vector.
* @return The x value of the Vector.
**/
float getY() const;
/**
* Sets the x value of the Vector.
* @param x The x value of the Vector.
**/
void setX(float x);
/**
* Sets the x value of the Vector.
* @param y The x value of the Vector.
**/
void setY(float y);
};
inline float Vector::getLength() const
{
return sqrtf(x*x + y*y);
}
inline Vector Vector::getNormal() const
{
return Vector(-y, x);
}
inline Vector Vector::getNormal(float scale) const
{
return Vector(-y * scale, x * scale);
}
inline float Vector::normalize(float length)
{
float length_current = getLength();
if (length_current > 0)
(*this) *= length / length_current;
return length_current;
}
/**
* Inline methods must have body in header.
**/
inline Vector::Vector()
{
x = 1;
y = 1;
}
inline Vector::Vector(float x, float y)
{
this->x = x;
this->y = y;
}
inline Vector Vector::operator + (const Vector &v) const
{
return Vector(x + v.x, y + v.y);
}
inline Vector Vector::operator - (const Vector &v) const
{
return Vector(x - v.getX(), y - v.getY());
}
inline Vector Vector::operator * (float s) const
{
return Vector(x*s, y*s);
}
inline Vector Vector::operator / (float s) const
{
return Vector(x/s, y/s);
}
inline Vector Vector::operator - () const
{
return Vector(-x, -y);
}
inline void Vector::operator += (const Vector &v)
{
x += v.getX();
y += v.getY();
}
inline void Vector::operator -= (const Vector &v)
{
x -= v.getX();
y -= v.getY();
}
inline void Vector::operator *= (float s)
{
x *= s;
y *= s;
}
inline void Vector::operator /= (float s)
{
x /= s;
y /= s;
}
inline float Vector::operator * (const Vector &v) const
{
return x * v.getX() + y * v.getY();
}
inline float Vector::operator ^ (const Vector &v) const
{
return x * v.getY() - y * v.getX();
}
inline bool Vector::operator == (const Vector &v) const
{
return getLength() == v.getLength();
}
inline bool Vector::operator < (const Vector &v) const
{
return getLength() < v.getLength();
}
/**
* Accessor methods
**/
inline float Vector::getX() const
{
return x;
}
inline float Vector::getY() const
{
return y;
}
inline void Vector::setX(float x)
{
this->x = x;
}
inline void Vector::setY(float y)
{
this->y = y;
}
} //love
#endif// LOVE_VECTOR_H
+80
View File
@@ -0,0 +1,80 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "b64.h"
namespace love
{
static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
void b64_decode_block(char in[4], char out[3])
{
out[0] = (char)(in[0] << 2 | in[1] >> 4);
out[1] = (char)(in[1] << 4 | in[2] >> 2);
out[2] = (char)(((in[2] << 6) & 0xc0) | in[3]);
}
char *b64_decode(const char *src, int slen, int &size)
{
size = (slen / 4) * 3;
char *dst = new char[size];
char *d = dst;
char in[4] = {0}, out[3], v;
int i, len, pos = 0;
while (pos <= slen)
{
for (len = 0, i = 0; i < 4 && pos <= slen; i++)
{
v = 0;
while (pos <= slen && v == 0)
{
v = src[pos++];
v = (char)((v < 43 || v > 122) ? 0 : cd64[v - 43]);
if (v)
v = (char)((v == '$') ? 0 : v - 61);
}
if (pos <= slen)
{
len++;
if (v)
in[i] = (char)(v - 1);
}
else
in[i] = 0;
}
if (len)
{
b64_decode_block(in, out);
for (i = 0; i < len - 1; i++)
*(d++) = out[i];
}
}
return dst;
}
} // love
+41
View File
@@ -0,0 +1,41 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "config.h"
#ifndef LOVE_B64_H
#define LOVE_B64_H
namespace love
{
/**
* Decode base64 encoded data.
*
* @param src The string containing the base64 data.
* @param slen The length of the string.
* @param size The size of the binary data is stored here.
* @return A chunk of memory containing the binary data (allocated with new[]).
*/
char *b64_decode(const char *src, int slen, int &size);
} // love
#endif // LOVE_B64_H
+91
View File
@@ -0,0 +1,91 @@
/**
* Copyright (c) 2006-2013 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_CONFIG_H
#define LOVE_CONFIG_H
// Platform stuff.
#if defined(WIN32) || defined(_WIN32)
# define LOVE_WINDOWS 1
#endif
#if defined(linux) || defined(__linux) || defined(__linux__)
# define LOVE_LINUX 1
#endif
#if defined(__APPLE__)
# define LOVE_MACOSX 1
# include <AvailabilityMacros.h>
#endif
// Endianness.
#if defined(__i386__) || defined(__i386)
# define LOVE_LITTLE_ENDIAN 1
#endif
#if defined(__ppc__) || defined(__ppc) || defined(__powerpc__) || defined(__powerpc)
# define LOVE_BIG_ENDIAN 1
#endif
// Warnings.
#ifndef _CRT_SECURE_NO_WARNINGS
# define _CRT_SECURE_NO_WARNINGS
#endif
// Preferably, and ironically, this macro should go unused.
#ifndef LOVE_UNUSED
# define LOVE_UNUSED(x) (void)sizeof(x)
#endif
#ifndef LOVE_BUILD
# define LOVE_BUILD
# define LOVE_BUILD_STANDALONE
# define LOVE_BUILD_EXE
//# define LOVE_BUILD_DLL
#endif
// DLL-stuff.
#ifdef LOVE_WINDOWS
# define LOVE_EXPORT __declspec(dllexport)
#else
# define LOVE_EXPORT
#endif
#if defined(LOVE_WINDOWS)
# define LOVE_LEGENDARY_UTF8_ARGV_HACK
# define LOVE_LEGENDARY_CONSOLE_IO_HACK
# define NOMINMAX
#endif
#if defined(LOVE_MACOSX)
# define LOVE_LEGENDARY_APP_ARGV_HACK
#endif
// Autotools config.h
#ifdef HAVE_CONFIG_H
# include <../config.h>
# undef VERSION
# ifdef WORDS_BIGENDIAN
# undef LOVE_LITTLE_ENDIAN
# define LOVE_BIG_ENDIAN 1
# else
# undef LOVE_BIG_ENDIAN
# define LOVE_LITTLE_ENDIAN 1
# endif
#endif
#endif // LOVE_CONFIG_H
+33
View File
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "delay.h"
#include <SDL_timer.h>
namespace love
{
void delay(unsigned int ms)
{
SDL_Delay(ms);
}
} // love
+31
View File
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2006-2013 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 DELAY_H_
#define DELAY_H_
namespace love
{
void delay(unsigned int ms);
} // namespace love
#endif // DELAY_H_
+65
View File
@@ -0,0 +1,65 @@
/**
* Copyright (c) 2006-2013 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_INT_H
#define LOVE_INT_H
#include "common/config.h"
#ifndef LOVE_WINDOWS
#include <stdint.h>
#endif
#define LOVE_INT8_MAX 0x7F
#define LOVE_UINT8_MAX 0xFF
#define LOVE_INT16_MAX 0x7FFF
#define LOVE_UINT16_MAX 0xFFFF
#define LOVE_INT32_MAX 0x7FFFFFFF
#define LOVE_UINT32_MAX 0xFFFFFFFF
#define LOVE_INT64_MAX 0x7FFFFFFFFFFFFFFF
#define LOVE_UINT64_MAX 0xFFFFFFFFFFFFFFFF
namespace love
{
// Blame Microsoft
#ifdef LOVE_WINDOWS
typedef __int8 int8;
typedef unsigned __int8 uint8;
typedef __int16 int16;
typedef unsigned __int16 uint16;
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else // LOVE_WINDOWS
typedef int8_t int8;
typedef uint8_t uint8;
typedef int16_t int16;
typedef uint16_t uint16;
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#endif // LOVE_WINDOWS
} // love
#endif // LOVE_INT_H
+94
View File
@@ -0,0 +1,94 @@
/**
* Copyright (c) 2006-2013 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_MATH_H
#define LOVE_MATH_H
#include <climits> // for CHAR_BIT
#include <cstdlib> // for rand() and RAND_MAX
/* Definitions of useful mathematical constants
* M_E - e
* M_LOG2E - log2(e)
* M_LOG10E - log10(e)
* M_LN2 - ln(2)
* M_LN10 - ln(10)
* M_PI - pi
* M_PI_2 - pi/2
* M_PI_4 - pi/4
* M_1_PI - 1/pi
* M_2_PI - 2/pi
* M_2_SQRTPI - 2/sqrt(pi)
* M_SQRT2 - sqrt(2)
* M_SQRT1_2 - 1/sqrt(2)
*/
#define LOVE_M_E 2.71828182845904523536
#define LOVE_M_LOG2E 1.44269504088896340736
#define LOVE_M_LOG10E 0.434294481903251827651
#define LOVE_M_LN2 0.693147180559945309417
#define LOVE_M_LN10 2.30258509299404568402
#define LOVE_M_PI 3.14159265358979323846
#define LOVE_M_PI_2 1.57079632679489661923
#define LOVE_M_PI_4 0.785398163397448309616
#define LOVE_M_1_PI 0.318309886183790671538
#define LOVE_M_2_PI 0.636619772367581343076
#define LOVE_M_2_SQRTPI 1.12837916709551257390
#define LOVE_M_SQRT2 1.41421356237309504880
#define LOVE_M_SQRT1_2 0.707106781186547524401
#define LOVE_M_TORAD (float)(LOVE_M_PI/180.0)
#define LOVE_M_TODEG (float)(180.0/LOVE_M_PI)
#define LOVE_TORAD(x) (float)(x*LOVE_M_TORAD)
#define LOVE_TODEG(x) (float)(x*LOVE_M_TODEG)
namespace love
{
struct Vertex
{
float x, y;
float s, t;
unsigned char r, g, b, a;
};
struct Triangle
{
Triangle(const Vertex &x, const Vertex &y, const Vertex &z)
: a(x), b(y), c(z)
{}
Vertex a, b, c;
};
inline int next_p2(int x)
{
x += (x == 0);
x--;
for (unsigned int i = 1; i < sizeof(int)*CHAR_BIT; i <<= 1) x |= x >> i;
return ++x;
}
inline float next_p2(float x)
{
return static_cast<float>(next_p2(static_cast<int>(x)));
}
} // love
#endif // LOVE_MATH_H
+757
View File
@@ -0,0 +1,757 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "config.h"
#include "runtime.h"
// LOVE
#include "Module.h"
#include "Object.h"
#include "Reference.h"
#include "StringMap.h"
#include <thread/threads.h>
// C++
#include <algorithm>
#include <iostream>
#include <cstdio>
namespace love
{
static thread::Mutex *gcmutex = 0;
void *_gcmutex = 0;
/**
* Called when an object is collected. The object is released
* once in this function, possibly deleting it.
**/
static int w__gc(lua_State *L)
{
if (!gcmutex)
{
gcmutex = thread::newMutex();
_gcmutex = (void *) gcmutex;
}
Proxy *p = (Proxy *)lua_touserdata(L, 1);
Object *t = (Object *)p->data;
thread::Lock lock(gcmutex);
int numretains = p->retains;
if (numretains >= 0)
numretains = std::min(numretains, t->getReferenceCount());
for (int i = numretains; i > 0; i--)
t->release();
// Signal that this Proxy is dead.
p->retains = -1;
return 0;
}
static int w__tostring(lua_State *L)
{
lua_pushvalue(L, lua_upvalueindex(1));
return 1;
}
static int w__typeOf(lua_State *L)
{
Proxy *p = (Proxy *)lua_touserdata(L, 1);
Type t = luax_type(L, 2);
luax_pushboolean(L, p->flags[t]);
return 1;
}
static int w__eq(lua_State *L)
{
Proxy *p1 = (Proxy *)lua_touserdata(L, 1);
Proxy *p2 = (Proxy *)lua_touserdata(L, 2);
luax_pushboolean(L, p1->data == p2->data);
return 1;
}
Reference *luax_refif(lua_State *L, int type)
{
Reference *r = 0;
// Create a reference only if the test succeeds.
if (lua_type(L, -1) == type)
r = new Reference(L);
else // Pop the value even if it fails (but also if it succeeds).
lua_pop(L, 1);
return r;
}
void luax_printstack(lua_State *L)
{
for (int i = 1; i<=lua_gettop(L); i++)
{
std::cout << i << " - " << luaL_typename(L, i) << std::endl;
}
}
bool luax_toboolean(lua_State *L, int idx)
{
return (lua_toboolean(L, idx) != 0);
}
void luax_pushboolean(lua_State *L, bool b)
{
lua_pushboolean(L, b ? 1 : 0);
}
bool luax_optboolean(lua_State *L, int idx, bool b)
{
if (lua_isboolean(L, idx) == 1)
return (lua_toboolean(L, idx) == 1 ? true : false);
return b;
}
std::string luax_tostring(lua_State *L, int idx)
{
size_t len;
const char *str = lua_tolstring(L, idx, &len);
return std::string(str, len);
}
std::string luax_checkstring(lua_State *L, int idx)
{
size_t len;
const char *str = luaL_checklstring(L, idx, &len);
return std::string(str, len);
}
void luax_pushstring(lua_State *L, const std::string &str)
{
lua_pushlstring(L, str.data(), str.size());
}
bool luax_boolflag(lua_State *L, int table_index, const char *key, bool defaultValue)
{
lua_getfield(L, table_index, key);
bool retval;
if (lua_isnoneornil(L, -1))
retval = defaultValue;
else
retval = lua_toboolean(L, -1);
lua_pop(L, 1);
return retval;
}
int luax_intflag(lua_State *L, int table_index, const char *key, int defaultValue)
{
lua_getfield(L, table_index, key);
int retval;
if (!lua_isnumber(L, -1))
retval = defaultValue;
else
retval = (int) lua_tointeger(L, -1);
lua_pop(L, 1);
return retval;
}
int luax_assert_argc(lua_State *L, int min)
{
int argc = lua_gettop(L);
if (argc < min)
return luaL_error(L, "Incorrect number of arguments. Got [%d], expected at least [%d]", argc, min);
return 0;
}
int luax_assert_argc(lua_State *L, int min, int max)
{
int argc = lua_gettop(L);
if (argc < min || argc > max)
return luaL_error(L, "Incorrect number of arguments. Got [%d], expected [%d-%d]", argc, min, max);
return 0;
}
int luax_assert_function(lua_State *L, int idx)
{
if (!lua_isfunction(L, idx))
return luaL_error(L, "Argument must be of type \"function\".");
return 0;
}
int luax_assert_nilerror(lua_State *L, int idx)
{
if (lua_isnoneornil(L, idx))
{
if (lua_isstring(L, idx + 1))
return luaL_error(L, lua_tostring(L, idx + 1));
else
return luaL_error(L, "assertion failed!");
}
return 0;
}
void luax_setfuncs(lua_State *L, const luaL_Reg *l)
{
if (l == 0)
return;
for (; l->name != 0; l++)
{
lua_pushcfunction(L, l->func);
lua_setfield(L, -2, l->name);
}
}
int luax_register_module(lua_State *L, const WrappedModule &m)
{
// Put a reference to the C++ module in Lua.
luax_insistregistry(L, REGISTRY_MODULES);
Proxy *p = (Proxy *)lua_newuserdata(L, sizeof(Proxy));
p->retains = 1;
p->data = m.module;
p->flags = m.flags;
luaL_newmetatable(L, m.module->getName());
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, w__gc);
lua_setfield(L, -2, "__gc");
lua_setmetatable(L, -2);
lua_setfield(L, -2, m.name); // _modules[name] = proxy
lua_pop(L, 1);
// Gets the love table.
luax_insistglobal(L, "love");
// Create new table for module.
lua_newtable(L);
// Register all the functions.
if (m.functions != 0)
luax_setfuncs(L, m.functions);
// Register types.
if (m.types != 0)
for (const lua_CFunction *t = m.types; *t != 0; t++)
(*t)(L);
lua_pushvalue(L, -1);
lua_setfield(L, -3, m.name); // love.graphics = table
lua_remove(L, -2); // love
// Register module instance
Module::registerInstance(m.module);
return 1;
}
int luax_preload(lua_State *L, lua_CFunction f, const char *name)
{
lua_getglobal(L, "package");
lua_getfield(L, -1, "preload");
lua_pushcfunction(L, f);
lua_setfield(L, -2, name);
lua_pop(L, 2);
return 0;
}
int luax_register_type(lua_State *L, const char *tname, const luaL_Reg *f)
{
// Verify that this type name has a matching Type ID and type name mapping.
love::Type ltype;
if (!love::getType(tname, ltype))
printf("Missing type entry for type name: %s\n", tname);
// Get the place for storing and re-using instantiated love types.
luax_getregistry(L, REGISTRY_TYPES);
// Create registry._lovetypes if it doesn't exist yet.
if (!lua_istable(L, -1))
{
lua_newtable(L);
lua_replace(L, -2);
// Create a metatable.
lua_newtable(L);
// metatable.__mode = "v". Weak userdata values.
lua_pushliteral(L, "v");
lua_setfield(L, -2, "__mode");
// setmetatable(newtable, metatable)
lua_setmetatable(L, -2);
// registry._lovetypes = newtable
lua_setfield(L, LUA_REGISTRYINDEX, "_lovetypes");
}
else
lua_pop(L, 1);
luaL_newmetatable(L, tname);
// m.__index = m
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
// setup gc
lua_pushcfunction(L, w__gc);
lua_setfield(L, -2, "__gc");
// Add equality
lua_pushcfunction(L, w__eq);
lua_setfield(L, -2, "__eq");
// Add tostring function.
lua_pushstring(L, tname);
lua_pushcclosure(L, w__tostring, 1);
lua_setfield(L, -2, "__tostring");
// Add tostring to as type() as well.
lua_pushstring(L, tname);
lua_pushcclosure(L, w__tostring, 1);
lua_setfield(L, -2, "type");
// Add typeOf
lua_pushcfunction(L, w__typeOf);
lua_setfield(L, -2, "typeOf");
if (f != 0)
luax_setfuncs(L, f);
lua_pop(L, 1); // Pops metatable.
return 0;
}
int luax_table_insert(lua_State *L, int tindex, int vindex, int pos)
{
if (tindex < 0)
tindex = lua_gettop(L)+1+tindex;
if (vindex < 0)
vindex = lua_gettop(L)+1+vindex;
if (pos == -1)
{
lua_pushvalue(L, vindex);
lua_rawseti(L, tindex, lua_objlen(L, tindex)+1);
return 0;
}
else if (pos < 0)
pos = lua_objlen(L, tindex)+1+pos;
for (int i = lua_objlen(L, tindex)+1; i > pos; i--)
{
lua_rawgeti(L, tindex, i-1);
lua_rawseti(L, tindex, i);
}
lua_pushvalue(L, vindex);
lua_rawseti(L, tindex, pos);
return 0;
}
int luax_register_searcher(lua_State *L, lua_CFunction f, int pos)
{
// Add the package loader to the package.loaders table.
lua_getglobal(L, "package");
if (lua_isnil(L, -1))
return luaL_error(L, "Can't register searcher: package table does not exist.");
lua_getfield(L, -1, "loaders");
// Lua 5.2 renamed package.loaders to package.searchers.
if (lua_isnil(L, -1))
{
lua_pop(L, 1);
lua_getfield(L, -1, "searchers");
}
if (lua_isnil(L, -1))
return luaL_error(L, "Can't register searcher: package.loaders table does not exist.");
lua_pushcfunction(L, f);
luax_table_insert(L, -2, -1, pos);
lua_pop(L, 3);
return 0;
}
void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own)
{
Proxy *u = (Proxy *)lua_newuserdata(L, sizeof(Proxy));
u->data = (void *) data;
u->flags = flags;
u->retains = own ? 1 : 0;
luaL_newmetatable(L, name);
lua_setmetatable(L, -2);
}
void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own)
{
// Fetch the registry table of instantiated types.
luax_getregistry(L, REGISTRY_TYPES);
// The table might not exist - it should be insisted in luax_register_type.
if (!lua_istable(L, -1))
{
lua_pop(L, 1);
return luax_rawnewtype(L, name, flags, data, own);
}
// Get the value of lovetypes[data] on the stack.
lua_pushlightuserdata(L, (void *) data);
lua_gettable(L, -2);
// If the Proxy userdata isn't in the instantiated types table yet, add it.
if (lua_type(L, -1) != LUA_TUSERDATA)
{
lua_pop(L, 1);
luax_rawnewtype(L, name, flags, data, own);
lua_pushlightuserdata(L, (void *) data);
lua_pushvalue(L, -2);
// lovetypes[data] = Proxy.
lua_settable(L, -4);
// Remove the lovetypes table from the stack.
lua_remove(L, -2);
// The Proxy userdata remains at the top of the stack.
return;
}
// Remove the lovetypes table from the stack.
lua_remove(L, -2);
// If the object should be released on GC and we already have a stored
// Proxy, we should tell the Proxy that the object was retained again.
if (own)
{
Proxy *p = (Proxy *) lua_touserdata(L, -1);
thread::EmptyLock lock;
if (gcmutex)
lock.setLock(gcmutex);
if (p->retains >= 0)
++(p->retains);
}
// Keep the Proxy userdata on the stack.
}
bool luax_istype(lua_State *L, int idx, love::bits type)
{
if (lua_isuserdata(L, idx) == 0)
return false;
return ((((Proxy *)lua_touserdata(L, idx))->flags & type) == type);
}
int luax_getfunction(lua_State *L, const char *mod, const char *fn)
{
lua_getglobal(L, "love");
if (lua_isnil(L, -1)) return luaL_error(L, "Could not find global love!");
lua_getfield(L, -1, mod);
if (lua_isnil(L, -1)) return luaL_error(L, "Could not find love.%s!", mod);
lua_getfield(L, -1, fn);
if (lua_isnil(L, -1)) return luaL_error(L, "Could not find love.%s.%s!", mod, fn);
lua_remove(L, -2); // remove mod
lua_remove(L, -2); // remove fn
return 0;
}
int luax_convobj(lua_State *L, int idx, const char *mod, const char *fn)
{
// Convert string to a file.
luax_getfunction(L, mod, fn);
lua_pushvalue(L, idx); // The initial argument.
lua_call(L, 1, 2); // Call the function, one arg, one return value (plus optional errstring.)
luax_assert_nilerror(L, -2); // Make sure the function returned something.
lua_pop(L, 1); // Pop the second return value now that we don't need it.
lua_replace(L, idx); // Replace the initial argument with the new object.
return 0;
}
int luax_convobj(lua_State *L, int idxs[], int n, const char *mod, const char *fn)
{
luax_getfunction(L, mod, fn);
for (int i = 0; i < n; i++)
{
lua_pushvalue(L, idxs[i]); // The arguments.
}
lua_call(L, n, 2); // Call the function, n args, one return value (plus optional errstring.)
luax_assert_nilerror(L, -2); // Make sure the function returned something.
lua_pop(L, 1); // Pop the second return value now that we don't need it.
lua_replace(L, idxs[0]); // Replace the initial argument with the new object.
return 0;
}
int luax_pconvobj(lua_State *L, int idx, const char *mod, const char *fn)
{
// Convert string to a file.
luax_getfunction(L, mod, fn);
lua_pushvalue(L, idx); // The initial argument.
int ret = lua_pcall(L, 1, 1, 0); // Call the function, one arg, one return value.
if (ret == 0)
lua_replace(L, idx); // Replace the initial argument with the new object.
return ret;
}
int luax_pconvobj(lua_State *L, int idxs[], int n, const char *mod, const char *fn)
{
luax_getfunction(L, mod, fn);
for (int i = 0; i < n; i++)
{
lua_pushvalue(L, idxs[i]); // The arguments.
}
int ret = lua_pcall(L, n, 1, 0); // Call the function, n args, one return value.
if (ret == 0)
lua_replace(L, idxs[0]); // Replace the initial argument with the new object.
return ret;
}
int luax_insist(lua_State *L, int idx, const char *k)
{
// Convert to absolute index if necessary.
if (idx < 0 && idx > LUA_REGISTRYINDEX)
idx = lua_gettop(L) + ++idx;
lua_getfield(L, idx, k);
// Create if necessary.
if (!lua_istable(L, -1))
{
lua_pop(L, 1); // Pop the non-table.
lua_newtable(L);
lua_pushvalue(L, -1); // Duplicate the table to leave on top.
lua_setfield(L, idx, k); // lua_stack[idx][k] = lua_stack[-1] (table)
}
return 1;
}
int luax_insistglobal(lua_State *L, const char *k)
{
lua_getglobal(L, k);
if (!lua_istable(L, -1))
{
lua_pop(L, 1); // Pop the non-table.
lua_newtable(L);
lua_pushvalue(L, -1);
lua_setglobal(L, k);
}
return 1;
}
int luax_insistlove(lua_State *L, const char *k)
{
luax_insistglobal(L, "love");
luax_insist(L, -1, k);
// The love table should be replaced with the top stack
// item. Only the reqested table should remain on the stack.
lua_replace(L, -2);
return 1;
}
int luax_getlove(lua_State *L, const char *k)
{
lua_getglobal(L, "love");
if (!lua_isnil(L, -1))
{
lua_getfield(L, -1, k);
lua_replace(L, -2);
}
return 1;
}
int luax_insistregistry(lua_State *L, Registry r)
{
switch (r)
{
case REGISTRY_GC:
return luax_insistlove(L, "_gc");
case REGISTRY_MODULES:
return luax_insistlove(L, "_modules");
case REGISTRY_TYPES:
return luax_insist(L, LUA_REGISTRYINDEX, "_lovetypes");
default:
return luaL_error(L, "Attempted to use invalid registry.");
}
}
int luax_getregistry(lua_State *L, Registry r)
{
switch (r)
{
case REGISTRY_GC:
return luax_getlove(L, "_gc");
case REGISTRY_MODULES:
return luax_getlove(L, "_modules");
case REGISTRY_TYPES:
lua_getfield(L, LUA_REGISTRYINDEX, "_lovetypes");
return 1;
default:
return luaL_error(L, "Attempted to use invalid registry.");
}
}
extern "C" int luax_typerror(lua_State *L, int narg, const char *tname)
{
int argtype = lua_type(L, narg);
const char *argtname = 0;
// We want to use the love type name for userdata, if possible.
if (argtype == LUA_TUSERDATA && luaL_getmetafield(L, narg, "__tostring") != 0)
{
lua_pushvalue(L, narg);
if (lua_pcall(L, 1, 1, 0) == 0 && lua_type(L, -1) == LUA_TSTRING)
{
argtname = lua_tostring(L, -1);
// Non-love userdata might have a tostring metamethod which doesn't
// describe its type, so we only use __tostring for love types.
love::Type t;
if (!love::getType(argtname, t))
argtname = 0;
}
}
if (argtname == 0)
argtname = lua_typename(L, argtype);
const char *msg = lua_pushfstring(L, "%s expected, got %s", tname, argtname);
return luaL_argerror(L, narg, msg);
}
StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[] =
{
{"Invalid", INVALID_ID},
{"Object", OBJECT_ID},
{"Data", DATA_ID},
{"Module", MODULE_ID},
// Filesystem
{"File", FILESYSTEM_FILE_ID},
{"FileData", FILESYSTEM_FILE_DATA_ID},
// Font
{"GlyphData", FONT_GLYPH_DATA_ID},
{"Rasterizer", FONT_RASTERIZER_ID},
// Graphics
{"Drawable", GRAPHICS_DRAWABLE_ID},
{"Image", GRAPHICS_IMAGE_ID},
{"Quad", GRAPHICS_QUAD_ID},
{"Font", GRAPHICS_FONT_ID},
{"ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_ID},
{"SpriteBatch", GRAPHICS_SPRITE_BATCH_ID},
{"Canvas", GRAPHICS_CANVAS_ID},
{"Shader", GRAPHICS_SHADER_ID},
{"Mesh", GRAPHICS_MESH_ID},
// Image
{"ImageData", IMAGE_IMAGE_DATA_ID},
{"CompressedData", IMAGE_COMPRESSED_DATA_ID},
// Joystick
{"Joystick", JOYSTICK_JOYSTICK_ID},
// Math
{"RandomGenerator", MATH_RANDOM_GENERATOR_ID},
{"BezierCurve", MATH_BEZIER_CURVE_ID},
// Audio
{"Source", AUDIO_SOURCE_ID},
// Sound
{"SoundData", SOUND_SOUND_DATA_ID},
{"Decoder", SOUND_DECODER_ID},
// Mouse
{"Cursor", MOUSE_CURSOR_ID},
// Physics
{"World", PHYSICS_WORLD_ID},
{"Contact", PHYSICS_CONTACT_ID},
{"Body", PHYSICS_BODY_ID},
{"Fixture", PHYSICS_FIXTURE_ID},
{"Shape", PHYSICS_SHAPE_ID},
{"CircleShape", PHYSICS_CIRCLE_SHAPE_ID},
{"PolygonShape", PHYSICS_POLYGON_SHAPE_ID},
{"EdgeShape", PHYSICS_EDGE_SHAPE_ID},
{"ChainShape", PHYSICS_CHAIN_SHAPE_ID},
{"Joint", PHYSICS_JOINT_ID},
{"MouseJoint", PHYSICS_MOUSE_JOINT_ID},
{"DistanceJoint", PHYSICS_DISTANCE_JOINT_ID},
{"PrismaticJoint", PHYSICS_PRISMATIC_JOINT_ID},
{"RevoluteJoint", PHYSICS_REVOLUTE_JOINT_ID},
{"PulleyJoint", PHYSICS_PULLEY_JOINT_ID},
{"GearJoint", PHYSICS_GEAR_JOINT_ID},
{"FrictionJoint", PHYSICS_FRICTION_JOINT_ID},
{"WeldJoint", PHYSICS_WELD_JOINT_ID},
{"RopeJoint", PHYSICS_ROPE_JOINT_ID},
{"WheelJoint", PHYSICS_WHEEL_JOINT_ID},
{"MotorJoint", PHYSICS_MOTOR_JOINT_ID},
// Thread
{"Thread", THREAD_THREAD_ID},
{"Channel", THREAD_CHANNEL_ID},
// The modules themselves. Only add abstracted modules here.
{"filesystem", MODULE_FILESYSTEM_ID},
{"graphics", MODULE_GRAPHICS_ID},
{"image", MODULE_IMAGE_ID},
{"sound", MODULE_SOUND_ID},
};
StringMap<Type, TYPE_MAX_ENUM> types(typeEntries, sizeof(typeEntries));
bool getType(const char *in, love::Type &out)
{
return types.find(in, out);
}
bool getType(love::Type in, const char *&out)
{
return types.find(in, out);
}
Type luax_type(lua_State *L, int idx)
{
Type t = INVALID_ID;
types.find(luaL_checkstring(L, idx), t);
return t;
}
} // love
+494
View File
@@ -0,0 +1,494 @@
/**
* Copyright (c) 2006-2013 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_RUNTIME_H
#define LOVE_RUNTIME_H
// LOVE
#include "types.h"
#include "Object.h"
// Lua
extern "C" {
#define LUA_COMPAT_ALL
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
namespace love
{
// Forward declarations.
class Module;
class Reference;
// Exposed mutex of the GC
extern void *_gcmutex;
/**
* Registries represent special tables which can be accessed with
* luax_insistregistry and luax_getregistry.
**/
enum Registry
{
REGISTRY_GC = 1,
REGISTRY_MODULES,
REGISTRY_TYPES
};
/**
* This structure wraps all Lua-exposed objects. It exists in the
* Lua state as a full userdata (so we can catch __gc "events"),
* though the Object it refers to is light userdata in the sense
* that it is not allocated by the Lua VM.
**/
struct Proxy
{
// Holds type information (see types.h).
bits flags;
// The light userdata (pointer to the love::Object).
void *data;
// The number of times release() should be called on GC.
int retains;
};
/**
* A Module with Lua wrapper functions and other data.
**/
struct WrappedModule
{
// The module containing the functions.
Module *module;
// The name for the table to put the functions in, without the 'love'-prefix.
const char *name;
// The type flags of this module.
love::bits flags;
// The functions of the module (last element {0,0}).
const luaL_Reg *functions;
// A list of functions which expose the types of the modules (last element 0).
const lua_CFunction *types;
};
/**
* Returns a reference to the top stack element (-1) if the value
* is of the specified type. If the value is incorrect, zero is returned.
*
* In any case, the top stack element is popped, regardless of its type.
**/
Reference *luax_refif(lua_State *L, int type);
/**
* Prints the current contents of the stack. Only useful for debugging.
* @param L The Lua state.
**/
void luax_printstack(lua_State *L);
/**
* Converts the value at idx to a bool. It follow the same rules
* as lua_toboolean, but returns a bool instead of an int.
* @param L The Lua state.
* @param idx The index on the Lua stack.
* @return True if the value evaluates to true, false otherwise.
**/
bool luax_toboolean(lua_State *L, int idx);
/**
* Pushes a bool onto the stack. It's the same as lua_pushboolean,
* but with bool instead of int.
* @param L The Lua state.
* @param b The bool to push.
**/
void luax_pushboolean(lua_State *L, bool b);
/**
* Converts the value at idx to a bool, or if not present, b is returned.
* @param L The Lua state.
* @param idx The index of the Lua stack.
* @param b The value to return if no value exist at the specified index.
* @return True if the value evaluates to true, false otherwise.
**/
bool luax_optboolean(lua_State *L, int idx, bool b);
/**
* Converts the value at idx to a std::string. It takes care of the string
* size and possible embedded nulls.
* @param L The Lua state.
* @param idx The index on the Lua stack.
* @return Copy of the string at the specified index.
**/
std::string luax_tostring(lua_State *L, int idx);
/**
* Converts the value at idx to a std::string. It takes care of the string
* size and possible embedded nulls.
* @param L The Lua state.
* @param idx The index on the Lua stack.
* @return Copy of the string at the specified index.
**/
std::string luax_checkstring(lua_State *L, int idx);
/**
* Pushes a std::string onto the stack. It uses the length of the string
* for lua_pushlstring's len argument.
* @param L The Lua state.
* @param str The string to push.
**/
void luax_pushstring(lua_State *L, const std::string &str);
bool luax_boolflag(lua_State *L, int table_index, const char *key, bool defaultValue);
int luax_intflag(lua_State *L, int table_index, const char *key, int defaultValue);
/**
* Convert the value at the specified index to an Lua number, and then
* convert to a float.
*
* @param L The Lua state.
* @param idx The index on the stack.
*/
inline float luax_tofloat(lua_State *L, int idx)
{
return static_cast<float>(lua_tonumber(L, idx));
}
/**
* Like luax_tofloat, but checks that the value is a number.
*
* @see luax_tofloat
*/
inline float luax_checkfloat(lua_State *L, int idx)
{
return static_cast<float>(luaL_checknumber(L, idx));
}
/**
* Require at least 'min' number of items on the stack.
* @param L The Lua state.
* @param min The minimum number of items on the stack.
* @return Zero if conditions are met, otherwise a Lua error (longjmp).
**/
int luax_assert_argc(lua_State *L, int min);
/**
* Require at least 'min', but more than 'max' items on the stack.
* @param L The Lua state.
* @param min The minimum number of items on the stack.
* @param max The maximum number of items on the stack.
* @return Zero if conditions are met, otherwise a Lua error (longjmp).
**/
int luax_assert_argc(lua_State *L, int min, int max);
/**
* Require that the value at idx is a function.
* @param L The Lua state.
*@param idx The index on the stack.
**/
int luax_assert_function(lua_State *L, int idx);
/**
* Require that the value at idx is not nil. If it is, the function throws an
* error using an optional error string at idx+1.
* @param L The Lua state.
* @param idx The index on the stack.
**/
int luax_assert_nilerror(lua_State *L, int idx);
/**
* Registers all functions in the array l (see luaL_Reg) into the table at the
* top of the stack.
* Similar to Lua 5.2's luaL_setfuncs without the upvalues, and to Lua 5.1's
* luaL_register without the library name.
**/
void luax_setfuncs(lua_State *L, const luaL_Reg *l);
/**
* Register a module in the love table. The love table will be created if it does not exist.
* @param L The Lua state.
**/
int luax_register_module(lua_State *L, const WrappedModule &m);
/**
* Inserts a module with 'name' into the package.preloaded table.
* @param f The function to be called when the module is opened.
* @param name The name of the module, with 'love'-prefix, for instance 'love.graphics'.
**/
int luax_preload(lua_State *L, lua_CFunction f, const char *name);
/**
* Register a new type.
* @param tname The name of the type. This must not conflict with other type names,
* even from other modules.
* @param f The list of member functions for the type.
**/
int luax_register_type(lua_State *L, const char *tname, const luaL_Reg *f = 0);
/**
* Do a table.insert from C
* @param L the state
* @param tindex the stack index of the table
* @param vindex the stack index of the value
* @param pos the position to insert it in
**/
int luax_table_insert(lua_State *L, int tindex, int vindex, int pos = -1);
/**
* Register a new searcher function for package.loaders. This can for instance enable
* loading of files through love.filesystem using standard require.
* @param L The Lua state.
* @param f The searcher function.
* @param pos The position to insert the loader in.
**/
int luax_register_searcher(lua_State *L, lua_CFunction f, int pos = -1);
/**
* Pushes a Lua representation of the given object onto the stack, creating and
* storing the Lua representation in a weak table if it doesn't exist yet.
* @param L The Lua state.
* @param name The name of the type. This must match the name used with luax_register_type.
* @param flags The type information of the object.
* @param data The pointer to the actual object.
* @param own Set this to true (default) if the object should be released upon garbage collection.
**/
void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own = true);
/**
* Creates a new Lua representation of the given object *without* checking if it
* exists yet, and *without* storing it in a weak table.
* This should only be used when performance is an extreme concern and the
* object is not ever expected to be pushed to Lua again, as it prevents the
* Lua-side objects from working in all cases when used as keys in tables.
* @param L The Lua state.
* @param name The name of the type. This must match the name used with luax_register_type.
* @param flags The type information of the object.
* @param data The pointer to the actual object.
* @param own Set this to true (default) if the object should be released upon garbage collection.
**/
void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own = true);
/**
* Checks whether the value at idx is a certain type.
* @param L The Lua state.
* @param idx The index on the stack.
* @param type The type to check for.
* @return True if the value is Proxy of the specified type, false otherwise.
**/
bool luax_istype(lua_State *L, int idx, love::bits type);
/**
* Gets the function love.module.function and puts it on top of the stack (alone). If the
* love table, the module, or the function does not exist, an error is returned.
* @return An error if nonexistent, or 1 if successful.
**/
int luax_getfunction(lua_State *L, const char *module, const char *function);
/**
* Converts an object into another object by the specified function love.module.function.
* The conversion function must accept a single object of the relevant type as a parameter,
* and returnone value. If the function does not exist (see luax_getfunction), an error is returned.
*
* Note that the initial object at idx is replaced by the new object.
*
* @param L The Lua state.
* @param idx The index on the stack.
* @param module The module in the love table.
* @param function The function in the module.
**/
int luax_convobj(lua_State *L, int idx, const char *module, const char *function);
/**
* Converts an object into another object by the specified function love.module.function.
* The conversion function must accept a single object of the relevant type as its first parameter,
* and return one value. If the function does not exist (see luax_getfunction), an error is returned.
*
* Note that the initial object at idx is replaced by the new object.
*
* @param L The Lua state.
* @param idxs An array of indices on the stack.
* @param n How many arguments are being passed.
* @param module The module in the love table.
* @param function The function in the module.
**/
int luax_convobj(lua_State *L, int idxs[], int n, const char *module, const char *function);
// pcall versions of the above
int luax_pconvobj(lua_State *L, int idx, const char *module, const char *function);
int luax_pconvobj(lua_State *L, int idxs[], int n, const char *module, const char *function);
/**
* 'Insist' that a table 'k' exists in the table at idx. Insistence involves that the
* table (k) is created if it does not exist in the table at idx. The table at idx must
* pre-exist, however. Also note that if the a non-table value exists at the specified
* location, it will be overwritten with a new table. The insisted table, and only the
* insisted table, will be placed on top of the stack.
*
* @param idx The index on the stack containing a table.
* @param k The name of the table we are insisting exist.
**/
int luax_insist(lua_State *L, int idx, const char *k);
/**
* Insist that a global table 'k' exists. See luax_insist.
* @param k The name of the table we are insisting exist.
**/
int luax_insistglobal(lua_State *L, const char *k);
/**
* Insists that a table 'k' exists inside the 'love' table. See luax_insist.
* @param k The name of the table we are insisting exist.
**/
int luax_insistlove(lua_State *L, const char *k);
/**
* Pushes the table 'k' in the love table onto the stack. Pushes nil if the
* table doesn't exist.
* @param k The name of the table we want to get.
**/
int luax_getlove(lua_State *L, const char *k);
/**
* Gets (creates if needed) the specified Registry, and pushes it into the
* stack.
* @param L The Lua state.
* @param r The Registry to get.
**/
int luax_insistregistry(lua_State *L, Registry r);
/**
* Gets the specified Registry, and pushes it onto the stack. Pushes nil if the
* registry hasn't been created (see luax_insistregistry.)
* @param L The Lua state.
* @param r The Registry to get.
**/
int luax_getregistry(lua_State *L, Registry r);
extern "C" { // Also called from luasocket
int luax_typerror(lua_State *L, int narg, const char *tname);
}
/**
* Like luax_totype, but causes an error if the value at idx is not Proxy,
* or is not the specified type.
* @param L The Lua state.
* @param idx The index on the stack.
* @param name The name of the type.
* @param type The type bit.
**/
template <typename T>
T *luax_checktype(lua_State *L, int idx, const char *name, love::bits type)
{
if (lua_isuserdata(L, idx) == 0)
luax_typerror(L, idx, name);
Proxy *u = (Proxy *)lua_touserdata(L, idx);
if ((u->flags & type) != type)
luax_typerror(L, idx, name);
return (T *)u->data;
}
template <typename T>
T *luax_getmodule(lua_State *L, const char *k, love::bits type)
{
luax_insistregistry(L, REGISTRY_MODULES);
lua_getfield(L, -1, k);
if (!lua_isuserdata(L, -1))
luaL_error(L, "Tried to get nonexistant module %s.", k);
Proxy *u = (Proxy *)lua_touserdata(L, -1);
if ((u->flags & type) != type)
luaL_error(L, "Incorrect module %s", k);
lua_pop(L, 2);
return (T *)u->data;
}
template <typename T>
T *luax_optmodule(lua_State *L, const char *k, love::bits type)
{
luax_insistregistry(L, REGISTRY_MODULES);
lua_getfield(L, -1, k);
if (!lua_isuserdata(L, -1))
{
lua_pop(L, 2);
return 0;
}
Proxy *u = (Proxy *)lua_touserdata(L, -1);
if ((u->flags & type) != type)
luaL_error(L, "Incorrect module %s", k);
lua_pop(L, 2);
return (T *) u->data;
}
/**
* Converts the value at idx to the specified type without checking that
* this conversion is valid. If the type has been previously verified with
* luax_istype, then this can be safely used. Otherwise, use luax_checktype.
* @param L The Lua state.
* @param idx The index on the stack.
* @param name The name of the type.
* @param type The type bit.
**/
template <typename T>
T *luax_totype(lua_State *L, int idx, const char * /* name */, love::bits /* type */)
{
return (T *)(((Proxy *)lua_touserdata(L, idx))->data);
}
Type luax_type(lua_State *L, int idx);
/**
* Macro for converting a LOVE exception into a Lua error.
* lua_error (and luaL_error) cannot be called from inside the exception handler
* because they use longjmp, which causes undefined behaviour when the
* destructor of the exception would have been called.
**/
#define EXCEPT_GUARD(A) \
{ \
bool should_error = false; \
try { A } \
catch (love::Exception &e) \
{ \
should_error = true; \
lua_pushstring(L, e.what()); \
} \
if (should_error) \
return luaL_error(L, "%s", lua_tostring(L, -1)); \
}
} // love
#endif // LOVE_RUNTIME_H
+202
View File
@@ -0,0 +1,202 @@
/**
* Copyright (c) 2006-2013 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_TYPES_H
#define LOVE_TYPES_H
// STD
#include <bitset>
namespace love
{
enum Type
{
INVALID_ID = 0,
// Cross-module types.
OBJECT_ID,
DATA_ID,
MODULE_ID,
// Filesystem.
FILESYSTEM_FILE_ID,
FILESYSTEM_FILE_DATA_ID,
// Font
FONT_GLYPH_DATA_ID,
FONT_RASTERIZER_ID,
// Graphics
GRAPHICS_DRAWABLE_ID,
GRAPHICS_DRAWQABLE_ID,
GRAPHICS_IMAGE_ID,
GRAPHICS_QUAD_ID,
GRAPHICS_FONT_ID,
GRAPHICS_PARTICLE_SYSTEM_ID,
GRAPHICS_SPRITE_BATCH_ID,
GRAPHICS_CANVAS_ID,
GRAPHICS_SHADER_ID,
GRAPHICS_MESH_ID,
// Image
IMAGE_IMAGE_DATA_ID,
IMAGE_COMPRESSED_DATA_ID,
// Joystick
JOYSTICK_JOYSTICK_ID,
// Math
MATH_RANDOM_GENERATOR_ID,
MATH_BEZIER_CURVE_ID,
// Audio
AUDIO_SOURCE_ID,
// Sound
SOUND_SOUND_DATA_ID,
SOUND_DECODER_ID,
// Mouse
MOUSE_CURSOR_ID,
// Physics
PHYSICS_WORLD_ID,
PHYSICS_CONTACT_ID,
PHYSICS_BODY_ID,
PHYSICS_FIXTURE_ID,
PHYSICS_SHAPE_ID,
PHYSICS_CIRCLE_SHAPE_ID,
PHYSICS_POLYGON_SHAPE_ID,
PHYSICS_EDGE_SHAPE_ID,
PHYSICS_CHAIN_SHAPE_ID,
PHYSICS_JOINT_ID,
PHYSICS_MOUSE_JOINT_ID,
PHYSICS_DISTANCE_JOINT_ID,
PHYSICS_PRISMATIC_JOINT_ID,
PHYSICS_REVOLUTE_JOINT_ID,
PHYSICS_PULLEY_JOINT_ID,
PHYSICS_GEAR_JOINT_ID,
PHYSICS_FRICTION_JOINT_ID,
PHYSICS_WELD_JOINT_ID,
PHYSICS_ROPE_JOINT_ID,
PHYSICS_WHEEL_JOINT_ID,
PHYSICS_MOTOR_JOINT_ID,
// Thread
THREAD_THREAD_ID,
THREAD_CHANNEL_ID,
// The modules themselves. Only add abstracted modules here.
MODULE_FILESYSTEM_ID,
MODULE_GRAPHICS_ID,
MODULE_IMAGE_ID,
MODULE_SOUND_ID,
// Count the number of bits needed.
TYPE_MAX_ENUM
};
typedef std::bitset<TYPE_MAX_ENUM> bits;
const bits INVALID_T = bits(1) << INVALID_ID;
const bits OBJECT_T = bits(1) << OBJECT_ID;
const bits DATA_T = (bits(1) << DATA_ID) | OBJECT_T;
const bits MODULE_T = (bits(1) << MODULE_ID) | OBJECT_T;
// Filesystem.
const bits FILESYSTEM_FILE_T = (bits(1) << FILESYSTEM_FILE_ID) | OBJECT_T;
const bits FILESYSTEM_FILE_DATA_T = (bits(1) << FILESYSTEM_FILE_DATA_ID) | DATA_T;
const bits FONT_GLYPH_DATA_T = (bits(1) << FONT_GLYPH_DATA_ID) | DATA_T;
const bits FONT_RASTERIZER_T = (bits(1) << FONT_RASTERIZER_ID) | OBJECT_T;
// Graphics.
const bits GRAPHICS_DRAWABLE_T = (bits(1) << GRAPHICS_DRAWABLE_ID) | OBJECT_T;
const bits GRAPHICS_DRAWQABLE_T = (bits(1) << GRAPHICS_DRAWQABLE_ID) | GRAPHICS_DRAWABLE_T;
const bits GRAPHICS_IMAGE_T = (bits(1) << GRAPHICS_IMAGE_ID) | GRAPHICS_DRAWQABLE_T;
const bits GRAPHICS_QUAD_T = (bits(1) << GRAPHICS_QUAD_ID) | OBJECT_T;
const bits GRAPHICS_FONT_T = (bits(1) << GRAPHICS_FONT_ID) | OBJECT_T;
const bits GRAPHICS_PARTICLE_SYSTEM_T = (bits(1) << GRAPHICS_PARTICLE_SYSTEM_ID) | GRAPHICS_DRAWABLE_T;
const bits GRAPHICS_SPRITE_BATCH_T = (bits(1) << GRAPHICS_SPRITE_BATCH_ID) | GRAPHICS_DRAWABLE_T;
const bits GRAPHICS_CANVAS_T = (bits(1) << GRAPHICS_CANVAS_ID) | GRAPHICS_DRAWQABLE_T;
const bits GRAPHICS_SHADER_T = (bits(1) << GRAPHICS_SHADER_ID) | OBJECT_T;
const bits GRAPHICS_MESH_T = (bits(1) << GRAPHICS_MESH_ID) | GRAPHICS_DRAWABLE_T;
// Image.
const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T;
const bits IMAGE_COMPRESSED_DATA_T = (bits(1) << IMAGE_COMPRESSED_DATA_ID) | DATA_T;
// Joystick.
const bits JOYSTICK_JOYSTICK_T = (bits(1) << JOYSTICK_JOYSTICK_ID) | OBJECT_T;
// Math.
const bits MATH_RANDOM_GENERATOR_T = (bits(1) << MATH_RANDOM_GENERATOR_ID) | OBJECT_T;
const bits MATH_BEZIER_CURVE_T = (bits(1) << MATH_BEZIER_CURVE_ID) | OBJECT_T;
// Audio.
const bits AUDIO_SOURCE_T = (bits(1) << AUDIO_SOURCE_ID) | OBJECT_T;
// Sound.
const bits SOUND_SOUND_DATA_T = (bits(1) << SOUND_SOUND_DATA_ID) | DATA_T;
const bits SOUND_DECODER_T = bits(1) << SOUND_DECODER_ID;
// Mouse.
const bits MOUSE_CURSOR_T = (bits(1) << MOUSE_CURSOR_ID) | OBJECT_T;
// Physics.
const bits PHYSICS_WORLD_T = (bits(1) << PHYSICS_WORLD_ID) | OBJECT_T;
const bits PHYSICS_CONTACT_T = (bits(1) << PHYSICS_CONTACT_ID) | OBJECT_T;
const bits PHYSICS_BODY_T = (bits(1) << PHYSICS_BODY_ID) | OBJECT_T;
const bits PHYSICS_FIXTURE_T = (bits(1) << PHYSICS_FIXTURE_ID) | OBJECT_T;
const bits PHYSICS_SHAPE_T = (bits(1) << PHYSICS_SHAPE_ID) | OBJECT_T;
const bits PHYSICS_CIRCLE_SHAPE_T = (bits(1) << PHYSICS_CIRCLE_SHAPE_ID) | PHYSICS_SHAPE_T;
const bits PHYSICS_POLYGON_SHAPE_T = (bits(1) << PHYSICS_POLYGON_SHAPE_ID) | PHYSICS_SHAPE_T;
const bits PHYSICS_EDGE_SHAPE_T = (bits(1) << PHYSICS_EDGE_SHAPE_ID) | PHYSICS_SHAPE_T;
const bits PHYSICS_CHAIN_SHAPE_T = (bits(1) << PHYSICS_CHAIN_SHAPE_ID) | PHYSICS_SHAPE_T;
const bits PHYSICS_JOINT_T = (bits(1) << PHYSICS_JOINT_ID) | OBJECT_T;
const bits PHYSICS_MOUSE_JOINT_T = (bits(1) << PHYSICS_MOUSE_JOINT_ID) | PHYSICS_JOINT_T;
const bits PHYSICS_DISTANCE_JOINT_T = (bits(1) << PHYSICS_DISTANCE_JOINT_ID) | PHYSICS_JOINT_T;
const bits PHYSICS_PRISMATIC_JOINT_T = (bits(1) << PHYSICS_PRISMATIC_JOINT_ID) | PHYSICS_JOINT_T;
const bits PHYSICS_REVOLUTE_JOINT_T = (bits(1) << PHYSICS_REVOLUTE_JOINT_ID) | PHYSICS_JOINT_T;
const bits PHYSICS_PULLEY_JOINT_T = (bits(1) << PHYSICS_PULLEY_JOINT_ID) | PHYSICS_JOINT_T;
const bits PHYSICS_GEAR_JOINT_T = (bits(1) << PHYSICS_GEAR_JOINT_ID) | PHYSICS_JOINT_T;
const bits PHYSICS_FRICTION_JOINT_T = (bits(1) << PHYSICS_FRICTION_JOINT_ID) | PHYSICS_JOINT_T;
const bits PHYSICS_WELD_JOINT_T = (bits(1) << PHYSICS_WELD_JOINT_ID) | PHYSICS_JOINT_T;
const bits PHYSICS_ROPE_JOINT_T = (bits(1) << PHYSICS_ROPE_JOINT_ID) | PHYSICS_JOINT_T;
const bits PHYSICS_WHEEL_JOINT_T = (bits(1) << PHYSICS_WHEEL_JOINT_ID) | PHYSICS_JOINT_T;
const bits PHYSICS_MOTOR_JOINT_T = (bits(1) << PHYSICS_MOTOR_JOINT_ID) | PHYSICS_JOINT_T;
// Thread.
const bits THREAD_THREAD_T = (bits(1) << THREAD_THREAD_ID) | OBJECT_T;
const bits THREAD_CHANNEL_T = (bits(1) << THREAD_CHANNEL_ID) | OBJECT_T;
// Modules.
const bits MODULE_FILESYSTEM_T = (bits(1) << MODULE_FILESYSTEM_ID) | MODULE_T;
const bits MODULE_GRAPHICS_T = (bits(1) << MODULE_GRAPHICS_ID) | MODULE_T;
const bits MODULE_IMAGE_T = (bits(1) << MODULE_IMAGE_ID) | MODULE_T;
const bits MODULE_SOUND_T = (bits(1) << MODULE_SOUND_ID) | MODULE_T;
bool getType(const char *in, Type &out);
bool getType(Type in, const char *&out);
} // love
#endif // LOVE_TYPES_H
+61
View File
@@ -0,0 +1,61 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "utf8.h"
#ifdef LOVE_WINDOWS
namespace love
{
std::string to_utf8(LPCWSTR wstr)
{
size_t wide_len = wcslen(wstr)+1;
// Get size in UTF-8.
int utf8_size = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, 0, 0, 0, 0);
char *utf8_str = new char[utf8_size];
// Convert to UTF-8.
int ok = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, utf8_str, utf8_size, 0, 0);
std::string ret;
if (ok)
ret = utf8_str;
delete[] utf8_str;
return ret;
}
void replace_char(std::string &str, char find, char replace)
{
int length = str.length();
for (int i = 0; i<length; i++)
{
if (str[i] == find)
str[i] = replace;
}
}
} // love
#endif // LOVE_WINDOWS
+48
View File
@@ -0,0 +1,48 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "config.h"
#ifdef LOVE_WINDOWS
#include <string>
#include <windows.h>
namespace love
{
/**
* Convert the wide string to a UTF-8 encoded string.
* @param wstr The wide-char string.
* @return A UTF-8 string.
**/
std::string to_utf8(LPCWSTR wstr);
/**
* Replace all occurences of 'find' with 'replace' in a string.
* @param str The string to modify.
* @param find The character to match.
* @param replace The character to replace matches.
**/
void replace_char(std::string &str, char find, char replace);
} // love
#endif // LOVE_WINDOWS
+37
View File
@@ -0,0 +1,37 @@
/**
* Copyright (c) 2006-2013 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_VERSION_H
#define LOVE_VERSION_H
namespace love
{
// Version stuff.
const int VERSION_MAJOR = 0;
const int VERSION_MINOR = 9;
const int VERSION_REV = 0;
const char *VERSION = "0.9.0";
const char *VERSION_COMPATIBILITY[] = { VERSION, 0 };
const char *VERSION_CODENAME = "Baby Inspector";
} // love
#endif // LOVE_VERSION_H
+66
View File
@@ -0,0 +1,66 @@
/**
* Copyright (c) 2006-2013 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.
**/
#include "wrap_Data.h"
namespace love
{
Data *luax_checkdata(lua_State *L, int idx)
{
return luax_checktype<Data>(L, idx, "Data", DATA_T);
}
int w_Data_getString(lua_State *L)
{
Data *t = luax_checkdata(L, 1);
lua_pushlstring(L, (const char *) t->getData(), (size_t) t->getSize());
return 1;
}
int w_Data_getPointer(lua_State *L)
{
Data *t = luax_checkdata(L, 1);
lua_pushlightuserdata(L, t->getData());
return 1;
}
int w_Data_getSize(lua_State *L)
{
Data *t = luax_checkdata(L, 1);
lua_pushinteger(L, t->getSize());
return 1;
}
const luaL_Reg w_Data_functions[] =
{
{ "getString", w_Data_getString },
{ "getPointer", w_Data_getPointer },
{ "getSize", w_Data_getSize },
{ 0, 0 }
};
int w_Data_open(lua_State *L)
{
luax_register_type(L, "Data", w_Data_functions);
return 0;
}
} // love
+39
View File
@@ -0,0 +1,39 @@
/**
* Copyright (c) 2006-2013 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_DATA_H
#define LOVE_WRAP_DATA_H
// LOVE
#include "runtime.h"
#include "Data.h"
namespace love
{
Data *luax_checkdata(lua_State *L, int idx);
int w_Data_getString(lua_State *L);
int w_Data_getPointer(lua_State *L);
int w_Data_getSize(lua_State *L);
int w_Data_open(lua_State *L);
} // love
#endif // LOVE_WRAP_DATA_H