612 lines
14 KiB
Lua
612 lines
14 KiB
Lua
SCR= require"Zframework/screen"
|
|
COLOR= require"Zframework/color"
|
|
SCN= require"Zframework/scene"
|
|
LOG= require"Zframework/log"
|
|
require"Zframework/toolfunc"
|
|
|
|
VIB= require"Zframework/vibrate"
|
|
SFX= require"Zframework/sfx"
|
|
|
|
LIGHT= require"Zframework/light"
|
|
BG= require"Zframework/background"
|
|
WIDGET= require"Zframework/widget"
|
|
TEXT= require"Zframework/text"
|
|
SYSFX= require"Zframework/sysFX"
|
|
|
|
IMG= require"Zframework/image"
|
|
BGM= require"Zframework/bgm"
|
|
VOC= require"Zframework/voice"
|
|
|
|
LANG= require"Zframework/languages"
|
|
TASK= require"Zframework/task"
|
|
FILE= require"Zframework/file"
|
|
PROFILE=require"Zframework/profile"
|
|
|
|
local ms,kb=love.mouse,love.keyboard
|
|
local gc=love.graphics
|
|
local int,rnd,abs=math.floor,math.random,math.abs
|
|
local min=math.min
|
|
local ins,rem=table.insert,table.remove
|
|
local SCR=SCR
|
|
local setFont=setFont
|
|
|
|
local mx,my,mouseShow=-20,-20,false
|
|
local touching=nil--First touching ID(userdata)
|
|
local xOy=SCR.xOy
|
|
joysticks={}
|
|
|
|
local devMode
|
|
|
|
local infoCanvas=gc.newCanvas(108,27)
|
|
local function updatePowerInfo()
|
|
local state,pow=love.system.getPowerInfo()
|
|
gc.setCanvas(infoCanvas)gc.push("transform")gc.origin()
|
|
gc.clear(0,0,0,.25)
|
|
if state~="unknown"then
|
|
gc.setLineWidth(4)
|
|
local charging=state=="charging"
|
|
if state=="nobattery"then
|
|
gc.setColor(1,1,1)
|
|
gc.setLineWidth(2)
|
|
gc.line(74,5,100,22)
|
|
elseif pow then
|
|
if charging then gc.setColor(0,1,0)
|
|
elseif pow>50 then gc.setColor(1,1,1)
|
|
elseif pow>26 then gc.setColor(1,1,0)
|
|
elseif pow<26 then gc.setColor(1,0,0)
|
|
else gc.setColor(.5,0,1)
|
|
end
|
|
gc.rectangle("fill",76,6,pow*.22,14)
|
|
if pow<100 then
|
|
setFont(15)
|
|
gc.setColor(0,0,0)
|
|
gc.print(pow,77,1)
|
|
gc.print(pow,77,3)
|
|
gc.print(pow,79,1)
|
|
gc.print(pow,79,3)
|
|
gc.setColor(1,1,1)
|
|
gc.print(pow,78,2)
|
|
end
|
|
end
|
|
gc.draw(IMG.batteryImage,73,3)
|
|
end
|
|
setFont(25)
|
|
gc.print(os.date("%H:%M",os.time()),3,-5)
|
|
gc.pop()gc.setCanvas()
|
|
end
|
|
-------------------------------------------------------------
|
|
Tmr,Pnt={},{}
|
|
mouseClick,touchClick={},{}
|
|
mouseDown,mouseMove,mouseUp,wheelMoved={},{},{},{}
|
|
touchDown,touchUp,touchMove={},{},{}
|
|
keyDown,keyUp={},{}
|
|
gamepadDown,gamepadUp={},{}
|
|
|
|
local Tmr,Pnt=Tmr,Pnt
|
|
local mouseClick,touchClick=mouseClick,touchClick
|
|
local mouseDown,mouseMove,mouseUp,wheelMoved=mouseDown,mouseMove,mouseUp,wheelMoved
|
|
local touchDown,touchUp,touchMove=touchDown,touchUp,touchMove
|
|
local keyDown,keyUp=keyDown,keyUp
|
|
local gamepadDown,gamepadUp=gamepadDown,gamepadUp
|
|
-------------------------------------------------------------
|
|
local lastX,lastY=0,0--Last clickDown pos
|
|
function love.mousepressed(x,y,k,touch)
|
|
if touch then return end
|
|
mouseShow=true
|
|
mx,my=xOy:inverseTransformPoint(x,y)
|
|
if devMode==1 then
|
|
local dx,dy=mx-lastX,my-lastY
|
|
DBP(("(%d,%d), D=(%d,%d)~~(%d,%d)(%d,%d)"):format(mx,my,dx,dy,int(mx/10)*10,int(my/10)*10,int(dx/10)*10,int(dy/10)*10))
|
|
end
|
|
if SCN.swapping then return end
|
|
if mouseDown[SCN.cur]then
|
|
mouseDown[SCN.cur](mx,my,k)
|
|
elseif k==2 then
|
|
SCN.back()
|
|
end
|
|
if k==1 then
|
|
WIDGET.press(mx,my)
|
|
end
|
|
lastX,lastY=mx,my
|
|
SYSFX.newRipple(3,mx,my,30)
|
|
end
|
|
function love.mousemoved(x,y,dx,dy,t)
|
|
if t then return end
|
|
mouseShow=true
|
|
mx,my=xOy:inverseTransformPoint(x,y)
|
|
if SCN.swapping then return end
|
|
dx,dy=dx/SCR.k,dy/SCR.k
|
|
if mouseMove[SCN.cur]then
|
|
mouseMove[SCN.cur](mx,my,dx,dy)
|
|
end
|
|
if ms.isDown(1) then
|
|
WIDGET.drag(mx,my)
|
|
else
|
|
WIDGET.moveCursor(mx,my)
|
|
end
|
|
end
|
|
function love.mousereleased(x,y,k,touch)
|
|
if touch or SCN.swapping then return end
|
|
mx,my=xOy:inverseTransformPoint(x,y)
|
|
WIDGET.release(mx,my)
|
|
WIDGET.moveCursor(mx,my)
|
|
if mouseUp[SCN.cur]then
|
|
mouseUp[SCN.cur](mx,my,k)
|
|
end
|
|
if lastX and(mx-lastX)^2+(my-lastY)^2<26 and mouseClick[SCN.cur]then
|
|
mouseClick[SCN.cur](mx,my,k)
|
|
end
|
|
end
|
|
function love.wheelmoved(x,y)
|
|
if SCN.swapping then return end
|
|
if wheelMoved[SCN.cur]then wheelMoved[SCN.cur](x,y)end
|
|
end
|
|
|
|
function love.touchpressed(id,x,y)
|
|
mouseShow=false
|
|
if SCN.swapping then return end
|
|
if not touching then
|
|
touching=id
|
|
love.touchmoved(id,x,y,0,0)
|
|
end
|
|
x,y=xOy:inverseTransformPoint(x,y)
|
|
lastX,lastY=x,y
|
|
if touchDown[SCN.cur]then
|
|
touchDown[SCN.cur](id,x,y)
|
|
end
|
|
if kb.hasTextInput()then kb.setTextInput(false)end
|
|
end
|
|
function love.touchmoved(id,x,y,dx,dy)
|
|
if SCN.swapping then return end
|
|
x,y=xOy:inverseTransformPoint(x,y)
|
|
if touchMove[SCN.cur]then
|
|
touchMove[SCN.cur](id,x,y,dx/SCR.k,dy/SCR.k)
|
|
end
|
|
if WIDGET.sel then
|
|
if touching then
|
|
WIDGET.drag(x,y)
|
|
end
|
|
else
|
|
WIDGET.moveCursor(x,y)
|
|
if not WIDGET.sel then
|
|
touching=nil
|
|
end
|
|
end
|
|
end
|
|
function love.touchreleased(id,x,y)
|
|
if SCN.swapping then return end
|
|
x,y=xOy:inverseTransformPoint(x,y)
|
|
if id==touching then
|
|
WIDGET.press(x,y)
|
|
WIDGET.release(x,y)
|
|
touching=nil
|
|
if WIDGET.sel and not WIDGET.sel.keepFocus then
|
|
WIDGET.sel=nil
|
|
end
|
|
end
|
|
if touchUp[SCN.cur]then
|
|
touchUp[SCN.cur](id,x,y)
|
|
end
|
|
if(x-lastX)^2+(y-lastY)^2<26 then
|
|
if touchClick[SCN.cur]then
|
|
touchClick[SCN.cur](x,y)
|
|
end
|
|
SYSFX.newRipple(3,x,y,30)
|
|
end
|
|
end
|
|
|
|
function love.keypressed(i)
|
|
mouseShow=false
|
|
if devMode then
|
|
if i=="f1"then
|
|
PROFILE.switch()
|
|
elseif i=="f2"then
|
|
LOG.print("System:"..SYSTEM.."["..jit.arch.."]")
|
|
LOG.print("luaVer:".._VERSION)
|
|
LOG.print("jitVer:"..jit.version)
|
|
LOG.print("jitVerNum:"..jit.version_num)
|
|
local r=rnd()<.5
|
|
love._setGammaCorrect(r)
|
|
LOG.print("GammaCorrect: "..(r and"on"or"off"),"warn")
|
|
elseif i=="f3"then
|
|
for _=1,8 do
|
|
local P=PLAYERS.alive[rnd(#PLAYERS.alive)]
|
|
if P~=PLAYERS[1]then
|
|
P.lastRecv=PLAYERS[1]
|
|
P:lose()
|
|
end
|
|
end
|
|
elseif i=="f4"then if not kb.isDown("lalt","ralt")then LOG.copy()end
|
|
elseif i=="f5"then if love._openConsole then love._openConsole()end
|
|
elseif i=="f6"then if WIDGET.sel then DBP(WIDGET.sel)end
|
|
elseif i=="f7"then for k,v in next,_G do DBP(k,v)end
|
|
elseif i=="f8"then devMode=nil LOG.print("DEBUG OFF",COLOR.yellow)
|
|
elseif i=="f9"then devMode=1 LOG.print("DEBUG 1",COLOR.yellow)
|
|
elseif i=="f10"then devMode=2 LOG.print("DEBUG 2",COLOR.yellow)
|
|
elseif i=="f11"then devMode=3 LOG.print("DEBUG 3",COLOR.yellow)
|
|
elseif i=="f12"then devMode=4 LOG.print("DEBUG 4",COLOR.yellow)
|
|
elseif devMode==2 then
|
|
if WIDGET.sel then
|
|
local W=WIDGET.sel
|
|
if i=="left"then W.x=W.x-10
|
|
elseif i=="right"then W.x=W.x+10
|
|
elseif i=="up"then W.y=W.y-10
|
|
elseif i=="down"then W.y=W.y+10
|
|
elseif i==","then W.w=W.w-10
|
|
elseif i=="."then W.w=W.w+10
|
|
elseif i=="/"then W.h=W.h-10
|
|
elseif i=="'"then W.h=W.h+10
|
|
elseif i=="["then W.font=W.font-1
|
|
elseif i=="]"then W.font=W.font+1
|
|
else goto NORMAL
|
|
end
|
|
else
|
|
goto NORMAL
|
|
end
|
|
else
|
|
goto NORMAL
|
|
end
|
|
return
|
|
end
|
|
::NORMAL::
|
|
if i~="f8"then
|
|
if SCN.swapping then return end
|
|
|
|
if keyDown[SCN.cur]then keyDown[SCN.cur](i)
|
|
elseif i=="escape"then SCN.back()
|
|
else WIDGET.keyPressed(i)
|
|
end
|
|
else
|
|
devMode=1
|
|
LOG.print("DEBUG ON",COLOR.yellow)
|
|
end
|
|
end
|
|
function love.keyreleased(i)
|
|
if SCN.swapping then return end
|
|
if keyUp[SCN.cur]then keyUp[SCN.cur](i)end
|
|
end
|
|
function love.textedited(text)
|
|
EDITING=text
|
|
end
|
|
function love.textinput(text)
|
|
local W=WIDGET.sel
|
|
if W and W.type=="textBox"then
|
|
if not W.regex or text:match(W.regex)then
|
|
WIDGET.sel.value=WIDGET.sel.value..text
|
|
SFX.play("move")
|
|
else
|
|
SFX.play("finesseError",.3)
|
|
end
|
|
end
|
|
end
|
|
|
|
function love.joystickadded(JS)
|
|
joysticks[#joysticks+1]=JS
|
|
end
|
|
function love.joystickremoved(JS)
|
|
for i=1,#joysticks do
|
|
if joysticks[i]==JS then
|
|
rem(joysticks,i)
|
|
LOG.print("Joystick removed",COLOR.yellow)
|
|
return
|
|
end
|
|
end
|
|
end
|
|
local keyMirror={
|
|
dpup="up",
|
|
dpdown="down",
|
|
dpleft="left",
|
|
dpright="right",
|
|
start="return",
|
|
back="escape",
|
|
}
|
|
function love.gamepadpressed(_,i)
|
|
mouseShow=false
|
|
if SCN.swapping then return end
|
|
if gamepadDown[SCN.cur]then gamepadDown[SCN.cur](i)
|
|
elseif keyDown[SCN.cur]then keyDown[SCN.cur](keyMirror[i]or i)
|
|
elseif i=="back"then SCN.back()
|
|
else WIDGET.gamepadPressed(keyMirror[i]or i)
|
|
end
|
|
end
|
|
function love.gamepadreleased(_,i)
|
|
if SCN.swapping then return end
|
|
if gamepadUp[SCN.cur]then gamepadUp[SCN.cur](i)
|
|
end
|
|
end
|
|
--[[
|
|
function love.joystickpressed(JS,k)
|
|
mouseShow=false
|
|
if SCN.swapping then return end
|
|
if gamepadDown[SCN.cur]then gamepadDown[SCN.cur](i)
|
|
elseif keyDown[SCN.cur]then keyDown[SCN.cur](keyMirror[i]or i)
|
|
elseif i=="back"then SCN.back()
|
|
else WIDGET.gamepadPressed(i)
|
|
end
|
|
end
|
|
function love.joystickreleased(JS,k)
|
|
if SCN.swapping then return end
|
|
if gamepadUp[SCN.cur]then gamepadUp[SCN.cur](i)
|
|
end
|
|
end
|
|
function love.joystickaxis(JS,axis,val)
|
|
|
|
end
|
|
function love.joystickhat(JS,hat,dir)
|
|
|
|
end
|
|
function love.sendData(data)end
|
|
function love.receiveData(id,data)end
|
|
]]
|
|
function love.lowmemory()
|
|
collectgarbage()
|
|
end
|
|
function love.resize(w,h)
|
|
SCR.w,SCR.h,SCR.dpi=w,h,gc.getDPIScale()
|
|
SCR.W,SCR.H=SCR.w*SCR.dpi,SCR.h*SCR.dpi
|
|
SCR.r=h/w
|
|
SCR.rad=(w^2+h^2)^.5
|
|
|
|
if SCR.r>=SCR.h0/SCR.w0 then
|
|
SCR.k=w/SCR.w0
|
|
SCR.x,SCR.y=0,(h-w*SCR.h0/SCR.w0)/2
|
|
else
|
|
SCR.k=h/SCR.h0
|
|
SCR.x,SCR.y=(w-h*SCR.w0/SCR.h0)/2,0
|
|
end
|
|
xOy:setTransformation(w/2,h/2,nil,SCR.k,nil,SCR.w0/2,SCR.h0/2)
|
|
if BG.resize then BG.resize(w,h)end
|
|
|
|
SHADER.warning:send("w",w*SCR.dpi)
|
|
SHADER.warning:send("h",h*SCR.dpi)
|
|
end
|
|
function love.focus(f)
|
|
if f then
|
|
love.timer.step()
|
|
elseif SCN.cur=="play"and SETTING.autoPause then
|
|
pauseGame()
|
|
end
|
|
end
|
|
function love.errorhandler(msg)
|
|
ms.setVisible(true)
|
|
love.audio.stop()
|
|
|
|
local err={"Error:"..msg}
|
|
local trace=debug.traceback("",2)
|
|
local c=2
|
|
for l in string.gmatch(trace,"(.-)\n")do
|
|
if c>2 then
|
|
if not string.find(l,"boot")then
|
|
err[c]=string.gsub(l,"^\t*","")
|
|
c=c+1
|
|
end
|
|
else
|
|
err[2]="Traceback"
|
|
c=3
|
|
end
|
|
end
|
|
DBP(table.concat(err,"\n"),1,c-2)
|
|
gc.reset()
|
|
|
|
local errScrShot
|
|
gc.captureScreenshot(function (_)errScrShot=gc.newImage(_)end)
|
|
gc.present()
|
|
|
|
SFX.fplay("error",SETTING.voc*.8)
|
|
|
|
local BGcolor=rnd()>.026 and{.3,.5,.9}or{.62,.3,.926}
|
|
local needDraw=true
|
|
local count=0
|
|
return function()
|
|
love.event.pump()
|
|
for E,a,b in love.event.poll()do
|
|
if E=="quit"or a=="escape"then
|
|
destroyPlayers()
|
|
return 1
|
|
elseif E=="resize"then
|
|
love.resize(a,b)
|
|
needDraw=true
|
|
elseif E=="focus"then
|
|
needDraw=true
|
|
elseif E=="touchpressed"and b<100 or E=="mousepressed" and a==2 or E=="keypressed"and a=="space"then
|
|
if count<3 then
|
|
count=count+1
|
|
SFX.play("ready")
|
|
else
|
|
local code=loadstring(love.system.getClipboardText())
|
|
if code then
|
|
code()
|
|
SFX.play("reach")
|
|
else
|
|
SFX.play("finesseError")
|
|
end
|
|
count=0
|
|
end
|
|
end
|
|
end
|
|
if needDraw then
|
|
gc.discard()
|
|
gc.clear(BGcolor)
|
|
gc.setColor(1,1,1)
|
|
gc.push("transform")
|
|
gc.replaceTransform(xOy)
|
|
gc.draw(errScrShot,100,365,nil,512/errScrShot:getWidth(),288/errScrShot:getHeight())
|
|
setFont(100)gc.print(":(",100,40,0,1.2)
|
|
setFont(40)gc.printf(text.errorMsg,100,200,SCR.w0-100)
|
|
setFont(20)
|
|
gc.print(SYSTEM.."-"..VERSION_NAME,100,660)
|
|
gc.print("scene:"..SCN.cur,400,660)
|
|
gc.printf(err[1],626,360,1260-626)
|
|
gc.print("TRACEBACK",626,426)
|
|
for i=4,#err-2 do
|
|
gc.print(err[i],626,370+20*i)
|
|
end
|
|
gc.pop()
|
|
gc.present()
|
|
needDraw=false
|
|
end
|
|
love.timer.sleep(.26)
|
|
end
|
|
end
|
|
local devColor={
|
|
COLOR.white,
|
|
COLOR.lMagenta,
|
|
COLOR.lGreen,
|
|
COLOR.lBlue,
|
|
}
|
|
local FPS=love.timer.getFPS
|
|
love.draw,love.update=nil--remove default draw/update
|
|
function love.run()
|
|
local SETTING=SETTING
|
|
local DISCARD=gc.discard
|
|
local PRESENT=gc.present
|
|
|
|
local T=love.timer
|
|
local Timer=T.getTime
|
|
local STEP,GETDelta,WAIT=T.step,T.getDelta,T.sleep
|
|
local mini=love.window.isMinimized
|
|
local PUMP,POLL=love.event.pump,love.event.poll
|
|
|
|
local frameTimeList={}
|
|
|
|
local lastFrame=Timer()
|
|
local lastFreshPow=lastFrame
|
|
local FCT=0--Framedraw counter
|
|
|
|
love.resize(gc.getWidth(),gc.getHeight())
|
|
|
|
--Scene Launch
|
|
if SETTING.appLock then
|
|
SCN.init("calculator")
|
|
else
|
|
SCN.init("load")
|
|
end
|
|
|
|
return function()
|
|
local _
|
|
|
|
lastFrame=Timer()
|
|
|
|
--EVENT
|
|
PUMP()
|
|
for N,a,b,c,d,e in POLL()do
|
|
if love[N]then
|
|
love[N](a,b,c,d,e)
|
|
elseif N=="quit"then
|
|
destroyPlayers()
|
|
return true
|
|
end
|
|
end
|
|
|
|
--UPDATE
|
|
STEP()
|
|
local dt=GETDelta()
|
|
TASK.update()
|
|
VOC.update()
|
|
BG.update(dt)
|
|
SYSFX.update(dt)
|
|
TEXT.update()
|
|
_=Tmr[SCN.cur]if _ then _(dt)end--Scene Updater
|
|
if SCN.swapping then SCN.swapUpdate()end--Scene swapping animation
|
|
WIDGET.update()--Widgets animation
|
|
LOG.update()
|
|
|
|
--DRAW
|
|
if not mini()then
|
|
FCT=FCT+SETTING.frameMul
|
|
if FCT>=100 then
|
|
FCT=FCT-100
|
|
|
|
--Draw background
|
|
BG.draw()
|
|
|
|
gc.push("transform")
|
|
gc.replaceTransform(xOy)
|
|
|
|
--Draw scene contents
|
|
if Pnt[SCN.cur]then Pnt[SCN.cur]()end
|
|
|
|
--Draw widgets
|
|
WIDGET.draw()
|
|
|
|
--Draw cursor
|
|
if mouseShow then
|
|
local r=Timer()*.5
|
|
local R=int(r)%7+1
|
|
_=SKIN.libColor[SETTING.skin[R]]
|
|
gc.setColor(_[1],_[2],_[3],min(1-abs(1-r%1*2),.3))
|
|
gc.draw(TEXTURE.miniBlock[R],mx,my,Timer()%3.1416*4,20,20,spinCenters[R][0][2]+.5,#BLOCKS[R][0]-spinCenters[R][0][1]-.5)
|
|
gc.setColor(1,1,1,.5)gc.circle("fill",mx,my,5)
|
|
gc.setColor(1,1,1)gc.circle("fill",mx,my,3)
|
|
end
|
|
SYSFX.draw()
|
|
TEXT.draw()
|
|
gc.pop()
|
|
|
|
--Draw power info.
|
|
gc.setColor(1,1,1)
|
|
if SETTING.powerInfo then
|
|
gc.draw(infoCanvas,0,0,0,SCR.k)
|
|
end
|
|
|
|
--Draw scene swapping animation
|
|
if SCN.swapping then
|
|
_=SCN.stat
|
|
_.draw(_.time)
|
|
end
|
|
|
|
--Draw network working
|
|
if TASK.netTaskCount>0 then
|
|
setFont(30)
|
|
gc.setColor(COLOR.rainbow(Timer()*5))
|
|
gc.print("E",1250,0,.26+.355*math.sin(Timer()*6.26))
|
|
end
|
|
|
|
--Draw FPS
|
|
gc.setColor(1,1,1)
|
|
setFont(15)
|
|
_=SCR.h
|
|
gc.print(FPS(),5,_-20)
|
|
|
|
--Debug info.
|
|
if devMode then
|
|
gc.setColor(devColor[devMode])
|
|
gc.print("Memory:"..gcinfo(),5,_-40)
|
|
gc.print("Lines:"..FREEROW.getCount(),5,_-60)
|
|
gc.print("Cursor:"..int(mx+.5).." "..int(my+.5),5,_-80)
|
|
gc.print("Voices:"..VOC.getCount(),5,_-100)
|
|
gc.print("Tasks:"..TASK.getCount(),5,_-120)
|
|
ins(frameTimeList,1,dt)rem(frameTimeList,126)
|
|
gc.setColor(1,1,1,.3)
|
|
for i=1,#frameTimeList do
|
|
gc.rectangle("fill",150+2*i,_-20,2,-frameTimeList[i]*4000)
|
|
end
|
|
if devMode==3 then WAIT(.1)
|
|
elseif devMode==4 then WAIT(.5)
|
|
end
|
|
end
|
|
LOG.draw()
|
|
|
|
PRESENT()
|
|
DISCARD()--SPEED UPUPUP!
|
|
end
|
|
end
|
|
|
|
--Fresh power info.
|
|
if Timer()-lastFreshPow>2.6 then
|
|
if SETTING.powerInfo and LOADED then
|
|
updatePowerInfo()
|
|
lastFreshPow=Timer()
|
|
end
|
|
if gc.getWidth()~=SCR.w then
|
|
love.resize(gc.getWidth(),gc.getHeight())
|
|
LOG.print("Screen Resized",COLOR.yellow)
|
|
end
|
|
end
|
|
|
|
--Keep 60fps
|
|
_=Timer()-lastFrame
|
|
if _<.016 then WAIT(.016-_)end
|
|
while Timer()-lastFrame<1/60-5e-6 do WAIT(0)end
|
|
end
|
|
end |