Remove material from graphics state;

It is now local state to models and meshes and can be passed as
an optional first argument to most primitives.
This commit is contained in:
bjorn 2017-11-25 19:02:28 -08:00
parent 093ef37bf3
commit cb2265e547
11 changed files with 546 additions and 454 deletions

View File

@ -397,22 +397,6 @@ int l_lovrGraphicsSetLineWidth(lua_State* L) {
return 0;
}
int l_lovrGraphicsGetMaterial(lua_State* L) {
Material* material = lovrGraphicsGetMaterial();
if (material && !material->isDefault) {
luax_pushtype(L, Material, material);
} else {
lua_pushnil(L);
}
return 1;
}
int l_lovrGraphicsSetMaterial(lua_State* L) {
Material* material = lua_isnoneornil(L, 1) ? NULL : luax_checktype(L, 1, Material);
lovrGraphicsSetMaterial(material);
return 0;
}
int l_lovrGraphicsGetPointSize(lua_State* L) {
lua_pushnumber(L, lovrGraphicsGetPointSize());
return 1;
@ -535,7 +519,14 @@ int l_lovrGraphicsLine(lua_State* L) {
}
int l_lovrGraphicsTriangle(lua_State* L) {
DrawMode* drawMode = (DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
DrawMode drawMode = DRAW_MODE_FILL;
Material* material = NULL;
if (lua_isuserdata(L, 1)) {
material = luax_checktype(L, 1, Material);
} else {
drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
}
int top = lua_gettop(L);
if (top != 10) {
return luaL_error(L, "Expected 9 coordinates to make a triangle, got %d values", top - 1);
@ -543,30 +534,42 @@ int l_lovrGraphicsTriangle(lua_State* L) {
vec_float_t points;
vec_init(&points);
luax_readvertices(L, 2, &points);
lovrGraphicsTriangle(*drawMode, points.data);
lovrGraphicsTriangle(drawMode, material, points.data);
vec_deinit(&points);
return 0;
}
int l_lovrGraphicsPlane(lua_State* L) {
if (lua_isuserdata(L, 1)) {
if (lua_isuserdata(L, 1) && lua_gettop(L) == 1) {
Texture* texture = luax_checktype(L, 1, Texture);
lovrGraphicsPlaneFullscreen(texture);
return 0;
}
DrawMode drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
DrawMode drawMode = DRAW_MODE_FILL;
Material* material = NULL;
if (lua_isuserdata(L, 1)) {
material = luax_checktype(L, 1, Material);
} else {
drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
}
float transform[16];
luax_readtransform(L, 2, transform, 1);
lovrGraphicsPlane(drawMode, transform);
lovrGraphicsPlane(drawMode, material, transform);
return 0;
}
static int luax_rectangularprism(lua_State* L, bool uniformScale) {
DrawMode drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
DrawMode drawMode = DRAW_MODE_FILL;
Material* material = NULL;
if (lua_isuserdata(L, 1)) {
material = luax_checktype(L, 1, Material);
} else {
drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
}
float transform[16];
luax_readtransform(L, 2, transform, uniformScale);
lovrGraphicsBox(drawMode, transform);
lovrGraphicsBox(drawMode, material, transform);
return 0;
}
@ -579,10 +582,16 @@ int l_lovrGraphicsBox(lua_State* L) {
}
int l_lovrGraphicsArc(lua_State* L) {
DrawMode drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
DrawMode drawMode = DRAW_MODE_FILL;
Material* material = NULL;
if (lua_isuserdata(L, 1)) {
material = luax_checktype(L, 1, Material);
} else {
drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
}
ArcMode arcMode = ARC_MODE_PIE;
int index = 2;
if (lua_type(L, 2) == LUA_TSTRING) {
if (lua_type(L, index) == LUA_TSTRING) {
arcMode = *(ArcMode*) luax_checkenum(L, index++, &ArcModes, "arc mode");
}
float transform[16];
@ -590,40 +599,49 @@ int l_lovrGraphicsArc(lua_State* L) {
float theta1 = luaL_optnumber(L, index++, 0);
float theta2 = luaL_optnumber(L, index++, 2 * M_PI);
int segments = luaL_optinteger(L, index, 32) * fabsf(theta2 - theta1) * 2 * M_PI + .5f;
lovrGraphicsArc(drawMode, arcMode, transform, theta1, theta2, segments);
lovrGraphicsArc(drawMode, arcMode, material, transform, theta1, theta2, segments);
return 0;
}
int l_lovrGraphicsCircle(lua_State* L) {
DrawMode drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
DrawMode drawMode = DRAW_MODE_FILL;
Material* material = NULL;
if (lua_isuserdata(L, 1)) {
material = luax_checktype(L, 1, Material);
} else {
drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
}
float transform[16];
int index = luax_readtransform(L, 2, transform, true);
int segments = luaL_optnumber(L, index, 32);
lovrGraphicsCircle(drawMode, transform, segments);
lovrGraphicsCircle(drawMode, material, transform, segments);
return 0;
}
int l_lovrGraphicsCylinder(lua_State* L) {
float x1 = luaL_checknumber(L, 1);
float y1 = luaL_checknumber(L, 2);
float z1 = luaL_checknumber(L, 3);
float x2 = luaL_checknumber(L, 4);
float y2 = luaL_checknumber(L, 5);
float z2 = luaL_checknumber(L, 6);
float r1 = luaL_optnumber(L, 7, 1);
float r2 = luaL_optnumber(L, 8, 1);
bool capped = lua_isnoneornil(L, 9) ? true : lua_toboolean(L, 9);
int segments = luaL_optnumber(L, 10, floorf(16 + 16 * MAX(r1, r2)));
lovrGraphicsCylinder(x1, y1, z1, x2, y2, z2, r1, r2, capped, segments);
int index = 1;
Material* material = lua_isuserdata(L, index) ? luax_checktype(L, index++, Material) : NULL;
float x1 = luaL_checknumber(L, index++);
float y1 = luaL_checknumber(L, index++);
float z1 = luaL_checknumber(L, index++);
float x2 = luaL_checknumber(L, index++);
float y2 = luaL_checknumber(L, index++);
float z2 = luaL_checknumber(L, index++);
float r1 = luaL_optnumber(L, index++, 1);
float r2 = luaL_optnumber(L, index++, 1);
bool capped = lua_isnoneornil(L, index) ? true : lua_toboolean(L, index++);
int segments = luaL_optnumber(L, index, floorf(16 + 16 * MAX(r1, r2)));
lovrGraphicsCylinder(material, x1, y1, z1, x2, y2, z2, r1, r2, capped, segments);
return 0;
}
int l_lovrGraphicsSphere(lua_State* L) {
float transform[16];
int index = 1;
Material* material = lua_isuserdata(L, index) ? luax_checktype(L, index++, Material) : NULL;
index = luax_readtransform(L, index, transform, 1);
int segments = luaL_optnumber(L, index, 30);
lovrGraphicsSphere(transform, segments);
lovrGraphicsSphere(material, transform, segments);
return 0;
}
@ -891,8 +909,6 @@ const luaL_Reg lovrGraphics[] = {
{ "getSystemLimits", l_lovrGraphicsGetSystemLimits },
{ "getLineWidth", l_lovrGraphicsGetLineWidth },
{ "setLineWidth", l_lovrGraphicsSetLineWidth },
{ "getMaterial", l_lovrGraphicsGetMaterial },
{ "setMaterial", l_lovrGraphicsSetMaterial },
{ "getPointSize", l_lovrGraphicsGetPointSize },
{ "setPointSize", l_lovrGraphicsSetPointSize },
{ "getShader", l_lovrGraphicsGetShader },

View File

@ -377,6 +377,28 @@ int l_lovrMeshSetDrawRange(lua_State* L) {
return 0;
}
int l_lovrMeshGetMaterial(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
Material* material = lovrMeshGetMaterial(mesh);
if (material) {
luax_pushtype(L, Material, material);
} else {
lua_pushnil(L);
}
return 1;
}
int l_lovrMeshSetMaterial(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
if (lua_isnoneornil(L, 2)) {
lovrMeshSetMaterial(mesh, NULL);
} else {
Material* material = luax_checktype(L, 2, Material);
lovrMeshSetMaterial(mesh, material);
}
return 0;
}
const luaL_Reg lovrMesh[] = {
{ "draw", l_lovrMeshDraw },
{ "getVertexFormat", l_lovrMeshGetVertexFormat },
@ -394,5 +416,7 @@ const luaL_Reg lovrMesh[] = {
{ "setDrawMode", l_lovrMeshSetDrawMode },
{ "getDrawRange", l_lovrMeshGetDrawRange },
{ "setDrawRange", l_lovrMeshSetDrawRange },
{ "getMaterial", l_lovrMeshGetMaterial },
{ "setMaterial", l_lovrMeshSetMaterial },
{ NULL, NULL }
};

View File

@ -42,6 +42,28 @@ int l_lovrModelGetAnimationCount(lua_State* L) {
return 1;
}
int l_lovrModelGetMaterial(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
Material* material = lovrModelGetMaterial(model);
if (material) {
luax_pushtype(L, Material, material);
} else {
lua_pushnil(L);
}
return 1;
}
int l_lovrModelSetMaterial(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
if (lua_isnoneornil(L, 2)) {
lovrModelSetMaterial(model, NULL);
} else {
Material* material = luax_checktype(L, 2, Material);
lovrModelSetMaterial(model, material);
}
return 0;
}
int l_lovrModelGetMesh(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
Mesh* mesh = lovrModelGetMesh(model);
@ -55,6 +77,8 @@ const luaL_Reg lovrModel[] = {
{ "getAnimator", l_lovrModelGetAnimator },
{ "setAnimator", l_lovrModelSetAnimator },
{ "getAnimationCount", l_lovrModelGetAnimationCount },
{ "getMaterial", l_lovrModelGetMaterial },
{ "setMaterial", l_lovrModelSetMaterial },
{ "getMesh", l_lovrModelGetMesh },
{ NULL, NULL }
};

View File

@ -80,8 +80,8 @@ if not lovr.filesystem.getSource() or not runnable then
local logo, controllers
function lovr.load()
logo = lovr.graphics.newMaterial()
logo:setTexture(lovr.graphics.newTexture(lovr.filesystem.newBlob(lovr._logo, 'logo.png')))
local texture = lovr.graphics.newTexture(lovr.filesystem.newBlob(lovr._logo, 'logo.png'))
logo = lovr.graphics.newMaterial(texture)
lovr.graphics.setBackgroundColor(.960, .988, 1.0)
refreshControllers()
end
@ -100,9 +100,7 @@ if not lovr.filesystem.getSource() or not runnable then
local titlePosition = 1.3 - padding
local subtitlePosition = titlePosition - font:getHeight() * .25 - padding
lovr.graphics.setMaterial(logo)
lovr.graphics.plane('fill', 0, 1.8, -3, 1, 0, 0, 1)
lovr.graphics.setMaterial()
lovr.graphics.plane(logo, 0, 1.8, -3, 1, 0, 0, 1)
lovr.graphics.setColor(.059, .059, .059)
lovr.graphics.print('LÖVR', -.01, titlePosition, -3, .25, 0, 0, 1, 0, nil, 'center', 'top')
lovr.graphics.setColor(.059, .059, .059, fade)

View File

@ -178,333 +178,328 @@ unsigned char boot_lua[] = {
0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
0x73, 0x0a, 0x0a, 0x20, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x28,
0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x67, 0x6f, 0x20, 0x3d,
0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69,
0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69,
0x61, 0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x67,
0x6f, 0x3a, 0x73, 0x65, 0x74, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65,
0x28, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69,
0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72,
0x65, 0x28, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73,
0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x42, 0x6c, 0x6f,
0x62, 0x28, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x5f, 0x6c, 0x6f, 0x67, 0x6f,
0x2c, 0x20, 0x27, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x6e, 0x67, 0x27,
0x29, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72,
0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65,
0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43,
0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x2e, 0x39, 0x36, 0x30, 0x2c, 0x20, 0x2e,
0x39, 0x38, 0x38, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x28, 0x29, 0x0a, 0x20,
0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x66, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x64, 0x72,
0x61, 0x77, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76,
0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73,
0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x31, 0x2e, 0x30, 0x2c,
0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x0a, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x6d, 0x6f, 0x64, 0x65,
0x6c, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x61, 0x69, 0x72, 0x73, 0x28, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x29, 0x20,
0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63,
0x61, 0x6c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x7a, 0x20, 0x3d,
0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x3a,
0x67, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28,
0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x65,
0x6c, 0x3a, 0x64, 0x72, 0x61, 0x77, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x2c,
0x20, 0x7a, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x3a, 0x67, 0x65, 0x74, 0x4f, 0x72, 0x69,
0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x29, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69,
0x6e, 0x67, 0x20, 0x3d, 0x20, 0x2e, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d,
0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69,
0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x46, 0x6f, 0x6e, 0x74, 0x28, 0x29,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66,
0x61, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x2e, 0x33, 0x31, 0x35, 0x20, 0x2b,
0x20, 0x2e, 0x36, 0x38, 0x35, 0x20, 0x2a, 0x20, 0x6d, 0x61, 0x74, 0x68,
0x2e, 0x61, 0x62, 0x73, 0x28, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69,
0x6e, 0x28, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72,
0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x20, 0x2a,
0x20, 0x32, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63,
0x61, 0x6c, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x50, 0x6f, 0x73, 0x69,
0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x33, 0x20, 0x2d,
0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x75, 0x62, 0x74, 0x69,
0x74, 0x6c, 0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20,
0x3d, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x50, 0x6f, 0x73, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x3a, 0x67,
0x65, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x28, 0x29, 0x20, 0x2a,
0x20, 0x2e, 0x32, 0x35, 0x20, 0x2d, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69,
0x6e, 0x67, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72,
0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65,
0x74, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x28, 0x6c, 0x6f,
0x67, 0x6f, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72,
0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x6c,
0x61, 0x6e, 0x65, 0x28, 0x27, 0x66, 0x69, 0x6c, 0x6c, 0x27, 0x2c, 0x20,
0x30, 0x2c, 0x20, 0x31, 0x2e, 0x38, 0x2c, 0x20, 0x2d, 0x33, 0x2c, 0x20,
0x31, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x31, 0x29, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61,
0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x4d, 0x61, 0x74,
0x65, 0x72, 0x69, 0x61, 0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63,
0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x2e,
0x30, 0x35, 0x39, 0x2c, 0x20, 0x2e, 0x30, 0x35, 0x39, 0x2c, 0x20, 0x2e,
0x30, 0x35, 0x39, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76,
0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70,
0x72, 0x69, 0x6e, 0x74, 0x28, 0x27, 0x4c, 0xc3, 0x96, 0x56, 0x52, 0x27,
0x2c, 0x20, 0x2d, 0x2e, 0x30, 0x31, 0x2c, 0x20, 0x74, 0x69, 0x74, 0x6c,
0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x2d,
0x33, 0x2c, 0x20, 0x2e, 0x32, 0x35, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30,
0x2c, 0x20, 0x31, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x6e, 0x69, 0x6c, 0x2c,
0x20, 0x27, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x27, 0x2c, 0x20, 0x27,
0x74, 0x6f, 0x70, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f,
0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20,
0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e,
0x73, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x2e, 0x30, 0x35,
0x39, 0x2c, 0x20, 0x2e, 0x30, 0x35, 0x39, 0x2c, 0x20, 0x2e, 0x30, 0x35,
0x39, 0x2c, 0x20, 0x66, 0x61, 0x64, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69,
0x63, 0x73, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x27, 0x4e, 0x6f,
0x20, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x3a, 0x28, 0x27, 0x2c, 0x20, 0x2d,
0x2e, 0x30, 0x31, 0x2c, 0x20, 0x73, 0x75, 0x62, 0x74, 0x69, 0x74, 0x6c,
0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x2d,
0x33, 0x2c, 0x20, 0x2e, 0x31, 0x35, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30,
0x2c, 0x20, 0x31, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x6e, 0x69, 0x6c, 0x2c,
0x20, 0x27, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x27, 0x2c, 0x20, 0x27,
0x74, 0x6f, 0x70, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x0a, 0x20, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73,
0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68,
0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20,
0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x5f, 0x2c, 0x20, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x20, 0x69, 0x6e,
0x20, 0x70, 0x61, 0x69, 0x72, 0x73, 0x28, 0x6c, 0x6f, 0x76, 0x72, 0x2e,
0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x43,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x28, 0x29,
0x29, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x5b, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x5d, 0x20, 0x3d,
0x6e, 0x65, 0x77, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74,
0x65, 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x42, 0x6c, 0x6f, 0x62, 0x28, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x5f, 0x6c, 0x6f, 0x67, 0x6f, 0x2c, 0x20, 0x27,
0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x6e, 0x67, 0x27, 0x29, 0x29, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x67, 0x6f, 0x20, 0x3d, 0x20, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73,
0x2e, 0x6e, 0x65, 0x77, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c,
0x28, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x29, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68,
0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67,
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x2e,
0x39, 0x36, 0x30, 0x2c, 0x20, 0x2e, 0x39, 0x38, 0x38, 0x2c, 0x20, 0x31,
0x2e, 0x30, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x66, 0x72,
0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
0x72, 0x73, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a,
0x20, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70,
0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f,
0x72, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20,
0x31, 0x2e, 0x30, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f,
0x72, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
0x2c, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x70,
0x61, 0x69, 0x72, 0x73, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
0x6c, 0x65, 0x72, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x78, 0x2c, 0x20,
0x79, 0x2c, 0x20, 0x7a, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x3a, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x3a, 0x64, 0x72, 0x61, 0x77,
0x28, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x7a, 0x2c, 0x20, 0x31, 0x2c,
0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x3a,
0x6e, 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x28, 0x29, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64,
0x0a, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x61, 0x64, 0x64, 0x65, 0x64,
0x20, 0x3d, 0x20, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x0a, 0x20, 0x20,
0x67, 0x65, 0x74, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x28, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e,
0x64, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x2e,
0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20,
0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e,
0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74,
0x46, 0x6f, 0x6e, 0x74, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c,
0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x61, 0x64, 0x65, 0x20, 0x3d, 0x20,
0x2e, 0x33, 0x31, 0x35, 0x20, 0x2b, 0x20, 0x2e, 0x36, 0x38, 0x35, 0x20,
0x2a, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x62, 0x73, 0x28, 0x6d,
0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6c, 0x6f, 0x76, 0x72,
0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69,
0x6d, 0x65, 0x28, 0x29, 0x20, 0x2a, 0x20, 0x32, 0x29, 0x29, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x69, 0x74,
0x6c, 0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d,
0x20, 0x31, 0x2e, 0x33, 0x20, 0x2d, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69,
0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
0x20, 0x73, 0x75, 0x62, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x50, 0x6f, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x69, 0x74, 0x6c,
0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x20,
0x66, 0x6f, 0x6e, 0x74, 0x3a, 0x67, 0x65, 0x74, 0x48, 0x65, 0x69, 0x67,
0x68, 0x74, 0x28, 0x29, 0x20, 0x2a, 0x20, 0x2e, 0x32, 0x35, 0x20, 0x2d,
0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x0a, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68,
0x69, 0x63, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x28, 0x6c, 0x6f,
0x67, 0x6f, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x38, 0x2c, 0x20,
0x2d, 0x33, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2c,
0x20, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72,
0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65,
0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x2e, 0x30, 0x35, 0x39, 0x2c,
0x20, 0x2e, 0x30, 0x35, 0x39, 0x2c, 0x20, 0x2e, 0x30, 0x35, 0x39, 0x29,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72,
0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74,
0x28, 0x27, 0x4c, 0xc3, 0x96, 0x56, 0x52, 0x27, 0x2c, 0x20, 0x2d, 0x2e,
0x30, 0x31, 0x2c, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x50, 0x6f, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x2d, 0x33, 0x2c, 0x20, 0x2e,
0x32, 0x35, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x31, 0x2c,
0x20, 0x30, 0x2c, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x20, 0x27, 0x63, 0x65,
0x6e, 0x74, 0x65, 0x72, 0x27, 0x2c, 0x20, 0x27, 0x74, 0x6f, 0x70, 0x27,
0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67,
0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43,
0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x2e, 0x30, 0x35, 0x39, 0x2c, 0x20, 0x2e,
0x30, 0x35, 0x39, 0x2c, 0x20, 0x2e, 0x30, 0x35, 0x39, 0x2c, 0x20, 0x66,
0x61, 0x64, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76,
0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70,
0x72, 0x69, 0x6e, 0x74, 0x28, 0x27, 0x4e, 0x6f, 0x20, 0x67, 0x61, 0x6d,
0x65, 0x20, 0x3a, 0x28, 0x27, 0x2c, 0x20, 0x2d, 0x2e, 0x30, 0x31, 0x2c,
0x20, 0x73, 0x75, 0x62, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x50, 0x6f, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x2d, 0x33, 0x2c, 0x20, 0x2e,
0x31, 0x35, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x31, 0x2c,
0x20, 0x30, 0x2c, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x20, 0x27, 0x63, 0x65,
0x6e, 0x74, 0x65, 0x72, 0x27, 0x2c, 0x20, 0x27, 0x74, 0x6f, 0x70, 0x27,
0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x66, 0x72,
0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
0x72, 0x73, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x20, 0x3d, 0x20, 0x7b,
0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f,
0x74, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73,
0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75,
0x72, 0x6e, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x66, 0x6f, 0x72, 0x20, 0x5f, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x61, 0x69,
0x72, 0x73, 0x28, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64,
0x73, 0x65, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x28, 0x29, 0x29, 0x20, 0x64, 0x6f,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x5b, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x5d, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x3a, 0x6e, 0x65, 0x77, 0x4d,
0x6f, 0x64, 0x65, 0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65,
0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20,
0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
0x6c, 0x65, 0x72, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x3d,
0x20, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x0a, 0x65, 0x6e, 0x64, 0x0a,
0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65,
0x73, 0x73, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3d, 0x20, 0x70, 0x63,
0x61, 0x6c, 0x6c, 0x28, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x2c,
0x20, 0x27, 0x63, 0x6f, 0x6e, 0x66, 0x27, 0x29, 0x0a, 0x6c, 0x6f, 0x63,
0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x65, 0x72, 0x72, 0x0a, 0x69,
0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x20,
0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65,
0x73, 0x73, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x65, 0x72, 0x72, 0x20,
0x3d, 0x20, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6c, 0x6f, 0x76, 0x72,
0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x29,
0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x5f,
0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x28, 0x63, 0x6f, 0x6e, 0x66,
0x29, 0x0a, 0x0a, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x66, 0x69, 0x6c, 0x65,
0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x49, 0x64,
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, 0x63, 0x6f, 0x6e, 0x66, 0x2e,
0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x29, 0x0a, 0x0a, 0x6c,
0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73,
0x20, 0x3d, 0x20, 0x7b, 0x20, 0x27, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x27,
0x2c, 0x20, 0x27, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x27, 0x2c, 0x20, 0x27,
0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x27, 0x2c, 0x20, 0x27,
0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x27, 0x2c, 0x20, 0x27, 0x6d,
0x61, 0x74, 0x68, 0x27, 0x2c, 0x20, 0x27, 0x70, 0x68, 0x79, 0x73, 0x69,
0x63, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x27,
0x20, 0x7d, 0x0a, 0x66, 0x6f, 0x72, 0x20, 0x5f, 0x2c, 0x20, 0x6d, 0x6f,
0x64, 0x75, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69,
0x72, 0x73, 0x28, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x29, 0x20,
0x64, 0x6f, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x66,
0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x5b, 0x6d, 0x6f, 0x64,
0x75, 0x6c, 0x65, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x5b, 0x6d, 0x6f, 0x64, 0x75, 0x6c,
0x65, 0x5d, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65,
0x28, 0x27, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x27, 0x20, 0x2e, 0x2e, 0x20,
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e,
0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x72,
0x72, 0x6f, 0x72, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x77, 0x69,
0x6e, 0x64, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x63, 0x72, 0x65, 0x61,
0x74, 0x65, 0x64, 0x0a, 0x69, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x65,
0x72, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x65, 0x72,
0x72, 0x6f, 0x72, 0x28, 0x63, 0x6f, 0x6e, 0x66, 0x65, 0x72, 0x72, 0x29,
0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68,
0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x65,
0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x7b,
0x0a, 0x20, 0x20, 0x71, 0x75, 0x69, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75,
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x65, 0x6e, 0x64,
0x2c, 0x0a, 0x20, 0x20, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x3d, 0x20,
0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x66, 0x29, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e,
0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x28, 0x66, 0x29,
0x6c, 0x65, 0x72, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x72,
0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x73, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72,
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x72,
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x66,
0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
0x65, 0x72, 0x73, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63,
0x61, 0x6c, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2c, 0x20,
0x65, 0x72, 0x72, 0x20, 0x3d, 0x20, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28,
0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x2c, 0x20, 0x27, 0x63, 0x6f,
0x6e, 0x66, 0x27, 0x29, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63,
0x6f, 0x6e, 0x66, 0x65, 0x72, 0x72, 0x0a, 0x69, 0x66, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x20, 0x74, 0x68, 0x65, 0x6e,
0x0a, 0x20, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2c, 0x20,
0x63, 0x6f, 0x6e, 0x66, 0x65, 0x72, 0x72, 0x20, 0x3d, 0x20, 0x70, 0x63,
0x61, 0x6c, 0x6c, 0x28, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e,
0x66, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x29, 0x0a, 0x65, 0x6e, 0x64,
0x0a, 0x0a, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x5f, 0x73, 0x65, 0x74, 0x43,
0x6f, 0x6e, 0x66, 0x28, 0x63, 0x6f, 0x6e, 0x66, 0x29, 0x0a, 0x0a, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74,
0x65, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69,
0x74, 0x79, 0x28, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x69, 0x64, 0x65, 0x6e,
0x74, 0x69, 0x74, 0x79, 0x29, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b,
0x20, 0x27, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x27, 0x2c, 0x20, 0x27, 0x65,
0x76, 0x65, 0x6e, 0x74, 0x27, 0x2c, 0x20, 0x27, 0x67, 0x72, 0x61, 0x70,
0x68, 0x69, 0x63, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x68, 0x65, 0x61, 0x64,
0x73, 0x65, 0x74, 0x27, 0x2c, 0x20, 0x27, 0x6d, 0x61, 0x74, 0x68, 0x27,
0x2c, 0x20, 0x27, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x73, 0x27, 0x2c,
0x20, 0x27, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x27, 0x20, 0x7d, 0x0a, 0x66,
0x6f, 0x72, 0x20, 0x5f, 0x2c, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, 0x73, 0x28, 0x6d,
0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x20,
0x20, 0x69, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x6d, 0x6f, 0x64,
0x75, 0x6c, 0x65, 0x73, 0x5b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5d,
0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x5b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5d, 0x20, 0x3d,
0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x27, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x27, 0x20, 0x2e, 0x2e, 0x20, 0x6d, 0x6f, 0x64, 0x75,
0x6c, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e,
0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20,
0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77,
0x20, 0x69, 0x73, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x0a,
0x69, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x65, 0x72, 0x72, 0x20, 0x74,
0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28,
0x63, 0x6f, 0x6e, 0x66, 0x65, 0x72, 0x72, 0x29, 0x0a, 0x65, 0x6e, 0x64,
0x0a, 0x0a, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c,
0x65, 0x72, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74,
0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x71,
0x75, 0x69, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x28, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x20, 0x20,
0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x28, 0x66, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x66, 0x6f, 0x63, 0x75,
0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e,
0x66, 0x6f, 0x63, 0x75, 0x73, 0x28, 0x66, 0x29, 0x20, 0x65, 0x6e, 0x64,
0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x20, 0x20, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x61, 0x64, 0x64, 0x65,
0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x28, 0x63, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
0x65, 0x72, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e,
0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x61, 0x64, 0x64, 0x65, 0x64, 0x28, 0x63, 0x29,
0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20,
0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x61, 0x64, 0x64, 0x65,
0x64, 0x28, 0x63, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65,
0x6e, 0x64, 0x2c, 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20,
0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63,
0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76,
0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75,
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x29, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x72, 0x65, 0x6d, 0x6f,
0x76, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76,
0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e,
0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x28,
0x63, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64,
0x2c, 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
0x65, 0x72, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20,
0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x2c, 0x20,
0x62, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f,
0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x28, 0x63, 0x29, 0x20, 0x65,
0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x20, 0x20,
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x70, 0x72,
0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x2c, 0x20, 0x62, 0x29, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x70, 0x72, 0x65,
0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
0x72, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65,
0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64,
0x28, 0x63, 0x2c, 0x20, 0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20,
0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x28, 0x63, 0x2c, 0x20, 0x62, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72,
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x72,
0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x28, 0x63, 0x2c, 0x20, 0x62,
0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x7d, 0x2c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x5f, 0x5f, 0x69, 0x6e, 0x64,
0x65, 0x78, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x65, 0x76, 0x65, 0x6e,
0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72,
0x28, 0x27, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x65, 0x76,
0x65, 0x6e, 0x74, 0x3a, 0x20, 0x27, 0x20, 0x2e, 0x2e, 0x20, 0x74, 0x6f,
0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74,
0x29, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x7d, 0x29, 0x0a,
0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x20, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x52,
0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
0x6b, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76,
0x72, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x28, 0x63, 0x2c, 0x20,
0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64,
0x2c, 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
0x65, 0x72, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x3d,
0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x2c,
0x20, 0x62, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
0x65, 0x72, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x74,
0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x72, 0x65, 0x6c, 0x65, 0x61,
0x73, 0x65, 0x64, 0x28, 0x63, 0x2c, 0x20, 0x62, 0x29, 0x20, 0x65, 0x6e,
0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x7d, 0x2c, 0x20, 0x7b,
0x0a, 0x20, 0x20, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d,
0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x65,
0x6c, 0x66, 0x2c, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x27, 0x55, 0x6e,
0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3a,
0x20, 0x27, 0x20, 0x2e, 0x2e, 0x20, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69,
0x6e, 0x67, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x29, 0x0a, 0x20,
0x20, 0x65, 0x6e, 0x64, 0x0a, 0x7d, 0x29, 0x0a, 0x0a, 0x6c, 0x6f, 0x63,
0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x52, 0x65, 0x6e, 0x64, 0x65,
0x72, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x0a,
0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65,
0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x4f, 0x72, 0x69,
0x67, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x28, 0x29, 0x20, 0x3d, 0x3d,
0x20, 0x27, 0x68, 0x65, 0x61, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x48, 0x65,
0x61, 0x64, 0x73, 0x65, 0x74, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x28,
0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x65, 0x6e,
0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x73, 0x74, 0x65, 0x70, 0x28, 0x29, 0x0a,
0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74,
0x2e, 0x70, 0x75, 0x6d, 0x70, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x66, 0x6f,
0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x62,
0x2c, 0x20, 0x63, 0x2c, 0x20, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x6f, 0x6c,
0x6c, 0x28, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
0x66, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x71,
0x75, 0x69, 0x74, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x6e, 0x6f,
0x74, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x71, 0x75, 0x69, 0x74, 0x20,
0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e,
0x71, 0x75, 0x69, 0x74, 0x28, 0x29, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
0x6e, 0x20, 0x61, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x61, 0x6e,
0x64, 0x6c, 0x65, 0x72, 0x73, 0x5b, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x28,
0x61, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x63, 0x2c, 0x20, 0x64, 0x29, 0x0a,
0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61,
0x6c, 0x20, 0x64, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e,
0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x65, 0x70, 0x28, 0x29,
0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68,
0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61,
0x64, 0x73, 0x65, 0x74, 0x2e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28,
0x64, 0x74, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20,
0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x61, 0x75, 0x64, 0x69,
0x6f, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x75, 0x70,
0x64, 0x61, 0x74, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73,
0x65, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e,
0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, 0x69, 0x73, 0x50, 0x72,
0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e,
0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x73, 0x65, 0x74, 0x4f, 0x72, 0x69,
0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6c, 0x6f, 0x76,
0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, 0x67, 0x65,
0x74, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x28,
0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x68, 0x65, 0x61, 0x64, 0x27, 0x20,
0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x70,
0x6c, 0x79, 0x48, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x4f, 0x66, 0x66,
0x73, 0x65, 0x74, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x28,
0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x73, 0x74, 0x65,
0x70, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65,
0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x75, 0x6d, 0x70, 0x28, 0x29, 0x0a,
0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20,
0x61, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x63, 0x2c, 0x20, 0x64, 0x20, 0x69,
0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74,
0x2e, 0x70, 0x6f, 0x6c, 0x6c, 0x28, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d,
0x3d, 0x20, 0x27, 0x71, 0x75, 0x69, 0x74, 0x27, 0x20, 0x61, 0x6e, 0x64,
0x20, 0x28, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x71,
0x75, 0x69, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x71, 0x75, 0x69, 0x74, 0x28, 0x29, 0x29, 0x20,
0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72,
0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x5b, 0x6e, 0x61,
0x6d, 0x65, 0x5d, 0x28, 0x61, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x63, 0x2c,
0x20, 0x64, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20,
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x74, 0x20, 0x3d, 0x20, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x74,
0x65, 0x70, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x20, 0x74,
0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72,
0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, 0x75, 0x70, 0x64,
0x61, 0x74, 0x65, 0x28, 0x64, 0x74, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e,
0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e,
0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x61, 0x75, 0x64, 0x69,
0x6f, 0x2e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x29, 0x0a, 0x20,
0x74, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x28, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x73, 0x65, 0x74,
0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6c, 0x6f, 0x76,
0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, 0x67, 0x65,
0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x29,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e,
0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x73, 0x65, 0x74, 0x56, 0x65, 0x6c,
0x6f, 0x63, 0x69, 0x74, 0x79, 0x28, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68,
0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x56, 0x65,
0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x28, 0x29, 0x29, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x75, 0x70,
0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x64, 0x74,
0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73,
0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e,
0x63, 0x6c, 0x65, 0x61, 0x72, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63,
0x73, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x64,
0x72, 0x61, 0x77, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68,
0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x2e,
0x69, 0x73, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x20,
0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x73, 0x65,
0x74, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x28, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65,
0x74, 0x2e, 0x67, 0x65, 0x74, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f,
0x2e, 0x73, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
0x28, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65,
0x74, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f,
0x6e, 0x28, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c,
0x6f, 0x76, 0x72, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x73, 0x65,
0x74, 0x56, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x28, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, 0x67,
0x65, 0x74, 0x56, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x28, 0x29,
0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20,
0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76,
0x72, 0x2e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65,
0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x75, 0x70, 0x64, 0x61, 0x74,
0x65, 0x28, 0x64, 0x74, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20,
0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70,
0x68, 0x69, 0x63, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68,
0x69, 0x63, 0x73, 0x2e, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x28, 0x29, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61,
0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e,
0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x20, 0x74, 0x68, 0x65, 0x6e,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x20, 0x61,
0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64,
0x73, 0x65, 0x74, 0x2e, 0x69, 0x73, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e,
0x74, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65,
0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72,
0x54, 0x6f, 0x28, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x52, 0x65,
0x6e, 0x64, 0x65, 0x72, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b,
0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x70,
0x6c, 0x79, 0x48, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x4f, 0x66, 0x66,
0x73, 0x65, 0x74, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x28,
0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65,
0x74, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, 0x6f, 0x28, 0x68,
0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72,
0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x29, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x48, 0x65,
0x61, 0x64, 0x73, 0x65, 0x74, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x28,
0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f,
0x76, 0x72, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63,
0x73, 0x2e, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x0a,
0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72,
0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x65, 0x65, 0x70,
0x28, 0x2e, 0x30, 0x30, 0x31, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a,
0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76,
0x72, 0x2e, 0x72, 0x75, 0x6e, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66,
0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x74,
0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x6c, 0x6f, 0x61,
0x64, 0x28, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x77, 0x68,
0x69, 0x6c, 0x65, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x64, 0x6f, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x78,
0x69, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x73, 0x74,
0x65, 0x70, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20,
0x65, 0x78, 0x69, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x78, 0x69, 0x74, 0x20, 0x65, 0x6e,
0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a,
0x0a, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x66, 0x69, 0x6c,
0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x69, 0x73, 0x46, 0x69,
0x6c, 0x65, 0x28, 0x27, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x6c, 0x75, 0x61,
0x27, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x72, 0x65,
0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x27, 0x6d, 0x61, 0x69, 0x6e, 0x27,
0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a
0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72,
0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72,
0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e,
0x64, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x74, 0x69, 0x6d,
0x65, 0x72, 0x2e, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x28, 0x2e, 0x30, 0x30,
0x31, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x72, 0x75,
0x6e, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76,
0x72, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20,
0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x29, 0x20,
0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20,
0x74, 0x72, 0x75, 0x65, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x78, 0x69, 0x74, 0x20, 0x3d,
0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x73, 0x74, 0x65, 0x70, 0x28, 0x29,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x65, 0x78, 0x69, 0x74,
0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
0x20, 0x65, 0x78, 0x69, 0x74, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20,
0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x69, 0x66, 0x20,
0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73,
0x74, 0x65, 0x6d, 0x2e, 0x69, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x28, 0x27,
0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x6c, 0x75, 0x61, 0x27, 0x29, 0x20, 0x74,
0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
0x65, 0x28, 0x27, 0x6d, 0x61, 0x69, 0x6e, 0x27, 0x29, 0x0a, 0x65, 0x6e,
0x64, 0x0a
};
unsigned int boot_lua_len = 6078;
unsigned int boot_lua_len = 6014;

View File

@ -69,7 +69,6 @@ void lovrGraphicsReset() {
lovrGraphicsSetDefaultFilter((TextureFilter) { .mode = FILTER_TRILINEAR });
lovrGraphicsSetDepthTest(COMPARE_LEQUAL);
lovrGraphicsSetFont(NULL);
lovrGraphicsSetMaterial(NULL);
lovrGraphicsSetLineWidth(1);
lovrGraphicsSetPointSize(1);
lovrGraphicsSetShader(NULL);
@ -89,7 +88,7 @@ void lovrGraphicsPresent() {
glfwSwapBuffers(state.window);
}
void lovrGraphicsPrepare(float* pose) {
void lovrGraphicsPrepare(Material* material, float* pose) {
Shader* shader = lovrGraphicsGetActiveShader();
if (!shader) {
@ -142,7 +141,9 @@ void lovrGraphicsPrepare(float* pose) {
}
// Material
Material* material = lovrGraphicsGetMaterial();
if (!material) {
material = lovrGraphicsGetDefaultMaterial();
}
for (int i = 0; i < MAX_MATERIAL_COLORS; i++) {
Color color = lovrMaterialGetColor(material, i);
@ -417,31 +418,6 @@ void lovrGraphicsSetLineWidth(float width) {
glLineWidth(width);
}
Material* lovrGraphicsGetMaterial() {
if (!state.material) {
if (!state.defaultMaterial) {
MaterialData* materialData = lovrMaterialDataCreateEmpty();
state.defaultMaterial = lovrMaterialCreate(materialData, true);
}
lovrGraphicsSetMaterial(state.defaultMaterial);
}
return state.material;
}
void lovrGraphicsSetMaterial(Material* material) {
if (state.material) {
lovrRelease(&state.material->ref);
}
state.material = material;
if (material) {
lovrRetain(&material->ref);
}
}
float lovrGraphicsGetPointSize() {
return state.pointSize;
}
@ -539,13 +515,13 @@ static void lovrGraphicsSetIndexData(unsigned int* data, int length) {
vec_pusharr(&state.streamIndices, data, length);
}
static void lovrGraphicsDrawPrimitive(GLenum mode, bool hasNormals, bool hasTexCoords, bool useIndices) {
static void lovrGraphicsDrawPrimitive(Material* material, GLenum mode, bool hasNormals, bool hasTexCoords, bool useIndices) {
int stride = 3 + (hasNormals ? 3 : 0) + (hasTexCoords ? 2 : 0);
int strideBytes = stride * sizeof(float);
float* data = state.streamData.data;
unsigned int* indices = state.streamIndices.data;
lovrGraphicsPrepare(NULL);
lovrGraphicsPrepare(material, NULL);
lovrGraphicsBindVertexArray(state.streamVAO);
lovrGraphicsBindVertexBuffer(state.streamVBO);
glBufferData(GL_ARRAY_BUFFER, state.streamData.length * sizeof(float), data, GL_STREAM_DRAW);
@ -582,21 +558,21 @@ static void lovrGraphicsDrawPrimitive(GLenum mode, bool hasNormals, bool hasTexC
void lovrGraphicsPoints(float* points, int count) {
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsSetStreamData(points, count);
lovrGraphicsDrawPrimitive(GL_POINTS, false, false, false);
lovrGraphicsDrawPrimitive(NULL, GL_POINTS, false, false, false);
}
void lovrGraphicsLine(float* points, int count) {
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsSetStreamData(points, count);
lovrGraphicsDrawPrimitive(GL_LINE_STRIP, false, false, false);
lovrGraphicsDrawPrimitive(NULL, GL_LINE_STRIP, false, false, false);
}
void lovrGraphicsTriangle(DrawMode mode, float* points) {
void lovrGraphicsTriangle(DrawMode mode, Material* material, float* points) {
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
if (mode == DRAW_MODE_LINE) {
lovrGraphicsSetStreamData(points, 9);
lovrGraphicsDrawPrimitive(GL_LINE_LOOP, false, false, false);
lovrGraphicsDrawPrimitive(material, GL_LINE_LOOP, false, false, false);
} else {
float normal[3];
vec3_cross(vec3_init(normal, &points[0]), &points[3]);
@ -608,11 +584,11 @@ void lovrGraphicsTriangle(DrawMode mode, float* points) {
};
lovrGraphicsSetStreamData(data, 18);
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, true, false, false);
lovrGraphicsDrawPrimitive(material, GL_TRIANGLE_STRIP, true, false, false);
}
}
void lovrGraphicsPlane(DrawMode mode, mat4 transform) {
void lovrGraphicsPlane(DrawMode mode, Material* material, mat4 transform) {
lovrGraphicsPush();
lovrGraphicsMatrixTransform(MATRIX_MODEL, transform);
@ -626,7 +602,7 @@ void lovrGraphicsPlane(DrawMode mode, mat4 transform) {
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsSetStreamData(points, 12);
lovrGraphicsDrawPrimitive(GL_LINE_LOOP, false, false, false);
lovrGraphicsDrawPrimitive(material, GL_LINE_LOOP, false, false, false);
} else if (mode == DRAW_MODE_FILL) {
float data[] = {
-.5, .5, 0, 0, 0, -1, 0, 0,
@ -637,7 +613,7 @@ void lovrGraphicsPlane(DrawMode mode, mat4 transform) {
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsSetStreamData(data, 32);
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, true, true, false);
lovrGraphicsDrawPrimitive(material, GL_TRIANGLE_STRIP, true, true, false);
}
lovrGraphicsPop();
@ -652,15 +628,14 @@ void lovrGraphicsPlaneFullscreen(Texture* texture) {
};
lovrGraphicsSetDefaultShader(SHADER_FULLSCREEN);
Material* material = lovrGraphicsGetMaterial();
Texture* lastTexture = lovrMaterialGetTexture(material, TEXTURE_DIFFUSE);
Material* material = lovrGraphicsGetDefaultMaterial();
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, texture);
lovrGraphicsSetStreamData(data, 20);
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, false, true, false);
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, lastTexture);
lovrGraphicsDrawPrimitive(material, GL_TRIANGLE_STRIP, false, true, false);
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, NULL);
}
void lovrGraphicsBox(DrawMode mode, mat4 transform) {
void lovrGraphicsBox(DrawMode mode, Material* material, mat4 transform) {
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsPush();
lovrGraphicsMatrixTransform(MATRIX_MODEL, transform);
@ -689,7 +664,7 @@ void lovrGraphicsBox(DrawMode mode, mat4 transform) {
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsSetStreamData(points, 24);
lovrGraphicsSetIndexData(indices, 24);
lovrGraphicsDrawPrimitive(GL_LINES, false, false, true);
lovrGraphicsDrawPrimitive(material, GL_LINES, false, false, true);
} else {
float data[] = {
// Front
@ -735,13 +710,13 @@ void lovrGraphicsBox(DrawMode mode, mat4 transform) {
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsSetStreamData(data, 208);
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, true, true, false);
lovrGraphicsDrawPrimitive(material, GL_TRIANGLE_STRIP, true, true, false);
}
lovrGraphicsPop();
}
void lovrGraphicsArc(DrawMode mode, ArcMode arcMode, mat4 transform, float theta1, float theta2, int segments) {
void lovrGraphicsArc(DrawMode mode, ArcMode arcMode, Material* material, mat4 transform, float theta1, float theta2, int segments) {
if (fabsf(theta1 - theta2) >= 2 * M_PI) {
theta1 = 0;
theta2 = 2 * M_PI;
@ -781,7 +756,7 @@ void lovrGraphicsArc(DrawMode mode, ArcMode arcMode, mat4 transform, float theta
}
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsDrawPrimitive(arcMode == ARC_MODE_OPEN ? GL_LINE_STRIP : GL_LINE_LOOP, false, false, false);
lovrGraphicsDrawPrimitive(material, arcMode == ARC_MODE_OPEN ? GL_LINE_STRIP : GL_LINE_LOOP, false, false, false);
} else if (mode == DRAW_MODE_FILL) {
for (int i = 0; i <= segments; i++) {
float x = cos(theta) * .5;
@ -800,17 +775,17 @@ void lovrGraphicsArc(DrawMode mode, ArcMode arcMode, mat4 transform, float theta
}
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsDrawPrimitive(GL_TRIANGLE_FAN, true, true, false);
lovrGraphicsDrawPrimitive(material, GL_TRIANGLE_FAN, true, true, false);
}
lovrGraphicsPop();
}
void lovrGraphicsCircle(DrawMode mode, mat4 transform, int segments) {
lovrGraphicsArc(mode, ARC_MODE_OPEN, transform, 0, 2 * M_PI, segments);
void lovrGraphicsCircle(DrawMode mode, Material* material, mat4 transform, int segments) {
lovrGraphicsArc(mode, ARC_MODE_OPEN, material, transform, 0, 2 * M_PI, segments);
}
void lovrGraphicsCylinder(float x1, float y1, float z1, float x2, float y2, float z2, float r1, float r2, bool capped, int segments) {
void lovrGraphicsCylinder(Material* material, float x1, float y1, float z1, float x2, float y2, float z2, float r1, float r2, bool capped, int segments) {
float axis[3] = { x1 - x2, y1 - y2, z1 - z2 };
float n[3] = { x1 - x2, y1 - y2, z1 - z2 };
float p[3];
@ -910,12 +885,12 @@ void lovrGraphicsCylinder(float x1, float y1, float z1, float x2, float y2, floa
}
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsDrawPrimitive(GL_TRIANGLES, true, false, true);
lovrGraphicsDrawPrimitive(material, GL_TRIANGLES, true, false, true);
#undef PUSH_CYLINDER_VERTEX
#undef PUSH_CYLINDER_TRIANGLE
}
void lovrGraphicsSphere(mat4 transform, int segments) {
void lovrGraphicsSphere(Material* material, mat4 transform, int segments) {
vec_clear(&state.streamData);
vec_clear(&state.streamIndices);
@ -962,7 +937,7 @@ void lovrGraphicsSphere(mat4 transform, int segments) {
}
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsDrawPrimitive(GL_TRIANGLES, true, true, true);
lovrGraphicsDrawPrimitive(material, GL_TRIANGLES, true, true, true);
if (transform) {
lovrGraphicsPop();
@ -1022,17 +997,15 @@ void lovrGraphicsSkybox(Texture* texture, float angle, float ax, float ay, float
lovrGraphicsSetStreamData(cube, 78);
lovrGraphicsSetDefaultShader(SHADER_SKYBOX);
Material* material = lovrGraphicsGetMaterial();
Texture* lastTexture = lovrMaterialGetTexture(material, TEXTURE_ENVIRONMENT_MAP);
Material* material = lovrGraphicsGetDefaultMaterial();
lovrMaterialSetTexture(material, TEXTURE_ENVIRONMENT_MAP, texture);
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, false, false, false);
lovrMaterialSetTexture(material, TEXTURE_ENVIRONMENT_MAP, lastTexture);
lovrGraphicsDrawPrimitive(material, GL_TRIANGLE_STRIP, false, false, false);
lovrMaterialSetTexture(material, TEXTURE_ENVIRONMENT_MAP, NULL);
} else if (texture->type == TEXTURE_2D) {
Material* material = lovrGraphicsGetMaterial();
Texture* lastTexture = lovrMaterialGetTexture(material, TEXTURE_DIFFUSE);
Material* material = lovrGraphicsGetDefaultMaterial();
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, texture);
lovrGraphicsSphere(NULL, 30);
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, lastTexture);
lovrGraphicsSphere(material, NULL, 30);
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, NULL);
}
lovrGraphicsSetCullingEnabled(wasCulling);
@ -1051,13 +1024,12 @@ void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAl
lovrGraphicsScale(MATRIX_MODEL, scale, scale, scale);
lovrGraphicsTranslate(MATRIX_MODEL, 0, offsety, 0);
lovrGraphicsSetDefaultShader(SHADER_FONT);
Material* material = lovrGraphicsGetMaterial();
Texture* lastTexture = lovrMaterialGetTexture(material, TEXTURE_DIFFUSE);
Material* material = lovrGraphicsGetDefaultMaterial();
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, font->texture);
glDepthMask(GL_FALSE);
lovrGraphicsDrawPrimitive(GL_TRIANGLES, false, true, false);
lovrGraphicsDrawPrimitive(NULL, GL_TRIANGLES, false, true, false);
glDepthMask(GL_TRUE);
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, lastTexture);
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, NULL);
lovrGraphicsPop();
}
@ -1127,6 +1099,15 @@ void lovrGraphicsBindTexture(Texture* texture, TextureType type, int slot) {
}
}
Material* lovrGraphicsGetDefaultMaterial() {
if (!state.defaultMaterial) {
MaterialData* materialData = lovrMaterialDataCreateEmpty();
state.defaultMaterial = lovrMaterialCreate(materialData, true);
}
return state.defaultMaterial;
}
void lovrGraphicsSetDefaultShader(DefaultShader shader) {
state.defaultShader = shader;
}

View File

@ -95,7 +95,6 @@ typedef struct {
bool gammaCorrect;
GraphicsLimits limits;
float lineWidth;
Material* material;
float pointSize;
Shader* shader;
Winding winding;
@ -120,7 +119,7 @@ void lovrGraphicsDestroy();
void lovrGraphicsReset();
void lovrGraphicsClear(bool color, bool depth);
void lovrGraphicsPresent();
void lovrGraphicsPrepare(float* pose);
void lovrGraphicsPrepare(Material* material, float* pose);
void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const char* title, const char* icon);
int lovrGraphicsGetWidth();
int lovrGraphicsGetHeight();
@ -145,8 +144,6 @@ void lovrGraphicsSetGammaCorrect(bool gammaCorrect);
GraphicsLimits lovrGraphicsGetLimits();
float lovrGraphicsGetLineWidth();
void lovrGraphicsSetLineWidth(float width);
Material* lovrGraphicsGetMaterial();
void lovrGraphicsSetMaterial(Material* material);
float lovrGraphicsGetPointSize();
void lovrGraphicsSetPointSize(float size);
Shader* lovrGraphicsGetShader();
@ -168,14 +165,14 @@ void lovrGraphicsMatrixTransform(MatrixType type, mat4 transform);
// Primitives
void lovrGraphicsPoints(float* points, int count);
void lovrGraphicsLine(float* points, int count);
void lovrGraphicsTriangle(DrawMode mode, float* points);
void lovrGraphicsPlane(DrawMode mode, mat4 transform);
void lovrGraphicsTriangle(DrawMode mode, Material* material, float* points);
void lovrGraphicsPlane(DrawMode mode, Material* material, mat4 transform);
void lovrGraphicsPlaneFullscreen(Texture* texture);
void lovrGraphicsBox(DrawMode mode, mat4 transform);
void lovrGraphicsArc(DrawMode mode, ArcMode, mat4 transform, float theta1, float theta2, int segments);
void lovrGraphicsCircle(DrawMode mode, mat4 transform, int segments);
void lovrGraphicsCylinder(float x1, float y1, float z1, float x2, float y2, float z2, float r1, float r2, bool capped, int segments);
void lovrGraphicsSphere(mat4 transform, int segments);
void lovrGraphicsBox(DrawMode mode, Material* material, mat4 transform);
void lovrGraphicsArc(DrawMode mode, ArcMode, Material* material, mat4 transform, float theta1, float theta2, int segments);
void lovrGraphicsCircle(DrawMode mode, Material* material, mat4 transform, int segments);
void lovrGraphicsCylinder(Material* material, float x1, float y1, float z1, float x2, float y2, float z2, float r1, float r2, bool capped, int segments);
void lovrGraphicsSphere(Material* material, mat4 transform, int segments);
void lovrGraphicsSkybox(Texture* texture, float angle, float ax, float ay, float az);
void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAlign halign, VerticalAlign valign);
@ -186,8 +183,9 @@ mat4 lovrGraphicsGetProjection();
void lovrGraphicsSetProjection(mat4 projection);
void lovrGraphicsSetViewport(int x, int y, int w, int h);
void lovrGraphicsBindFramebuffer(int framebuffer);
Texture* lovrGraphicsGetTexture();
Texture* lovrGraphicsGetTexture(int slot);
void lovrGraphicsBindTexture(Texture* texture, TextureType type, int slot);
Material* lovrGraphicsGetDefaultMaterial();
void lovrGraphicsSetDefaultShader(DefaultShader defaultShader);
Shader* lovrGraphicsGetActiveShader();
void lovrGraphicsUseProgram(uint32_t program);

View File

@ -99,6 +99,7 @@ Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, Me
mesh->isRangeEnabled = false;
mesh->rangeStart = 0;
mesh->rangeCount = mesh->count;
mesh->material = NULL;
mesh->lastShader = NULL;
glGenBuffers(1, &mesh->vbo);
@ -138,7 +139,7 @@ void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose) {
}
lovrGraphicsSetDefaultShader(SHADER_DEFAULT);
lovrGraphicsPrepare(pose);
lovrGraphicsPrepare(mesh->material, pose);
lovrGraphicsBindVertexArray(mesh->vao);
lovrMeshBindAttributes(mesh);
size_t start = mesh->rangeStart;
@ -254,6 +255,24 @@ void lovrMeshSetDrawRange(Mesh* mesh, int start, int count) {
mesh->rangeCount = count;
}
Material* lovrMeshGetMaterial(Mesh* mesh) {
return mesh->material;
}
void lovrMeshSetMaterial(Mesh* mesh, Material* material) {
if (mesh->material != material) {
if (mesh->material) {
lovrRelease(&mesh->material->ref);
}
mesh->material = material;
if (material) {
lovrRetain(&material->ref);
}
}
}
void* lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write) {
#ifdef EMSCRIPTEN
mesh->isMapped = true;

View File

@ -1,6 +1,6 @@
#include "util.h"
#include "graphics/shader.h"
#include "graphics/texture.h"
#include "graphics/material.h"
#include "math/math.h"
#include "lib/glfw.h"
@ -55,6 +55,7 @@ typedef struct {
bool isRangeEnabled;
int rangeStart;
int rangeCount;
Material* material;
Shader* lastShader;
} Mesh;
@ -74,7 +75,7 @@ bool lovrMeshIsRangeEnabled(Mesh* mesh);
void lovrMeshSetRangeEnabled(Mesh* mesh, char isEnabled);
void lovrMeshGetDrawRange(Mesh* mesh, int* start, int* count);
void lovrMeshSetDrawRange(Mesh* mesh, int start, int count);
Texture* lovrMeshGetTexture(Mesh* mesh);
void lovrMeshSetTexture(Mesh* mesh, Texture* texture);
Material* lovrMeshGetMaterial(Mesh* mesh);
void lovrMeshSetMaterial(Mesh* mesh, Material* material);
void* lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write);
void lovrMeshUnmap(Mesh* mesh);

View File

@ -6,8 +6,6 @@
static void renderNode(Model* model, int nodeIndex) {
ModelNode* node = &model->modelData->nodes[nodeIndex];
Material* currentMaterial = lovrGraphicsGetMaterial();
bool useMaterials = currentMaterial->isDefault;
if (node->primitives.length > 0) {
lovrGraphicsPush();
@ -35,8 +33,8 @@ static void renderNode(Model* model, int nodeIndex) {
}
}
if (useMaterials) {
lovrGraphicsSetMaterial(model->materials[primitive->material]);
if (!model->material) {
lovrMeshSetMaterial(model->mesh, model->materials[primitive->material]);
}
lovrMeshSetDrawRange(model->mesh, primitive->drawStart, primitive->drawCount);
@ -49,10 +47,6 @@ static void renderNode(Model* model, int nodeIndex) {
for (int i = 0; i < node->children.length; i++) {
renderNode(model, node->children.data[i]);
}
if (useMaterials) {
lovrGraphicsSetMaterial(currentMaterial);
}
}
Model* lovrModelCreate(ModelData* modelData) {
@ -62,6 +56,7 @@ Model* lovrModelCreate(ModelData* modelData) {
model->modelData = modelData;
model->aabbDirty = true;
model->animator = NULL;
model->material = NULL;
MeshFormat format;
vec_init(&format);
@ -123,6 +118,12 @@ void lovrModelDestroy(const Ref* ref) {
for (int i = 0; i < model->modelData->materialCount; i++) {
lovrRelease(&model->materials[i]->ref);
}
if (model->animator) {
lovrRelease(&model->animator->ref);
}
if (model->material) {
lovrRelease(&model->material->ref);
}
free(model->materials);
lovrModelDataDestroy(model->modelData);
lovrRelease(&model->mesh->ref);
@ -155,6 +156,10 @@ void lovrModelDraw(Model* model, mat4 transform) {
}
}
if (model->material) {
lovrMeshSetMaterial(model->mesh, model->material);
}
lovrGraphicsPush();
lovrGraphicsMatrixTransform(MATRIX_MODEL, transform);
renderNode(model, 0);
@ -166,13 +171,41 @@ Animator* lovrModelGetAnimator(Model* model) {
}
void lovrModelSetAnimator(Model* model, Animator* animator) {
model->animator = animator;
if (model->animator != animator) {
if (model->animator) {
lovrRelease(&model->animator->ref);
}
model->animator = animator;
if (animator) {
lovrRetain(&animator->ref);
}
}
}
int lovrModelGetAnimationCount(Model* model) {
return model->modelData->animationCount;
}
Material* lovrModelGetMaterial(Model* model) {
return model->material;
}
void lovrModelSetMaterial(Model* model, Material* material) {
if (model->material != material) {
if (model->material) {
lovrRelease(&model->material->ref);
}
model->material = material;
if (material) {
lovrRetain(&material->ref);
}
}
}
Mesh* lovrModelGetMesh(Model* model) {
return model->mesh;
}

View File

@ -16,6 +16,7 @@ typedef struct {
ModelData* modelData;
Mesh* mesh;
Material** materials;
Material* material;
Animator* animator;
float pose[MAX_BONES][16];
float (*nodeTransforms)[16];
@ -29,5 +30,7 @@ void lovrModelDraw(Model* model, mat4 transform);
Animator* lovrModelGetAnimator(Model* model);
void lovrModelSetAnimator(Model* model, Animator* animator);
int lovrModelGetAnimationCount(Model* model);
Material* lovrModelGetMaterial(Model* model);
void lovrModelSetMaterial(Model* model, Material* material);
Mesh* lovrModelGetMesh(Model* model);
const float* lovrModelGetAABB(Model* model);