Browse Source

Merged default into minor

--HG--
branch : minor
Alex Szpakowski 11 years ago
parent
commit
34688e929e

+ 5 - 7
platform/macosx/OSX.mm

@@ -34,13 +34,11 @@ std::string getLoveInResources()
 
 	@autoreleasepool
 	{
-		// check to see if there are any .love files in Resources - props to stevejohnson/diordna
-		NSArray *lovePaths = [[NSBundle mainBundle] pathsForResourcesOfType:@"love" inDirectory:nil];
-		if ([lovePaths count] > 0)
-		{
-			NSString *firstLovePath = [lovePaths objectAtIndex:0];
-			path = std::string([firstLovePath UTF8String]);
-		}
+		// Check to see if there are any .love files in Resources.
+		NSString *lovepath = [[NSBundle mainBundle] pathForResource:nil ofType:@"love"];
+
+		if (lovepath != nil)
+			path = [lovepath UTF8String];
 	}
 
 	return path;

+ 0 - 1
src/modules/audio/openal/Audio.h

@@ -24,7 +24,6 @@
 // STD
 #include <queue>
 #include <map>
-#include <iostream>
 #include <cmath>
 
 // LOVE

+ 0 - 1
src/modules/audio/openal/Pool.h

@@ -24,7 +24,6 @@
 // STD
 #include <queue>
 #include <map>
-#include <iostream>
 #include <cmath>
 
 // LOVE

+ 1 - 1
src/modules/audio/openal/Source.h

@@ -144,7 +144,7 @@ private:
 	ALuint source;
 	bool valid;
 
-	static const unsigned int MAX_BUFFERS = 32;
+	static const unsigned int MAX_BUFFERS = 8;
 	ALuint streamBuffers[MAX_BUFFERS];
 
 	Object::StrongRef<StaticDataBuffer> staticBuffer;

+ 3 - 0
src/modules/audio/wrap_Audio.cpp

@@ -26,6 +26,9 @@
 
 #include "common/runtime.h"
 
+// C++
+#include <iostream>
+
 namespace love
 {
 namespace audio

+ 12 - 20
src/modules/event/sdl/Event.cpp

@@ -42,17 +42,12 @@ namespace sdl
 // we want them in pixel coordinates (may be different with high-DPI enabled.)
 static void windowToPixelCoords(int *x, int *y)
 {
-	double scale = 1.0;
-
 	window::Window *window = Module::getInstance<window::Window>(Module::M_WINDOW);
-	if (window != nullptr)
-		scale = window->getPixelScale();
-
-	if (x != nullptr)
-		*x = int(double(*x) * scale);
 
-	if (y != nullptr)
-		*y = int(double(*y) * scale);
+	if (window && x)
+		*x = (int) window->toPixels(*x);
+	if (window && y)
+		*y = (int) window->toPixels(*y);
 }
 
 
@@ -74,15 +69,11 @@ Event::~Event()
 
 void Event::pump()
 {
-	SDL_PumpEvents();
-
-	static SDL_Event e;
-
-	Message *msg;
+	SDL_Event e;
 
 	while (SDL_PollEvent(&e))
 	{
-		msg = convert(e);
+		Message *msg = convert(e);
 		if (msg)
 		{
 			push(msg);
@@ -93,16 +84,17 @@ void Event::pump()
 
 Message *Event::wait()
 {
-	static SDL_Event e;
-	bool ok = (SDL_WaitEvent(&e) == 1);
-	if (!ok)
-		return NULL;
+	SDL_Event e;
+
+	if (SDL_WaitEvent(&e) != 1)
+		return nullptr;
+
 	return convert(e);
 }
 
 void Event::clear()
 {
-	static SDL_Event e;
+	SDL_Event e;
 
 	while (SDL_PollEvent(&e))
 	{

+ 1 - 1
src/modules/event/sdl/Event.h

@@ -27,7 +27,7 @@
 #include "common/EnumMap.h"
 
 // SDL
-#include <SDL.h>
+#include <SDL_events.h>
 
 // STL
 #include <map>

+ 0 - 1
src/modules/filesystem/physfs/Filesystem.h

@@ -24,7 +24,6 @@
 // STD
 #include <cstdlib>
 #include <cstring>
-#include <iostream>
 #include <string>
 #include <vector>
 

+ 5 - 4
src/modules/graphics/opengl/Graphics.cpp

@@ -35,6 +35,7 @@
 
 // C
 #include <cmath>
+#include <cstdio>
 
 namespace love
 {
@@ -223,7 +224,7 @@ bool Graphics::setMode(int width, int height, bool &sRGB)
 		message += "\nThe program may crash or have graphical issues.";
 
 		::printf("%s\n%s\n", title.c_str(), message.c_str());
-		currentWindow->showMessageBox(type, title, message, true);
+		currentWindow->showMessageBox(title, message, type, true);
 
 		// We should only show the message once, instead of after every setMode.
 		displayedMinReqWarning = true;
@@ -283,7 +284,7 @@ bool Graphics::setMode(int width, int height, bool &sRGB)
 
 	// Reload all volatile objects.
 	if (!Volatile::loadAll())
-		std::cerr << "Could not reload all volatile objects." << std::endl;
+		::printf("Could not reload all volatile objects.\n");
 
 	// Restore the graphics state.
 	restoreState(states.back());
@@ -650,9 +651,9 @@ Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int ms
 	return nullptr; // never reached
 }
 
-Shader *Graphics::newShader(const Shader::ShaderSources &sources)
+Shader *Graphics::newShader(const Shader::ShaderSource &source)
 {
-	return new Shader(sources);
+	return new Shader(source);
 }
 
 Mesh *Graphics::newMesh(const std::vector<Vertex> &vertices, Mesh::DrawMode mode)

+ 1 - 2
src/modules/graphics/opengl/Graphics.h

@@ -22,7 +22,6 @@
 #define LOVE_GRAPHICS_OPENGL_GRAPHICS_H
 
 // STD
-#include <iostream>
 #include <stack>
 #include <vector>
 
@@ -154,7 +153,7 @@ public:
 
 	Canvas *newCanvas(int width, int height, Canvas::Format format = Canvas::FORMAT_NORMAL, int msaa = 0);
 
-	Shader *newShader(const Shader::ShaderSources &sources);
+	Shader *newShader(const Shader::ShaderSource &source);
 
 	Mesh *newMesh(const std::vector<Vertex> &vertices, Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN);
 	Mesh *newMesh(int vertexcount, Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN);

+ 107 - 129
src/modules/graphics/opengl/Shader.cpp

@@ -64,20 +64,20 @@ namespace
 Shader *Shader::current = nullptr;
 Shader *Shader::defaultShader = nullptr;
 
-Shader::ShaderSources Shader::defaultCode[1]; // TODO: RENDERER_MAX_ENUM
+Shader::ShaderSource Shader::defaultCode[1]; // TODO: RENDERER_MAX_ENUM
 
 GLint Shader::maxTexUnits = 0;
 std::vector<int> Shader::textureCounters;
 
-Shader::Shader(const ShaderSources &sources)
-	: shaderSources(sources)
+Shader::Shader(const ShaderSource &source)
+	: shaderSource(source)
 	, program(0)
 	, builtinUniforms()
-	, vertexAttributes()
+	, builtinAttributes()
 	, lastCanvas((Canvas *) -1)
 	, lastViewport()
 {
-	if (shaderSources.empty())
+	if (source.vertex.empty() && source.pixel.empty())
 		throw love::Exception("Cannot create shader: no source code!");
 
 	if (maxTexUnits <= 0)
@@ -108,21 +108,21 @@ Shader::~Shader()
 	unloadVolatile();
 }
 
-GLuint Shader::compileCode(ShaderType type, const std::string &code)
+GLuint Shader::compileCode(ShaderStage stage, const std::string &code)
 {
-	GLenum glshadertype;
+	GLenum glstage;
 	const char *typestr;
 
-	if (!typeNames.find(type, typestr))
+	if (!stageNames.find(stage, typestr))
 		typestr = "";
 
-	switch (type)
+	switch (stage)
 	{
-	case TYPE_VERTEX:
-		glshadertype = GL_VERTEX_SHADER;
+	case STAGE_VERTEX:
+		glstage = GL_VERTEX_SHADER;
 		break;
-	case TYPE_PIXEL:
-		glshadertype = GL_FRAGMENT_SHADER;
+	case STAGE_PIXEL:
+		glstage = GL_FRAGMENT_SHADER;
 		break;
 	default:
 		throw love::Exception("Cannot create shader object: unknown shader type.");
@@ -132,128 +132,75 @@ GLuint Shader::compileCode(ShaderType type, const std::string &code)
 	// clear existing errors
 	while (glGetError() != GL_NO_ERROR);
 
-	GLuint shaderid = glCreateShader(glshadertype);
+	GLuint shaderid = glCreateShader(glstage);
 
-	if (shaderid == 0) // oh no!
+	if (shaderid == 0)
 	{
-		GLenum err = glGetError();
-
-		if (err == GL_INVALID_ENUM)
+		if (glGetError() == GL_INVALID_ENUM)
 			throw love::Exception("Cannot create %s shader object: %s shaders not supported.", typestr, typestr);
 		else
 			throw love::Exception("Cannot create %s shader object.", typestr);
 	}
 
 	const char *src = code.c_str();
-	size_t srclen = code.length();
-	glShaderSource(shaderid, 1, (const GLchar **)&src, (GLint *)&srclen);
+	GLint srclen = (GLint) code.length();
+	glShaderSource(shaderid, 1, (const GLchar **)&src, &srclen);
 
 	glCompileShader(shaderid);
 
-	// Get any warnings the shader compiler may have produced.
 	GLint infologlen;
 	glGetShaderiv(shaderid, GL_INFO_LOG_LENGTH, &infologlen);
 
-	GLchar *infolog = new GLchar[infologlen + 1];
-	glGetShaderInfoLog(shaderid, infologlen, nullptr, infolog);
-
-	// Save any warnings for later querying.
+	// Get any warnings the shader compiler may have produced.
 	if (infologlen > 0)
-		shaderWarnings[type] = infolog;
-
-	delete[] infolog;
-
-	GLint status;
-	glGetShaderiv(shaderid, GL_COMPILE_STATUS, &status);
-
-	if (status == GL_FALSE)
 	{
-		throw love::Exception("Cannot compile %s shader code:\n%s",
-		                      typestr, shaderWarnings[type].c_str());
-	}
+		GLchar *infolog = new GLchar[infologlen];
+		glGetShaderInfoLog(shaderid, infologlen, nullptr, infolog);
 
-	return shaderid;
-}
+		// Save any warnings for later querying.
+		shaderWarnings[stage] = infolog;
 
-void Shader::createProgram(const std::vector<GLuint> &shaderids)
-{
-	program = glCreateProgram();
-	if (program == 0)
-		throw love::Exception("Cannot create shader program object.");
-
-	try
-	{
-		for (GLuint id : shaderids)
-			glAttachShader(program, id);
-	}
-	catch (love::Exception &)
-	{
-		glDeleteProgram(program);
-		throw;
+		delete[] infolog;
 	}
 
-	// Bind love's vertex attribute indices to names in the shader.
-	for (int i = 0; i < int(ATTRIB_MAX_ENUM); i++)
-	{
-		VertexAttribID attrib = (VertexAttribID) i;
-
-		// FIXME: We skip this both because pseudo-instancing is temporarily
-		// disabled (see graphics.lua), and because binding a non-existant
-		// attribute name to a location can cause a shader linker warning.
-		if (attrib == ATTRIB_PSEUDO_INSTANCE_ID)
-			continue;
-
-		const char *name = nullptr;
-		if (attribNames.find(attrib, name))
-			glBindAttribLocation(program, i, (const GLchar *) name);
-	}
-
-	glLinkProgram(program);
-
 	GLint status;
-	glGetProgramiv(program, GL_LINK_STATUS, &status);
+	glGetShaderiv(shaderid, GL_COMPILE_STATUS, &status);
 
 	if (status == GL_FALSE)
 	{
-		std::string warnings = getProgramWarnings();
-		glDeleteProgram(program);
-		program = 0;
-		throw love::Exception("Cannot link shader program object:\n%s", warnings.c_str());
+		glDeleteShader(shaderid);
+		throw love::Exception("Cannot compile %s shader code:\n%s",
+		                      typestr, shaderWarnings[stage].c_str());
 	}
 
-	// flag shaders for auto-deletion when the program object is deleted.
-	for (GLuint id : shaderids)
-		glDeleteShader(id);
+	return shaderid;
 }
 
 void Shader::mapActiveUniforms()
 {
+	// Built-in uniform locations default to -1 (nonexistant.)
+	for (int i = 0; i < int(BUILTIN_MAX_ENUM); i++)
+		builtinUniforms[i] = -1;
+
 	uniforms.clear();
 
 	GLint numuniforms;
 	glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numuniforms);
 
-	GLsizei bufsize;
-	glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, (GLint *) &bufsize);
-
-	if (bufsize <= 0)
-		return;
+	GLchar cname[256];
+	const GLint bufsize = (GLint) (sizeof(cname) / sizeof(GLchar));
 
 	for (int i = 0; i < numuniforms; i++)
 	{
-		GLchar *cname = new GLchar[bufsize];
-		GLsizei namelength;
-
-		Uniform u;
+		GLsizei namelen = 0;
+		Uniform u = {};
 
-		glGetActiveUniform(program, (GLuint) i, bufsize, &namelength, &u.count, &u.type, cname);
+		glGetActiveUniform(program, (GLuint) i, bufsize, &namelen, &u.count, &u.type, cname);
 
-		u.name = std::string(cname, (size_t) namelength);
+		u.name = std::string(cname, (size_t) namelen);
 		u.location = glGetUniformLocation(program, u.name.c_str());
 		u.baseType = getUniformBaseType(u.type);
 
-		delete[] cname;
-
 		// glGetActiveUniform appends "[0]" to the end of array uniform names...
 		if (u.name.length() > 3)
 		{
@@ -278,35 +225,18 @@ bool Shader::loadVolatile()
 	activeTexUnits.clear();
 	activeTexUnits.insert(activeTexUnits.begin(), maxTexUnits, 0);
 
-	// Built-in uniform locations default to -1 (nonexistant.)
-	for (int i = 0; i < int(BUILTIN_MAX_ENUM); i++)
-		builtinUniforms[i] = -1;
-
 	std::vector<GLuint> shaderids;
 
-	for (const auto &source : shaderSources)
-	{
-		GLuint shaderid = compileCode(source.first, source.second);
-		shaderids.push_back(shaderid);
-	}
-
 	// The shader program must have both vertex and pixel shader stages.
-	ShaderSources &defaults = defaultCode[0];
+	const ShaderSource &defaults = defaultCode[0];
 
-	ShaderSources::const_iterator source = shaderSources.find(TYPE_VERTEX);
-	if (source == shaderSources.end())
-		shaderids.push_back(compileCode(TYPE_VERTEX, defaults[TYPE_VERTEX]));
-
-	source = shaderSources.find(TYPE_PIXEL);
-	if (source == shaderSources.end())
-		shaderids.push_back(compileCode(TYPE_PIXEL, defaults[TYPE_PIXEL]));
-
-	if (shaderids.empty())
-		throw love::Exception("Cannot create shader: no valid source code!");
+	const std::string &vertexcode = shaderSource.vertex.empty() ? defaults.vertex : shaderSource.vertex;
+	const std::string &pixelcode = shaderSource.pixel.empty() ? defaults.pixel : shaderSource.pixel;
 
 	try
 	{
-		createProgram(shaderids);
+		shaderids.push_back(compileCode(STAGE_VERTEX, vertexcode));
+		shaderids.push_back(compileCode(STAGE_PIXEL, pixelcode));
 	}
 	catch (love::Exception &)
 	{
@@ -315,6 +245,51 @@ bool Shader::loadVolatile()
 		throw;
 	}
 
+	program = glCreateProgram();
+
+	if (program == 0)
+	{
+		for (GLuint id : shaderids)
+			glDeleteShader(id);
+		throw love::Exception("Cannot create shader program object.");
+	}
+
+	for (GLuint id : shaderids)
+		glAttachShader(program, id);
+
+	// Bind generic vertex attribute indices to names in the shader.
+	for (int i = 0; i < int(ATTRIB_MAX_ENUM); i++)
+	{
+		VertexAttribID attrib = (VertexAttribID) i;
+
+		// FIXME: We skip this both because pseudo-instancing is temporarily
+		// disabled (see graphics.lua), and because binding a non-existant
+		// attribute name to a location causes a shader linker warning.
+		if (attrib == ATTRIB_PSEUDO_INSTANCE_ID)
+			continue;
+
+		const char *name = nullptr;
+		if (attribNames.find(attrib, name))
+			glBindAttribLocation(program, i, (const GLchar *) name);
+	}
+
+	glLinkProgram(program);
+
+	// Flag shaders for auto-deletion when the program object is deleted.
+	for (GLuint id : shaderids)
+		glDeleteShader(id);
+
+	GLint status;
+	glGetProgramiv(program, GL_LINK_STATUS, &status);
+
+	if (status == GL_FALSE)
+	{
+		std::string warnings = getProgramWarnings();
+		glDeleteProgram(program);
+		program = 0;
+		throw love::Exception("Cannot link shader program object:\n%s", warnings.c_str());
+	}
+
 	// Retreive all active uniform variables in this shader from OpenGL.
 	mapActiveUniforms();
 
@@ -322,9 +297,9 @@ bool Shader::loadVolatile()
 	{
 		const char *name = nullptr;
 		if (attribNames.find(VertexAttribID(i), name))
-			vertexAttributes[i] = glGetAttribLocation(program, name);
+			builtinAttributes[i] = glGetAttribLocation(program, name);
 		else
-			vertexAttributes[i] = -1;
+			builtinAttributes[i] = -1;
 	}
 
 	if (current == this)
@@ -371,13 +346,16 @@ void Shader::unloadVolatile()
 
 std::string Shader::getProgramWarnings() const
 {
-	GLint strlen, nullpos;
-	glGetProgramiv(program, GL_INFO_LOG_LENGTH, &strlen);
+	GLint strsize, nullpos;
+	glGetProgramiv(program, GL_INFO_LOG_LENGTH, &strsize);
+
+	if (strsize == 0)
+		return "";
 
-	char *tempstr = new char[strlen+1];
+	char *tempstr = new char[strsize];
 	// be extra sure that the error string will be 0-terminated
-	memset(tempstr, '\0', strlen+1);
-	glGetProgramInfoLog(program, strlen, &nullpos, tempstr);
+	memset(tempstr, '\0', strsize);
+	glGetProgramInfoLog(program, strsize, &nullpos, tempstr);
 	tempstr[nullpos] = '\0';
 
 	std::string warnings(tempstr);
@@ -389,13 +367,13 @@ std::string Shader::getProgramWarnings() const
 std::string Shader::getWarnings() const
 {
 	std::string warnings;
-	const char *typestr;
+	const char *stagestr;
 
 	// Get the individual shader stage warnings
 	for (const auto &warning : shaderWarnings)
 	{
-		if (typeNames.find(warning.first, typestr))
-			warnings += std::string(typestr) + std::string(" shader:\n") + warning.second;
+		if (stageNames.find(warning.first, stagestr))
+			warnings += std::string(stagestr) + std::string(" shader:\n") + warning.second;
 	}
 
 	warnings += getProgramWarnings();
@@ -644,7 +622,7 @@ Shader::UniformType Shader::getExternVariable(const std::string &name, int &comp
 
 bool Shader::hasVertexAttrib(VertexAttribID attrib) const
 {
-	return vertexAttributes[int(attrib)] != -1;
+	return builtinAttributes[int(attrib)] != -1;
 }
 
 bool Shader::hasBuiltinUniform(BuiltinUniform builtin) const
@@ -816,13 +794,13 @@ bool Shader::getConstant(UniformType in, const char *&out)
 	return uniformTypes.find(in, out);
 }
 
-StringMap<Shader::ShaderType, Shader::TYPE_MAX_ENUM>::Entry Shader::typeNameEntries[] =
+StringMap<Shader::ShaderStage, Shader::STAGE_MAX_ENUM>::Entry Shader::stageNameEntries[] =
 {
-	{"vertex", Shader::TYPE_VERTEX},
-	{"pixel", Shader::TYPE_PIXEL},
+	{"vertex", Shader::STAGE_VERTEX},
+	{"pixel", Shader::STAGE_PIXEL},
 };
 
-StringMap<Shader::ShaderType, Shader::TYPE_MAX_ENUM> Shader::typeNames(Shader::typeNameEntries, sizeof(Shader::typeNameEntries));
+StringMap<Shader::ShaderStage, Shader::STAGE_MAX_ENUM> Shader::stageNames(Shader::stageNameEntries, sizeof(Shader::stageNameEntries));
 
 StringMap<Shader::UniformType, Shader::UNIFORM_MAX_ENUM>::Entry Shader::uniformTypeEntries[] =
 {

+ 19 - 17
src/modules/graphics/opengl/Shader.h

@@ -46,11 +46,11 @@ class Shader : public Object, public Volatile
 {
 public:
 
-	enum ShaderType
+	enum ShaderStage
 	{
-		TYPE_VERTEX,
-		TYPE_PIXEL,
-		TYPE_MAX_ENUM
+		STAGE_VERTEX,
+		STAGE_PIXEL,
+		STAGE_MAX_ENUM
 	};
 
 	// Built-in uniform (extern) variables.
@@ -71,8 +71,11 @@ public:
 		UNIFORM_MAX_ENUM
 	};
 
-	// Type for a list of shader source codes in the form of sources[shadertype] = code
-	typedef std::map<ShaderType, std::string> ShaderSources;
+	struct ShaderSource
+	{
+		std::string vertex;
+		std::string pixel;
+	};
 
 	// Pointer to currently active Shader.
 	static Shader *current;
@@ -81,13 +84,13 @@ public:
 	static Shader *defaultShader;
 
 	// Default shader code (a shader is always required internally.)
-	static ShaderSources defaultCode[1]; // TODO: RENDERER_MAX_ENUM
+	static ShaderSource defaultCode[1]; // TODO: RENDERER_MAX_ENUM
 
 	/**
 	 * Creates a new Shader using a list of source codes.
-	 * Sources must contain either vertex or pixel shader code, or both.
+	 * Source must contain either vertex or pixel shader code, or both.
 	 **/
-	Shader(const ShaderSources &sources);
+	Shader(const ShaderSource &source);
 
 	virtual ~Shader();
 
@@ -202,8 +205,7 @@ private:
 	UniformType getUniformBaseType(GLenum type) const;
 	void checkSetUniformError(const Uniform &u, int size, int count, UniformType sendtype) const;
 
-	GLuint compileCode(ShaderType type, const std::string &code);
-	void createProgram(const std::vector<GLuint> &shaderids);
+	GLuint compileCode(ShaderStage stage, const std::string &code);
 
 	int getTextureUnit(const std::string &name);
 
@@ -212,11 +214,11 @@ private:
 	// Get any warnings or errors generated only by the shader program object.
 	std::string getProgramWarnings() const;
 
-	// List of all shader code attached to this Shader
-	ShaderSources shaderSources;
+	// Source code used for this Shader.
+	ShaderSource shaderSource;
 
 	// Shader compiler warning strings for individual shader stages.
-	std::map<ShaderType, std::string> shaderWarnings;
+	std::map<ShaderStage, std::string> shaderWarnings;
 
 	// volatile
 	GLuint program;
@@ -225,7 +227,7 @@ private:
 	GLint builtinUniforms[BUILTIN_MAX_ENUM];
 
 	// Location values for any generic vertex attribute variables.
-	GLint vertexAttributes[ATTRIB_MAX_ENUM];
+	GLint builtinAttributes[ATTRIB_MAX_ENUM];
 
 	// Uniform location buffer map
 	std::map<std::string, Uniform> uniforms;
@@ -247,8 +249,8 @@ private:
 	// Counts total number of textures bound to each texture unit in all shaders
 	static std::vector<int> textureCounters;
 
-	static StringMap<ShaderType, TYPE_MAX_ENUM>::Entry typeNameEntries[];
-	static StringMap<ShaderType, TYPE_MAX_ENUM> typeNames;
+	static StringMap<ShaderStage, STAGE_MAX_ENUM>::Entry stageNameEntries[];
+	static StringMap<ShaderStage, STAGE_MAX_ENUM> stageNames;
 
 	static StringMap<UniformType, UNIFORM_MAX_ENUM>::Entry uniformTypeEntries[];
 	static StringMap<UniformType, UNIFORM_MAX_ENUM> uniformTypes;

+ 8 - 14
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -445,27 +445,21 @@ int w_newShader(lua_State *L)
 	if (lua_pcall(L, 2, 2, 0) != 0)
 		return luaL_error(L, "%s", lua_tostring(L, -1));
 
-	Shader::ShaderSources sources;
+	Shader::ShaderSource source;
 
 	// vertex shader code
 	if (lua_isstring(L, -2))
-	{
-		std::string vertexcode(luaL_checkstring(L, -2));
-		sources[Shader::TYPE_VERTEX] = vertexcode;
-	}
+		source.vertex = luax_checkstring(L, -2);
 	else if (has_arg1 && has_arg2)
 		return luaL_error(L, "Could not parse vertex shader code (missing 'position' function?)");
 
 	// pixel shader code
 	if (lua_isstring(L, -1))
-	{
-		std::string pixelcode(luaL_checkstring(L, -1));
-		sources[Shader::TYPE_PIXEL] = pixelcode;
-	}
+		source.pixel = luax_checkstring(L, -1);
 	else if (has_arg1 && has_arg2)
 		return luaL_error(L, "Could not parse pixel shader code (missing 'effect' function?)");
 
-	if (sources.empty())
+	if (source.vertex.empty() && source.pixel.empty())
 	{
 		// Original args had source code, but effectCodeToGLSL couldn't translate it
 		for (int i = 1; i <= 2; i++)
@@ -478,7 +472,7 @@ int w_newShader(lua_State *L)
 	bool should_error = false;
 	try
 	{
-		Shader *shader = instance()->newShader(sources);
+		Shader *shader = instance()->newShader(source);
 		luax_pushtype(L, "Shader", GRAPHICS_SHADER_T, shader);
 		shader->release();
 	}
@@ -982,9 +976,9 @@ int w_setDefaultShaderCode(lua_State *L)
 	lua_rawgeti(L, -1, 1);
 	lua_rawgeti(L, -2, 2);
 
-	Shader::ShaderSources openglcode;
-	openglcode[Shader::TYPE_VERTEX] = luax_checkstring(L, -2);
-	openglcode[Shader::TYPE_PIXEL] = luax_checkstring(L, -1);
+	Shader::ShaderSource openglcode;
+	openglcode.vertex = luax_checkstring(L, -2);
+	openglcode.pixel = luax_checkstring(L, -1);
 
 	lua_pop(L, 3);
 

+ 1 - 1
src/modules/keyboard/Keyboard.h

@@ -241,7 +241,7 @@ public:
 		KEY_EJECT,
 		KEY_SLEEP,
 
-		KEY_MAX_ENUM = 512
+		KEY_MAX_ENUM
 	};
 
 	virtual ~Keyboard() {}

+ 6 - 7
src/modules/keyboard/sdl/Keyboard.cpp

@@ -18,8 +18,6 @@
  * 3. This notice may not be removed or altered from any source distribution.
  **/
 
-#include "common/config.h"
-
 #include "Keyboard.h"
 
 namespace love
@@ -55,8 +53,8 @@ bool Keyboard::isDown(Key *keylist) const
 
 	for (Key key = *keylist; key != KEY_MAX_ENUM; key = *(++keylist))
 	{
-		auto it = keys.find(key);
-		if (it != keys.end() && keystate[SDL_GetScancodeFromKey(it->second)])
+		SDL_Scancode scancode = SDL_GetScancodeFromKey(keymap[key]);
+		if (keystate[scancode])
 			return true;
 	}
 
@@ -76,9 +74,10 @@ bool Keyboard::hasTextInput() const
 	return SDL_IsTextInputActive();
 }
 
-std::map<Keyboard::Key, SDL_Keycode> Keyboard::createKeyMap()
+const SDL_Keycode *Keyboard::createKeyMap()
 {
-	std::map<Keyboard::Key, SDL_Keycode> k;
+	// Array must be static so its lifetime continues once the function returns.
+	static SDL_Keycode k[Keyboard::KEY_MAX_ENUM] = {SDLK_UNKNOWN};
 
 	k[Keyboard::KEY_UNKNOWN] = SDLK_UNKNOWN;
 
@@ -287,7 +286,7 @@ std::map<Keyboard::Key, SDL_Keycode> Keyboard::createKeyMap()
 	return k;
 }
 
-std::map<Keyboard::Key, SDL_Keycode> Keyboard::keys = Keyboard::createKeyMap();
+const SDL_Keycode *Keyboard::keymap = Keyboard::createKeyMap();
 
 } // sdl
 } // keyboard

+ 3 - 6
src/modules/keyboard/sdl/Keyboard.h

@@ -26,10 +26,7 @@
 #include "common/EnumMap.h"
 
 // SDL
-#include <SDL.h>
-
-// STL
-#include <map>
+#include <SDL_keyboard.h>
 
 namespace love
 {
@@ -60,8 +57,8 @@ private:
 	// The real implementation is in love::event::sdl::Event::Convert.
 	bool key_repeat;
 
-	static std::map<Key, SDL_Keycode> createKeyMap();
-	static std::map<Key, SDL_Keycode> keys;
+	static const SDL_Keycode *createKeyMap();
+	static const SDL_Keycode *keymap;
 
 }; // Keyboard
 

+ 0 - 5
src/modules/math/RandomGenerator.cpp

@@ -81,11 +81,6 @@ void RandomGenerator::setSeed(RandomGenerator::Seed newseed)
 
 	seed = newseed;
 	rng_state = seed;
-
-	// Xorshift's first couple results after seeding will be similar to results
-	// from very similar seeds, so we immediately discard them here.
-	for (int i = 0; i < 2; i++)
-		rand();
 }
 
 RandomGenerator::Seed RandomGenerator::getSeed() const

+ 10 - 20
src/modules/mouse/sdl/Mouse.cpp

@@ -36,33 +36,23 @@ namespace sdl
 // we want them in pixel coordinates (may be different with high-DPI enabled.)
 static void windowToPixelCoords(int *x, int *y)
 {
-	double scale = 1.0;
+	window::Window *window = Module::getInstance<window::Window>(Module::M_WINDOW);
 
-	love::window::Window *window = love::window::sdl::Window::getSingleton();
-	if (window != nullptr)
-		scale = window->getPixelScale();
-
-	if (x != nullptr)
-		*x = int(double(*x) * scale);
-
-	if (y != nullptr)
-		*y = int(double(*y) * scale);
+	if (window && x)
+		*x = (int) window->toPixels(*x);
+	if (window && y)
+		*y = (int) window->toPixels(*y);
 }
 
 // And vice versa for setting mouse coordinates.
 static void pixelToWindowCoords(int *x, int *y)
 {
-	double scale = 1.0;
-
-	love::window::Window *window = love::window::sdl::Window::getSingleton();
-	if (window != nullptr)
-		scale = window->getPixelScale();
-
-	if (x != nullptr)
-		*x = int(double(*x) / scale);
+	window::Window *window = Module::getInstance<window::Window>(Module::M_WINDOW);
 
-	if (y != nullptr)
-		*y = int(double(*y) / scale);
+	if (window && x)
+		*x = (int) window->fromPixels(*x);
+	if (window && y)
+		*y = (int) window->fromPixels(*y);
 }
 
 const char *Mouse::getName() const

+ 55 - 13
src/modules/physics/box2d/Physics.cpp

@@ -93,6 +93,12 @@ EdgeShape *Physics::newEdgeShape(float x1, float y1, float x2, float y2)
 int Physics::newPolygonShape(lua_State *L)
 {
 	int argc = lua_gettop(L);
+
+	bool istable = lua_istable(L, 1);
+
+	if (istable)
+		argc = lua_objlen(L, 1);
+
 	if (argc % 2 != 0)
 		return luaL_error(L, "Number of vertex components must be a multiple of two.");
 
@@ -103,16 +109,31 @@ int Physics::newPolygonShape(lua_State *L)
 	else if (vcount > b2_maxPolygonVertices)
 		return luaL_error(L, "Expected a maximum of %d vertices, got %d.", b2_maxPolygonVertices, vcount);
 
-	b2PolygonShape *s = new b2PolygonShape();
-
 	b2Vec2 vecs[b2_maxPolygonVertices];
 
-	for (int i = 0; i < vcount; i++)
+	if (istable)
 	{
-		float x = (float)luaL_checknumber(L, 1 + i * 2);
-		float y = (float)luaL_checknumber(L, 2 + i * 2);
-		vecs[i] = Physics::scaleDown(b2Vec2(x, y));
+		for (int i = 0; i < vcount; i++)
+		{
+			lua_rawgeti(L, 1, 1 + i * 2);
+			lua_rawgeti(L, 1, 2 + i * 2);
+			float x = (float)luaL_checknumber(L, -2);
+			float y = (float)luaL_checknumber(L, -1);
+			vecs[i] = Physics::scaleDown(b2Vec2(x, y));
+			lua_pop(L, 2);
+		}
 	}
+	else
+	{
+		for (int i = 0; i < vcount; i++)
+		{
+			float x = (float)luaL_checknumber(L, 1 + i * 2);
+			float y = (float)luaL_checknumber(L, 2 + i * 2);
+			vecs[i] = Physics::scaleDown(b2Vec2(x, y));
+		}
+	}
+
+	b2PolygonShape *s = new b2PolygonShape();
 
 	try
 	{
@@ -133,22 +154,42 @@ int Physics::newPolygonShape(lua_State *L)
 int Physics::newChainShape(lua_State *L)
 {
 	int argc = lua_gettop(L)-1; // first argument is looping
+
+	bool istable = lua_istable(L, 2);
+
+	if (istable)
+		argc = lua_objlen(L, 2);
+
 	if (argc % 2 != 0)
 		return luaL_error(L, "Number of vertex components must be a multiple of two.");
 
 	int vcount = (int)argc/2;
-	b2ChainShape *s = new b2ChainShape();
 	bool loop = luax_toboolean(L, 1);
 	b2Vec2 *vecs = new b2Vec2[vcount];
 
-	for (int i = 0; i<vcount; i++)
+	if (istable)
 	{
-		float x = (float)lua_tonumber(L, -2);
-		float y = (float)lua_tonumber(L, -1);
-		vecs[i].Set(x, y);
-		vecs[i] = Physics::scaleDown(vecs[i]);
-		lua_pop(L, 2);
+		for (int i = 0; i < vcount; i++)
+		{
+			lua_rawgeti(L, 2, 1 + i * 2);
+			lua_rawgeti(L, 2, 2 + i * 2);
+			float x = (float)lua_tonumber(L, -2);
+			float y = (float)lua_tonumber(L, -1);
+			vecs[i] = Physics::scaleDown(b2Vec2(x, y));
+			lua_pop(L, 2);
+		}
 	}
+	else
+	{
+		for (int i = 0; i < vcount; i++)
+		{
+			float x = (float)luaL_checknumber(L, 2 + i * 2);
+			float y = (float)luaL_checknumber(L, 3 + i * 2);
+			vecs[i] = Physics::scaleDown(b2Vec2(x, y));
+		}
+	}
+
+	b2ChainShape *s = new b2ChainShape();
 
 	try
 	{
@@ -160,6 +201,7 @@ int Physics::newChainShape(lua_State *L)
 	catch (love::Exception &)
 	{
 		delete[] vecs;
+		delete s;
 		throw;
 	}
 

+ 1 - 1
src/modules/sound/Decoder.h

@@ -40,7 +40,7 @@ public:
 	 * Indicates how many bytes of raw data should be generated at each
 	 * call to Decode.
 	 **/
-	static const int DEFAULT_BUFFER_SIZE = 2048;
+	static const int DEFAULT_BUFFER_SIZE = 16384;
 
 	/**
 	 * Indicates the quality of the sound.

+ 6 - 1
src/modules/window/Window.h

@@ -83,6 +83,11 @@ public:
 	{
 		int width;
 		int height;
+
+		bool operator == (const WindowSize &w) const
+		{
+			return w.width == width && w.height == height;
+		}
 	};
 
 	struct MessageBoxData
@@ -156,7 +161,7 @@ public:
 
 	virtual const void *getHandle() const = 0;
 
-	virtual bool showMessageBox(MessageBoxType type, const std::string &title, const std::string &message, bool attachtowindow) = 0;
+	virtual bool showMessageBox(const std::string &title, const std::string &message, MessageBoxType type, bool attachtowindow) = 0;
 	virtual int showMessageBox(const MessageBoxData &data) = 0;
 
 	//virtual static Window *createSingleton() = 0;

+ 5 - 17
src/modules/window/sdl/Window.cpp

@@ -497,29 +497,17 @@ std::vector<WindowSize> Window::getFullscreenSizes(int displayindex) const
 {
 	std::vector<WindowSize> sizes;
 
-	SDL_DisplayMode mode = {};
-	std::vector<WindowSize>::const_iterator it;
 	for (int i = 0; i < SDL_GetNumDisplayModes(displayindex); i++)
 	{
+		SDL_DisplayMode mode = {};
 		SDL_GetDisplayMode(displayindex, i, &mode);
 
+		WindowSize w = {mode.w, mode.h};
+
 		// SDL2's display mode list has multiple entries for modes of the same
 		// size with different bits per pixel, so we need to filter those out.
-		bool alreadyhassize = false;
-		for (it = sizes.begin(); it != sizes.end(); ++it)
-		{
-			if (it->width == mode.w && it->height == mode.h)
-			{
-				alreadyhassize = true;
-				break;
-			}
-		}
-
-		if (!alreadyhassize)
-		{
-			WindowSize w = {mode.w, mode.h};
+		if (std::find(sizes.begin(), sizes.end(), w) == sizes.end())
 			sizes.push_back(w);
-		}
 	}
 
 	return sizes;
@@ -767,7 +755,7 @@ SDL_MessageBoxFlags Window::convertMessageBoxType(MessageBoxType type) const
 	}
 }
 
-bool Window::showMessageBox(MessageBoxType type, const std::string &title, const std::string &message, bool attachtowindow)
+bool Window::showMessageBox(const std::string &title, const std::string &message, MessageBoxType type, bool attachtowindow)
 {
 	SDL_MessageBoxFlags flags = convertMessageBoxType(type);
 	SDL_Window *sdlwindow = attachtowindow ? window : nullptr;

+ 1 - 1
src/modules/window/sdl/Window.h

@@ -92,7 +92,7 @@ public:
 
 	const void *getHandle() const;
 
-	bool showMessageBox(MessageBoxType type, const std::string &title, const std::string &message, bool attachtowindow);
+	bool showMessageBox(const std::string &title, const std::string &message, MessageBoxType type, bool attachtowindow);
 	int showMessageBox(const MessageBoxData &data);
 
 	static love::window::Window *createSingleton();

+ 17 - 12
src/modules/window/wrap_Window.cpp

@@ -395,32 +395,29 @@ int w_minimize(lua_State* /*L*/)
 int w_showMessageBox(lua_State *L)
 {
 	Window::MessageBoxData data = {};
+	data.type = Window::MESSAGEBOX_INFO;
 
-	const char *typestr = luaL_checkstring(L, 1);
-	if (!Window::getConstant(typestr, data.type))
-		return luaL_error(L, "Invalid messagebox type: %s", typestr);
-
-	data.title = luaL_checkstring(L, 2);
-	data.message = luaL_checkstring(L, 3);
+	data.title = luaL_checkstring(L, 1);
+	data.message = luaL_checkstring(L, 2);
 
 	// If we have a table argument, we assume a list of button names, which
 	// means we should use the more complex message box API.
-	if (lua_istable(L, 4))
+	if (lua_istable(L, 3))
 	{
-		size_t numbuttons = lua_objlen(L, 4);
+		size_t numbuttons = lua_objlen(L, 3);
 		if (numbuttons == 0)
 			return luaL_error(L, "Must have at least one messagebox button.");
 
 		// Array of button names.
 		for (size_t i = 0; i < numbuttons; i++)
 		{
-			lua_rawgeti(L, 4, i + 1);
+			lua_rawgeti(L, 3, i + 1);
 			data.buttons.push_back(luax_checkstring(L, -1));
 			lua_pop(L, 1);
 		}
 
 		// Optional table entry specifying the button to use when enter is pressed.
-		lua_getfield(L, 4, "enterbutton");
+		lua_getfield(L, 3, "enterbutton");
 		if (!lua_isnoneornil(L, -1))
 			data.enterButtonIndex = luaL_checkint(L, -1) - 1;
 		else
@@ -428,13 +425,17 @@ int w_showMessageBox(lua_State *L)
 		lua_pop(L, 1);
 
 		// Optional table entry specifying the button to use when esc is pressed.
-		lua_getfield(L, 4, "escapebutton");
+		lua_getfield(L, 3, "escapebutton");
 		if (!lua_isnoneornil(L, -1))
 			data.escapeButtonIndex = luaL_checkint(L, -1) - 1;
 		else
 			data.escapeButtonIndex = (int) data.buttons.size() - 1;
 		lua_pop(L, 1);
 
+		const char *typestr = lua_isnoneornil(L, 4) ? nullptr : luaL_checkstring(L, 4);
+		if (typestr && !Window::getConstant(typestr, data.type))
+			return luaL_error(L, "Invalid messagebox type: %s", typestr);
+
 		data.attachToWindow = luax_optboolean(L, 5, true);
 
 		int pressedbutton = instance()->showMessageBox(data);
@@ -442,10 +443,14 @@ int w_showMessageBox(lua_State *L)
 	}
 	else
 	{
+		const char *typestr = lua_isnoneornil(L, 3) ? nullptr : luaL_checkstring(L, 3);
+		if (typestr && !Window::getConstant(typestr, data.type))
+			return luaL_error(L, "Invalid messagebox type: %s", typestr);
+
 		data.attachToWindow = luax_optboolean(L, 4, true);
 
 		// Display a simple message box.
-		bool success = instance()->showMessageBox(data.type, data.title, data.message, data.attachToWindow);
+		bool success = instance()->showMessageBox(data.title, data.message, data.type, data.attachToWindow);
 		luax_pushboolean(L, success);
 	}
 

+ 1 - 0
src/scripts/boot.lua

@@ -479,6 +479,7 @@ function love.run()
 
 	if love.math then
 		love.math.setRandomSeed(os.time())
+		for i=1,3 do love.math.random() end
 	end
 
 	if love.event then

+ 3 - 0
src/scripts/boot.lua.h

@@ -858,6 +858,9 @@ const unsigned char boot_lua[] =
 	0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
 	0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x61, 0x6e, 
 	0x64, 0x6f, 0x6d, 0x53, 0x65, 0x65, 0x64, 0x28, 0x6f, 0x73, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x29, 0x0a,
+	0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, 0x33, 0x20, 0x64, 0x6f, 0x20, 0x6c, 0x6f, 0x76, 
+	0x65, 0x2e, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, 0x20, 0x65, 0x6e, 
+	0x64, 0x0a,
 	0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 
 	0x6e, 0x0a,