boot.lua 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. --[[
  2. Copyright (c) 2006-2012 LOVE Development Team
  3. This software is provided 'as-is', without any express or implied
  4. warranty. In no event will the authors be held liable for any damages
  5. arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it
  8. freely, subject to the following restrictions:
  9. 1. The origin of this software must not be misrepresented; you must not
  10. claim that you wrote the original software. If you use this software
  11. in a product, an acknowledgment in the product documentation would be
  12. appreciated but is not required.
  13. 2. Altered source versions must be plainly marked as such, and must not be
  14. misrepresented as being the original software.
  15. 3. This notice may not be removed or altered from any source distribution.
  16. --]]
  17. -- Make sure love table exists.
  18. if not love then love = {} end
  19. -- Used for setup:
  20. love.path = {}
  21. love.arg = {}
  22. -- Unparsed arguments:
  23. argv = {}
  24. -- Replace any \ with /.
  25. function love.path.normalslashes(p)
  26. return string.gsub(p, "\\", "/")
  27. end
  28. -- Makes sure there is a slash at the end
  29. -- of a path.
  30. function love.path.endslash(p)
  31. if string.sub(p, string.len(p)-1) ~= "/" then
  32. return p .. "/"
  33. else
  34. return p
  35. end
  36. end
  37. -- Checks whether a path is absolute or not.
  38. function love.path.abs(p)
  39. local tmp = love.path.normalslashes(p)
  40. -- Path is absolute if it starts with a "/".
  41. if string.find(tmp, "/") == 1 then
  42. return true
  43. end
  44. -- Path is absolute if it starts with a
  45. -- letter followed by a colon.
  46. if string.find(tmp, "%a:") == 1 then
  47. return true
  48. end
  49. -- Relative.
  50. return false
  51. end
  52. -- Converts any path into a full path.
  53. function love.path.getfull(p)
  54. if love.path.abs(p) then
  55. return love.path.normalslashes(p)
  56. end
  57. local cwd = love.filesystem.getWorkingDirectory()
  58. cwd = love.path.normalslashes(cwd)
  59. cwd = love.path.endslash(cwd)
  60. -- Construct a full path.
  61. local full = cwd .. love.path.normalslashes(p)
  62. -- Remove trailing /., if applicable
  63. return full:match("(.-)/%.$") or full
  64. end
  65. -- Returns the leaf of a full path.
  66. function love.path.leaf(p)
  67. local a = 1
  68. local last = p
  69. while a do
  70. a = string.find(p, "/", a+1)
  71. if a then
  72. last = string.sub(p, a+1)
  73. end
  74. end
  75. return last
  76. end
  77. -- Finds the key in the table with the lowest integral index. The lowest
  78. -- will typically the executable, for instance "lua5.1.exe".
  79. function love.arg.getLow(a)
  80. local m = math.huge
  81. for k,v in pairs(a) do
  82. if k < m then
  83. m = k
  84. end
  85. end
  86. return a[m]
  87. end
  88. love.arg.options = {
  89. console = { a = 0 },
  90. fused = {a = 0 },
  91. game = { a = 1 }
  92. }
  93. function love.arg.parse_option(m, i)
  94. m.set = true
  95. if m.a > 0 then
  96. m.arg = {}
  97. for j=i,i+m.a-1 do
  98. table.insert(m.arg, arg[j])
  99. i = j
  100. end
  101. end
  102. return i
  103. end
  104. function love.arg.parse_options()
  105. local game
  106. local argc = #arg
  107. for i=1,argc do
  108. -- Look for options.
  109. local s, e, m = string.find(arg[i], "%-%-(.+)")
  110. if m and love.arg.options[m] then
  111. i = love.arg.parse_option(love.arg.options[m], i+1)
  112. elseif not game then
  113. game = i
  114. end
  115. end
  116. if not love.arg.options.game.set then
  117. love.arg.parse_option(love.arg.options.game, game or 0)
  118. end
  119. end
  120. function love.createhandlers()
  121. -- Standard callback handlers.
  122. love.handlers = setmetatable({
  123. keypressed = function (b, u)
  124. if love.keypressed then love.keypressed(b, u) end
  125. end,
  126. keyreleased = function (b)
  127. if love.keyreleased then love.keyreleased(b) end
  128. end,
  129. mousepressed = function (x,y,b)
  130. if love.mousepressed then love.mousepressed(x,y,b) end
  131. end,
  132. mousereleased = function (x,y,b)
  133. if love.mousereleased then love.mousereleased(x,y,b) end
  134. end,
  135. joystickpressed = function (j,b)
  136. if love.joystickpressed then love.joystickpressed(j,b) end
  137. end,
  138. joystickreleased = function (j,b)
  139. if love.joystickreleased then love.joystickreleased(j,b) end
  140. end,
  141. focus = function (f)
  142. if love.focus then love.focus(f) end
  143. end,
  144. quit = function ()
  145. return
  146. end,
  147. }, {
  148. __index = function(self, name)
  149. error("Unknown event: " .. name)
  150. end,
  151. })
  152. end
  153. local is_fused_game = false
  154. local no_game_code = false
  155. -- This can't be overriden.
  156. function love.boot()
  157. -- This is absolutely needed.
  158. require("love")
  159. require("love.filesystem")
  160. love.arg.parse_options()
  161. local o = love.arg.options
  162. local arg0 = love.arg.getLow(arg)
  163. love.filesystem.init(arg0)
  164. -- Is this one of those fancy "fused" games?
  165. local can_has_game = pcall(love.filesystem.setSource, arg0)
  166. is_fused_game = can_has_game
  167. if love.arg.options.fused.set then
  168. is_fused_game = true
  169. end
  170. if not can_has_game and o.game.set and o.game.arg[1] then
  171. local full_source = love.path.getfull(o.game.arg[1])
  172. local leaf = love.path.leaf(full_source)
  173. love.filesystem.setIdentity(leaf)
  174. can_has_game = pcall(love.filesystem.setSource, full_source)
  175. end
  176. if can_has_game and not (love.filesystem.exists("main.lua") or love.filesystem.exists("conf.lua")) then
  177. no_game_code = true
  178. end
  179. if not can_has_game then
  180. love.nogame()
  181. end
  182. end
  183. function love.init()
  184. -- Create default configuration settings.
  185. -- NOTE: Adding a new module to the modules list
  186. -- will NOT make it load, see below.
  187. local c = {
  188. title = "Untitled",
  189. author = "Unnamed",
  190. version = love._version,
  191. screen = {
  192. width = 800,
  193. height = 600,
  194. fullscreen = false,
  195. vsync = true,
  196. fsaa = 0,
  197. },
  198. modules = {
  199. event = true,
  200. keyboard = true,
  201. mouse = true,
  202. timer = true,
  203. joystick = true,
  204. image = true,
  205. graphics = true,
  206. audio = true,
  207. physics = true,
  208. sound = true,
  209. font = true,
  210. thread = true,
  211. },
  212. console = false, -- Only relevant for windows.
  213. identity = false,
  214. release = false,
  215. }
  216. -- If config file exists, load it and allow it to update config table.
  217. if not love.conf and love.filesystem and love.filesystem.exists("conf.lua") then
  218. require("conf")
  219. end
  220. -- Yes, conf.lua might not exist, but there are other ways of making
  221. -- love.conf appear, so we should check for it anyway.
  222. if love.conf then
  223. local ok, err = pcall(love.conf, c)
  224. if not ok then
  225. print(err)
  226. -- continue
  227. end
  228. end
  229. if c.release then
  230. love._release = {
  231. title = c.title ~= "Untitled" and c.title or nil,
  232. author = c.author ~= "Unnamed" and c.author or nil,
  233. url = c.url
  234. }
  235. end
  236. if love.arg.options.console.set then
  237. c.console = true
  238. end
  239. -- Gets desired modules.
  240. for k,v in ipairs{
  241. "thread",
  242. "timer",
  243. "event",
  244. "keyboard",
  245. "joystick",
  246. "mouse",
  247. "sound",
  248. "audio",
  249. "image",
  250. "font",
  251. "graphics",
  252. "physics",
  253. } do
  254. if c.modules[v] then
  255. require("love." .. v)
  256. end
  257. end
  258. if love.event then
  259. love.createhandlers()
  260. end
  261. -- Setup screen here.
  262. if c.screen and c.modules.graphics then
  263. if love.graphics.checkMode(c.screen.width, c.screen.height, c.screen.fullscreen) or (c.screen.width == 0 and c.screen.height == 0) then
  264. assert(love.graphics.setMode(c.screen.width, c.screen.height, c.screen.fullscreen, c.screen.vsync, c.screen.fsaa), "Could not set screen mode")
  265. else
  266. error("Could not set screen mode")
  267. end
  268. love.graphics.setCaption(c.title)
  269. end
  270. -- Our first timestep, because screen creation can take some time
  271. if love.timer then
  272. love.timer.step()
  273. end
  274. if love.filesystem then
  275. love.filesystem.setRelease(c.release and is_fused_game)
  276. if c.identity then love.filesystem.setIdentity(c.identity) end
  277. if love.filesystem.exists("main.lua") then require("main") end
  278. end
  279. if no_game_code then
  280. error("No code to run\nYour game might be packaged incorrectly\nMake sure main.lua is at the top level of the zip")
  281. end
  282. -- Console hack
  283. if c.console and love._openConsole then
  284. love._openConsole()
  285. end
  286. -- Check the version
  287. local compat = false
  288. c.version = tostring(c.version)
  289. for i, v in ipairs(love._version_compat) do
  290. if c.version == v then
  291. compat = true
  292. break
  293. end
  294. end
  295. if not compat then
  296. local major, minor, revision = c.version:match("^(%d+)%.(%d+)%.(%d+)$")
  297. if (not major or not minor or not revision) or (major ~= love._version_major and minor ~= love._version_minor) then
  298. local msg = "This game was made for a version that is probably incompatible.\n"..
  299. "The game might still work, but it is not guaranteed.\n" ..
  300. "Furthermore, this means one should not judge this game or the engine if not."
  301. print(msg)
  302. if love.graphics and love.timer and love.event then
  303. love.event.pump()
  304. love.graphics.setBackgroundColor(89, 157, 220)
  305. love.graphics.clear()
  306. love.graphics.print(msg, 70, 70)
  307. love.graphics.present()
  308. love.graphics.setBackgroundColor(0, 0, 0)
  309. love.timer.sleep(3)
  310. end
  311. end
  312. end
  313. end
  314. function love.run()
  315. math.randomseed(os.time())
  316. math.random() math.random()
  317. if love.load then love.load(arg) end
  318. local dt = 0
  319. -- Main loop time.
  320. while true do
  321. -- Process events.
  322. if love.event then
  323. love.event.pump()
  324. for e,a,b,c,d in love.event.poll() do
  325. if e == "quit" then
  326. if not love.quit or not love.quit() then
  327. if love.audio then
  328. love.audio.stop()
  329. end
  330. return
  331. end
  332. end
  333. love.handlers[e](a,b,c,d)
  334. end
  335. end
  336. -- Update dt, as we'll be passing it to update
  337. if love.timer then
  338. love.timer.step()
  339. dt = love.timer.getDelta()
  340. end
  341. -- Call update and draw
  342. if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
  343. if love.graphics then
  344. love.graphics.clear()
  345. if love.draw then love.draw() end
  346. end
  347. if love.timer then love.timer.sleep(0.001) end
  348. if love.graphics then love.graphics.present() end
  349. end
  350. end
  351. -----------------------------------------------------------
  352. -- Default screen.
  353. -----------------------------------------------------------
  354. function love.nogame()
  355. local pig_png =
  356. "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ\
  357. bWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdp\
  358. bj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6\
  359. eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEz\
  360. NDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJo\
  361. dHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlw\
  362. dGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAv\
  363. IiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RS\
  364. ZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpD\
  365. cmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlE\
  366. PSJ4bXAuaWlkOjdCQTYxREYxOUQ5RDExRTBBNjY4RTc1NEVEQTU1MERDIiB4bXBNTTpEb2N1bWVu\
  367. dElEPSJ4bXAuZGlkOjdCQTYxREYyOUQ5RDExRTBBNjY4RTc1NEVEQTU1MERDIj4gPHhtcE1NOkRl\
  368. cml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6N0JBNjFERUY5RDlEMTFFMEE2NjhF\
  369. NzU0RURBNTUwREMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6N0JBNjFERjA5RDlEMTFFMEE2\
  370. NjhFNzU0RURBNTUwREMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1l\
  371. dGE+IDw/eHBhY2tldCBlbmQ9InIiPz6gRGuzAAAYXklEQVR42uydX2hcV37Hz4xkeTdxNrITkpBk\
  372. 0/EmgWxLbKlhyZZCPYJtSw3FUpe+FTzzsG9LLdFCH2W9FzwufeuDRtDX4tGLS0tBo0IpS1s8Tmk3\
  373. S9x4kniXeMnKk7/eWLLU87vzu9LV/L/3nnPv79z7/cBlFEcjjc45v+/5/s7fwsHBgQIA5JMiigAA\
  374. CAAAAAIAAIAAAAAgAAAACAAAAAIAAIAAAAAgAAAACAAAAAIAAIAAAAAgAAAACAAAAAIAAIAAAAAg\
  375. AAAACAAAAAIAAIAAAAAgAAAACAAAAAIAAIAAAAAgAAAACAAAAAIAADDBdNg3FAoFax+m89f/XNYv\
  376. 9JzXz6x+5viVaPJrSz8f0OvsX/5BE1UIQD+T3vlZCHs5qGkB0EFPAb6sn8v6KYV9OwvDpn4aWhA6\
  377. qHoAHBEAHfwU+KuBXj4uDf1saCFooAkACIBQAeBe/wbbfRu09XNdP3W4AgABECQAHPxbnN/bpsNC\
  378. UIMQAAhAP4nOAiQc/IpTC0ox7urffRXNAoAUHYAOwi2Ltn/S1GAFYwQgLXimi2jZdKXiUgDugVeF\
  379. 1ENTP1VdAW00SWAgqMnRltjZPh1wuMFp7HG0OGX1p7mbun22MiEArHpbAutuTRcyUgMQJoWdU0dr\
  380. VUqW09nI09zSBOBWgnl/WFrsBlpo4qCn3ZY42C9w+02zDVPwN7jTajsjALoQK/pl3YH6hhtAwFMP\
  381. v8gBX1bhF6YlRY3ba8cFAbgruCAHuYEll8cGdi7WZgf0VOWYPU/QHXXO3FxuZSjo5zjoLwl2qYNo\
  382. s3NtihUAh3r/3gZflThToIPbH1TyX/09E7MpNd6gONDrpyowmKWFoiM46C9z4JeU21BbrUsVgLsO\
  383. FzAtHlpJKdB9+1liO1pyuBybLAi3WRxIGNoIersikLoACB75D5sSLNicr+Vgn+PePO2BpqSFoeUL\
  384. g420ggfxrmQ06HuZDw5kSxAAsv6VLKSJLAItA8E+q45Glcs5CvYw6cQ2iYMWhGbEoPcH8q7krHzb\
  385. uo2elSQAD5S5XX4SGufKoFwLAW/dJWyyILQmDH6bm8ykcziTlaoA6IpY5IrIVGPUhbswQdD7C0Uu\
  386. 5bgh2hLhBjuExqgBxoD1r2SoE5qojHQbPS1BALJi/4m6GrP4goM+qwNMUmkE3EF7RFuscN3kRYy9\
  387. AcG0BcB1++9vI64PC3wEvbhUYWOUM+BZgCsZ6piGCqNus0upCQAX9C3HA3/g+QE66EvqaIAJQS/X\
  388. GWxoIWiMSA8qXIeZTA902y2kKQB0zNe1jAX+YqC3B+7UKaVv1welCDHPopTOwtN/8fvNtATApfx/\
  389. aOBzb1/JaAPJZYqghaA+YpxgNUP1vKIFoJaWAEje+TdJ4Jc56CuIm8zR5rGC2qCxggwJQU0LwEpa\
  390. AnDgcOBT5ZcRJ7lID7yttUPSgwqnsa6OETS1ACwkLgDCl/8O3EKpAz9r9g+Eoz5ICAJjBC4OFqYm\
  391. ABRM6xIruHc6D4EPQgrBahYFYNrwL5YUTE3VXb7bGmD1ryksywXHoQ6hotvHMSFgx3hVC0GdRaCS\
  392. pT/atANI+9Rfgiqu76AE5PggJGtqwGAhp7nSO5CJHUCWbgf2N+ycDQY/TefpZ53HJhD8YFK8+yQ4\
  393. VTyE2pZ+5qmT4TbnNKYFIK0AI3tGgV/r6fWvqu6qxAraM4gA5f/ruh3dYgcZFAKvzanu4LKzTDte\
  394. QaPs/rrCAB8wA9n9LR4fWPHTAh4fWNFpwaawtKCduAPgNdZJUhtg92f1c43tPoIfmKbCacHikLRg\
  395. Tcjn/CCNFCCpgPNP6Fnp6fWpUugMwmW0U2A5Lbih29sNPvAlKASUcs6H6YEz4wASgqb05of0+jdU\
  396. vg5/AOmyOMQNtFgEGhAAs9S552/35Pq30OsDSW6AxgZoT35aKcGwuwJsC0DZ4t9E03vV4DJeHuFH\
  397. rg+kuIFbfEhMb0qQ9HRhqPRDugPw8/1aj+WnwF9FuwOCKLEILPeIgOdcExSBVlYEwD+TP5jvk8Le\
  398. VVjQA+RyjRae9aQELRaBdgK/fzsLAuAHfysQ/BXO9zHQB6RDbXWLD5UJisB82B46Ak3XBYAO4pzv\
  399. yfdpUc862hVwiDlOCcoBEeiwE7AlAp2wF9gUBQZ/tSffv6GwlBe4ySw7gUpCItAM+wZJArDWG/yq\
  400. O8qPgziB66zzrJVtEdh2VQCq/pVGHPxzHPzYsw+ywiqnsjZFoOGiABy72hjBDzJMxaIItEbdXiVV\
  401. AIYFP0b6AUQgHBtR3lRE8AOQCRFouCQAdQQ/gAgYE4FI9j8tAeid6kPwA4jAkQjQJqKwy4Y3on6A\
  402. pAWgOWCqD9t4AUTgSATaKvzegYYEARhnQVqsbsHgx24+ALoisBwQgWOxMi74o9r/JAWA1KzacysP\
  403. 9fyY6gOgy7WeFYNN1d1KbM3+J5kCVHs29pDlKaPOAegTgbmACNTV6FOH2/p7GtIFoBb8kKxyFdQ1\
  404. AH34eweCW4np7Mumjd4/iRSgFTy8k9UNu/oAGCMCPf+2NCS+amIEYMBARCeYwwRG/AEAo5njg279\
  405. 2PKnB4PUe2+6lpYCrPXsTcZFHQBMznLwxGGOpeBR+EYOHDUtAO2A9Q+e40dTHNjWC0A4eo8Wq/F4\
  406. QD3O1F+QaQsCUAoqFR+LhAM8AYg2HkBpc/Cm36rJX2DaAXRYnZqBf8NKPwCiU+5ZJNQ21fvbEIDb\
  407. wdyEPzgW+wAQj9XgAaMmKRwcHIR7Q6Ew0ffxB8YpvgCYoXHm5vKky4PVpHFtcxbgGoIfAGMsBk8Y\
  408. lpoC+L0/fVCM+gNglnUnBEBhtR8ANigFTxcWKQC81r+EugLACleCawMkOgDM+QNgDwr+ZZECgN4f\
  409. ALdcgGkHgN4fAIdcgDEBQO8PgHsuwKQDQO8PQLIuoCJCAHjeH70/AAm7ACkO4ArqAoDEKQXPDEhF\
  410. AHjNP1b9AZAOl9N2AAh+ANJjMc5goAkBuIw6ACBVKqkIANt/7PcHwNE0IK4DgP0HIH3moh4YElcA\
  411. YP8BkEE5UQHggQfYfwBkcClpBwD7D0BeHYDmAsocADHMRjkyLI4AlFHmALjtAiIJAOf/JZQ3AKI4\
  412. n5QDwOAfAPKYS0oAYP8BkEcp7LLgqAJwHmUNgPsuIKoA4MIPAHIsAEgBAJCJ3RTA5JnkAADjXLAq\
  413. AAozAABkhiKKAACMAYShhDIGIKdjABAAAJACAAAgAAAACAAAQAxhtgVDAACAAwAAZIgWBACAnHLm\
  414. 5nIHAgAAsCIAHRQbAPkVgBaKDYD8CgAAQC5N2wLQRhkDkFMHcObmMgQAALmEStGnI/4SEoESytod\
  415. CqefUIWZqeP/9uRJVTh1cuh79u9/1v9vD75S6tFjFKhcPoUA5M3GPf+UUiemVfHME/p1ygt279/p\
  416. tSfowzD15osj//+BFoMDEoPdPf31Q/31XvffvnikDr78GhXjwBhAVAHYVjgXMJVA93pt6s31EzfA\
  417. jbgK/z9ePj1YILQQkDiQm4B7SIR2EgKAcQDbwcWB7gU9vzqZdpBIaXHw3URXEL7SgvC599DXwBxh\
  418. x+iiCgDWAtjo4XWgUKD7QZ9ZYdNP0XcM2hHs//KzriB81EHqkKD9jywAWmVaOxdrtCLQ6gnBD/cf\
  419. qZ98eUc//6fuPdo5/hmmT6lz33xFvf3kq+rlmTNuVpe271MU9N+ePQqIvKHLwBM++vvfesUTABKC\
  420. x+9/4qQ7oDb7zsMPvTb73q8/7muzr598Qb196lXv1QLbiQhAQG0WbRXkP356W219/r9egQ5iZ+8L\
  421. 1dT/n563n3xN/fD099Q3izMI+gw4hKk3nveeQzF4974TzoAC/+9/9W8j2+xP9u54ndrr33hB/cns\
  422. 90x3Xq0kBWDbhgBQ4f3NL/+pr8cfBRUoFf6fP/eHYt0AWXqvYVPQpzhw56wYaDdAQkDOQCIU+NQO\
  423. J4XcAbVz6rioA0srBSgm+csmIWzw9woHqawkpr7zrDrxgzfUzMXf8r5G8EcX0OnfOatO/ulvq+lz\
  424. L3ni4GrwB9ssvZc6LxO9f5htwLEFgMYBlOHZgH948B+Rgj9YoH/3yZaYwJ9ZPOc1WhdH8EWnUG++\
  425. eFi2aQtBN9+/E1tAhqUNIdiM8qa4m4GMuQA/p48LCUjcCjEV+JJ6qSwSLOu0nBV1WibSXgM/p5GG\
  426. AGyaKsitz39qrFKaBn9WGItKVh+Bn44QnLx03ksNkoQ6GlMpJ/2sGC6gzY48WQHQv5RUx8gBIYby\
  427. oEMXkNhYgO55pt96xcvxYfVlpAZJ1cN7v75vPJ1Isvc34QCIuqkUwCT3dnesNwBqaN7g3hvPIwCF\
  428. QO7Lc2JalK0LwNcfG/15O3tfRn3rRpoCsCGtIImfP3pgtfLJblJDg90XmhZoUSZxtlk/xjutaAPg\
  429. raj234gA8C/Pz9JgbTVPXHht7E45IMANnH7CqdTs4UGkMYDrsVysoc8e60O8fML84p0z009aCf4Z\
  430. 3etjBZ9jgq3rzFuDYbyNnTL68yIsD+7Eyf9NCkCswUBawmt6Ge9LpkWFgz+rm3SyDs3OmBYB0x1X\
  431. hE6rEWXxj3EB4A8RywXQxh6Tymx0STCCHyIwqMf+htnB3wgOYC3u7zR5KnA9zptph5Qpvm9ubbXH\
  432. CZrbR/BnQwTeesVYXdIaflPOlTYHhUwp6ibO5zQmAPxhIosAqZ8JF0CFWH7qu+YazLmXkPNnbUzg\
  433. wmtGVg5S8C889ZtGPhbtDAzJhonfa/pegFiW5M+e+d3YimriZ/h4O/gw2p85aGpw+k0zqwb/6Onz\
  434. Xu8dB9oRGDJlpdy/KU4A2AXU4igqbemNGsAU/CYPWkhiMQlIB1onYGp68EfPLkQec6I0ohzeRayY\
  435. KgcbNwORC4g8MkkFufbiD0OpKtn+v3rhj03uqz48mgtkWAQMuQC/4woTyPQe6rDoCUnd5N0chYOD\
  436. g3BvKBTGfs/OxdpV/bIa98PRCsHmZz8dukaaxILy/bcND/oRlCci988+jxrvGD1tiFYH3vz0ttdm\
  437. B23uoc7q+16v/90oTpc61vlJBGDSuLYiACwCd5XBuwN6lwvTHKy1I8BmpryDJ0D2oVOG9v7rQys/\
  438. m5b2Blf3PTN1Ku7ioTUd/Fcn+cZJ43raYtlW9WPsdA5LhygOtobo+XODzTTP8PF07UmDP+0xgK7V\
  439. 6Y5SNlxsFJjzzw8O1XXVigAm8KE7aBQgry7AEDVT036JCgAvEa6iiQEQ3forA0t+03IA/qlBDdRj\
  440. 91os72jr//6F99BtOGAy6Dhwv9y8o8Hzc8dgNe6Gn1FMJ/VH6GdO5fhGYWq4e+/8fKD9PPF7r+O4\
  441. 8GGi+eArtbt9p2+qbm/mQ6/cMr5Ww5r1T8wBBFKBJWeKfXcvkeAnyAU8+pd3EelDHBOVzcB5eu0A\
  442. dun/Gbg+jK4zFwid9LNi+5cUk/pr+OSgFSca3oOHRhvxsOAP9nJSb7xJk73//Gis1Y89h69/vsBr\
  443. xxLrMItJ/lVaBGifQF28Xf/I3HmCdLfdRN8HAegvk3vj68G7YjxGANPNxAJZMrncV4wAMOQCRJ8h\
  444. SD2ysV5h9zEiOUpghhggjWPhJxXoJOPDdt6fqgDweMCCEr4+YP/9X5n5QScwuBepYYZYi1E4FXFJ\
  445. uLb/j+89kPRn19klq8wKgCsisPfux0ammuga8Im+D8uPjzMzNdEIPy3ainr09+Of3Zc0ndjUcZH4\
  446. mpliWn8tDwrKXSREvcPP4t/84l9xPa4R43KRfrzzGMZMj0Y9s8EbnH33Yyl/KsVCKrNkxTT/al4k\
  447. JFYEaPTexDQTNdJhAe6dXf+DNxDtQ8pm6BoJupItxs3Lk8wwJBj8CzYX+4wsY1vbgcOwc7FW0S/r\
  448. UhuhF6AGFuqQmOzf66j9+595zqCgG6+N8+ozB7mx9z85HBgs+uUWsU5sbgEOSYeD3/igeOrnAWRJ\
  449. BCg/9w6SBM5DIrIrY+GVteAPIwBFKRWjC6IuNR2g+ei9f7+L6HEcb1nxv76X+eB3ZgzAJREgCwoR\
  450. cDv4vSXX6ef9YoJfnABABIAt2y8k+Cnoz0oJfpECEBCBJSVwnQCJwKOb/5On7ahOQwN+u3KCP7XR\
  451. fqcEgEWApghFLhYiO/n15m3s55cM7RbcviNltL8uMfgJMbMAw9i5WCvplxuqe56AOGh+37tlBvv5\
  452. RVl+StWE7PKrJbGtt6+Tcm0acIwI0HpamiJclNjgvKumYixKAeZ6ferxBW2trnI6qyAAZoTgqjJw\
  453. 4Yi1fEoLAAlB1LXpIEauT4euGNq/YYDUR/ozKQAsAovsBmalNkZapTZ17kUIQRKBT2cFvvMLSYd6\
  454. NFV3P3+q+X5mBcCFcQEIgX2rT9t4hQU+sWbj8g4IwHAhuKZflqW3V2/tOt1Giy2/8Rq1DnY6p0GQ\
  455. 1Q9a/qUkD/KAAByJQJlTgpL0BuxtDX71WVX8zjNwBSFtPp3csy/r8A4fb0ertCm+3AgAiwCNB6y6\
  456. 4AYOy5HOANApAh0YAjHoh4Kdgt47sUfmoqsOB77IOy9yJQAuuoE+Mfj2aZ0izOb3WjLO6w/ufy45\
  457. 6EX3+rkXAFfdwDFmprzbiemsABo7yKw70AFOJ/LSoh3vZF8DB68kQFt1D+0Uf9NVbgUgIAQ0Q0CD\
  458. hGWnA4XOxnvuW6p45glVeO6p7mGZDq469I/vph5+n05ddiPgg9D9fDXJvT4EYLAQVFgIZlVWIFGg\
  459. wzD5QEzv9dRM+m6BenUK7N0973KV/Z3u8eoOBnuQJtv99jEr8LdNak/l0o/LGANwQARmOSW4kikh\
  460. GCEORPH5bx3V23P9y5THLV327kfoycW9YOa7Dg6++Lob4HS7jttBPszuVwdN7engr3CaWdLPvBaB\
  461. FgTADSEoccVVFADDA39t0Br+nsA/dAhaABYgABAC4DaU218flOfrwC9zeykPee+CFoEmBABCAPIV\
  462. +GJdAAQAQgAmsPr6acQI/CCixgIgAP35Gw0CtkZZNRYCEoHsDxbmFwrS60Ny/CiB71PXbasKAZAr\
  463. AA84qEkANnRl1UcIAX3fouof8AHuQvW9MWRUP07gB1OJs7pddSAAMgXgYJgFHFVpvLz4MtIDZ23+\
  464. hureutse0CZ8t2dqW3l1VMcCAZAlAEHlpkq7riuvPYErMNlgQPK9vb8m5LIFd0edyRIEwC0BOFaB\
  465. LATNUd/EYwVXWBCQIsiA6m5TDRjU4/qf4zqz6eQ6uu2chgDIC36y8VshrePY9IDFYI57E4iBvKCf\
  466. VUeDuknVjYjZAAhAv/rfiqLoAVcwtlJZDPwxA6QJFnpY1R3EHRr0XN+LAVFOGhHjABCAaCnAKLzp\
  467. o0lcQc+YwQUWBbiD6OXuBf2oI7dY5P3B2jSncNd0+7gKAcieAAy0npNO+wTcwQV2BxCE0QG/Ta+j\
  468. tt8Ggl5S+gUByIEABPEbayNM7scDiSQI51kQyjkM9jYH/G0O9uYE9VjigJeaZkEAhArA3QR6CT9H\
  469. 9Rp02A0i7BJ8d3CBX7PiFJoc8B/w162wh2voOtxyQCidEoDpnPU2toPJz/u9VYS6wQYdQotFYWij\
  470. 55tkWgOEocw/m8ThaX6dFdYDdgKffTvw3+1Bi3Aisp1Tp2SNPDkAKXcItAMuoWViGykLhE/w698Y\
  471. IXqDBKQ5JvgGBbvJAJfi5OLg1CxAnhzAB0I+BzXeSqBB+4G3qRtOLcoP7MmdmxmvR9pwsyX487Vc\
  472. KsxijgRAcmD4Fh+MU8+uY6oJ/XhticeDQQC6DafF1hUC5X5drgjtaTdcK8tiztpOQ3CjhgCEY0mY\
  473. oHcEOxMIALOJ3j8zLqCtXxYEicCalLMAIADDG01DaBqwiZCOnNatSHCWUQdwIQDJcx2pSaZEoK66\
  474. MwNp0Ur590MAQlIT5gJaow4iAROLwHwK9Uqp24KL1j+3AsCVJckFXEcIG0sHFlRyswM1Ogrc5eDP\
  475. qwPwXYCEXrcD+29FBGzm4y3u9VeyUGa5vRcgwilBNhCxcSSLGDrp99iP5Pqqu/D3YzfgZI3kKjeS\
  476. tHr/s65bSEeEwD+/MQrk0Dak3gIMAYjfQNZVOkd+V13pTTJSzyV2A5dUdz/GsJ2UTbb53oEkrgo0\
  477. BEC2CIg5Phpkk0njuoii8gaPaB43qd6YcskqSh1IAAJwXASqyu5cMv3sJeT9AAIgUwTIBdCCEhsD\
  478. PtTzL7i2XRRkG4wBDB8XKCtz00gkKFX0/EDaGAAEYLwQlFT0a8Cot19zbQoJQAAgAIPFwD+++zyL\
  479. QXlAju9PITVg90HmBAAAkB0wCAgABAAAAAEAAEAAAAAQAAAABAAAAAEAAEAAAAAQAAAABAAAAAEA\
  480. AEAAAAAQAAAABAAAAAEAAEAAAAAQAAAABAAAAAEAAEAAAAAQAAAABAAAAAEAAEAAAAD2+H8BBgCz\
  481. 4xkvbY9d6gAAAABJRU5ErkJggg=="
  482. local heart_png =
  483. "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ\
  484. bWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdp\
  485. bj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6\
  486. eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEz\
  487. NDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJo\
  488. dHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlw\
  489. dGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAv\
  490. IiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RS\
  491. ZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpD\
  492. cmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlE\
  493. PSJ4bXAuaWlkOjk3NUYxN0NGOUQ5RDExRTA5MTgyQjc4MkNEQkY5RkI1IiB4bXBNTTpEb2N1bWVu\
  494. dElEPSJ4bXAuZGlkOjk3NUYxN0QwOUQ5RDExRTA5MTgyQjc4MkNEQkY5RkI1Ij4gPHhtcE1NOkRl\
  495. cml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OTc1RjE3Q0Q5RDlEMTFFMDkxODJC\
  496. NzgyQ0RCRjlGQjUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OTc1RjE3Q0U5RDlEMTFFMDkx\
  497. ODJCNzgyQ0RCRjlGQjUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1l\
  498. dGE+IDw/eHBhY2tldCBlbmQ9InIiPz7MtgYTAAACd0lEQVR42uyajW2CUBDHH8YBWKBJR8AJChvY\
  499. AZriBNYJrBOIE9imA6gTyAZlg9p0ATaw99IzfSEgvI9DlLvk5UUUuPu9/71PvePxKPpsA9FzYwAM\
  500. gAEwAAbAABgAA2AADIABMAAG0EcbmtzkeV7p9Z+nVQhViB8PUNK7j+nBxkF4ZgzVHMp9ydeZfAeU\
  501. d3hPVnZ/3X6HZ7IhUgQATgZQraEEJT+XDi7AwVQzcB+qjQK0zuTzJ0Xg5ACw1aWjfs1tCTg30wh+\
  502. XwH0nOVQIlUNpACw5fcNglclKx3MCYJXIYxOSqiLb2CRm75m8AKD+kJwVba2CF6gP+s2RoGlZvCq\
  503. g/syCHDtFaqxg849hGeNyQDAw2WPHFu20gZVpKbT3OEI90ypgKkDB+9RCScIG8dDfCMFDE0l5shJ\
  504. 2epLgPBdMc5bGaoqowAQOPQzFnTmU6XAVViTydctA2g0Bb9lAGnfAewoAaQdDz6H/N9SAth1HMCK\
  505. eiq87XLry5UnKQBcaXUVwurcatNlJzi79ta3AoAqSDoGYKHT+tYbIjjf/nQ8NTa1DIIfFS+SbYgo\
  506. 9ojSu7RNTG6yBoCpEF0YwqJqV5g8BQpLT90tMjLpt5kCJyVkqIRDi8HnptInWQsghFHdJoRDm5lK\
  507. n2wxhMOQVMIbcfDynMH6Hc76gDKDfuFF/O0eO1/qQvBRkx+21gdUqCHBlHDZL2Q49Dox8v0ApV9I\
  508. HAUf6c72LpYCJSkRYkoEbQXfyumwAYhYVB95O235TgIogJjWKCKVOW8q+04DKMwi5UnOg/g/dMlx\
  509. imvVd5AAuCXjP0kxAAbAABgAA2AADIABMAAGwAB6ab8CDACjlPepVvE3rwAAAABJRU5ErkJggg=="
  510. local hearts = {}
  511. local rings = {}
  512. local cx = 400
  513. local cy = 300
  514. local pig
  515. local heart_image
  516. local function add_heart_ring(radius, number, speed)
  517. local step = math.pi*2/number
  518. for i = 1,number do
  519. local heart = {
  520. radius = radius,
  521. position = step*i,
  522. speed = speed,
  523. opacity = radius/450
  524. }
  525. table.insert(hearts, heart)
  526. end
  527. table.insert(rings, radius)
  528. end
  529. local function update_hearts(dt)
  530. for i,v in ipairs(hearts) do
  531. v.position = v.position + v.speed*dt*0.6
  532. end
  533. end
  534. local function draw_hearts()
  535. for i,v in ipairs(hearts) do
  536. local x = math.cos(v.position) * v.radius + cx
  537. local y = math.sin(v.position) * v.radius + cy
  538. love.graphics.setColor(255, 255, 255, v.opacity*255)
  539. love.graphics.draw(heart_image, x, y, v.position+0.4, 1, 1, 32, 32)
  540. end
  541. end
  542. local function draw_pig(p)
  543. love.graphics.setColor(255, 255, 255, 255)
  544. love.graphics.draw(p.img, p.x, p.y, 0, 1, 1, 128, 128)
  545. end
  546. local function loadimage(file, name)
  547. return love.graphics.newImage(love.image.newImageData(love.filesystem.newFileData(file, name:gsub("_", "."), "base64")))
  548. end
  549. function love.load()
  550. math.randomseed(os.time())
  551. pig = {
  552. x = cx,
  553. y = cy,
  554. img = loadimage(pig_png, "pig.png")
  555. }
  556. heart_image = loadimage(heart_png, "heart.png")
  557. add_heart_ring(100, 10, 2.4)
  558. add_heart_ring(150, 20, 2.2)
  559. add_heart_ring(200, 25, 2.0)
  560. add_heart_ring(250, 35, 1.8)
  561. add_heart_ring(300, 40, 1.6)
  562. add_heart_ring(350, 50, 1.4)
  563. add_heart_ring(400, 60, 1.2)
  564. add_heart_ring(450, 70, 1)
  565. end
  566. function love.update(dt)
  567. update_hearts(dt)
  568. end
  569. function love.draw()
  570. love.graphics.setBackgroundColor(254, 224, 238)
  571. draw_hearts()
  572. draw_pig(pig)
  573. end
  574. function love.keyreleased(key)
  575. if key == "escape" then
  576. love.event.quit()
  577. end
  578. end
  579. function love.conf(t)
  580. t.title = "L\195\150VE " .. love._version .. " (" .. love._version_codename .. ")"
  581. t.modules.audio = false
  582. t.modules.sound = false
  583. t.modules.physics = false
  584. t.modules.joystick = false
  585. end
  586. end
  587. -----------------------------------------------------------
  588. -- Error screen.
  589. -----------------------------------------------------------
  590. local debug = debug
  591. local function error_printer(msg, layer)
  592. print((debug.traceback("Error: " .. tostring(msg), 1+(layer or 1)):gsub("\n[^\n]+$", "")))
  593. end
  594. function love.errhand(msg)
  595. msg = tostring(msg)
  596. error_printer(msg, 2)
  597. if not love.graphics or not love.event or not love.graphics.isCreated() then
  598. return
  599. end
  600. -- Load.
  601. if love.audio then love.audio.stop() end
  602. love.graphics.reset()
  603. love.graphics.setBackgroundColor(89, 157, 220)
  604. local font = love.graphics.newFont(14)
  605. love.graphics.setFont(font)
  606. love.graphics.setColor(255, 255, 255, 255)
  607. local trace = debug.traceback()
  608. love.graphics.clear()
  609. local err = {}
  610. table.insert(err, "Error\n")
  611. table.insert(err, msg.."\n\n")
  612. for l in string.gmatch(trace, "(.-)\n") do
  613. if not string.match(l, "boot.lua") then
  614. l = string.gsub(l, "stack traceback:", "Traceback\n")
  615. table.insert(err, l)
  616. end
  617. end
  618. local p = table.concat(err, "\n")
  619. p = string.gsub(p, "\t", "")
  620. p = string.gsub(p, "%[string \"(.-)\"%]", "%1")
  621. local function draw()
  622. love.graphics.clear()
  623. love.graphics.printf(p, 70, 70, love.graphics.getWidth() - 70)
  624. love.graphics.present()
  625. end
  626. draw()
  627. local e, a, b, c
  628. while true do
  629. e, a, b, c = love.event.wait()
  630. if e == "quit" then
  631. return
  632. end
  633. if e == "keypressed" and a == "escape" then
  634. return
  635. end
  636. draw()
  637. end
  638. end
  639. function love.releaseerrhand(msg)
  640. print("An error has occured, the game has been stopped.")
  641. if not love.graphics or not love.event or not love.graphics.isCreated() then
  642. return
  643. end
  644. love.graphics.setCanvas()
  645. love.graphics.setPixelEffect()
  646. -- Load.
  647. if love.audio then love.audio.stop() end
  648. love.graphics.reset()
  649. love.graphics.setBackgroundColor(89, 157, 220)
  650. local font = love.graphics.newFont(14)
  651. love.graphics.setFont(font)
  652. love.graphics.setColor(255, 255, 255, 255)
  653. love.graphics.clear()
  654. local err = {}
  655. p = string.format("An error has occured that caused %s to stop.\nYou can notify %s about this%s.", love._release.title or "this game", love._release.author or "the author", love._release.url and " at " .. love._release.url or "")
  656. local function draw()
  657. love.graphics.clear()
  658. love.graphics.printf(p, 70, 70, love.graphics.getWidth() - 70)
  659. love.graphics.present()
  660. end
  661. draw()
  662. local e, a, b, c
  663. while true do
  664. e, a, b, c = love.event.wait()
  665. if e == "quit" then
  666. return
  667. end
  668. if e == "keypressed" and a == "escape" then
  669. return
  670. end
  671. draw()
  672. end
  673. end
  674. -----------------------------------------------------------
  675. -- The root of all calls.
  676. -----------------------------------------------------------
  677. local result = xpcall(love.boot, error_printer)
  678. if not result then return 1 end
  679. local result = xpcall(love.init, love._release and love.releaseerrhand or love.errhand)
  680. if not result then return 1 end
  681. local result, retval = xpcall(love.run, love._release and love.releaseerrhand or love.errhand)
  682. if not result then return 1 end
  683. return tonumber(retval) or 0