boot.lua 27 KB

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