mirror of
https://github.com/love2d/love-android.git
synced 2026-08-19 04:05:22 +02:00
imported Löve GLES branch (changeset 1ba9037e558b)
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 ®istryInstance()
|
||||
{
|
||||
if (!registry)
|
||||
registry = new ModuleRegistry;
|
||||
|
||||
return *registry;
|
||||
}
|
||||
|
||||
void freeEmptyRegistry()
|
||||
{
|
||||
if (registry && registry->empty())
|
||||
{
|
||||
delete registry;
|
||||
registry = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace love
|
||||
{
|
||||
|
||||
Module::~Module()
|
||||
{
|
||||
ModuleRegistry ®istry = 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 ®istry = 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 ®istry = registryInstance();
|
||||
|
||||
auto it = registry.find(name);
|
||||
|
||||
if (registry.end() == it)
|
||||
return nullptr;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
Module *Module::findInstance(const std::string &name)
|
||||
{
|
||||
ModuleRegistry ®istry = registryInstance();
|
||||
|
||||
for (auto it = registry.begin(); it != registry.end(); ++it)
|
||||
{
|
||||
if (it->first.find(name) == 0)
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // love
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user