init.lua 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. --The BIOS should control the system of LIKO-12 and load the peripherals--
  2. --For now it's just a simple BIOS to get LIKO-12 working.
  3. local DevMode = love.filesystem.getInfo("devmode.txt") and true or false
  4. local BuildMode = love.filesystem.getInfo("build.json") and true or false
  5. local json = require("Engine.JSON")
  6. if BuildMode then
  7. DevMode = false
  8. BuildMode = json:decode(love.filesystem.read("build.json"))
  9. end
  10. local _LIKO_Version, _LIKO_Old = _LVERSION:sub(2,-1)
  11. if love.filesystem.getInfo(".version","file") then
  12. _LIKO_Old = love.filesystem.read(".version")
  13. if _LIKO_Old == _LIKO_Version then
  14. _LIKO_Old = false
  15. end
  16. else
  17. love.filesystem.write(".version",tostring(_LIKO_Version))
  18. end
  19. --Require the engine libraries--
  20. local events = require("Engine.events")
  21. local coreg = require("Engine.coreg")
  22. local function splitFilePath(path) return path:match("(.-)([^\\/]-%.?([^%.\\/]*))$") end --A function to split path to path, name, extension.
  23. local Peripherals = {} --The loaded peripherals chunks.
  24. local APIS = {} --The initialized peripherals apis.
  25. local yAPIS = {} --The initialized peripherals yielding apis.
  26. local Mounted = {} --The mounted peripherals list and types.
  27. local Handled = {} --The handled peripherals functions.
  28. local Devkits = {} --The mounted peripherals devkits.
  29. --A function to load the peripherals.
  30. local function indexPeripherals(path)
  31. local files = love.filesystem.getDirectoryItems(path)
  32. for k,filename in ipairs(files) do
  33. if love.filesystem.getInfo(path..filename,"directory") then
  34. if love.filesystem.getInfo(path..filename.."/init.lua","file") then
  35. local chunk, err = love.filesystem.load(path..filename.."/init.lua")
  36. if not chunk then Peripherals[filename] = "Err: "..tostring(err) else
  37. Peripherals[filename] = chunk(path..filename.."/") end
  38. end
  39. else
  40. local p, n, e = splitFilePath(path..filename)
  41. if e == "lua" then
  42. local chunk, err = love.filesystem.load(path..n)
  43. if not chunk then Peripherals[n:sub(0,-5)] = "Err: "..tostring(err) else
  44. Peripherals[n:sub(0,-5)] = chunk(path) end
  45. end
  46. end
  47. end
  48. end
  49. indexPeripherals("/Peripherals/") --Index and Load the peripherals
  50. --Initializes a specific peripheral, and mount it under a specific name.
  51. --Peripheral, Err = P(PeriheralName, MountedName, ConfigTabel)
  52. local function P(per,m,conf)
  53. if not per then return false, "Should provide peripheral name" end
  54. if type(per) ~= "string" then return false, "Peripheral name should be a string, provided "..type(per) end
  55. if not Peripherals[per] then return false, "'"..per.."' Peripheral doesn't exists" end
  56. if type(Peripherals[per]) == "string" then return false, "Compile "..Peripherals[per] end
  57. local m = m or per
  58. if type(m) ~= "string" then return false, "Mounting name should be a string, provided "..type(m) end
  59. if Mounted[m] then return false, "Mounting name '"..m.."' is already taken" end
  60. local conf = conf or {}
  61. if type(conf) ~= "table" then return false, "Configuration table should be a table, provided "..type(conf) end
  62. events:group(per..":"..m)
  63. local success, API, yAPI, devkit = pcall(Peripherals[per],conf)
  64. events:group()
  65. if success then
  66. APIS[m] = API or {} --The direct API
  67. yAPIS[m] = yAPI or {} --The yielding API
  68. Mounted[m] = per --The peripheral type
  69. Devkits[m] = devkit or {} --The peripheral Devkit.
  70. else
  71. API = "Init Err: "..tostring(API)
  72. end
  73. return success, API, yAPI, devkit
  74. end
  75. --Initialize a peripheral, and crash LIKO-12 if failed.
  76. local function PA(...)
  77. local ok, api, yapi, devkit = P(...)
  78. if ok then
  79. return api, yapi, devkit
  80. else
  81. return error(tostring(api))
  82. end
  83. end
  84. --BIOS APIS--
  85. do
  86. Mounted.BIOS = "BIOS"
  87. APIS.BIOS = {}
  88. yAPIS.BIOS = {}
  89. --Returns a list of mounted peripherals and their types.
  90. function yAPIS.BIOS.Peripherals()
  91. local pList = {}
  92. for mountName, pType in pairs(Mounted) do
  93. pList[mountName] = pType
  94. end
  95. return true, pList
  96. end
  97. --Returns the handled APIS, that can be used directly.
  98. function yAPIS.BIOS.HandledAPIS()
  99. local hAPIS = {}
  100. for mountName,funcList in pairs(Handled) do
  101. hAPIS[mountName] = {}
  102. for funcName, func in pairs(funcList) do
  103. hAPIS[mountName][funcName] = func
  104. end
  105. end
  106. return true, hAPIS
  107. end
  108. --Returns the list of available peripheral functions, and their type (Direct,Yield)
  109. function yAPIS.BIOS.PeripheralFunctions(mountName)
  110. if type(mountName) ~= "string" then return false, "MountName should be a string, provided: "..type(mountName) end
  111. if not Mounted[mountName] then return false, "No mounted peripheral '"..mountName"..'" end
  112. local funcList = {}
  113. for funcName, func in pairs(APIS[mountName]) do
  114. funcList[funcName] = "Direct"
  115. end
  116. for funcName, func in pairs(yAPIS[mountName]) do
  117. funcList[funcName] = "Yield"
  118. end
  119. return true, funcList
  120. end
  121. --Returns LIKO-12 Version
  122. function yAPIS.BIOS.getVersion()
  123. return true, _LIKO_Version, _LIKO_Old
  124. end
  125. end
  126. --The BIOS config sandbox
  127. local bconfSandbox = {
  128. P=P, PA=PA,
  129. error=error, assert=assert,
  130. _OS = love.system.getOS(),
  131. Build = BuildMode
  132. }
  133. --Load and execute the bios config
  134. local bconfChunk = love.filesystem.load(BuildMode and "BIOS/bconf_splash.lua" or "BIOS/bconf.lua")
  135. setfenv(bconfChunk, bconfSandbox)
  136. bconfChunk(BuildMode)
  137. --Register yielding APIS
  138. for mountName, yAPI in pairs(yAPIS) do
  139. coreg:register(yAPI,mountName)
  140. end
  141. --Create handled functions
  142. for mountName, pType in pairs(Mounted) do
  143. Handled[mountName] = {}
  144. for funcName, func in pairs(APIS[mountName]) do
  145. Handled[mountName][funcName] = func
  146. end
  147. for funcName, func in pairs(yAPIS[mountName]) do
  148. local funcCommand = mountName..":"..funcName
  149. Handled[mountName][funcName] = function(...)
  150. local respond = {coroutine.yield(funcCommand,...)}
  151. if respond[1] then
  152. return select(2,unpack(respond))
  153. else
  154. return error(tostring(respond[2]))
  155. end
  156. end
  157. end
  158. end
  159. --Bootup the POST chunk
  160. local POST = love.filesystem.load(BuildMode and "/BIOS/splash.lua" or "/BIOS/post.lua")
  161. local POSTCo = coroutine.create(POST)
  162. coreg:setCoroutine(POSTCo)
  163. coreg:resumeCoroutine(Handled,Devkits)