api.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. _Class = require("class")
  2. require("offsets")
  3. _LK12VER = "V0.0.3 PRE"
  4. _LK12VERC = 10--9 DEV, 10 PRE
  5. --Mobiles Cursor FIX--
  6. if love.system.getOS() == "Android" or love.system.getOS() == "iOS" then
  7. love.mouse.newCursor = function() end
  8. love.mouse.setCursor = function() end
  9. _IsMobile = true
  10. end
  11. --Internal Variables--
  12. _FontChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"\'`-_/1234567890!?[](){}.,;:<>+=%#^*~ '
  13. _Font = love.graphics.newImageFont("/font.png",_FontChars,1)
  14. --love.graphics.newFont("font.ttf",20)
  15. _ShouldDraw = false
  16. _ForceDraw = false
  17. _ScreenTitle = "Liko 12"
  18. _ColorSet = { --Pico8 Colorset, Should add other 16 color because it's double the width of pico8
  19. {0,0,0,255}, --Black 1
  20. {28,43,83,255}, --Dark Blue 2
  21. {127,36,84,255}, --Dark Red 3
  22. {0,135,81,255}, --Dark Green 4
  23. {171,82,54,255}, --Brown 5
  24. {96,88,79,255}, --Dark Gray 6
  25. {195,195,198,255}, --Gray 7
  26. {255,241,233,255}, --White 8
  27. {237,27,81,255}, --Red 9
  28. {250,162,27,255}, --Orange 10
  29. {247,236,47,255}, --Yellow 11
  30. {93,187,77,255}, --Green 12
  31. {81,166,220,255}, --Blue 13
  32. {131,118,156,255}, --Purple 14
  33. {241,118,166,255}, --Pink 15
  34. {252,204,171,255} --Human Skin 16
  35. }
  36. _ColorSet[0] = {0,0,0,0}
  37. --Internal Funtions--
  38. function _ScreenToLiko(x,y)
  39. x, y = x-_ScreenX, y-_ScreenY
  40. return api.floor(x/_ScreenScaleX)+1, api.floor(y/_ScreenScaleY)+1
  41. end
  42. function _GetColor(c) return _ColorSet[c or 1] end
  43. function _GetColorID(r,g,b,a)
  44. for id,col in pairs(_ColorSet) do
  45. if col[1] == r and col[2] == g and col[3] == b and col[4] == (a or 255) then
  46. return id
  47. end
  48. end
  49. return false
  50. end
  51. local function newAPI(noFS,sprsheetmap)
  52. local api = {}
  53. --Callbacks--
  54. function api._init() end --Called at the start of the program
  55. function api._update(dt) end --Called when the program updates
  56. function api._mpress(x,y,button,it) end --Called when a mouse button is pressed
  57. function api._mmove(x,y,dx,dy,it,iw) end --Called when the mouse moves
  58. function api._mrelease(x,y,button,it) end --Called when a mouse button is released
  59. function api._tpress(id,x,y,dx,dy,button,pressure) end --Called when the screen is touched
  60. function api._tmove(id,x,y,dx,dy,pressure) end --Called when the screen touch moves
  61. function api._trelease(id,x,y,dx,dy,pressure) end --Called when the screen touch releases
  62. function api._kpress(key,scancode,isrepeat) end --Called when a key is pressed
  63. function api._krelease(key,scancode) end --Called when a key is released
  64. function api._tinput(text) end --Called when text input, uses utf8 format
  65. --API Functions--
  66. --Graphics Section--
  67. function api.clear(c) --Clears the screen (fills it with a specific color)
  68. api.color(c or 1)
  69. api.rect(1,1,192,128)
  70. _ShouldDraw = true
  71. end
  72. function api.color(id)
  73. love.graphics.setColor(_ColorSet[id or 1] or _ColorSet[1])
  74. end
  75. function api.stroke(width) --Sets the lines and the points width
  76. love.graphics.setPointSize(width or 1)
  77. love.graphics.setLineWidth(width or 1)
  78. end
  79. function api.points(...) --Draws the points: x1,y1, x2, y2, ...
  80. local args = {...}
  81. if not (#args % 2 == 0) then api.color(args[#args]) table.remove(args,#args) end
  82. for k,v in ipairs(args) do if (k % 2 == 0) then args[k] = v + _goffset.pointY else args[k] = v + _goffset.pointX end end
  83. love.graphics.points(unpack(args))
  84. _ShouldDraw = true
  85. end
  86. api.point = api.points
  87. function api.line(...)
  88. local args = {...}
  89. if not (#args % 2 == 0) then api.color(args[#args]) table.remove(args,#args) end
  90. love.graphics.line(unpack(args))
  91. _ShouldDraw = true
  92. end
  93. api.lines = api.line
  94. function api.circle(x,y,r,s,c) --x,y,radius,segments,color
  95. if c then api.color(c) end
  96. love.graphics.circle("fill",x,y,r,s)
  97. _ShouldDraw = true
  98. end
  99. function api.circle_line(x,y,r,s,c) --x,y,radius,segments,color
  100. if c then api.color(c) end
  101. love.graphics.circle("line",x,y,r,s)
  102. _ShouldDraw = true
  103. end
  104. function api.rect(x,y,w,h,c)
  105. if c then api.color(c) end
  106. local x,y = x + _goffset.rectX, y + _goffset.rectY
  107. love.graphics.rectangle("fill",x,y,w,h)
  108. _ShouldDraw = true
  109. end
  110. function api.rect_line(x,y,w,h,c)
  111. if c then api.color(c) end
  112. local x,y = x + _goffset.rect_lineX, y + _goffset.rect_lineY
  113. local w, h = w + _goffset.rect_lineW, h + _goffset.rect_lineH
  114. love.graphics.rectangle("line",x,y,w,h)
  115. _ShouldDraw = true
  116. end
  117. function api.print(text,lx,ly)
  118. love.graphics.print(text, api.floor((lx or 1)+_goffset.printX), api.floor((ly or 1)+_goffset.printY)) _ShouldDraw = true --_goffset.rectX
  119. end
  120. function api.print_grid(text,lx,ly)
  121. love.graphics.print(text, api.floor(((lx or 1)*8-6)+_goffset.printX), api.floor(((ly or 1)*8-6)+_goffset.printY)) _ShouldDraw = true
  122. end
  123. --Image Section--
  124. api.Image = _Class("Liko12.image")
  125. function api.Image:initialize(path) if type(path) == "string" then self.image = love.graphics.newImage(path) else self.image = love.graphics.newImage(path.imageData) end end
  126. function api.Image:draw(x,y,r,sx,sy,quad) love.graphics.setColor(255,255,255,255) if quad then love.graphics.draw(self.image,quad,x+_goffset.quadX,y+_goffset.quadY,r,sx,sy) else love.graphics.draw(self.image,x+_goffset.imageX,y+_goffset.imageY,r,sx,sy) end api.color(8) _ShouldDraw = true return self end
  127. function api.Image:size() return self.image:getDimensions() end
  128. function api.Image:width() return self.image:getWidth() end
  129. function api.Image:height() return self.image:getHeight() end
  130. function api.Image:data() return api.ImageData(self.image:getData()) end
  131. function api.Image:quad(x,y,w,h) return love.graphics.newQuad(x-1,y-1,w or self:width(),h or self:height(),self:width(),self:height()) end
  132. api.ImageData = _Class("Liko12.imageData")
  133. function api.ImageData:initialize(w,h) if h then self.imageData = love.image.newImageData(w or 192, h or 128) elseif type(w) == "string" then self.imageData = love.image.newImageData(love.filesystem.newFileData(w,"spritemap","base64")) else self.imageData = w end end
  134. function api.ImageData:size() return self.imageData:getDimensions() end
  135. function api.ImageData:getPixel(x,y) return self.imageData:getPixel((x or 1)-1,(y or 1)-1) end
  136. function api.ImageData:setPixel(x,y,c) self.imageData:setPixel((x or 1)-1,(y or 1)-1,unpack(_GetColor(c))) return self end
  137. function api.ImageData:map(mf)
  138. self.imageData:mapPixel(
  139. function(x,y,r,g,b,a)
  140. local newCol = mf(x+1,y+1,_GetColorID(r,g,b,a))
  141. newCol = newCol and _GetColor(newCol) or {r,g,b,a}
  142. return unpack(newCol)
  143. end)
  144. return self
  145. end
  146. function api.ImageData:height() return self.imageData:getHeight() end
  147. function api.ImageData:width() return self.imageData:getWidth() end
  148. function api.ImageData:paste(sprData,dx,dy,sx,sy,sw,sh) self.imageData:paste(sprData.imageData,(dx or 1)-1,(dy or 1)-1,(sx or 1)-1,(sy or 1)-1,sw or sprData:width(), sh or sprData:height()) return self end
  149. function api.ImageData:quad(x,y,w,h) return love.graphics.newQuad(x-1,y-1,w or self:width(),h or self:height(),self:width(),self:height()) end
  150. function api.ImageData:image() return api.Image(self) end
  151. function api.ImageData:export(filename) return self.imageData:encode("png",filename and (filename..".png") or nil) end
  152. function api.ImageData:enlarge(scale)
  153. local scale = api.floor(scale or 1)
  154. if scale <= 0 then scale = 1 end --Protection
  155. if scale == 1 then return self end
  156. local newData = api.ImageData(self:width()*scale,self:height()*scale)
  157. self:map(function(x,y,c)
  158. for iy=1, scale do for ix=1, scale do
  159. newData:setPixel((x-1)*scale + ix,(y-1)*scale + iy,c)
  160. end end
  161. end)
  162. return newData
  163. end
  164. api.SpriteSheet = _Class("Liko12.spriteSheet")
  165. function api.SpriteSheet:initialize(img,w,h)
  166. self.img, self.w, self.h = img, w, h
  167. self.cw, self.ch, self.quads = self.img:width()/self.w, self.img:height()/self.h, {}
  168. for y=1,self.h do for x=1,self.w do
  169. table.insert(self.quads,self.img:quad(x*self.cw-(self.cw-1),y*self.ch-(self.ch-1),self.cw,self.ch))
  170. end end
  171. end
  172. function api.SpriteSheet:image() return self.img end
  173. function api.SpriteSheet:data() return self.img:data() end
  174. function api.SpriteSheet:quad(id) return self.quads[id] end
  175. function api.SpriteSheet:rect(id) local x,y,w,h = self.quads[id]:getViewport() return x+1,y+1,w,h end
  176. function api.SpriteSheet:draw(id,x,y,r,sx,sy) self.img:draw(x,y,r,sx,sy,self.quads[id]) _ShouldDraw = true return self end
  177. function api.SpriteSheet:extract(id) return api.ImageData(8,8):paste(self:data(),1,1,self:rect(id)) end
  178. function api.Sprite(id,x,y,r,sx,sy,sheet) (sheet or api.SpriteMap):draw(id,x,y,r,sx,sy) end
  179. function api.SpriteGroup(id,x,y,w,h,sx,sy,sheet)
  180. local sx,sy = api.floor(sx or 1), api.floor(sy or 1)
  181. for spry = 1, h or 1 do for sprx = 1, w or 1 do
  182. (sheet or api.SpriteMap):draw((id-1)+sprx+(spry*24-24),x+(sprx*sx*8-sx*8),y+(spry*sy*8-sy*8),0,sx,sy)
  183. end end
  184. end
  185. --Cursors Section--
  186. api._CurrentCursor = "normal"
  187. api._Cursors = {}
  188. api._CachedCursors = {}
  189. function api.newCursor(data,name,hotx,hoty)
  190. api._Cursors[name] = {data = data, hotx = hotx or 1, hoty = hoty or 1}
  191. api._CachedCursors[name or "custom"] = love.mouse.newCursor(api._Cursors[name].data:enlarge(_ScreenScale).imageData,(api._Cursors[name].hotx-1)*_ScreenScale,(api._Cursors[name].hoty-1)*_ScreenScale)
  192. end
  193. function api.loadDefaultCursors()
  194. api.newCursor(api.EditorSheet:extract(1),"normal",2,2)
  195. api.newCursor(api.EditorSheet:extract(2),"handrelease",3,2)
  196. api.newCursor(api.EditorSheet:extract(3),"handpress",3,4)
  197. api.newCursor(api.EditorSheet:extract(4),"hand",5,5)
  198. api.newCursor(api.EditorSheet:extract(5),"cross",4,4)
  199. api.setCursor(api._CurrentCursor)
  200. end
  201. function api.setCursor(name)
  202. if not api._CachedCursors[name] then api._CachedCursors[name or "custom"] = love.mouse.newCursor(api._Cursors[name].data:enlarge(_ScreenScale).imageData,(api._Cursors[name].hotx-1)*_ScreenScale,(api._Cursors[name].hoty-1)*_ScreenScale) end
  203. love.mouse.setCursor(api._CachedCursors[name]) api._CurrentCursor = name or "custom"
  204. end
  205. function api.clearCursorsCache() api._CachedCursors = {} api.setCursor(api._CurrentCursor) end
  206. --Math Section--
  207. api.ostime = os.time
  208. function api.rand_seed(newSeed)
  209. love.math.setRandomSeed(newSeed)
  210. end
  211. function api.rand(minV,maxV) return love.math.random(minV,maxV) end
  212. function api.floor(num) return math.floor(num) end
  213. --Gui Function--
  214. function api.isInRect(x,y,rect)
  215. if x >= rect[1] and y >= rect[2] and x <= rect[1]+rect[3] and y <= rect[2]+rect[4] then return true end return false
  216. end
  217. function api.whereInGrid(x,y, grid) --Grid X, Grid Y, Grid Width, Grid Height, NumOfCells in width, NumOfCells in height
  218. local gx,gy,gw,gh,cw,ch = unpack(grid)
  219. if api.isInRect(x,y,{gx,gy,gw,gh}) then
  220. local clw, clh = api.floor(gw/cw), api.floor(gh/ch)
  221. local x, y = x-gx, y-gy
  222. local hx = api.floor(x/clw)+1 hx = hx <= cw and hx or hx-1
  223. local hy = api.floor(y/clh)+1 hy = hy <= ch and hy or hy-1
  224. return hx,hy
  225. end
  226. return false, false
  227. end
  228. function api.getMPos()
  229. return _ScreenToLiko(love.mouse.getPosition())
  230. end
  231. function api.isMDown(b) return love.mouse.isDown(b) end
  232. --FileSystem Function--
  233. if not noFS then
  234. api.fs = {}
  235. function api.fs.write(path,data)
  236. return love.filesystem.write("/data/"..path,data)
  237. end
  238. function api.fs.exists(path) return love.filesystem.exists("/data/"..path) end
  239. function api.fs.isDir(path) return love.filesystem.isDirectory("/data/"..path) end
  240. function api.fs.isFile(path) return love.filesystem.isFile("/data/"..path) end
  241. function api.fs.mkDir(path) return love.filesystem.createDirectory("/data/"..path) end
  242. function api.fs.dirItems(path) return love.filesystem.getDirectoryItems("/data/"..path) end
  243. function api.fs.del(path) return love.filesystem.remove("/data/"..path) end
  244. function api.fs.read(path) return love.filesystem.read("/data/"..path) end
  245. end
  246. --Misc Functions--
  247. function api.keyrepeat(state) love.keyboard.setKeyRepeat(state) end
  248. function api.showkeyboard(state) love.keyboard.setTextInput(state) end
  249. function api.isMobile() return _isMobile or false end
  250. TextBuffer = love.filesystem.load("/libraries/textbuffer.lua")()
  251. --Spritesheet--
  252. api.EditorSheet = api.SpriteSheet(api.Image("/editorsheet.png"),24,12)
  253. api.SpriteMap = sprsheetmap or api.SpriteSheet(api.ImageData(24*8,12*8):image(),24,12)
  254. return api
  255. end
  256. local sapi = newAPI()
  257. sapi.newAPI = newAPI
  258. return sapi