Browse Source

love.event can now handle any number of event arguments.

--HG--
branch : minor
Alex Szpakowski 10 years ago
parent
commit
c106d9ff53

+ 27 - 26
src/modules/event/Event.cpp

@@ -28,56 +28,57 @@ namespace love
 namespace event
 {
 
-Message::Message(const std::string &name, Variant *a, Variant *b, Variant *c, Variant *d)
+Message::Message(const std::string &name, const std::vector<StrongRef<Variant>> &vargs)
 	: name(name)
-	, nargs(0)
+	, args(vargs)
 {
-	args[0] = a;
-	args[1] = b;
-	args[2] = c;
-	args[3] = d;
-	for (int i = 0; i < 4; i++)
-	{
-		if (!args[i])
-			break;
-		args[i]->retain();
-		nargs++;
-	}
 }
 
 Message::~Message()
 {
-	for (int i = 0; i < nargs; i++)
-		args[i]->release();
 }
 
 int Message::toLua(lua_State *L)
 {
 	luax_pushstring(L, name);
-	for (int i = 0; i < nargs; i++)
-		args[i]->toLua(L);
-	return nargs+1;
+
+	for (const StrongRef<Variant> &v : args)
+	{
+		if (v.get() != nullptr)
+			v->toLua(L);
+		else
+			lua_pushnil(L);
+	}
+
+	return (int) args.size() + 1;
 }
 
 Message *Message::fromLua(lua_State *L, int n)
 {
 	std::string name = luax_checkstring(L, n);
+	std::vector<StrongRef<Variant>> vargs;
+
+	int count = lua_gettop(L) - n;
 	n++;
-	Message *m = new Message(name);
-	for (int i = 0; i < 4; i++)
+
+	for (int i = 0; i < count; i++)
 	{
 		if (lua_isnoneornil(L, n+i))
 			break;
-		m->args[i] = Variant::fromLua(L, n+i);
-		if (!m->args[i])
+
+		vargs.push_back(Variant::fromLua(L, n+i));
+
+		if (!vargs.back().get())
 		{
-			delete m;
+			vargs.clear();
 			luaL_error(L, "Argument %d can't be stored safely\nExpected boolean, number, string or userdata.", n+i);
-			return NULL;
+			return nullptr;
 		}
-		m->nargs++;
+
+		vargs.back()->release(); // fromLua gave a +1 ref.
 	}
-	return m;
+
+	return new Message(name, vargs);
 }
 
 Event::Event()

+ 12 - 8
src/modules/event/Event.h

@@ -30,27 +30,31 @@
 #include "joystick/Joystick.h"
 #include "thread/threads.h"
 
-// STL
+// C++
 #include <queue>
+#include <vector>
 
 namespace love
 {
 namespace event
 {
+
 class Message : public Object
 {
-private:
-	std::string name;
-	Variant *args[4];
-	int nargs;
-
 public:
-	Message(const std::string &name, Variant *a = NULL, Variant *b = NULL, Variant *c = NULL, Variant *d = NULL);
+
+	Message(const std::string &name, const std::vector<StrongRef<Variant>> &vargs = {});
 	~Message();
 
 	int toLua(lua_State *L);
 	static Message *fromLua(lua_State *L, int n);
-};
+
+private:
+
+	std::string name;
+	std::vector<StrongRef<Variant>> args;
+
+}; // Message
 
 class Event : public Module
 {

+ 98 - 109
src/modules/event/sdl/Event.cpp

@@ -108,14 +108,16 @@ void Event::clear()
 
 Message *Event::convert(const SDL_Event &e) const
 {
-	Message *msg = NULL;
+	Message *msg = nullptr;
+
+	std::vector<StrongRef<Variant>> vargs;
+	vargs.reserve(4);
 
 	love::keyboard::Keyboard *kb = nullptr;
 	love::filesystem::Filesystem *filesystem = nullptr;
 
 	love::keyboard::Keyboard::Key key;
 	love::mouse::Mouse::Button button;
-	Variant *arg1, *arg2, *arg3, *arg4;
 	const char *txt;
 	std::map<SDL_Keycode, love::keyboard::Keyboard::Key>::const_iterator keyit;
 
@@ -137,11 +139,9 @@ Message *Event::convert(const SDL_Event &e) const
 
 		if (!love::keyboard::Keyboard::getConstant(key, txt))
 			txt = "unknown";
-		arg1 = new Variant(txt, strlen(txt));
-		arg2 = new Variant(e.key.repeat != 0);
-		msg = new Message("keypressed", arg1, arg2);
-		arg1->release();
-		arg2->release();
+		vargs.push_back(new Variant(txt, strlen(txt)));
+		vargs.push_back(new Variant(e.key.repeat != 0));
+		msg = new Message("keypressed", vargs);
 		break;
 	case SDL_KEYUP:
 		keyit = keys.find(e.key.keysym.sym);
@@ -152,25 +152,20 @@ Message *Event::convert(const SDL_Event &e) const
 
 		if (!love::keyboard::Keyboard::getConstant(key, txt))
 			txt = "unknown";
-		arg1 = new Variant(txt, strlen(txt));
-		msg = new Message("keyreleased", arg1);
-		arg1->release();
+		vargs.push_back(new Variant(txt, strlen(txt)));
+		msg = new Message("keyreleased", vargs);
 		break;
 	case SDL_TEXTINPUT:
 		txt = e.text.text;
-		arg1 = new Variant(txt, strlen(txt));
-		msg = new Message("textinput", arg1);
-		arg1->release();
+		vargs.push_back(new Variant(txt, strlen(txt)));
+		msg = new Message("textinput", vargs);
 		break;
 	case SDL_TEXTEDITING:
 		txt = e.edit.text;
-		arg1 = new Variant(txt, strlen(txt));
-		arg2 = new Variant((double) e.edit.start);
-		arg3 = new Variant((double) e.edit.length);
-		msg = new Message("textedit", arg1, arg2, arg3);
-		arg1->release();
-		arg2->release();
-		arg3->release();
+		vargs.push_back(new Variant(txt, strlen(txt)));
+		vargs.push_back(new Variant((double) e.edit.start));
+		vargs.push_back(new Variant((double) e.edit.length));
+		msg = new Message("textedit", vargs);
 		break;
 	case SDL_MOUSEMOTION:
 		{
@@ -180,15 +175,11 @@ Message *Event::convert(const SDL_Event &e) const
 			double yrel = (double) e.motion.yrel;
 			windowToPixelCoords(&x, &y);
 			windowToPixelCoords(&xrel, &yrel);
-			arg1 = new Variant(x);
-			arg2 = new Variant(y);
-			arg3 = new Variant(xrel);
-			arg4 = new Variant(yrel);
-			msg = new Message("mousemoved", arg1, arg2, arg3, arg4);
-			arg1->release();
-			arg2->release();
-			arg3->release();
-			arg4->release();
+			vargs.push_back(new Variant(x));
+			vargs.push_back(new Variant(y));
+			vargs.push_back(new Variant(xrel));
+			vargs.push_back(new Variant(yrel));
+			msg = new Message("mousemoved", vargs);
 		}
 		break;
 	case SDL_MOUSEBUTTONDOWN:
@@ -198,23 +189,18 @@ Message *Event::convert(const SDL_Event &e) const
 			double x = (double) e.button.x;
 			double y = (double) e.button.y;
 			windowToPixelCoords(&x, &y);
-			arg1 = new Variant(x);
-			arg2 = new Variant(y);
-			arg3 = new Variant(txt, strlen(txt));
+			vargs.push_back(new Variant(x));
+			vargs.push_back(new Variant(y));
+			vargs.push_back(new Variant(txt, strlen(txt)));
 			msg = new Message((e.type == SDL_MOUSEBUTTONDOWN) ?
 							  "mousepressed" : "mousereleased",
-							  arg1, arg2, arg3);
-			arg1->release();
-			arg2->release();
-			arg3->release();
+							  vargs);
 		}
 		break;
 	case SDL_MOUSEWHEEL:
-		arg1 = new Variant((double) e.wheel.x);
-		arg2 = new Variant((double) e.wheel.y);
-		msg = new Message("wheelmoved", arg1, arg2);
-		arg1->release();
-		arg2->release();
+		vargs.push_back(new Variant((double) e.wheel.x));
+		vargs.push_back(new Variant((double) e.wheel.y));
+		msg = new Message("wheelmoved", vargs);
 		break;
 	case SDL_JOYBUTTONDOWN:
 	case SDL_JOYBUTTONUP:
@@ -240,18 +226,16 @@ Message *Event::convert(const SDL_Event &e) const
 
 			if (filesystem->isRealDirectory(e.drop.file))
 			{
-				arg1 = new Variant(e.drop.file, strlen(e.drop.file));
-				msg = new Message("directorydropped", arg1);
-				arg1->release();
+				vargs.push_back(new Variant(e.drop.file, strlen(e.drop.file)));
+				msg = new Message("directorydropped", vargs);
 			}
 			else
 			{
 				Proxy proxy;
 				proxy.data = new love::filesystem::DroppedFile(e.drop.file);
 				proxy.flags = FILESYSTEM_DROPPED_FILE_T;
-				arg1 = new Variant(FILESYSTEM_DROPPED_FILE_ID, &proxy);
-				msg = new Message("filedropped", arg1);
-				arg1->release();
+				vargs.push_back(new Variant(FILESYSTEM_DROPPED_FILE_ID, &proxy));
+				msg = new Message("filedropped", vargs);
 				((Object *) proxy.data)->release();
 			}
 		}
@@ -264,6 +248,13 @@ Message *Event::convert(const SDL_Event &e) const
 		break;
 	}
 
+	// We gave +1 refs to the StrongRef list, so we should release them.
+	for (const StrongRef<Variant> &v : vargs)
+	{
+		if (v.get() != nullptr)
+			v->release();
+	}
+
 	return msg;
 }
 
@@ -271,14 +262,17 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 {
 	joystick::JoystickModule *joymodule = Module::getInstance<joystick::JoystickModule>(Module::M_JOYSTICK);
 	if (!joymodule)
-		return 0;
+		return nullptr;
+
+	Message *msg = nullptr;
+
+	std::vector<StrongRef<Variant>> vargs;
+	vargs.reserve(4);
 
-	Message *msg = 0;
 	Proxy proxy;
 	love::joystick::Joystick::Hat hat;
 	love::joystick::Joystick::GamepadButton padbutton;
 	love::joystick::Joystick::GamepadAxis padaxis;
-	Variant *arg1, *arg2, *arg3;
 	const char *txt;
 
 	switch (e.type)
@@ -290,13 +284,11 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 		if (!proxy.data)
 			break;
 
-		arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
-		arg2 = new Variant((double)(e.jbutton.button+1));
+		vargs.push_back(new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy));
+		vargs.push_back(new Variant((double)(e.jbutton.button+1)));
 		msg = new Message((e.type == SDL_JOYBUTTONDOWN) ?
 						  "joystickpressed" : "joystickreleased",
-						  arg1, arg2);
-		arg1->release();
-		arg2->release();
+						  vargs);
 		break;
 	case SDL_JOYAXISMOTION:
 		{
@@ -305,14 +297,11 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 			if (!proxy.data)
 				break;
 
-			arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
-			arg2 = new Variant((double)(e.jaxis.axis+1));
+			vargs.push_back(new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy));
+			vargs.push_back(new Variant((double)(e.jaxis.axis+1)));
 			float value = joystick::Joystick::clampval(e.jaxis.value / 32768.0f);
-			arg3 = new Variant((double) value);
-			msg = new Message("joystickaxis", arg1, arg2, arg3);
-			arg1->release();
-			arg2->release();
-			arg3->release();
+			vargs.push_back(new Variant((double) value));
+			msg = new Message("joystickaxis", vargs);
 		}
 		break;
 	case SDL_JOYHATMOTION:
@@ -324,13 +313,10 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 		if (!proxy.data)
 			break;
 
-		arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
-		arg2 = new Variant((double)(e.jhat.hat+1));
-		arg3 = new Variant(txt, strlen(txt));
-		msg = new Message("joystickhat", arg1, arg2, arg3);
-		arg1->release();
-		arg2->release();
-		arg3->release();
+		vargs.push_back(new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy));
+		vargs.push_back(new Variant((double)(e.jhat.hat+1)));
+		vargs.push_back(new Variant(txt, strlen(txt)));
+		msg = new Message("joystickhat", vargs);
 		break;
 	case SDL_CONTROLLERBUTTONDOWN:
 	case SDL_CONTROLLERBUTTONUP:
@@ -345,12 +331,10 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 		if (!proxy.data)
 			break;
 
-		arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
-		arg2 = new Variant(txt, strlen(txt));
+		vargs.push_back(new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy));
+		vargs.push_back(new Variant(txt, strlen(txt)));
 		msg = new Message(e.type == SDL_CONTROLLERBUTTONDOWN ?
-						  "gamepadpressed" : "gamepadreleased", arg1, arg2);
-		arg1->release();
-		arg2->release();
+						  "gamepadpressed" : "gamepadreleased", vargs);
 		break;
 	case SDL_CONTROLLERAXISMOTION:
 		if (joystick::sdl::Joystick::getConstant((SDL_GameControllerAxis) e.caxis.axis, padaxis))
@@ -363,15 +347,12 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 			if (!proxy.data)
 				break;
 
-			arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
+			vargs.push_back(new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy));
 
-			arg2 = new Variant(txt, strlen(txt));
+			vargs.push_back(new Variant(txt, strlen(txt)));
 			float value = joystick::Joystick::clampval(e.caxis.value / 32768.0f);
-			arg3 = new Variant((double) value);
-			msg = new Message("gamepadaxis", arg1, arg2, arg3);
-			arg1->release();
-			arg2->release();
-			arg3->release();
+			vargs.push_back(new Variant((double) value));
+			msg = new Message("gamepadaxis", vargs);
 		}
 		break;
 	case SDL_JOYDEVICEADDED:
@@ -380,9 +361,8 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 		proxy.flags = JOYSTICK_JOYSTICK_T;
 		if (proxy.data)
 		{
-			arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
-			msg = new Message("joystickadded", arg1);
-			arg1->release();
+			vargs.push_back(new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy));
+			msg = new Message("joystickadded", vargs);
 		}
 		break;
 	case SDL_JOYDEVICEREMOVED:
@@ -392,26 +372,35 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 		if (proxy.data)
 		{
 			joymodule->removeJoystick((joystick::Joystick *) proxy.data);
-			arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
-			msg = new Message("joystickremoved", arg1);
-			arg1->release();
+			vargs.push_back(new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy));
+			msg = new Message("joystickremoved", vargs);
 		}
 		break;
 	default:
 		break;
 	}
 
+	// We gave +1 refs to the StrongRef list, so we should release them.
+	for (const StrongRef<Variant> &v : vargs)
+	{
+		if (v.get() != nullptr)
+			v->release();
+	}
+
 	return msg;
 }
 
 Message *Event::convertWindowEvent(const SDL_Event &e) const
 {
-	Message *msg = 0;
-	Variant *arg1, *arg2, *arg3, *arg4;
-	window::Window *win = 0;
+	Message *msg = nullptr;
+
+	std::vector<StrongRef<Variant>> vargs;
+	vargs.reserve(4);
+
+	window::Window *win = nullptr;
 
 	if (e.type != SDL_WINDOWEVENT)
-		return 0;
+		return nullptr;
 
 	switch (e.window.event)
 	{
@@ -423,21 +412,18 @@ Message *Event::convertWindowEvent(const SDL_Event &e) const
 			SDL_DisableScreenSaver();
 		else
 			SDL_EnableScreenSaver();
-		arg1 = new Variant(e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED);
-		msg = new Message("focus", arg1);
-		arg1->release();
+		vargs.push_back(new Variant(e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED));
+		msg = new Message("focus", vargs);
 		break;
 	case SDL_WINDOWEVENT_ENTER:
 	case SDL_WINDOWEVENT_LEAVE:
-		arg1 = new Variant(e.window.event == SDL_WINDOWEVENT_ENTER);
-		msg = new Message("mousefocus", arg1);
-		arg1->release();
+		vargs.push_back(new Variant(e.window.event == SDL_WINDOWEVENT_ENTER));
+		msg = new Message("mousefocus", vargs);
 		break;
 	case SDL_WINDOWEVENT_SHOWN:
 	case SDL_WINDOWEVENT_HIDDEN:
-		arg1 = new Variant(e.window.event == SDL_WINDOWEVENT_SHOWN);
-		msg = new Message("visible", arg1);
-		arg1->release();
+		vargs.push_back(new Variant(e.window.event == SDL_WINDOWEVENT_SHOWN));
+		msg = new Message("visible", vargs);
 		break;
 	case SDL_WINDOWEVENT_RESIZED:
 		win = Module::getInstance<window::Window>(Module::M_WINDOW);
@@ -459,19 +445,22 @@ Message *Event::convertWindowEvent(const SDL_Event &e) const
 			if (gfx)
 				gfx->setViewportSize(px_w, px_h);
 
-			arg1 = new Variant((double) px_w);
-			arg2 = new Variant((double) px_h);
-			arg3 = new Variant((double) e.window.data1);
-			arg4 = new Variant((double) e.window.data2);
-			msg = new Message("resize", arg1, arg2, arg3, arg4);
-			arg1->release();
-			arg2->release();
-			arg3->release();
-			arg4->release();
+			vargs.push_back(new Variant((double) px_w));
+			vargs.push_back(new Variant((double) px_h));
+			vargs.push_back(new Variant((double) e.window.data1));
+			vargs.push_back(new Variant((double) e.window.data2));
+			msg = new Message("resize", vargs);
 		}
 		break;
 	}
 
+	// We gave +1 refs to the StrongRef list, so we should release them.
+	for (const StrongRef<Variant> &v : vargs)
+	{
+		if (v.get() != nullptr)
+			v->release();
+	}
+
 	return msg;
 }
 

+ 9 - 5
src/modules/thread/LuaThread.cpp

@@ -112,11 +112,15 @@ void LuaThread::onError()
 	p.flags = THREAD_THREAD_T;
 	p.data = this;
 
-	Variant *arg1 = new Variant(THREAD_THREAD_ID, &p);
-	Variant *arg2 = new Variant(error.c_str(), error.length());
-	event::Message *msg = new event::Message("threaderror", arg1, arg2);
-	arg1->release();
-	arg2->release();
+	std::vector<StrongRef<Variant>> vargs = {
+		new Variant(THREAD_THREAD_ID, &p),
+		new Variant(error.c_str(), error.length())
+	};
+
+	event::Message *msg = new event::Message("threaderror", vargs);
+
+	for (const StrongRef<Variant> &v : vargs)
+		v->release();
 
 	event->push(msg);
 	msg->release();

+ 3 - 3
src/scripts/boot.lua

@@ -505,13 +505,13 @@ function love.run()
 		-- Process events.
 		if love.event then
 			love.event.pump()
-			for e,a,b,c,d in love.event.poll() do
-				if e == "quit" then
+			for name, a,b,c,d,e in love.event.poll() do
+				if name == "quit" then
 					if not love.quit or not love.quit() then
 						return
 					end
 				end
-				love.handlers[e](a,b,c,d)
+				love.handlers[name](a,b,c,d,e)
 			end
 		end
 

+ 6 - 6
src/scripts/boot.lua.h

@@ -912,11 +912,11 @@ const unsigned char boot_lua[] =
 	0x65, 0x6e, 0x0a,
 	0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x75, 0x6d, 0x70, 
 	0x28, 0x29, 0x0a,
-	0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x2c, 0x61, 0x2c, 0x62, 0x2c, 0x63, 0x2c, 0x64, 0x20, 0x69, 
-	0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x6f, 0x6c, 0x6c, 0x28, 
-	0x29, 0x20, 0x64, 0x6f, 0x0a,
-	0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x71, 0x75, 0x69, 0x74, 0x22, 
-	0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x61, 0x2c, 0x62, 0x2c, 0x63, 
+	0x2c, 0x64, 0x2c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 
+	0x2e, 0x70, 0x6f, 0x6c, 0x6c, 0x28, 0x29, 0x20, 0x64, 0x6f, 0x0a,
+	0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x71, 0x75, 
+	0x69, 0x74, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
 	0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x71, 
 	0x75, 0x69, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x71, 0x75, 
 	0x69, 0x74, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
@@ -924,7 +924,7 @@ const unsigned char boot_lua[] =
 	0x09, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x5b, 
-	0x65, 0x5d, 0x28, 0x61, 0x2c, 0x62, 0x2c, 0x63, 0x2c, 0x64, 0x29, 0x0a,
+	0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x28, 0x61, 0x2c, 0x62, 0x2c, 0x63, 0x2c, 0x64, 0x2c, 0x65, 0x29, 0x0a,
 	0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x09, 0x2d, 0x2d, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x64, 0x74, 0x2c, 0x20, 0x61, 0x73,