From 514f0a17b5a94467012005198d998d6fd258ada2 Mon Sep 17 00:00:00 2001 From: MrZ_26 <1046101471@qq.com> Date: Mon, 12 Jun 2023 11:42:17 +0800 Subject: [PATCH 01/14] =?UTF-8?q?=E5=B9=B2=E6=8E=89=E6=89=80=E6=9C=89?= =?UTF-8?q?=E7=9A=84goto=E6=9D=A5=E6=B5=8B=E8=AF=95love.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.lua | 55 ++++---- parts/bot/bot_9s.lua | 13 +- parts/data.lua | 23 ++-- parts/eventsets/secret_grade.lua | 12 +- parts/player/player.lua | 207 +++++++++++++++++-------------- parts/player/seqGenerators.lua | 29 +++-- parts/scenes/app_UTTT.lua | 8 +- parts/scenes/app_link.lua | 14 ++- parts/scenes/app_triple.lua | 46 +++---- parts/scenes/customGame.lua | 31 ++--- parts/scenes/custom_field.lua | 15 ++- parts/scenes/game.lua | 12 +- parts/scenes/net_game.lua | 12 +- 13 files changed, 265 insertions(+), 212 deletions(-) diff --git a/main.lua b/main.lua index 794b0957..41513e85 100644 --- a/main.lua +++ b/main.lua @@ -569,36 +569,37 @@ for _,fileName in next,fs.getDirectoryItems('replay') do player, fileData=STRING.readLine(fileData) if player=="Local Player" then player="Stacker" end local success success,fileData=pcall(love.data.decompress,'string','zlib',fileData) - if not success then goto BREAK_cannotParse end - seed, fileData=STRING.readLine(fileData) - setting,fileData=STRING.readLine(fileData)setting=JSON.decode(setting) - mod, fileData=STRING.readLine(fileData)mod=JSON.decode(mod) - if - not setting or - not mod or - not mode or - #mode==0 - then goto BREAK_cannotParse end + repeat + if not success then break end-- goto BREAK_cannotParse + seed, fileData=STRING.readLine(fileData) + setting,fileData=STRING.readLine(fileData)setting=JSON.decode(setting) + mod, fileData=STRING.readLine(fileData)mod=JSON.decode(mod) + if + not setting or + not mod or + not mode or + #mode==0 + then break end-- goto BREAK_cannotParse - fs.remove('replay/'..fileName) - local newName=fileName:sub(1,10)..fileName:sub(15) - fs.write('replay/'..newName, - love.data.compress('string','zlib', - JSON.encode{ - date=date, - mode=mode, - version=version, - player=player, - seed=seed, - setting=setting, - mod=mod, - }.."\n".. - fileData + fs.remove('replay/'..fileName) + local newName=fileName:sub(1,10)..fileName:sub(15) + fs.write('replay/'..newName, + love.data.compress('string','zlib', + JSON.encode{ + date=date, + mode=mode, + version=version, + player=player, + seed=seed, + setting=setting, + mod=mod, + }.."\n".. + fileData + ) ) - ) - fileName=newName + fileName=newName + until true-- ::BREAK_cannotParse:: end - ::BREAK_cannotParse:: local rep=DATA.parseReplay('replay/'..fileName) table.insert(REPLAY,rep) end diff --git a/parts/bot/bot_9s.lua b/parts/bot/bot_9s.lua index ac13f8ba..5f91e2cc 100644 --- a/parts/bot/bot_9s.lua +++ b/parts/bot/bot_9s.lua @@ -65,14 +65,19 @@ local function _getScore(field,cb,cy) local hole=0 for i=cy+#cb-1,cy,-1 do + local full=true for j=1,10 do if field[i][j]==0 then - goto CONTINUE_notFull + -- goto CONTINUE_notFull + full=false + break end end - discardRow(rem(field,i)) - clear=clear+1 - ::CONTINUE_notFull:: + if full then + -- ::CONTINUE_notFull:: + discardRow(rem(field,i)) + clear=clear+1 + end end if #field==0 then-- PC return 1e99 diff --git a/parts/data.lua b/parts/data.lua index 9498026b..bd8ff4ce 100644 --- a/parts/data.lua +++ b/parts/data.lua @@ -376,22 +376,26 @@ function DATA.parseReplay(fileName,ifFull) return DATA.parseReplayData(fileName,fileData,ifFull) end function DATA.parseReplayData(fileName,fileData,ifFull) - local success,metaData,rep + local success,metaData + local rep={-- unavailable replay object + fileName=fileName, + available=false, + } - if not (fileData and #fileData>0) then goto BREAK_cannotParse end + if not (fileData and #fileData>0) then return rep end-- goto BREAK_cannotParse -- Decompress file success,fileData=pcall(love.data.decompress,'string','zlib',fileData) - if not success then goto BREAK_cannotParse end + if not success then return rep end-- goto BREAK_cannotParse -- Load metadata metaData,fileData=STRING.readLine(fileData) metaData=JSON.decode(metaData) - if not metaData then goto BREAK_cannotParse end + if not metaData then return rep end-- goto BREAK_cannotParse -- Convert ancient replays metaData.mode=MODE_UPDATE_MAP[metaData.mode] or metaData.mode - if not MODES[metaData.mode] then goto BREAK_cannotParse end + if not MODES[metaData.mode] then return rep end-- goto BREAK_cannotParse -- Create replay object rep={ @@ -409,13 +413,6 @@ function DATA.parseReplayData(fileName,fileData,ifFull) tasUsed=metaData.tasUsed, } if ifFull then rep.data=fileData end - do return rep end - - -- Create unavailable replay object - ::BREAK_cannotParse:: - return { - fileName=fileName, - available=false, - } + return rep end return DATA diff --git a/parts/eventsets/secret_grade.lua b/parts/eventsets/secret_grade.lua index 81b42f1a..c3d17d09 100644 --- a/parts/eventsets/secret_grade.lua +++ b/parts/eventsets/secret_grade.lua @@ -76,15 +76,17 @@ return { D.rankPts=1 for i=1,#P.field do local h=getOpenHole(i) + local flag for j=1,10 do - if P.field[i][j]>0 and h==j then goto post_pts_calc end - if P.field[i][j]==0 and h~=j then goto post_pts_calc end + if P.field[i][j]>0 and h==j then flag=true break end-- goto post_pts_calc + if P.field[i][j]==0 and h~=j then flag=true break end-- goto post_pts_calc end - if i==#P.field then goto post_pts_calc end - if P.field[i+1][h]==0 then goto post_pts_calc end + if flag then break end + if i==#P.field then break end-- goto post_pts_calc + if P.field[i+1][h]==0 then break end-- goto post_pts_calc D.rankPts=D.rankPts+1 end - ::post_pts_calc:: + -- ::post_pts_calc:: generateGuide(D.rankPts+20) end } diff --git a/parts/player/player.lua b/parts/player/player.lua index 34f70158..4e6d958b 100644 --- a/parts/player/player.lua +++ b/parts/player/player.lua @@ -77,16 +77,19 @@ function Player:createLockFX() for i=1,#CB do local y=self.curY+i-1 local L=self.clearedRow + local skip for j=1,#L do - if L[j]==y then goto CONTINUE_skip end + if L[j]==y then skip=true break end-- goto CONTINUE_skip end - y=-30*y - for j=1,#CB[1] do - if CB[i][j] then - ins(self.lockFX,{30*(self.curX+j-2),y,0,t}) + if not skip then + y=-30*y + for j=1,#CB[1] do + if CB[i][j] then + ins(self.lockFX,{30*(self.curX+j-2),y,0,t}) + end end end - ::CONTINUE_skip:: + -- ::CONTINUE_skip:: end end end @@ -1041,16 +1044,20 @@ function Player:_checkClear(field,start,height,CB,CX) h=h+1 -- Row filled + local full=true for x=1,10 do if field[h][x]<=0 then - goto CONTINUE_notFull + full=false + break-- goto CONTINUE_notFull end end - cc=cc+1 - if field[h].garbage then gbcc=gbcc+1 end - ins(self.clearingRow,h-cc+1) - ins(self.clearedRow,h) - ::CONTINUE_notFull:: + if full then + cc=cc+1 + if field[h].garbage then gbcc=gbcc+1 end + ins(self.clearingRow,h-cc+1) + ins(self.clearedRow,h) + end + -- ::CONTINUE_notFull:: end return cc,gbcc end @@ -1265,20 +1272,24 @@ function Player:hold_norm(ifpre) y=y+(#C.bk-#H.bk)*.5 local iki=phyHoldKickX[x==int(x)] + local success for Y=int(y),ceil(y+.5) do for i=1,#iki do local X=x+iki[i] if not self:ifoverlap(H.bk,X,Y) then x,y=X,Y - goto BREAK_success + success=true + break-- goto BREAK_success end end end -- All test failed, interrupt with sound + if not success then SFX.play('drop_cancel') do return end + end -- - ::BREAK_success:: + -- ::BREAK_success:: self.spinLast=false @@ -1332,20 +1343,24 @@ function Player:hold_swap(ifpre) y=y+(#C.bk-#H.bk)*.5 local iki=phyHoldKickX[x==int(x)] + local success for Y=int(y),ceil(y+.5) do for i=1,#iki do local X=x+iki[i] if not self:ifoverlap(H.bk,X,Y) then x,y=X,Y - goto BREAK_success + success=true + break-- goto BREAK_success end end end -- All test failed, interrupt with sound + if not success then SFX.play('finesseError') do return end + end -- - ::BREAK_success:: + -- ::BREAK_success:: self.spinLast=false @@ -2508,90 +2523,92 @@ local function update_alive(P,dt) local stopAtFalling -- Falling animation - if P.falling>0 then - stopAtFalling=true - P:_updateFalling(P.falling-1) + repeat if P.falling>0 then - goto THROW_stop - end - end - - -- Update block state - if P.control then - -- Try spawn new block - if not P.cur then - if not stopAtFalling and P.waiting>0 then - P.waiting=P.waiting-1 + stopAtFalling=true + P:_updateFalling(P.falling-1) + if P.falling>0 then + break-- goto THROW_stop end - if P.waiting<=0 then - P:popNext() - end - goto THROW_stop end - -- Natural block falling - if P.cur then - if P.curY>P.ghoY then - local D=P.dropDelay - local dist-- Drop distance - if D>1 then - D=D-1 - if P.keyPressing[7] and P.downing>=ENV.sddas then - D=D-ceil(ENV.drop/ENV.sdarr) - end - if D<=0 then - dist=1 - P.dropDelay=(D-1)%ENV.drop+1 - else - P.dropDelay=D - goto THROW_stop - end - elseif D==1 then-- We don't know why dropDelay is 1, so checking ENV.drop>1 is neccessary - if ENV.drop>1 and P.downing>=ENV.sddas and (P.downing-ENV.sddas)%ENV.sdarr==0 then - dist=2 - else - dist=1 - end - -- Reset drop delay - P.dropDelay=ENV.drop - else-- High gravity case (>1G) - -- Add extra 1 if time to auto softdrop - if P.downing>ENV.sddas and (P.downing-ENV.sddas)%ENV.sdarr==0 then - dist=1/D+1 - else - dist=1/D - end + -- Update block state + if P.control then + -- Try spawn new block + if not P.cur then + if not stopAtFalling and P.waiting>0 then + P.waiting=P.waiting-1 end + if P.waiting<=0 then + P:popNext() + end + break-- goto THROW_stop + end - -- Limit dropping to ghost at max - dist=min(dist,P.curY-P.ghoY) - - -- Drop and create FXs - if ENV.moveFX and ENV.block and dist>1 then - for _=1,dist do - P:createMoveFX('down') - P.curY=P.curY-1 + -- Natural block falling + if P.cur then + if P.curY>P.ghoY then + local D=P.dropDelay + local dist-- Drop distance + if D>1 then + D=D-1 + if P.keyPressing[7] and P.downing>=ENV.sddas then + D=D-ceil(ENV.drop/ENV.sdarr) + end + if D<=0 then + dist=1 + P.dropDelay=(D-1)%ENV.drop+1 + else + P.dropDelay=D + break-- goto THROW_stop + end + elseif D==1 then-- We don't know why dropDelay is 1, so checking ENV.drop>1 is neccessary + if ENV.drop>1 and P.downing>=ENV.sddas and (P.downing-ENV.sddas)%ENV.sdarr==0 then + dist=2 + else + dist=1 + end + -- Reset drop delay + P.dropDelay=ENV.drop + else-- High gravity case (>1G) + -- Add extra 1 if time to auto softdrop + if P.downing>ENV.sddas and (P.downing-ENV.sddas)%ENV.sdarr==0 then + dist=1/D+1 + else + dist=1/D + end end + + -- Limit dropping to ghost at max + dist=min(dist,P.curY-P.ghoY) + + -- Drop and create FXs + if ENV.moveFX and ENV.block and dist>1 then + for _=1,dist do + P:createMoveFX('down') + P.curY=P.curY-1 + end + else + P.curY=P.curY-dist + end + + P.spinLast=false + P:freshBlock('fresh') + P:checkTouchSound() else - P.curY=P.curY-dist - end - - P.spinLast=false - P:freshBlock('fresh') - P:checkTouchSound() - else - P.lockDelay=P.lockDelay-1 - if P.lockDelay>=0 then - goto THROW_stop - end - P:drop(true) - if P.bot then - P.bot:lockWrongPlace() + P.lockDelay=P.lockDelay-1 + if P.lockDelay>=0 then + break-- goto THROW_stop + end + P:drop(true) + if P.bot then + P.bot:lockWrongPlace() + end end end end - end - ::THROW_stop:: + until true + -- ::THROW_stop:: -- B2B bar animation if P.b2b1~=P.b2b then @@ -2911,16 +2928,20 @@ function Player:lose(force) self:dropPosition() freshPlayerPosition('update') + local finished=true for i=1,#PLY_ALIVE-1 do if PLY_ALIVE[i].group==0 or PLY_ALIVE[i].group~=PLY_ALIVE[i+1].group then - goto BREAK_notFinished + finished=false + break-- goto BREAK_notFinished end end -- Only 1 people or only 1 team survived, they win - for i=1,#PLY_ALIVE do - PLY_ALIVE[i]:win() + if finished then + for i=1,#PLY_ALIVE do + PLY_ALIVE[i]:win() + end end - ::BREAK_notFinished:: + -- ::BREAK_notFinished:: end end --------------------------<\Event>-------------------------- diff --git a/parts/player/seqGenerators.lua b/parts/player/seqGenerators.lua index 191ba3be..0de68d8f 100644 --- a/parts/player/seqGenerators.lua +++ b/parts/player/seqGenerators.lua @@ -65,13 +65,15 @@ local seqGenerators={ local r for _=1,hisLen do-- Reroll up to [hisLen] times r=rndGen:random(len) + local rollAgain for i=1,hisLen do if r==history[i] then - goto CONTINUE_rollAgain + rollAgain=true + break-- goto CONTINUE_rollAgain end end - do break end - ::CONTINUE_rollAgain:: + if not rollAgain then break end + -- ::CONTINUE_rollAgain:: end if history[1]~=0 then P:getNext(seq0[r]) @@ -128,16 +130,21 @@ local seqGenerators={ -- print"======================" -- Pick a mino from pool local tryTime=0 - ::REPEAT_pickAgain:: - local r=_poolPick()-- Random mino-index in pool - for i=1,len do - if r==history[i] then - tryTime=tryTime+1 - if tryTime1 and not field[ruy-1][x2] do ruy=ruy-1 end while rdy1 and not field[y2][dlx-1] do dlx=dlx-1 end while drx2 then - merged=true - self.board=b1 - b1[y][x]=cur+1 + repeat-- ::REPEAT_merge:: + local repeating + local cur=self.board[y][x] + local b1=TABLE.shift(self.board) + self.mergedTiles={} + local count=self:merge(b1,cur,y,x) + if count>2 then + merged=true + self.board=b1 + b1[y][x]=cur+1 - if cur+1>self.maxTile then - self.maxTile=cur+1 - if self.maxTile>=6 then - ins(self.progress,("%s - %.3fs"):format(self.maxTile,TIME()-player.startTime)) + if cur+1>self.maxTile then + self.maxTile=cur+1 + if self.maxTile>=6 then + ins(self.progress,("%s - %.3fs"):format(self.maxTile,TIME()-player.startTime)) + end + SFX.play('reach') end - SFX.play('reach') - end - local getScore=4^cur*count - self.score=self.score+getScore - TEXT.show(getScore,player.x+self.selectX*100-50,player.y+self.selectY*100-50,40,'score',1.626/math.log(getScore,3)) - for i=1,#self.mergedTiles do - newMergeFX(self.mergedTiles[i][1],self.mergedTiles[i][2],cur+1) + local getScore=4^cur*count + self.score=self.score+getScore + TEXT.show(getScore,player.x+self.selectX*100-50,player.y+self.selectY*100-50,40,'score',1.626/math.log(getScore,3)) + for i=1,#self.mergedTiles do + newMergeFX(self.mergedTiles[i][1],self.mergedTiles[i][2],cur+1) + end + repeating=true-- goto REPEAT_merge end - goto REPEAT_merge - end + until not repeating ins(self.nexts,self:newTile()) diff --git a/parts/scenes/customGame.lua b/parts/scenes/customGame.lua index e928bf84..b134259f 100644 --- a/parts/scenes/customGame.lua +++ b/parts/scenes/customGame.lua @@ -104,20 +104,23 @@ function scene.keyDown(key,isRep) elseif key=='v' and kb.isDown('lctrl','rctrl') or key=='cV' then local str=sys.getClipboardText() local args=str:sub((str:find(":") or 0)+1):split("!") - if #args<4 then goto THROW_fail end - if not ( - DATA.pasteQuestArgs(args[1]) and - DATA.pasteSequence(args[2]) and - DATA.pasteMission(args[3]) - ) then goto THROW_fail end - TABLE.cut(FIELD) - FIELD[1]=DATA.newBoard() - for i=4,#args do - if args[i]:find("%S") and not DATA.pasteBoard(args[i],i-3) and i<#args then goto THROW_fail end - end - MES.new('check',text.importSuccess) - do return end - ::THROW_fail::MES.new('error',text.dataCorrupted) + repeat + if #args<4 then break end-- goto THROW_fail + if not ( + DATA.pasteQuestArgs(args[1]) and + DATA.pasteSequence(args[2]) and + DATA.pasteMission(args[3]) + ) then break end-- goto THROW_fail + TABLE.cut(FIELD) + FIELD[1]=DATA.newBoard() + for i=4,#args do + if args[i]:find("%S") and not DATA.pasteBoard(args[i],i-3) and i<#args then break end-- goto THROW_fail + end + MES.new('check',text.importSuccess) + return + until true + -- ::THROW_fail:: + MES.new('error',text.dataCorrupted) else return true end diff --git a/parts/scenes/custom_field.lua b/parts/scenes/custom_field.lua index 5bac9175..ac7bc33b 100644 --- a/parts/scenes/custom_field.lua +++ b/parts/scenes/custom_field.lua @@ -195,14 +195,17 @@ function scene.keyDown(key) local F=FIELD[page] local cleared=false for i=#F,1,-1 do + local full for j=1,10 do - if F[i][j]<=0 then goto CONTINUE_notFull end + if F[i][j]<=0 then full=false break end-- goto CONTINUE_notFull end - cleared=true - SYSFX.newShade(3,200,660-30*i,300,30) - SYSFX.newRectRipple(3,200,660-30*i,300,30) - rem(F,i) - ::CONTINUE_notFull:: + if full then + cleared=true + SYSFX.newShade(3,200,660-30*i,300,30) + SYSFX.newRectRipple(3,200,660-30*i,300,30) + rem(F,i) + end + -- ::CONTINUE_notFull:: end if cleared then SFX.play('clear_3',.8) diff --git a/parts/scenes/game.lua b/parts/scenes/game.lua index 66937854..a0dad185 100644 --- a/parts/scenes/game.lua +++ b/parts/scenes/game.lua @@ -195,15 +195,19 @@ function scene.touchMove() for n=1,#keys do local B=keys[n] if B.ava then + local nextKey for i=1,#L,2 do if (L[i]-B.x)^2+(L[i+1]-B.y)^2<=B.r^2 then - goto CONTINUE_nextKey + nextKey=true + break-- goto CONTINUE_nextKey end end - PLAYERS[1]:releaseKey(n) - VK.release(n) + if not nextKey then + PLAYERS[1]:releaseKey(n) + VK.release(n) + end + -- ::CONTINUE_nextKey:: end - ::CONTINUE_nextKey:: end end function scene.keyDown(key,isRep) diff --git a/parts/scenes/net_game.lua b/parts/scenes/net_game.lua index 60a57ffc..c3b731f7 100644 --- a/parts/scenes/net_game.lua +++ b/parts/scenes/net_game.lua @@ -109,15 +109,19 @@ function scene.touchMove() for n=1,#keys do local B=keys[n] if B.ava then + local nextKey for i=1,#L,2 do if (L[i]-B.x)^2+(L[i+1]-B.y)^2<=B.r^2 then - goto CONTINUE_nextKey + nextKey=true + break-- goto CONTINUE_nextKey end end - PLAYERS[1]:releaseKey(n) - VK.release(n) + if not nextKey then + PLAYERS[1]:releaseKey(n) + VK.release(n) + end + -- ::CONTINUE_nextKey:: end - ::CONTINUE_nextKey:: end end function scene.keyDown(key,isRep) From 7772c9b424e739b6c081c22a3454ceb3834dc779 Mon Sep 17 00:00:00 2001 From: MrZ_26 <1046101471@qq.com> Date: Mon, 12 Jun 2023 11:45:58 +0800 Subject: [PATCH 02/14] =?UTF-8?q?=E8=8B=A5=E4=B8=BALinux=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E5=88=99override=E6=8E=89=E5=8E=9F=E6=9D=A5=E7=9A=84file.read?= =?UTF-8?q?=EF=BC=8C=E5=8A=A0=E4=B8=80=E4=B8=AAgetInfo=E7=A1=AE=E4=BF=9D?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=AD=98=E5=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/conf.lua b/conf.lua index f66d41bf..d949e037 100644 --- a/conf.lua +++ b/conf.lua @@ -2,6 +2,15 @@ SYSTEM=love._os if SYSTEM=='OS X' then SYSTEM='macOS' end MOBILE=SYSTEM=='Android' or SYSTEM=='iOS' FNNS=SYSTEM:find'\79\83'-- What does FNSF stand for? IDK so don't ask me lol +if SYSTEM=='Linux' then + local oldRead=love.filesystem.read + function love.filesystem.read(name,size) + if love.filesystem.getInfo(name) then + return oldRead(name,size) + end + end +end + function love.conf(t) local identity='Techmino' local msaa=0 From 4ec1f7c5c83892413d58f03a26f25502f7b4e2f1 Mon Sep 17 00:00:00 2001 From: ParticleG Date: Mon, 12 Jun 2023 12:10:46 +0800 Subject: [PATCH 03/14] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=81=97=E6=BC=8Fbreak?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.lua | 60 ++++++++++++++++++++--------------------- parts/player/player.lua | 34 +++++++++++------------ 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/main.lua b/main.lua index 41513e85..6905035c 100644 --- a/main.lua +++ b/main.lua @@ -10,8 +10,7 @@ Instructions: 1. I made a framework called Zframework, *most* code in Zframework are not directly relevant to game; 2. "xxx" are texts for reading by player, 'xxx' are string values just used in program; - 3. Some goto statement are used for better performance. All goto-labes have detailed names so don't be afraid; - 4. Except "gcinfo" function of lua itself, other "gc" are short for "graphics"; + 3. Except "gcinfo" function of lua itself, other "gc" are short for "graphics"; ]]-- @@ -560,7 +559,7 @@ applySettings() -- Load replays for _,fileName in next,fs.getDirectoryItems('replay') do - if fileName:sub(12,12):match("[a-zA-Z]") then + while fileName:sub(12,12):match("[a-zA-Z]") do local date,mode,version,player,seed,setting,mod local fileData=fs.read('replay/'..fileName) date, fileData=STRING.readLine(fileData)date=date:gsub("[a-zA-Z]","") @@ -569,36 +568,35 @@ for _,fileName in next,fs.getDirectoryItems('replay') do player, fileData=STRING.readLine(fileData) if player=="Local Player" then player="Stacker" end local success success,fileData=pcall(love.data.decompress,'string','zlib',fileData) - repeat - if not success then break end-- goto BREAK_cannotParse - seed, fileData=STRING.readLine(fileData) - setting,fileData=STRING.readLine(fileData)setting=JSON.decode(setting) - mod, fileData=STRING.readLine(fileData)mod=JSON.decode(mod) - if - not setting or - not mod or - not mode or - #mode==0 - then break end-- goto BREAK_cannotParse + if not success then break end + seed, fileData=STRING.readLine(fileData) + setting,fileData=STRING.readLine(fileData)setting=JSON.decode(setting) + mod, fileData=STRING.readLine(fileData)mod=JSON.decode(mod) + if + not setting or + not mod or + not mode or + #mode==0 + then break end - fs.remove('replay/'..fileName) - local newName=fileName:sub(1,10)..fileName:sub(15) - fs.write('replay/'..newName, - love.data.compress('string','zlib', - JSON.encode{ - date=date, - mode=mode, - version=version, - player=player, - seed=seed, - setting=setting, - mod=mod, - }.."\n".. - fileData - ) + fs.remove('replay/'..fileName) + local newName=fileName:sub(1,10)..fileName:sub(15) + fs.write('replay/'..newName, + love.data.compress('string','zlib', + JSON.encode{ + date=date, + mode=mode, + version=version, + player=player, + seed=seed, + setting=setting, + mod=mod, + }.."\n".. + fileData ) - fileName=newName - until true-- ::BREAK_cannotParse:: + ) + fileName=newName + break end local rep=DATA.parseReplay('replay/'..fileName) table.insert(REPLAY,rep) diff --git a/parts/player/player.lua b/parts/player/player.lua index 4e6d958b..58dbbfc2 100644 --- a/parts/player/player.lua +++ b/parts/player/player.lua @@ -1279,17 +1279,17 @@ function Player:hold_norm(ifpre) if not self:ifoverlap(H.bk,X,Y) then x,y=X,Y success=true - break-- goto BREAK_success + break end end + if success then + break + end end - -- All test failed, interrupt with sound - if not success then + if not success then -- All test failed, interrupt with sound SFX.play('drop_cancel') do return end end - -- - -- ::BREAK_success:: self.spinLast=false @@ -1344,23 +1344,23 @@ function Player:hold_swap(ifpre) local iki=phyHoldKickX[x==int(x)] local success - for Y=int(y),ceil(y+.5) do - for i=1,#iki do - local X=x+iki[i] - if not self:ifoverlap(H.bk,X,Y) then - x,y=X,Y - success=true - break-- goto BREAK_success + for Y=int(y),ceil(y+.5) do + for i=1,#iki do + local X=x+iki[i] + if not self:ifoverlap(H.bk,X,Y) then + x,y=X,Y + success=true + break + end + end + if success then + break end end - end - -- All test failed, interrupt with sound - if not success then + if not success then -- All test failed, interrupt with sound SFX.play('finesseError') do return end end - -- - -- ::BREAK_success:: self.spinLast=false From aff7ffb2c434935915495d2724414cb5ebabaf05 Mon Sep 17 00:00:00 2001 From: MrZ_26 <1046101471@qq.com> Date: Mon, 12 Jun 2023 12:16:06 +0800 Subject: [PATCH 04/14] =?UTF-8?q?=E5=B0=8F=E4=BF=AE=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.lua | 8 +++----- parts/player/player.lua | 12 ++++-------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/main.lua b/main.lua index 6905035c..a3915726 100644 --- a/main.lua +++ b/main.lua @@ -559,14 +559,13 @@ applySettings() -- Load replays for _,fileName in next,fs.getDirectoryItems('replay') do - while fileName:sub(12,12):match("[a-zA-Z]") do + if fileName:sub(12,12):match("[a-zA-Z]") then repeat local date,mode,version,player,seed,setting,mod - local fileData=fs.read('replay/'..fileName) + local success,fileData=true,fs.read('replay/'..fileName) date, fileData=STRING.readLine(fileData)date=date:gsub("[a-zA-Z]","") mode, fileData=STRING.readLine(fileData)mode=MODE_UPDATE_MAP[mode] or mode version,fileData=STRING.readLine(fileData) player, fileData=STRING.readLine(fileData) if player=="Local Player" then player="Stacker" end - local success success,fileData=pcall(love.data.decompress,'string','zlib',fileData) if not success then break end seed, fileData=STRING.readLine(fileData) @@ -596,8 +595,7 @@ for _,fileName in next,fs.getDirectoryItems('replay') do ) ) fileName=newName - break - end + until true end local rep=DATA.parseReplay('replay/'..fileName) table.insert(REPLAY,rep) end diff --git a/parts/player/player.lua b/parts/player/player.lua index 58dbbfc2..748c72d0 100644 --- a/parts/player/player.lua +++ b/parts/player/player.lua @@ -1282,13 +1282,11 @@ function Player:hold_norm(ifpre) break end end - if success then - break - end + if success then break end end if not success then -- All test failed, interrupt with sound SFX.play('drop_cancel') - do return end + return end self.spinLast=false @@ -1353,13 +1351,11 @@ function Player:hold_swap(ifpre) break end end - if success then - break - end + if success then break end end if not success then -- All test failed, interrupt with sound SFX.play('finesseError') - do return end + return end self.spinLast=false From 886adc3534b952f3fe3a739326b66979733011a4 Mon Sep 17 00:00:00 2001 From: ParticleG Date: Mon, 12 Jun 2023 12:38:56 +0800 Subject: [PATCH 05/14] - Only build Core --- .github/workflows/main.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a96e8aee..5360ad68 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -143,7 +143,8 @@ jobs: build-android: runs-on: ubuntu-latest needs: [get-info, build-core, auto-test] - if: github.event_name != 'pull_request' + # if: github.event_name != 'pull_request' + if: ${{ !always() }} env: OUTPUT_FOLDER: ./build RELEASE_FOLDER: ./release @@ -216,7 +217,8 @@ jobs: build-ios: runs-on: macos-latest needs: [get-info, build-core, auto-test] - if: github.event_name != 'pull_request' + # if: github.event_name != 'pull_request' + if: ${{ !always() }} env: OUTPUT_FOLDER: ./build RELEASE_FOLDER: ./release @@ -296,7 +298,8 @@ jobs: build-linux: runs-on: ubuntu-latest - needs: [get-info, build-core, auto-test] + # needs: [get-info, build-core, auto-test] + if: ${{ !always() }} env: OUTPUT_FOLDER: ./build RELEASE_FOLDER: ./release @@ -380,7 +383,8 @@ jobs: build-macos-appstore: runs-on: macos-latest needs: [get-info, build-core, auto-test] - if: github.event_name != 'pull_request' + # if: github.event_name != 'pull_request' + if: ${{ !always() }} env: OUTPUT_FOLDER: ./build RELEASE_FOLDER: ./release @@ -464,7 +468,8 @@ jobs: build-macos-portable: runs-on: macos-latest needs: [get-info, build-core, auto-test] - if: github.event_name != 'pull_request' + # if: github.event_name != 'pull_request' + if: ${{ !always() }} env: OUTPUT_FOLDER: ./build RELEASE_FOLDER: ./release @@ -560,6 +565,7 @@ jobs: build-windows: runs-on: windows-latest needs: [get-info, build-core, auto-test] + if: ${{ !always() }} env: OUTPUT_FOLDER: ./build RELEASE_FOLDER: ./release From 1e76b8e533b57aa0dbec7a9d27982a370203623f Mon Sep 17 00:00:00 2001 From: ParticleG Date: Mon, 12 Jun 2023 12:53:53 +0800 Subject: [PATCH 06/14] =?UTF-8?q?=E6=A3=80=E6=B5=8B=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E6=A0=87=E8=AF=86=E4=B8=BAWeb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/main.yml | 2 +- conf.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5360ad68..2adc6826 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -298,7 +298,7 @@ jobs: build-linux: runs-on: ubuntu-latest - # needs: [get-info, build-core, auto-test] + needs: [get-info, build-core, auto-test] if: ${{ !always() }} env: OUTPUT_FOLDER: ./build diff --git a/conf.lua b/conf.lua index d949e037..a62defa6 100644 --- a/conf.lua +++ b/conf.lua @@ -2,7 +2,7 @@ SYSTEM=love._os if SYSTEM=='OS X' then SYSTEM='macOS' end MOBILE=SYSTEM=='Android' or SYSTEM=='iOS' FNNS=SYSTEM:find'\79\83'-- What does FNSF stand for? IDK so don't ask me lol -if SYSTEM=='Linux' then +if SYSTEM=='Web' then local oldRead=love.filesystem.read function love.filesystem.read(name,size) if love.filesystem.getInfo(name) then From d22aa81fa06ca5b09e325c7f3736d4cba7cab732 Mon Sep 17 00:00:00 2001 From: ParticleG Date: Wed, 14 Jun 2023 14:35:08 +0800 Subject: [PATCH 07/14] Add polyfill.lua for fallback support --- conf.lua | 1 + polyfill.lua | 3391 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3392 insertions(+) create mode 100644 polyfill.lua diff --git a/conf.lua b/conf.lua index a62defa6..7ade3138 100644 --- a/conf.lua +++ b/conf.lua @@ -3,6 +3,7 @@ MOBILE=SYSTEM=='Android' or SYSTEM=='iOS' FNNS=SYSTEM:find'\79\83'-- What does FNSF stand for? IDK so don't ask me lol if SYSTEM=='Web' then + POLYFILL = require"polyfill" local oldRead=love.filesystem.read function love.filesystem.read(name,size) if love.filesystem.getInfo(name) then diff --git a/polyfill.lua b/polyfill.lua new file mode 100644 index 00000000..093a710e --- /dev/null +++ b/polyfill.lua @@ -0,0 +1,3391 @@ +-- Written by Rabia Alhaffar in 24/February/2021 +-- polyfill.lua, Polyfills for Lua and LuaJIT in one file! +-- Updated: 11/April/2021 +--[[ +MIT License + +Copyright (c) 2021 - 2022 Rabia Alhaffar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +]] + +-- require +if (not require) and package then + require = function(p) + if package.loaded[p] then + return package.loaded[p] + else + return package.searchpath(p, "./?/?.lua;./?.lua;./?.lc;./"..package.loaddir.."/?/init.lua"..";./"..package.loaddir.."/?.lua") + end + end +end + +local polyfill = { + _VERSION = 0.1, + _AUTHOR = "Rabia Alhaffar (steria773/@Rabios)", + _AUTHOR_URL = "https://github.com/Rabios", + _URL = "https://github.com/Rabios/polyfill.lua", + _LICENSE = "MIT", + _DATE = "3/March/2021", + _LUAJIT = ((require("jit") or jit) and true or false), +} + +local ffi = ((require("ffi") or require("luaffi") or ffi) or nil) --> Do we have FFI? + +if not _VERSION then + _VERSION = "Lua 5.1" +end + +-- module: ffi +-- Partial FFI polyfill for LuaJIT (And PUC-RIO's Lua if yours have FFI installed) +if ffi then + -- ffi.string + if not ffi.string then + ffi.string = function(s) + local str = ffi.new("char[?]", #s) + ffi.copy(str, s) + return str + end + end + + -- ffi.os + if polyfill._LUAJIT then + if not ffi.os then + ffi.os = (require("jit").os or jit.os) + end + end + + -- ffi.arch + if not ffi.arch then + if (0xfffffffff == 0xffffffff) then + ffi.arch = "x86" + else + ffi.arch = "x64" + end + end +end + +-- module: Runtime (Global functions) +-- Functions +-- setglobal +if not setglobal then + setglobal = function(var, val) + _G[var] = val + end +end + +-- getglobal +if not getglobal then + getglobal = function(var) + return _G[var] + end +end + +-- rawgetglobal +if not rawgetglobal then + rawgetglobal = function(var) + return _G[var] + end +end + +-- rawsetglobal +if not rawsetglobal then + rawsetglobal = function(var, val) + _G[var] = val + end +end + +-- globals +if not globals then + globals = function(t) + if not t then + return _G + else + _G = t + end + end +end + +-- newtag +if not newtag then + newtag = function() + return { __index = self } + end +end + +-- setfallback +if not setfallback then + setfallback = function(fname, f) + _G[fname] = f + end +end + +-- select +if not select then + select = function(n, ...) + local args = { ... } + return args[n] + end +end + +-- _ALERT +if not _ALERT then + _ALERT = function(msg) + local n = select("#", msg) + for i = 1, n do + local v = tostring(select(i, msg)) + io.stderr:write(v) + if i ~= n then + io.stderr:write("\t") + end + end + io.stderr:write("\n") + io.stderr:flush() + end +end + +-- error +if not error then + error = function(msg) + coroutine.yield(msg) + end +end + +-- print +if not print then + print = function(...) + local n = select("#", ...) + for i = 1, n do + local v = tostring(select(i, ...)) + io.write(v) + if i ~= n then + io.write("\t") + end + end + io.write("\n") + io.flush() + end +end + +-- next +if not next then + next = function(t, k) + local m = getmetatable(t) + local n = m and m.__next or next + return n(t, k) + end +end + +-- nextvar +if not nextvar then + nextvar = function(name) + local m = _G[name] + local n = m and m.__next or nextvar + return n(_G, name) + end +end + +-- tostring +if not tostring then + tostring = function(n) + return "\""..(n).."\"" + end +end + +-- tonumber (Requires FFI for atof function) +if not tonumber then + if ffi then + ffi.cdef("float atof(const char *_Str);") + tonumber = function(s) + return ffi.C.atof(s) + end + end +end + +-- ipairs +if not ipairs then + iterate = function(t, i) + i = i + 1 + local v = t[i] + if v then + return i, v + end + end + + ipairs = function(t) + return iterate, t, 0 + end +end + +-- pairs +if not pairs then + pairs = function(t) + return next, t, nil + end +end + +-- foreach +if not foreach then + foreach = function(t, f) + for k, v in pairs(t) do + f(k, v) + end + end +end + +-- foreachi +if not foreachi then + foreachi = function(t, f) + for k, v in ipairs(t) do + f(k, v) + end + end +end + +-- foreachvar +if not foreachvar then + foreachvar = function(f) + local n, v = nextvar(nil) + while n do + local res = f(n, v) + if res then + return res + end + n, v = nextvar(n) + end + end +end + +-- gcinfo +if not gcinfo then + gcinfo = function() + return collectgarbage("count") + end +end + +-- settag +if not settag then + settag = function(t, tag) + setmetatable(t, tag) + end +end + +-- assert +if not assert then + assert = function(v, m) + if not v then + m = m or "" + error("assertion failed! " .. m) + end + end +end + +-- loadfile +if not loadfile then + loadfile = function(src) + local file = io.open(src) + content = "" + if not (_VERSION == "Lua 5.4" or _VERSION == "Lua 5.3") then + content = file:read("*all") + else + content = file:read("*a") + end + file:close() + return function() + if assert(load(content), "Loading code string failed!") then + return load(content) + end + end + end +end + +-- loadstring +if not loadstring then + loadstring = function(str) + if assert(load(str), "Loading code string failed!") then + return load(str) + end + end +end + +-- dofile +if not dofile then + dofile = function(path) + if assert(loadfile(path), "Loading file " .. path .. " failed!\n") then + return loadfile(path)() + end + end +end + +-- dostring +if not dostring then + dostring = function(str) + if assert(load(str), "Loading code string failed!") then + return load(str) + end + end +end + +-- loadlib +if not loadlib then + if package.loadlib then + loadlib = function(lib, fname) + return package.loadlib(lib, fname) + end + end +end + +-- rawlen +if not rawlen then + rawlen = function(o) + if o then + return #o + end + end +end + +-- rawget +if not rawget then + rawget = function(t, i) + if t then + return t[i] + end + end +end + +-- rawset +if not rawset then + rawset = function(t, i, v) + if t then + t[i] = v + end + end +end + +-- rawequal +if not rawequal then + rawequal = function(a, b) + if (a and type(a) == "table") and (b and type(b) == "table") then + return (#a == #b) + end + end +end + +-- copytagmethods +if not copytagmethods then + copytagmethods = function(from, to) + local funcs = {} + for k, v in pairs(getmetatable(from)) do + if (type(v) == "function") then + funcs[k] = v + end + end + for k, v in pairs(getmetatable(to)) do + getmetatable(to)[k] = funcs[k] + end + end +end + +-- gettagmethod +if not gettagmethod then + gettagmethod = function(tag, method) + return getmetatable(tag)[method] + end +end + +-- settagmethod +if not settagmethod then + settagmethod = function(tag, event, newmethod) + getmetatable(tag)[event] = newmethod or function() end + end +end + +-- call +if not call then + call = function(f, args) + if (type(f) == "function") then + return f(table.unpack(args)) + end + end +end + +-- pcall +if not pcall then + pcall = function(f, ...) + local args = { ... } + local co = coroutine.create(f) + local err = coroutine.resume(co, table.unpack(args)) + if (coroutine.status == "dead") then + return true + else + return false, err + end + end +end + +-- xpcall +if not xpcall then + xpcall = function(f, msgh, ...) + local args = { ... } + local co = coroutine.create(f) + local err = coroutine.resume(co, table.unpack(args)) + if (coroutine.status == "dead") then + return true + else + return false, "Error: " .. msgh + end + end +end + +-- setenv +if not setenv then + setenv = function(t) + _ENV = t + --_G = t + end +end + +-- getinfo +if not getinfo then + getinfo = debug.getinfo +end + +-- getlocal +if not getlocal then + getlocal = debug.getlocal +end + +-- setlocal +if not setlocal then + setlocal = debug.setlocal +end + +-- getlinehook +if not getlinehook then + getlinehook = debug.gethook +end + +-- setlinehook +if not setlinehook then + setlinehook = debug.sethook +end + +-- rawgettable +if not rawgettable then + rawgettable = rawget +end + +-- rawsettable +if not rawsettable then + rawsettable = rawset +end + +-- debug.debug +if type(debug) == "function" then + local df = debug + debug = {} + debug.debug = df +end + +-- module: table +table = require("table") or {} + +-- Functions +-- table.insert +if not table.insert then + table.insert = function(t, i, v) + if not v then + t[#t + 1] = i + else + t[i] = v + end + end +end + +-- tinsert +if not tinsert then + tinsert = function(t, i, v) + if not v then + t[#t + 1] = i + else + t[i] = v + end + end +end + +-- table.remove +if not table.remove then + table.remove = function(t, i) + if not i then + i = #t + end + local result = t[i] + t[i] = nil + return result + end +end + +-- tremove +if not tremove then + tremove = function(t, i) + if not i then + i = #t + end + local result = t[i] + t[i] = nil + return result + end +end + +-- table.concat +if not table.concat then + table.concat = function(t, s) + local result = "" + for str in ipairs(t, str) do + if (type(t[str]) == "string") then + if (str == #t) then s = "" end + result = result..(t[str]..s) + elseif (type(t[str]) == "number") then + if (str == #t) then s = "" end + result = result..(tostring(t[str])..s) + end + end + return result + end +end + +-- table.unpack +if not table.unpack then + table.unpack = function(t, i) + i = i or 1 + if (i <= #t) then + return t[i], table.unpack(t, i + 1) + end + end +end + +-- unpack +if not unpack then + unpack = function(t, i) + i = i or 1 + if (t[i] ~= nil) then + return t[i], unpack(t, i + 1) + end + end +end + +-- table.pack +if not table.pack then + table.pack = function(...) + local t = { ... } + t.n = #t + return t + end +end + +-- table.move +if not table.move then + table.move = function(t1, f, e, t, t2) + local nums = (e - 1) + for i = 0, nums, 1 do + t2[t + i] = t1[f + i] + end + end +end + +-- table.sort +if not table.sort then + table.sort = function(t, f) + f = f or nil + if #t < 2 then + return t + end + local pivot = t[1] + if (type(pivot) == "string") then + pivot = #t[1] + end + local a, b, c = {}, {}, {} + for _, v in ipairs(t) do + if (type(f) == "function") then + if (type(v) == "number") then + if (f(v, pivot) == true) then + a[#a + 1] = v + elseif(f(v, pivot) == false) then + c[#c + 1] = v + elseif (type(f(v, pivot)) ~= "boolean") then + b[#b + 1] = v + end + end + else + if (type(v) == "number") then + if v < pivot then + a[#a + 1] = v + elseif v > pivot then + c[#c + 1] = v + else + b[#b + 1] = v + end + elseif (type(v) == "string") then + if #v < pivot then + a[#a + 1] = v + elseif #v > pivot then + c[#c + 1] = v + else + b[#b + 1] = v + end + end + end + end + a = table.sort(a) + c = table.sort(c) + for _, v in ipairs(b) do a[#a + 1] = v end + for _, v in ipairs(c) do a[#a + 1] = v end + return a + end +end + +-- sort +if not sort then + sort = function(t, f) + f = f or nil + if #t < 2 then + return t + end + local pivot = t[1] + if (type(pivot) == "string") then + pivot = #t[1] + end + local a, b, c = {}, {}, {} + for _, v in ipairs(t) do + if (type(f) == "function") then + if (type(v) == "number") then + if (f(v, pivot) == true) then + a[#a + 1] = v + elseif(f(v, pivot) == false) then + c[#c + 1] = v + elseif (type(f(v, pivot)) ~= "boolean") then + b[#b + 1] = v + end + end + else + if (type(v) == "number") then + if v < pivot then + a[#a + 1] = v + elseif v > pivot then + c[#c + 1] = v + else + b[#b + 1] = v + end + elseif (type(v) == "string") then + if #v < pivot then + a[#a + 1] = v + elseif #v > pivot then + c[#c + 1] = v + else + b[#b + 1] = v + end + end + end + end + a = sort(a) + c = sort(c) + for _, v in ipairs(b) do a[#a + 1] = v end + for _, v in ipairs(c) do a[#a + 1] = v end + return a + end +end + +-- table.getn +if not table.getn then + table.getn = function(t) + if type(t.n) == "number" then + return t.n + end + local m = 0 + for i, _ in t do + if (type(i) == "number" and i > max) then + m = i + end + end + return m + end +end + +-- getn +if not getn then + getn = function(t) + if type(t.n) == "number" then + return t.n + end + local m = 0 + for i, _ in t do + if (type(i) == "number" and i > max) then + m = i + end + end + return m + end +end + +-- table.setn +if not table.setn then + table.setn = function(t, n) + setmetatable(t, { + __len = function() + return n + end + }) + end +end + +-- table.foreach +if not table.foreach then + table.foreach = function(t, f) + for k, v in pairs(t) do + if (type(f) == "function") then + f(k, v) + end + end + end +end + +-- table.foreachi +if not table.foreachi then + table.foreachi = function(t, f) + for k, v in pairs(t) do + if (type(f) == "function") then + if (type(k) == "number") then + f(k, v) + end + end + end + end +end + +-- table.maxn +if not table.maxn then + table.maxn = function(t) + local result = 0 + for i, k in ipairs(t) do + if (i > result) then + result = i + end + end + return result + end +end + +-- table_ext_solar2d.lua +-- Written by Rabia Alhaffar in 11/March/2021 +-- Polyfill for some table functions from Corona SDK/Solar2D +-- Updated: 27/March/2021 +if CoronaPrototype then + + -- table.indexOf + if not table.indexOf then + table.indexOf = function(arr, elem) + for i = 1, #arr do + if arr[i] == elem then + return i + end + end + end + end + + -- table.copy + if not table.copy then + table.copy = function(...) + local arg = { ... } + local result = {} + if #arg == 1 then + return arg[1] + else + for i = 1, #arg do + for j = 1, #arg[i] do + table.insert(result, arg[i][j]) + end + end + end + return result + end + end + +end + +-- table_ext_amulet.lua +-- Written by Rabia Alhaffar in 11/March/2021 +-- Polyfill for some table functions from Amulet +-- Updated: 27/March/2021 +if (type(am) == "table") then + + -- table.search + if not table.search then + table.search = function(arr, elem) + for i = 1, #arr do + if arr[i] == elem then + return i + end + end + end + end + + -- table.clear + if not table.clear then + table.clear = function(t) + for k, v in pairs(t) do + if t[k] then + t[k] = nil + end + end + end + end + + -- table.remove_all + if not table.remove_all then + table.remove_all = function(arr, elem) + for i = 1, #arr do + if arr[i] == elem then + arr[i] = nil + end + end + end + end + + -- table.append + if not table.append then + table.append = function(t1, t2) + for i = 1, #t2 do + table.insert(t1, t2[i]) + end + end + end + + -- table.merge + if not table.merge then + table.merge = function(t1, t2) + for k, v in pairs(t2) do + t1[k] = t2[k] + end + end + end + + -- table.keys + if not table.keys then + table.keys = function(t) + local result = {} + for k in pairs(t) do + table.insert(result, k) + end + end + return result + end + + -- table.values + if not table.values then + table.values = function(t) + local result = {} + for k, v in pairs(t) do + table.insert(result, v) + end + end + return result + end + + -- table.count + if not table.count then + table.count = function(t) + local result = 0 + for k, v in pairs(t) do + if t[k] then + result = result + 1 + end + end + return result + end + end + + -- table.filter + if not table.filter then + table.filter = function(t, f) + local result = {} + for i = 1, #t do + local a = t[i] + local b = t[i + 1] or t[i] + if (f(a, b) == true) then + t[i] = a + t[i + 1] = b + else + t[i] = b + t[i + 1] = a + end + end + return result + end + end + + -- table.tostring + if not table.tostring then + table.tostring = function(t) + local result = "{" + for k, v in pairs(t) do + if assert(type(tonumber(k)) == "number") then + result = result .. v .. "," + else + result = result .. "\"" .. k .. "\"" .. " = " .. v .. "," + end + end + result = result .. "}" + return result + end + end + + -- table.shuffle + if not table.shuffle then + table.shuffle = function(t, r) + math.randomseed(os.time()) + for i = #t, 2, -1 do + local j = r or math.random(i) + t[i], t[j] = t[j], t[i] + end + return t + end + end + +end + +-- module: package (Config for require function polyfill) +if package then + if ffi then + if not package.loaddir then + package.loaddir = "lualibs" + end + if not package.config then + if (ffi.os == "Windows") then + package.config = "\\\n;\n?\n!\n-" + else + package.config = "///n;/n?/n!/n-" + end + end + end +end + +-- module: os (Requires FFI) +os = require("os") or {} + +if ffi then + if ffi.arch == "x86" then + ffi.cdef([[ + typedef long __time32_t; + typedef __time32_t time_t; + ]]) + elseif ffi.arch == "x64" then + ffi.cdef([[ + typedef __int64 __time64_t; + typedef __time64_t time_t; + ]]) + end + ffi.cdef([[ + typedef long clock_t; + time_t time(time_t *_Time); + char * ctime(const time_t *_Time); + int system(const char *_Command); + void exit(int _Code); + int rename(const char *_OldFilename, const char *_NewFilename); + int remove(const char *_Filename); + char* setlocale(int _Category, const char *_Locale); + char* getenv(const char *_VarName); + double difftime(time_t _Time1, time_t _Time2); + char tmpnam(char *_Buffer); + char *_strdate(char *_Buffer); + clock_t clock(void); + ]]) +end + +-- os.time +if not os.time then + if ffi then + os.time = function() + return ffi.C.time(ffi.new("time_t *")) + end + end +end + +-- os.execute +if not os.execute then + if ffi then + os.execute = function(cmd) + return (ffi.C.system(cmd) == 0) + end + end +end + +-- execute +if not execute then + if ffi then + execute = function(cmd) + return (ffi.C.system(cmd) == 0) + end + end +end + +-- os.exit +if not os.exit then + if ffi then + os.exit = function(c) + return ffi.C.exit(c or 0) + end + end +end + +-- exit +if not exit then + if ffi then + exit = function(c) + return ffi.C.exit(c or 0) + end + end +end + +-- os.rename +if not os.rename then + if ffi then + os.rename = function(o, n) + return (ffi.C.rename(o, n) == 0) + end + end +end + +-- rename +if not rename then + if ffi then + rename = function(o, n) + return (ffi.C.rename(o, n) == 0) + end + end +end + +-- os.remove +if not os.remove then + if ffi then + os.remove = function(f) + return (ffi.C.remove(f) == 0) + end + end +end + +-- remove +if not remove then + if ffi then + remove = function(f) + return (ffi.C.remove(f) == 0) + end + end +end + +-- os.setlocale +if not os.setlocale then + if ffi then + os.setlocale = function(v) + return ffi.string(ffi.C.setlocale(v)) + end + end +end + +-- setlocale +if not setlocale then + if ffi then + setlocale = function(v) + return ffi.string(ffi.C.setlocale(v)) + end + end +end + +-- os.getenv +if not os.getenv then + if ffi then + os.getenv = function(v) + return ffi.string(ffi.C.getenv(v)) + end + end +end + +-- getenv +if not getenv then + if ffi then + getenv = function(v) + return ffi.string(ffi.C.getenv(v)) + end + end +end + +-- os.difftime +if not os.difftime then + if ffi then + os.difftime = function(t1, t2) + return ffi.C.difftime(t1, t2) + end + end +end + +-- os.tmpname +if not os.tmpname then + if ffi then + os.tmpname = function(str) + return ffi.string(ffi.C.tmpnam(str)) + end + end +end + +-- os.date +if not os.date == "nil" then + if ffi then + os.date = function(form) + return ffi.string(ffi.C._strdate(form)) + end + end +end + +-- date +if not date == "nil" then + if ffi then + date = function(form) + return ffi.string(ffi.C._strdate(form)) + end + end +end + +-- os.clock +if not os.clock then + if ffi then + os.clock = function() + return ffi.C.clock() + end + end +end + +-- clock +if not clock then + if ffi then + clock = function() + return ffi.C.clock() + end + end +end + +-- module: math +math = require("math") or {} + +-- Variables +-- math.pi +if not math.pi then + math.pi = 3.14159265358979323846 +end + +-- PI +if not PI then + PI = 3.14159265358979323846 +end + +-- math.huge +if not math.huge then + math.huge = 1 / 0 +end + +-- math.mininteger +if not math.mininteger then + math.mininteger = -2147483648 +end + +-- math.maxinteger +if not math.maxinteger then + math.maxinteger = 2147483647 +end + +-- Functions +-- math.sqrt +if not math.sqrt then + if ffi then + ffi.cdef("double sqrt(double);") + math.sqrt = function(n) + return ffi.C.sqrt(n) + end + end +end + +-- sqrt +if not sqrt then + if ffi then + ffi.cdef("double sqrt(double);") + sqrt = function(n) + return ffi.C.sqrt(n) + end + end +end + +-- math.sinh +if not math.sinh then + if ffi then + ffi.cdef("double sinh(double);") + math.sinh = function(n) + return ffi.C.sinh(n) + end + end +end + +-- math.cosh +if not math.cosh then + if ffi then + ffi.cdef("double cosh(double);") + math.cosh = function(n) + return ffi.C.cosh(n) + end + end +end + +-- math.tanh +if not math.tanh then + if ffi then + ffi.cdef("double tanh(double);") + math.tanh = function(n) + return ffi.C.tanh(n) + end + end +end + +-- math.asin +if not math.asin then + if ffi then + ffi.cdef("double asin(double);") + math.asin = function(n) + return ffi.C.asin(n) + end + else + math.asin = function(n) + return (n + (1 / 2) * (math.pow(n, 3) / 3) + ((1 * 3) / (2 * 4)) * (math.pow(n, 5) / 5) + ((1 * 3 * 5) / (2 * 4 * 6)) * (math.pow(n, 7) / 7)) + end + end +end + +-- asin +if not asin then + if ffi then + ffi.cdef("double asin(double);") + asin = function(n) + return ffi.C.asin(n) + end + else + asin = function(n) + return (n + (1 / 2) * (math.pow(n, 3) / 3) + ((1 * 3) / (2 * 4)) * (math.pow(n, 5) / 5) + ((1 * 3 * 5) / (2 * 4 * 6)) * (math.pow(n, 7) / 7)) + end + end +end + +-- math.acos +if not math.acos then + if ffi then + ffi.cdef("double acos(double);") + math.acos = function(n) + return ffi.C.acos(n) + end + else + math.acos = function(n) + return (-0.69813170079773212 * n * n - 0.87266462599716477) * n + 1.5707963267948966 + end + end +end + +-- acos +if not acos then + if ffi then + ffi.cdef("double acos(double);") + acos = function(n) + return ffi.C.acos(n) + end + else + acos = function(n) + return (-0.69813170079773212 * n * n - 0.87266462599716477) * n + 1.5707963267948966 + end + end +end + +-- math.atan +if not math.atan then + if ffi then + math.atan = function(...) + local args = { ... } + if (#args == 1) then + ffi.cdef("double atan(double);") + return ffi.C.atan(args[1]) + elseif (#args == 2) then + ffi.cdef("double atan2(double, double);") + return ffi.C.atan2(args[1], args[2]) + end + end + end +end + +-- atan +if not atan then + if ffi then + atan = function(...) + local args = { ... } + if (#args == 1) then + ffi.cdef("double atan(double);") + return ffi.C.atan(args[1]) + elseif (#args == 2) then + ffi.cdef("double atan2(double, double);") + return ffi.C.atan2(args[1], args[2]) + end + end + end +end + +-- math.atan2 +if not math.atan2 then + if ffi then + ffi.cdef("double atan2(double, double);") + math.atan2 = function(x, y) + return ffi.C.atan2(args[1], args[2]) + end + end +end + +-- atan2 +if not atan2 then + if ffi then + ffi.cdef("double atan2(double, double);") + atan2 = function(x, y) + return ffi.C.atan2(args[1], args[2]) + end + end +end + +-- math.exp +if not math.exp then + if ffi then + ffi.cdef("double exp(double);") + math.exp = function(n) + return ffi.C.exp(n) + end + end +end + +-- exp +if not exp then + if ffi then + ffi.cdef("double exp(double);") + exp = function(n) + return ffi.C.exp(n) + end + end +end + +-- math.log +if not math.log then + if ffi then + ffi.cdef("double log(double);") + math.log = function(n) + return ffi.C.log(n) + end + end +end + +-- log +if not log then + if ffi then + ffi.cdef("double log(double);") + log = function(n) + return ffi.C.log(n) + end + end +end + +-- math.log10 +if not math.log10 then + if ffi then + ffi.cdef("double log10(double);") + math.log10 = function(n) + return ffi.C.log10(n) + end + end +end + +-- log10 +if not log10 then + if ffi then + ffi.cdef("double log10(double);") + log10 = function(n) + return ffi.C.log10(n) + end + end +end + +-- math.ldexp +if not math.ldexp then + if ffi then + ffi.cdef("double ldexp(double, int);") + math.ldexp = function(x, y) + return ffi.C.ldexp(x, y) + end + end +end + +-- ldexp +if not ldexp then + if ffi then + ffi.cdef("double ldexp(double, int);") + ldexp = function(x, y) + return ffi.C.ldexp(x, y) + end + end +end + +-- math.frexp +if not math.frexp then + if ffi then + ffi.cdef("double frexp(double, int*);") + math.frexp = function(x, y) + return ffi.C.frexp(x, y) + end + end +end + +-- frexp +if not frexp then + if ffi then + ffi.cdef("double frexp(double, int*);") + frexp = function(x, y) + return ffi.C.frexp(x, y) + end + end +end + +-- math.modf +if not math.modf then + if ffi then + ffi.cdef("double modf(double, double*);") + math.modf = function(x, y) + return ffi.C.modf(x, y) + end + end +end + +-- math.mod +if not math.mod then + if ffi then + ffi.cdef("double fmod(double, double);") + math.mod = function(x, y) + return ffi.C.fmod(x, y) + end + end +end + +-- math.fmod +if not math.fmod then + if ffi then + ffi.cdef("double fmod(double, double);") + math.fmod = function(x, y) + return ffi.C.fmod(x, y) + end + end +end + +-- mod +if not mod then + if ffi then + ffi.cdef("double fmod(double, double);") + mod = function(x, y) + return ffi.C.fmod(x, y) + end + end +end + +-- math.pow +if not math.pow then + if ffi then + ffi.cdef("double pow(double, double);") + math.pow = function(n, p) + return ffi.C.pow(n, p) + end + else + math.pow = function(n, p) + local e = n + if (p == 0) then + return 1 + end + if (p < 0) then + p = p * -1 + end + for c = p, 2, -1 do + e = e * n + end + return e + end + end +end + +-- math.abs +if not math.abs then + math.abs = function(n) + if (n < 0) then + return -n + else + return n + end + end +end + +-- abs +if not abs then + abs = function(n) + if (n < 0) then + return -n + else + return n + end + end +end + +-- math.deg +if not math.deg then + math.deg = function(n) + return n * (180 / math.pi) + end +end + +-- deg +if not deg then + deg = function(n) + return n * (180 / math.pi) + end +end + +-- math.rad +if not math.rad then + math.rad = function(d) + return d * (math.pi / 180) + end +end + +-- rad +if not rad then + rad = function(d) + return d * (math.pi / 180) + end +end + +-- math.min +if not math.min then + math.min = function(x, y) + if x < y then + return x + else + return y + end + end +end + +-- min +if not min then + min = function(x, y) + if x < y then + return x + else + return y + end + end +end + +-- math.max +if not math.max then + math.max = function(x, y) + if x > y then + return x + else + return y + end + end +end + +-- max +if not max then + max = function(x, y) + if x > y then + return x + else + return y + end + end +end + +-- math.tointeger +if not math.tointeger then + math.tointeger = function(n) + return math.floor(n) + end +end + +-- math.hypot +if not math.hypot then + if ffi then + ffi.cdef("double hypot(double, double);") + math.hypot = function(x, y) + return ffi.C.hypot(x, y) + end + else + math.hypot = function(x, y) + return math.sqrt(math.pow(x, 2) + math.pow(y, 2)) + end + end +end + +-- math.sin +if not math.sin then + if ffi then + ffi.cdef("double sin(double);") + math.sin = function(n) + return ffi.C.sin(n) + end + end +end + +-- sin +if not sin then + if ffi then + ffi.cdef("double sin(double);") + sin = function(n) + return ffi.C.sin(n) + end + end +end + +-- math.cos +if not math.cos then + if ffi then + ffi.cdef("double cos(double);") + math.cos = function(n) + return ffi.C.cos(n) + end + else + function fact(a) + if (a == 1) or (a == 0) then + return 1 + end + local e = 1 + for c = a, 1, -1 do + e = e * c + end + return e + end + + function correctRadians(v) + while v > math.pi * 2 do + v = v - math.pi * 2 + end + while v < -math.pi * 2 do + v = v + math.pi * 2 + end + return v + end + + math.cos = function(a, b) + local e = 1 + a = correctRadians(a) + b = b or 10 + for i = 1, b do + e = e + (math.pow(-1, i) * math.pow(a, 2 * i) / fact(2 * i)) + end + return e + end + end +end + +-- cos +if not cos then + if ffi then + ffi.cdef("double cos(double);") + cos = function(n) + return ffi.C.cos(n) + end + else + function fact(a) + if (a == 1) or (a == 0) then + return 1 + end + local e = 1 + for c = a, 1, -1 do + e = e * c + end + return e + end + + function correctRadians(v) + while v > math.pi * 2 do + v = v - math.pi * 2 + end + while v < -math.pi * 2 do + v = v + math.pi * 2 + end + return v + end + + cos = function(a, b) + local e = 1 + a = correctRadians(a) + b = b or 10 + for i = 1, b do + e = e + (math.pow(-1, i) * math.pow(a, 2 * i) / fact(2 * i)) + end + return e + end + end +end + +-- math.tan +if not math.tan then + if ffi then + ffi.cdef("double tan(double);") + math.tan = function(n) + return ffi.C.tan(n) + end + end +end + +-- tan +if not tan then + if ffi then + ffi.cdef("double tan(double);") + tan = function(n) + return ffi.C.tan(n) + end + end +end + +-- math.ult +if not math.ult then + if ffi then + math.ult = function(x, y) + return (ffi.cast("unsigned int", x) < ffi.cast("unsigned int", y)) + end + end +end + +-- math.ceil +if not math.ceil then + if ffi then + math.ceil = function(n) + ffi.cdef("double ceil(double);") + return ffi.C.ceil(n) + end + end +end + +-- ceil +if not ceil then + if ffi then + ceil = function(n) + ffi.cdef("double ceil(double);") + return ffi.C.ceil(n) + end + end +end + +-- math.round +if not math.round then + if ffi then + math.round = function(n) + ffi.cdef("double round(double);") + return ffi.C.round(n) + end + end +end + +-- round +if not round then + if ffi then + round = function(n) + ffi.cdef("double round(double);") + return ffi.C.round(n) + end + end +end + +-- math.floor +if not math.floor then + if ffi then + math.floor = function(n) + ffi.cdef("double floor(double);") + return ffi.C.floor(n) + end + end +end + +-- floor +if not floor then + if ffi then + floor = function(n) + ffi.cdef("double floor(double);") + return ffi.C.floor(n) + end + end +end + +-- math.randomseed +if not math.randomseed then + if ffi then + ffi.cdef("void srand(unsigned int _Seed);") + math.randomseed = function(n) + ffi.C.srand(n) + end + end +end + +-- randomseed +if not randomseed then + if ffi then + ffi.cdef("void srand(unsigned int _Seed);") + randomseed = function(n) + ffi.C.srand(n) + end + end +end + +-- math.random +if not math.random then + if ffi then + ffi.cdef("int rand(void);") + math.random = function(...) + local pownum = 100000 + local n = { ... } + if (#n == 0) then + return (ffi.C.rand() / pownum) + elseif (#n == 1) then + local num = (n[1] * (n[1] - 2)) + local result = math.floor((ffi.C.rand() / pownum) * num) + if (result > n[1]) then + return n[1] + end + return result + elseif (#n == 2) then + local num1 = (n[1] * (n[1] - 2)) + local num2 = (n[2] * (n[2] - 2)) + local result = math.floor((ffi.C.rand() / pownum) * (num2 - num1) + num1) + if (result > n[2]) then + return n[2] + end + if (result < n[1]) then + return n[1] + end + return result + end + end + end +end + +-- random +if not random then + if ffi then + ffi.cdef("int rand(void);") + random = function(...) + local pownum = 100000 + local n = { ... } + if (#n == 0) then + return (ffi.C.rand() / pownum) + elseif (#n == 1) then + local num = (n[1] * (n[1] - 2)) + local result = math.floor((ffi.C.rand() / pownum) * num) + if (result > n[1]) then + return n[1] + end + return result + elseif (#n == 2) then + local num1 = (n[1] * (n[1] - 2)) + local num2 = (n[2] * (n[2] - 2)) + local result = math.floor((ffi.C.rand() / pownum) * (num2 - num1) + num1) + if (result > n[2]) then + return n[2] + end + if (result < n[1]) then + return n[1] + end + return result + end + end + end +end + +-- module: bit32 +bit32 = bit32 or {} + +bit32.bits = 32 +bit32.powtab = { 1 } + +for b = 1, bit32.bits - 1 do + bit32.powtab[#bit32.powtab + 1] = math.pow(2, b) +end + +-- Functions +-- bit32.band +if not bit32.band then + bit32.band = function(a, b) + local result = 0 + for x = 1, bit32.bits do + result = result + result + if (a < 0) then + if (b < 0) then + result = result + 1 + end + end + a = a + a + b = b + b + end + return result + end +end + +-- bit32.bor +if not bit32.bor then + bit32.bor = function(a, b) + local result = 0 + for x = 1, bit32.bits do + result = result + result + if (a < 0) then + result = result + 1 + elseif (b < 0) then + result = result + 1 + end + a = a + a + b = b + b + end + return result + end +end + +-- bit32.bnot +if not bit32.bnot then + bit32.bnot = function(x) + return bit32.bxor(x, math.pow((bit32.bits or math.floor(math.log(x, 2))), 2) - 1) + end +end + +-- bit32.lshift +if not bit32.lshift then + bit32.lshift = function(a, n) + if (n > bit32.bits) then + a = 0 + else + a = a * bit32.powtab[n] + end + return a + end +end + +-- bit32.rshift +if not bit32.rshift then + bit32.rshift = function(a, n) + if (n > bit32.bits) then + a = 0 + elseif (n > 0) then + if (a < 0) then + a = a - bit32.powtab[#bit32.powtab] + a = a / bit32.powtab[n] + a = a + bit32.powtab[bit32.bits - n] + else + a = a / bit32.powtab[n] + end + end + return a + end +end + +-- bit32.arshift +if not bit32.arshift then + bit32.arshift = function(a, n) + if (n >= bit32.bits) then + if (a < 0) then + a = -1 + else + a = 0 + end + elseif (n > 0) then + if (a < 0) then + a = a - bit32.powtab[#bit32.powtab] + a = a / bit32.powtab[n] + a = a - bit32.powtab[bit32.bits - n] + else + a = a / bit32.powtab[n] + end + end + return a + end +end + +-- bit32.bxor +if not bit32.bxor then + bit32.bxor = function(a, b) + local result = 0 + for x = 1, bit32.bits, 1 do + result = result + result + if (a < 0) then + if (b >= 0) then + result = result + 1 + end + elseif (b < 0) then + result = result + 1 + end + a = a + a + b = b + b + end + return result + end +end + +-- bit32.btest +if not bit32.btest then + bit32.btest = function(a, b) + return (bit32.band(a, b) ~= 0) + end +end + +-- bit32.lrotate +if not bit32.lrotate then + bit32.lrotate = function(a, b) + local bits = bit32.band(b, bit32.bits - 1) + a = bit32.band(a, 0xffffffff) + a = bit32.bor(bit32.lshift(a, b), bit32.rshift(a, ((bit32.bits - 1) - b))) + return bit32.band(n, 0xffffffff) + end +end + +-- bit32.rrotate +if not bit32.rrotate then + bit32.rrotate = function(a, b) + return bit32.lrotate(a, -b) + end +end + +-- bit32.extract +if not bit32.extract then + bit32.extract = function(a, b, c) + c = c or 1 + return bit32.band(bit32.rshift(a, b, c), math.pow(b, 2) - 1) + end +end + +-- bit32.replace +if not bit32.replace then + bit32.replace = function(a, b, c, d) + d = d or 1 + local mask1 = math.pow(d, 2) -1 + b = bit32.band(b, mask1) + local mask = bit32.bnot(bit32.lshift(mask1, c)) + return bit32.band(n, mask) + bit32.lshift(b, c) + end +end + +-- module: bit +bit = bit or {} + +bit.bits = 32 +bit.powtab = { 1 } + +for b = 1, bit.bits - 1 do + bit.powtab[#bit.powtab + 1] = math.pow(2, b) +end + +-- Functions +-- bit.band +if not bit.band then + bit.band = function(a, b) + local result = 0 + for x = 1, bit.bits do + result = result + result + if (a < 0) then + if (b < 0) then + result = result + 1 + end + end + a = a + a + b = b + b + end + return result + end +end + +-- bit.bor +if not bit.bor then + bit.bor = function(a, b) + local result = 0 + for x = 1, bit.bits do + result = result + result + if (a < 0) then + result = result + 1 + elseif (b < 0) then + result = result + 1 + end + a = a + a + b = b + b + end + return result + end +end + +-- bit.bnot +if not bit.bnot then + bit.bnot = function(x) + return bit.bxor(x, math.pow((bit.bits or math.floor(math.log(x, 2))), 2) - 1) + end +end + +-- bit.lshift +if not bit.lshift then + bit.lshift = function(a, n) + if (n > bit.bits) then + a = 0 + else + a = a * bit.powtab[n] + end + return a + end +end + +-- bit.rshift +if not bit.rshift then + bit.rshift = function(a, n) + if (n > bit.bits) then + a = 0 + elseif (n > 0) then + if (a < 0) then + a = a - bit.powtab[#bit.powtab] + a = a / bit.powtab[n] + a = a + bit.powtab[bit.bits - n] + else + a = a / bit.powtab[n] + end + end + return a + end +end + +-- bit.arshift +if not bit.arshift then + bit.arshift = function(a, n) + if (n >= bit.bits) then + if (a < 0) then + a = -1 + else + a = 0 + end + elseif (n > 0) then + if (a < 0) then + a = a - bit.powtab[#bit.powtab] + a = a / bit.powtab[n] + a = a - bit.powtab[bit.bits - n] + else + a = a / bit.powtab[n] + end + end + return a + end +end + +-- bit.bxor +if not bit.bxor then + bit.bxor = function(a, b) + local result = 0 + for x = 1, bit.bits, 1 do + result = result + result + if (a < 0) then + if (b >= 0) then + result = result + 1 + end + elseif (b < 0) then + result = result + 1 + end + a = a + a + b = b + b + end + return result + end +end + +-- bit.rol +if not bit.rol then + bit.rol = function(a, b) + local bits = bit.band(b, bit.bits - 1) + a = bit.band(a,0xffffffff) + a = bit.bor(bit.lshift(a, b), bit.rshift(a, ((bit.bits - 1) - b))) + return bit.band(n, 0xffffffff) + end +end + +-- bit.ror +if not bit.ror then + bit.ror = function(a, b) + return bit.rol(a, -b) + end +end + +-- bit.bswap +if not bit.bswap then + bit.bswap = function(n) + local a = bit.band(n, 0xff) + n = bit.rshift(n, 8) + local b = bit.band(n, 0xff) + n = bit.rshift(n, 8) + local c = bit.band(n, 0xff) + n = bit.rshift(n, 8) + local d = bit.band(n, 0xff) + return bit.lshift(bit.lshift(bit.lshift(a, 8) + b, 8) + c, 8) + d + end +end + +-- bit.tobit +if not bit.tobit then + bit.tobit = function(n) + local MOD = 2^32 + n = n % MOD + if (n >= 0x80000000) then + n = n - MOD + end + return n + end +end + +-- bit.tohex +if not bit.tohex then + bit.tohex = function(x, n) + n = n or 8 + local up + if n <= 0 then + if n == 0 then + return '' + end + up = true + n = -n + end + x = bit.band(x, 16^n-1) + return ('%0'..n..(up and 'X' or 'x')):format(x) + end +end + +-- module: io +io = require("io") or {} + +if not _INPUT then + _INPUT = io.stdin +end + +if not _OUTPUT then + _OUTPUT = io.stdout +end + +if not _STDIN then + _STDIN = io.stdin +end + +if not _STDOUT then + _STDOUT = io.stdout +end + +if not _STDERR then + _STDERR = io.stderr +end + +-- Used by io.input and io.output, And works as usable file with IO functions lol +io.__DEFAULT__INPUT__FILE__ = nil +io.__DEFAULT__OUTPUT__FILE__ = nil + +if ffi then + ffi.cdef([[ + struct _iobuf { + char *_ptr; + int _cnt; + char *_base; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char *_tmpfname; + }; + typedef struct _iobuf FILE; + typedef struct SExIO_Stream { + FILE *f; /* stream (NULL for incompletely created streams) */ + } SExIO_Stream; + ]]) +end + +-- Native file type +_FILE = {} + +function _FILE:new(f, m, s) + o = {} + setmetatable(o, self) + self.__index = self + self.__FILE = f + self.__MODE = m + self.__STATE = "file" + self.__SRC = s + return o +end + +function _FILE:close() + if ffi then + ffi.cdef("int fclose(FILE *_File);") + local result = (ffi.C.fclose(self.__FILE) == 0) + if result then + self.__STATE = "closed file" + end + end +end + +function _FILE:flush() + if ffi then + ffi.cdef("int fflush(FILE *_File);") + return (ffi.C.flush(self.__FILE) == 0) + end +end + +function _FILE:seek(w, o) + if ffi then + ffi.cdef("int fseek(FILE *stream, long int offset, int whence);") + if (w == "set") then + return ffi.C.fseek(self.__FILE, o, 0) + elseif (w == "cur") then + return ffi.C.fseek(self.__FILE, o, 1) + elseif (w == "end") then + return ffi.C.fseek(self.__FILE, o, 2) + else + return ffi.C.fseek(self.__FILE, o, w) + end + end +end + +function _FILE:read(t) + if (t == "*all" or t == "*a") then + while not cast("bool", ffi.C.feof(f)) do + local content = "" + local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f))) + if (ch ~= nil) then + content = content .. ch + end + end + elseif (t == "*line" or t == "*l") then + if not cast("bool", ffi.C.feof(f)) then + local line = "" + while not cast("bool", ffi.C.feof(f)) do + local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f))) + if (ch == "\n") then + break + else + line = line .. ch + end + end + return line + end + elseif (t == "*number" or t == "*n") then + local line = "" + while not cast("bool", ffi.C.feof(f)) do + local ch = tonumber(ffi.string(ffi.cast("char", ffi.C.fgetc(f)))) + if not ch then + break + else + line = line .. ch + end + end + return line + elseif (type(t) == "number") then + if not cast("bool", ffi.C.feof(f)) then + local line = ffi.new("char[?]", t) + return ffi.string(ffi.C.fgets(line, t, f)) + end + end +end + +function _FILE:write(...) + if ffi then + ffi.cdef("int fprintf(FILE *stream, const char *format, ...);") + local args = { ... } + if (#args == 0) then + args[1] = f + end + local form = args[1] + table.remove(args, 1) + if (#args == 0) then + ffi.C.fprintf(f.__FILE, form) + else + ffi.C.fprintf(f.__FILE, form, table.unpack(args)) + end + end +end + +function _FILE:setvbuf(m, s) + if ffi then + ffi.cdef("int setvbuf(FILE *stream, char *buffer, int mode, size_t size);") + if (m == "no") then + return (ffi.C.setvbuf(self.__FILE, nil, 0x0004, s) == 0) + elseif (m == "full") then + return (ffi.C.setvbuf(self.__FILE, nil, 0x0000, s) == 0) + elseif (m == "line") then + return (ffi.C.setvbuf(self.__FILE, nil, 0x0040, s) == 0) + end + end +end + +function _FILE:lines() + if ffi then + local lines = {} + local line = "" + while not cast("bool", ffi.C.feof(self.__FILE)) do + local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(self.__FILE))) + if (ch == "\n") then + lines[#lines + 1] = line + line = "" + else + line = line .. ch + end + end + return ipairs(lines) + end +end + +-- Functions and Variables +-- io.tmpfile +if not io.tmpfile then + io.tmpfile = function() + if ffi then + ffi.cdef("FILE *tmpfile(void);") + return _FILE:new(ffi.C.tmpfile(), nil, nil) + end + end +end + +-- tmpfile +if not tmpfile then + tmpfile = function() + if ffi then + ffi.cdef("FILE *tmpfile(void);") + return _FILE:new(ffi.C.tmpfile(), nil, nil) + end + end +end + +-- io.open +if not io.open then + if ffi then + io.open = function(s, m) + ffi.cdef("FILE *fopen(const char *_Filename,const char *_Mode);") + return _FILE:new(ffi.C.fopen(s, m), m, s) + end + end +end + +-- openfile +if not openfile then + if ffi then + openfile = function(s, m) + ffi.cdef("FILE *fopen(const char *_Filename,const char *_Mode);") + return _FILE:new(ffi.C.fopen(s, m), m, s) + end + end +end + +-- io.write +if not io.write then + if ffi then + io.write = function(f, ...) + ffi.cdef("int fprintf(FILE *stream, const char *format, ...);") + local args = { ... } + if ((#args == 0) and (io.__DEFAULT__OUTPUT__FILE__)) then + args[1] = f + return (ffi.C.fprintf(io.__DEFAULT__OUTPUT__FILE__, args[1]) == 0) + elseif (f.__FILE) then + local form = args[1] + table.remove(args, 1) + return (ffi.C.fprintf(f.__FILE, form, table.unpack(args)) == 0) + end + end + end +end + +-- write +if not write then + if ffi then + write = function(f, ...) + ffi.cdef("int fprintf(FILE *stream, const char *format, ...);") + local args = { ... } + if ((#args == 0) and (io.__DEFAULT__OUTPUT__FILE__)) then + args[1] = f + return (ffi.C.fprintf(io.__DEFAULT__OUTPUT__FILE__, args[1]) == 0) + elseif (f.__FILE) then + local form = args[1] + table.remove(args, 1) + return (ffi.C.fprintf(f.__FILE, form, table.unpack(args)) == 0) + end + end + end +end + +-- io.seek +if not io.seek then + if ffi then + io.seek = function(f, w, o) + ffi.cdef("int fseek(FILE *stream, long int offset, int whence);") + if (w == "set") then + return ffi.C.fseek(f, o, 0) + elseif (w == "cur") then + return ffi.C.fseek(f, o, 1) + elseif (w == "end") then + return ffi.C.fseek(f, o, 2) + else + return ffi.C.fseek(f, o, w) + end + end + end +end + +-- seek +if not seek then + if ffi then + seek = function(f, w, o) + ffi.cdef("int fseek(FILE *stream, long int offset, int whence);") + if (w == "set") then + return ffi.C.fseek(f, o, 0) + elseif (w == "cur") then + return ffi.C.fseek(f, o, 1) + elseif (w == "end") then + return ffi.C.fseek(f, o, 2) + else + return ffi.C.fseek(f, o, w) + end + end + end +end + +-- io.read +if not io.read then + if ffi then + io.read = function(f, t) + ffi.cdef([[ + char *fgets(char *str, int n, FILE *stream); + int fgetc(FILE *stream); + int feof(FILE *stream); + int scanf(const char *format, ...); + ]]) + if t and f then + if (t == "*all" or t == "*a") then + while not cast("bool", ffi.C.feof(f)) do + local content = "" + local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f))) + if (ch ~= nil) then + content = content .. ch + end + end + elseif (t == "*line" or t == "*l") then + if not cast("bool", ffi.C.feof(f)) then + local line = "" + while not cast("bool", ffi.C.feof(f)) do + local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f))) + if (ch == "\n") then + break + else + line = line .. ch + end + end + return line + end + elseif (t == "*number" or t == "*n") then + local line = "" + while not cast("bool", ffi.C.feof(f)) do + local ch = tonumber(ffi.string(ffi.cast("char", ffi.C.fgetc(f)))) + if not ch then + break + else + line = line .. ch + end + end + return line + elseif (type(t) == "number") then + if not cast("bool", ffi.C.feof(f)) then + local line = ffi.new("char[?]", t) + return ffi.string(ffi.C.fgets(line, t, f)) + end + elseif io.__DEFAULT__INPUT__FILE__ then + --if not cast("bool", ffi.C.feof(io.__DEFAULT__INPUT__FILE__)) then + --local line = ffi.new("char[?]", 512) + local line = "" + while not cast("bool", ffi.C.feof(io.__DEFAULT__INPUT__FILE__)) do + local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(io.__DEFAULT__INPUT__FILE__))) + if (ch == "\n") then + break + else + line = line .. ch + end + end + return line + --return ffi.string(ffi.C.fgets(line, 512, io.__DEFAULT__INPUT__FILE__)) + else + local input = ffi.new("char[?]", 512) + local execution_code = ffi.C.scanf("%s\0", input) + return input, (execution_code == 0) + end + end + end + end +end + +-- read +if not read then + if ffi then + read = function(f, t) + ffi.cdef([[ + char *fgets(char *str, int n, FILE *stream); + int fgetc(FILE *stream); + int feof(FILE *stream); + int scanf(const char *format, ...); + ]]) + if t and f then + if (t == "*all" or t == "*a") then + while not cast("bool", ffi.C.feof(f)) do + local content = "" + local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f))) + if (ch ~= nil) then + content = content .. ch + end + end + elseif (t == "*line" or t == "*l") then + if not cast("bool", ffi.C.feof(f)) then + local line = "" + while not cast("bool", ffi.C.feof(f)) do + local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f))) + if (ch == "\n") then + break + else + line = line .. ch + end + end + return line + end + elseif (t == "*number" or t == "*n") then + local line = "" + while not cast("bool", ffi.C.feof(f)) do + local ch = tonumber(ffi.string(ffi.cast("char", ffi.C.fgetc(f)))) + if not ch then + break + else + line = line .. ch + end + end + return line + elseif (type(t) == "number") then + if not cast("bool", ffi.C.feof(f)) then + local line = ffi.new("char[?]", t) + return ffi.string(ffi.C.fgets(line, t, f)) + end + elseif io.__DEFAULT__INPUT__FILE__ then + --if not cast("bool", ffi.C.feof(io.__DEFAULT__INPUT__FILE__)) then + --local line = ffi.new("char[?]", 512) + local line = "" + while not cast("bool", ffi.C.feof(io.__DEFAULT__INPUT__FILE__)) do + local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(io.__DEFAULT__INPUT__FILE__))) + if (ch == "\n") then + break + else + line = line .. ch + end + end + return line + --return ffi.string(ffi.C.fgets(line, 512, io.__DEFAULT__INPUT__FILE__)) + else + local input = ffi.new("char[?]", 512) + local execution_code = ffi.C.scanf("%s\0", input) + return input, (execution_code == 0) + end + end + end + end +end + +-- io.close +if not io.close then + if ffi then + io.close = function(f) + if f and (f.__FILE or f.__STATE) then + ffi.cdef("int fclose(FILE *_File);") + local result = (ffi.C.fclose(f.__FILE) == 0) + if result then + f.__STATE = "closed file" + end + end + end + end +end + +-- closefile +if not closefile then + if ffi then + closefile = function(f) + if f and (f.__FILE or f.__STATE) then + ffi.cdef("int fclose(FILE *_File);") + local result = (ffi.C.fclose(f.__FILE) == 0) + if result then + f.__STATE = "closed file" + end + end + end + end +end + +-- io.flush +if not io.flush then + if ffi then + io.flush = function(f) + ffi.cdef("int fflush(FILE *_File);") + return (ffi.C.fflush(f or io.stdout) == 0) + end + end +end + +-- flush +if not flush then + if ffi then + flush = function(f) + ffi.cdef("int fflush(FILE *_File);") + return (ffi.C.fflush(f or io.stdout) == 0) + end + end +end + +-- io.type +if not io.type then + io.type = function(f) + if f and f.__STATE and ffi.istype("FILE", f) then + return f.__STATE + else + return nil + end + end +end + +-- io.input +if not io.input then + io.input = function(f) + if f and (f.__FILE or f.__STATE) then + if (f.__FILE or f.__MODE or f.__STATE) then + io.__DEFAULT__INPUT__FILE__ = f + end + end + end +end + +-- readfrom +if not readfrom then + readfrom = function(f) + if f and (f.__FILE or f.__STATE) then + if (f.__FILE or f.__MODE or f.__STATE) then + io.__DEFAULT__OUTPUT__FILE__ = f + end + end + end +end + +-- io.output +if not io.output then + io.output = function(f) + if f and (f.__FILE or f.__STATE) then + if (f.__FILE or f.__MODE or f.__STATE) then + io.__DEFAULT__OUTPUT__FILE__ = f + end + end + end +end + +-- writeto +if not writeto then + writeto = function(f) + if f and (f.__FILE or f.__STATE) then + if (f.__FILE or f.__MODE or f.__STATE) then + io.__DEFAULT__OUTPUT__FILE__ = f + end + end + end +end + +-- appendto +if not appendto then + appendto = function(f) + if f and (f.__FILE or f.__STATE) then + if (f.__FILE or f.__MODE or f.__STATE) then + io.__DEFAULT__OUTPUT__FILE__ = f + end + end + end +end + +-- io.popen +if not io.popen then + if ffi then + io.popen = function(c, m) + ffi.cdef("FILE *_popen(const char *_Command, const char *_Mode);") + return _FILE:new(ffi.C._popen(c, m), m, nil) + end + end +end + +-- io.lines +if not io.lines then + if ffi then + io.lines = function(filename) + local lines = {} + local line = "" + local file = nil + if (not filename) and io.__DEFAULT__INPUT__FILE__ and io.__DEFAULT__INPUT__FILE__.__FILE then + filename = io.__DEFAULT__INPUT__FILE__ + file = io.__DEFAULT__INPUT__FILE__.__FILE + else + file = io.open(filename, "r") + end + while not cast("bool", ffi.C.feof(file)) do + local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(file))) + if (ch == "\n") then + lines[#lines + 1] = line + line = "" + else + line = line .. ch + end + end + return ipairs(lines) + end + end +end + +-- io.stdin +if not io.stdin then + if ffi then + io.stdin = _FILE:new(io.open("stdin", "w"), "w", "stdin") + end +end + +-- io.stdout +if not io.stdout then + if ffi then + io.stdout = _FILE:new(io.open("stdout", "w"), "w", "stdout") + end +end + +-- io.stderr +if not io.stderr then + if ffi then + io.stderr = _FILE:new(io.open("stderr", "w"), "w", "stderr") + end +end + +-- module: string +-- Functions +string = require("string") or {} + +string.chars = {} +string.chars["a"] = 97 +string.chars["b"] = 98 +string.chars["c"] = 99 +string.chars["d"] = 100 +string.chars["e"] = 101 +string.chars["f"] = 102 +string.chars["g"] = 103 +string.chars["h"] = 104 +string.chars["i"] = 105 +string.chars["j"] = 106 +string.chars["k"] = 107 +string.chars["l"] = 108 +string.chars["m"] = 109 +string.chars["n"] = 110 +string.chars["o"] = 111 +string.chars["p"] = 112 +string.chars["q"] = 113 +string.chars["r"] = 114 +string.chars["s"] = 115 +string.chars["t"] = 116 +string.chars["u"] = 117 +string.chars["v"] = 118 +string.chars["w"] = 119 +string.chars["x"] = 120 +string.chars["y"] = 121 +string.chars["z"] = 122 +string.chars["0"] = 48 +string.chars["1"] = 49 +string.chars["2"] = 50 +string.chars["3"] = 51 +string.chars["4"] = 52 +string.chars["5"] = 53 +string.chars["6"] = 54 +string.chars["7"] = 55 +string.chars["8"] = 56 +string.chars["9"] = 57 +string.chars["!"] = 33 +string.chars["@"] = 64 +string.chars["#"] = 35 +string.chars["$"] = 36 +string.chars["%"] = 37 +string.chars["^"] = 94 +string.chars["&"] = 38 +string.chars["*"] = 42 +string.chars["("] = 40 +string.chars[")"] = 41 +string.chars["-"] = 45 +string.chars["+"] = 43 +string.chars["_"] = 95 +string.chars["="] = 61 +string.chars["{"] = 123 +string.chars["}"] = 125 +string.chars["["] = 91 +string.chars["]"] = 93 +string.chars[":"] = 58 +string.chars["'"] = 39 +string.chars["\""] = 34 +string.chars[";"] = 95 +string.chars["/"] = 47 +string.chars["`"] = 96 +string.chars["~"] = 126 +string.chars["|"] = 124 +string.chars["\\"] = 92 +string.chars[","] = 44 +string.chars["."] = 46 +string.chars["<"] = 60 +string.chars[">"] = 62 +string.chars["?"] = 63 + +-- string.split +if not string.split then + string.split = function(s, sep) + local result = {} + local line = "" + for i = 1, #s do + if (string.char(string.byte(s, i)) == sep) then + result[#result + 1] = line + line = "" + else + line = line .. string.char(string.byte(s, i)) + end + end + return result + end +end + +-- string.rep +if not string.rep then + string.rep = function(s, n, sep) + local str = "" + local sp = sep or "" + for i = 1, n, 1 do + if (i == n) then + sp = "" + end + str = str .. s .. sp + end + return str + end +end + +-- strrep +if not strrep then + strrep = function(s, n, sep) + local str = "" + local sp = sep or "" + for i = 1, n, 1 do + if (i == n) then + sp = "" + end + str = str .. s .. sp + end + return str + end +end + +-- string.len +if not string.len then + string.len = function(s) + if not ffi then + return #n + else + ffi.cdef("size_t strlen(const char *_Str);") + return ffi.cast("int", ffi.C.strlen(s)) + end + end +end + +-- strlen +if not strlen then + strlen = function(s) + if not ffi then + return #n + else + ffi.cdef("size_t strlen(const char *_Str);") + return ffi.cast("int", ffi.C.strlen(s)) + end + end +end + +-- string.byte +if not string.byte then + if (type(ffi) == "string") then + string.byte = function(s, i) + i = i or 1 + local strarr = ffi.new("char[?]", #s) + ffi.copy(strarr, s) + return ffi.cast("int", strarr[i]) + end + end +end + +-- strbyte +if not strbyte then + if (type(ffi) == "string") then + strbyte = function(s, i) + i = i or 1 + local strarr = ffi.new("char[?]", #s) + ffi.copy(strarr, s) + return ffi.cast("int", strarr[i]) + end + end +end + +-- string.char +if not string.char then + string.char = function(...) + local args = { ... } + local str = "" + for i = 1, #args do + for k, v in pairs(string.chars) do + if (v == args[i]) then + str = str .. k + end + end + end + return str + end +end + +-- strchar +if not strchar then + strchar = function(...) + local args = { ... } + local str = "" + for i = 1, #args do + for k, v in pairs(string.chars) do + if (v == args[i]) then + str = str .. k + end + end + end + return str + end +end + +-- string.upper +if not string.upper then + if ffi then + string.upper = function(s) + ffi.cdef("int toupper(int _C);") + local result = {} + local t = ffi.new("char[?]", #s) + ffi.copy(t, s) + for i = 1, #s, 1 do + result[i] = ffi.C.toupper(string.char(ffi.cast("int", t[i]))) + end + return table.concat(result, "") + end + end +end + +-- strupper +if not strupper then + if ffi then + strupper = function(s) + ffi.cdef("int toupper(int _C);") + local result = {} + local t = ffi.new("char[?]", #s) + ffi.copy(t, s) + for i = 1, #s, 1 do + result[i] = ffi.C.toupper(string.char(ffi.cast("int", t[i]))) + end + return table.concat(result, "") + end + end +end + +-- string.lower +if not string.lower then + if ffi then + string.lower = function(s) + ffi.cdef("int tolower(int _C);") + local result = {} + local t = ffi.new("char[?]", #s) + ffi.copy(t, s) + for i = 1, #s, 1 do + result[i] = ffi.C.tolower(string.char(ffi.cast("int", t[i]))) + end + return table.concat(result, "") + end + end +end + +-- strlower +if not strlower then + if ffi then + string.lower = function(s) + ffi.cdef("int tolower(int _C);") + local result = {} + local t = ffi.new("char[?]", #s) + ffi.copy(t, s) + for i = 1, #s, 1 do + result[i] = ffi.C.tolower(string.char(ffi.cast("int", t[i]))) + end + return table.concat(result, "") + end + end +end + +-- string.pack +if not string.pack then + if ffi then + string.pack = function(f, ...) + local packtype = string.char(string.byte(f, 1)) + local arrtype = "" + local arrsize = 0 + if packtype == "i" then + arrtype = "int" + arrsize = 2 + elseif packtype == "f" then + arrtype = "float" + arrsize = 4 + elseif packtype == "d" then + arrtype = "double" + arrsize = 8 + elseif packtype == "c" then + arrtype = "char" -- char could be int? + arrsize = 1 + end + local occurences = string.match(args[1], packtype) + local args = { ... } + return ffi.string(ffi.new(arrtype.."[?]", #args, args), arrsize * #args) + end + end +end + +-- string.unpack +if not string.unpack then + if ffi then + string.unpack = function(f, s, o) + local packtype = string.char(string.byte(f, 1)) + local arrtype = "" + local arrsize = 0 + if packtype == "i" then + arrtype = "int" + arrsize = 2 + elseif packtype == "f" then + arrtype = "float" + arrsize = 4 + elseif packtype == "d" then + arrtype = "double" + arrsize = 8 + elseif packtype == "c" then + arrtype = "char" -- char could be int? + arrsize = 1 + end + local str = ffi.cast(arrtype .. "*", ffi.new("char[?]", #str, str)) + local t = {} + for i = o, #str / arrsize do + t[#t + 1] = str[#t] + end + return table.concat(t) + end + end +end + +-- string.packsize +if not string.packsize then + if ffi then + string.packsize = function(str) + if str[1] then + return #str + end + end + end +end + +-- string.sub +if not string.sub then + string.sub = function(s, f, t) + t = t or #s + local result = "" + for i = f, t do + result = result .. string.char(string.byte(s, i)) + end + return result + end +end + +-- strsub +if not strsub then + strsub = function(s, f, t) + t = t or #s + local result = "" + for i = f, t do + result = result .. string.char(string.byte(s, i)) + end + return result + end +end + +-- string.format +if not string.format then + if ffi then + string.format = function(...) + ffi.cdef("int sprintf(char *str, const char *format, ...);") + local args = { ... } + local str = "" + ffi.C.sprintf(str, table.unpack(args)) + return ffi.string(str) + end + end +end + +-- format +if not format then + if ffi then + format = function(...) + ffi.cdef("int sprintf(char *str, const char *format, ...);") + local args = { ... } + local str = "" + ffi.C.sprintf(str, table.unpack(args)) + return ffi.string(str) + end + end +end + +-- string.match +if not string.match then + if ffi then + string.match = function(s1, s2, init) + ffi.cdef("char* strstr(const char*, const char*);") + init = init or 0 + local occurences = 0 + local count = 0 + local ptr = s1 + local lastfind = nil + while (ffi.C.strstr(ptr, s2) ~= nil) do + lastfind = ffi.C.strstr(ptr, s2) + ptr = lastfind + 1 + if (occurences >= init) then + count = count + 1 + end + occurences = occurences + 1 + end + if (occurences > 1) then + return (occurences * #s2) - 1, #s2 + else + return occurences, #s2 + end + end + end +end + +-- string.gmatch +if not string.gmatch then + if ffi then + string.gmatch = function(s1, s2) + ffi.cdef("char* strstr(const char*, const char*);") + local occurences = {} + local ptr = s1 + local lastfind = nil + while (ffi.C.strstr(ptr, s2) ~= nil) do + lastfind = ffi.C.strstr(ptr, s2) + ptr = lastfind + 1 + occurences[#occurences + 1] = lastfind + end + return ipairs(occurences) + end + end +end + +-- string.find +if not string.find then + if ffi then + string.find = function(s1, s2, init) + ffi.cdef("char* strstr(const char*, const char*);") + init = init or 0 + local occurences = 0 + local count = 0 + local ptr = s1 + local lastfind = nil + while (ffi.C.strstr(ptr, s2) ~= nil) do + lastfind = ffi.C.strstr(ptr, s2) + ptr = lastfind + 1 + if (occurences >= init) then + count = count + 1 + end + occurences = occurences + 1 + end + return occurences, #s2 + end + end +end + +-- strfind +if not strfind then + if ffi then + strfind = function(s1, s2, init) + ffi.cdef("char* strstr(const char*, const char*);") + init = init or 0 + local occurences = 0 + local count = 0 + local ptr = s1 + local lastfind = nil + while (ffi.C.strstr(ptr, s2) ~= nil) do + lastfind = ffi.C.strstr(ptr, s2) + ptr = lastfind + 1 + if (occurences >= init) then + count = count + 1 + end + occurences = occurences + 1 + end + return occurences, #s2 + end + end +end + +-- string.gfind +if not string.gfind then + if ffi then + string.gfind = function(s1, s2) + ffi.cdef("char* strstr(const char*, const char*);") + local occurences = {} + local ptr = s1 + local lastfind = nil + while (ffi.C.strstr(ptr, s2) ~= nil) do + lastfind = strstr(ptr, s2) + ptr = lastfind + 1 + occurences[#occurences + 1] = lastfind + end + return ipairs(occurences) + end + end +end + +return polyfill From 4c3b80a1fb34b0a79351170c85d433f70560ad08 Mon Sep 17 00:00:00 2001 From: ParticleG Date: Wed, 14 Jun 2023 16:44:54 +0800 Subject: [PATCH 08/14] =?UTF-8?q?=E6=A1=86=E6=9E=B6=E8=B7=9F=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Zframework | 2 +- conf.lua | 1 - polyfill.lua | 3391 -------------------------------------------------- 3 files changed, 1 insertion(+), 3393 deletions(-) delete mode 100644 polyfill.lua diff --git a/Zframework b/Zframework index 20a5757a..6d9b1439 160000 --- a/Zframework +++ b/Zframework @@ -1 +1 @@ -Subproject commit 20a5757a9c6f90c484ec550d5a048cf04987d9bf +Subproject commit 6d9b1439eb348bbb618746516d86538b5f3fb8df diff --git a/conf.lua b/conf.lua index 7ade3138..a62defa6 100644 --- a/conf.lua +++ b/conf.lua @@ -3,7 +3,6 @@ MOBILE=SYSTEM=='Android' or SYSTEM=='iOS' FNNS=SYSTEM:find'\79\83'-- What does FNSF stand for? IDK so don't ask me lol if SYSTEM=='Web' then - POLYFILL = require"polyfill" local oldRead=love.filesystem.read function love.filesystem.read(name,size) if love.filesystem.getInfo(name) then diff --git a/polyfill.lua b/polyfill.lua deleted file mode 100644 index 093a710e..00000000 --- a/polyfill.lua +++ /dev/null @@ -1,3391 +0,0 @@ --- Written by Rabia Alhaffar in 24/February/2021 --- polyfill.lua, Polyfills for Lua and LuaJIT in one file! --- Updated: 11/April/2021 ---[[ -MIT License - -Copyright (c) 2021 - 2022 Rabia Alhaffar - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -]] - --- require -if (not require) and package then - require = function(p) - if package.loaded[p] then - return package.loaded[p] - else - return package.searchpath(p, "./?/?.lua;./?.lua;./?.lc;./"..package.loaddir.."/?/init.lua"..";./"..package.loaddir.."/?.lua") - end - end -end - -local polyfill = { - _VERSION = 0.1, - _AUTHOR = "Rabia Alhaffar (steria773/@Rabios)", - _AUTHOR_URL = "https://github.com/Rabios", - _URL = "https://github.com/Rabios/polyfill.lua", - _LICENSE = "MIT", - _DATE = "3/March/2021", - _LUAJIT = ((require("jit") or jit) and true or false), -} - -local ffi = ((require("ffi") or require("luaffi") or ffi) or nil) --> Do we have FFI? - -if not _VERSION then - _VERSION = "Lua 5.1" -end - --- module: ffi --- Partial FFI polyfill for LuaJIT (And PUC-RIO's Lua if yours have FFI installed) -if ffi then - -- ffi.string - if not ffi.string then - ffi.string = function(s) - local str = ffi.new("char[?]", #s) - ffi.copy(str, s) - return str - end - end - - -- ffi.os - if polyfill._LUAJIT then - if not ffi.os then - ffi.os = (require("jit").os or jit.os) - end - end - - -- ffi.arch - if not ffi.arch then - if (0xfffffffff == 0xffffffff) then - ffi.arch = "x86" - else - ffi.arch = "x64" - end - end -end - --- module: Runtime (Global functions) --- Functions --- setglobal -if not setglobal then - setglobal = function(var, val) - _G[var] = val - end -end - --- getglobal -if not getglobal then - getglobal = function(var) - return _G[var] - end -end - --- rawgetglobal -if not rawgetglobal then - rawgetglobal = function(var) - return _G[var] - end -end - --- rawsetglobal -if not rawsetglobal then - rawsetglobal = function(var, val) - _G[var] = val - end -end - --- globals -if not globals then - globals = function(t) - if not t then - return _G - else - _G = t - end - end -end - --- newtag -if not newtag then - newtag = function() - return { __index = self } - end -end - --- setfallback -if not setfallback then - setfallback = function(fname, f) - _G[fname] = f - end -end - --- select -if not select then - select = function(n, ...) - local args = { ... } - return args[n] - end -end - --- _ALERT -if not _ALERT then - _ALERT = function(msg) - local n = select("#", msg) - for i = 1, n do - local v = tostring(select(i, msg)) - io.stderr:write(v) - if i ~= n then - io.stderr:write("\t") - end - end - io.stderr:write("\n") - io.stderr:flush() - end -end - --- error -if not error then - error = function(msg) - coroutine.yield(msg) - end -end - --- print -if not print then - print = function(...) - local n = select("#", ...) - for i = 1, n do - local v = tostring(select(i, ...)) - io.write(v) - if i ~= n then - io.write("\t") - end - end - io.write("\n") - io.flush() - end -end - --- next -if not next then - next = function(t, k) - local m = getmetatable(t) - local n = m and m.__next or next - return n(t, k) - end -end - --- nextvar -if not nextvar then - nextvar = function(name) - local m = _G[name] - local n = m and m.__next or nextvar - return n(_G, name) - end -end - --- tostring -if not tostring then - tostring = function(n) - return "\""..(n).."\"" - end -end - --- tonumber (Requires FFI for atof function) -if not tonumber then - if ffi then - ffi.cdef("float atof(const char *_Str);") - tonumber = function(s) - return ffi.C.atof(s) - end - end -end - --- ipairs -if not ipairs then - iterate = function(t, i) - i = i + 1 - local v = t[i] - if v then - return i, v - end - end - - ipairs = function(t) - return iterate, t, 0 - end -end - --- pairs -if not pairs then - pairs = function(t) - return next, t, nil - end -end - --- foreach -if not foreach then - foreach = function(t, f) - for k, v in pairs(t) do - f(k, v) - end - end -end - --- foreachi -if not foreachi then - foreachi = function(t, f) - for k, v in ipairs(t) do - f(k, v) - end - end -end - --- foreachvar -if not foreachvar then - foreachvar = function(f) - local n, v = nextvar(nil) - while n do - local res = f(n, v) - if res then - return res - end - n, v = nextvar(n) - end - end -end - --- gcinfo -if not gcinfo then - gcinfo = function() - return collectgarbage("count") - end -end - --- settag -if not settag then - settag = function(t, tag) - setmetatable(t, tag) - end -end - --- assert -if not assert then - assert = function(v, m) - if not v then - m = m or "" - error("assertion failed! " .. m) - end - end -end - --- loadfile -if not loadfile then - loadfile = function(src) - local file = io.open(src) - content = "" - if not (_VERSION == "Lua 5.4" or _VERSION == "Lua 5.3") then - content = file:read("*all") - else - content = file:read("*a") - end - file:close() - return function() - if assert(load(content), "Loading code string failed!") then - return load(content) - end - end - end -end - --- loadstring -if not loadstring then - loadstring = function(str) - if assert(load(str), "Loading code string failed!") then - return load(str) - end - end -end - --- dofile -if not dofile then - dofile = function(path) - if assert(loadfile(path), "Loading file " .. path .. " failed!\n") then - return loadfile(path)() - end - end -end - --- dostring -if not dostring then - dostring = function(str) - if assert(load(str), "Loading code string failed!") then - return load(str) - end - end -end - --- loadlib -if not loadlib then - if package.loadlib then - loadlib = function(lib, fname) - return package.loadlib(lib, fname) - end - end -end - --- rawlen -if not rawlen then - rawlen = function(o) - if o then - return #o - end - end -end - --- rawget -if not rawget then - rawget = function(t, i) - if t then - return t[i] - end - end -end - --- rawset -if not rawset then - rawset = function(t, i, v) - if t then - t[i] = v - end - end -end - --- rawequal -if not rawequal then - rawequal = function(a, b) - if (a and type(a) == "table") and (b and type(b) == "table") then - return (#a == #b) - end - end -end - --- copytagmethods -if not copytagmethods then - copytagmethods = function(from, to) - local funcs = {} - for k, v in pairs(getmetatable(from)) do - if (type(v) == "function") then - funcs[k] = v - end - end - for k, v in pairs(getmetatable(to)) do - getmetatable(to)[k] = funcs[k] - end - end -end - --- gettagmethod -if not gettagmethod then - gettagmethod = function(tag, method) - return getmetatable(tag)[method] - end -end - --- settagmethod -if not settagmethod then - settagmethod = function(tag, event, newmethod) - getmetatable(tag)[event] = newmethod or function() end - end -end - --- call -if not call then - call = function(f, args) - if (type(f) == "function") then - return f(table.unpack(args)) - end - end -end - --- pcall -if not pcall then - pcall = function(f, ...) - local args = { ... } - local co = coroutine.create(f) - local err = coroutine.resume(co, table.unpack(args)) - if (coroutine.status == "dead") then - return true - else - return false, err - end - end -end - --- xpcall -if not xpcall then - xpcall = function(f, msgh, ...) - local args = { ... } - local co = coroutine.create(f) - local err = coroutine.resume(co, table.unpack(args)) - if (coroutine.status == "dead") then - return true - else - return false, "Error: " .. msgh - end - end -end - --- setenv -if not setenv then - setenv = function(t) - _ENV = t - --_G = t - end -end - --- getinfo -if not getinfo then - getinfo = debug.getinfo -end - --- getlocal -if not getlocal then - getlocal = debug.getlocal -end - --- setlocal -if not setlocal then - setlocal = debug.setlocal -end - --- getlinehook -if not getlinehook then - getlinehook = debug.gethook -end - --- setlinehook -if not setlinehook then - setlinehook = debug.sethook -end - --- rawgettable -if not rawgettable then - rawgettable = rawget -end - --- rawsettable -if not rawsettable then - rawsettable = rawset -end - --- debug.debug -if type(debug) == "function" then - local df = debug - debug = {} - debug.debug = df -end - --- module: table -table = require("table") or {} - --- Functions --- table.insert -if not table.insert then - table.insert = function(t, i, v) - if not v then - t[#t + 1] = i - else - t[i] = v - end - end -end - --- tinsert -if not tinsert then - tinsert = function(t, i, v) - if not v then - t[#t + 1] = i - else - t[i] = v - end - end -end - --- table.remove -if not table.remove then - table.remove = function(t, i) - if not i then - i = #t - end - local result = t[i] - t[i] = nil - return result - end -end - --- tremove -if not tremove then - tremove = function(t, i) - if not i then - i = #t - end - local result = t[i] - t[i] = nil - return result - end -end - --- table.concat -if not table.concat then - table.concat = function(t, s) - local result = "" - for str in ipairs(t, str) do - if (type(t[str]) == "string") then - if (str == #t) then s = "" end - result = result..(t[str]..s) - elseif (type(t[str]) == "number") then - if (str == #t) then s = "" end - result = result..(tostring(t[str])..s) - end - end - return result - end -end - --- table.unpack -if not table.unpack then - table.unpack = function(t, i) - i = i or 1 - if (i <= #t) then - return t[i], table.unpack(t, i + 1) - end - end -end - --- unpack -if not unpack then - unpack = function(t, i) - i = i or 1 - if (t[i] ~= nil) then - return t[i], unpack(t, i + 1) - end - end -end - --- table.pack -if not table.pack then - table.pack = function(...) - local t = { ... } - t.n = #t - return t - end -end - --- table.move -if not table.move then - table.move = function(t1, f, e, t, t2) - local nums = (e - 1) - for i = 0, nums, 1 do - t2[t + i] = t1[f + i] - end - end -end - --- table.sort -if not table.sort then - table.sort = function(t, f) - f = f or nil - if #t < 2 then - return t - end - local pivot = t[1] - if (type(pivot) == "string") then - pivot = #t[1] - end - local a, b, c = {}, {}, {} - for _, v in ipairs(t) do - if (type(f) == "function") then - if (type(v) == "number") then - if (f(v, pivot) == true) then - a[#a + 1] = v - elseif(f(v, pivot) == false) then - c[#c + 1] = v - elseif (type(f(v, pivot)) ~= "boolean") then - b[#b + 1] = v - end - end - else - if (type(v) == "number") then - if v < pivot then - a[#a + 1] = v - elseif v > pivot then - c[#c + 1] = v - else - b[#b + 1] = v - end - elseif (type(v) == "string") then - if #v < pivot then - a[#a + 1] = v - elseif #v > pivot then - c[#c + 1] = v - else - b[#b + 1] = v - end - end - end - end - a = table.sort(a) - c = table.sort(c) - for _, v in ipairs(b) do a[#a + 1] = v end - for _, v in ipairs(c) do a[#a + 1] = v end - return a - end -end - --- sort -if not sort then - sort = function(t, f) - f = f or nil - if #t < 2 then - return t - end - local pivot = t[1] - if (type(pivot) == "string") then - pivot = #t[1] - end - local a, b, c = {}, {}, {} - for _, v in ipairs(t) do - if (type(f) == "function") then - if (type(v) == "number") then - if (f(v, pivot) == true) then - a[#a + 1] = v - elseif(f(v, pivot) == false) then - c[#c + 1] = v - elseif (type(f(v, pivot)) ~= "boolean") then - b[#b + 1] = v - end - end - else - if (type(v) == "number") then - if v < pivot then - a[#a + 1] = v - elseif v > pivot then - c[#c + 1] = v - else - b[#b + 1] = v - end - elseif (type(v) == "string") then - if #v < pivot then - a[#a + 1] = v - elseif #v > pivot then - c[#c + 1] = v - else - b[#b + 1] = v - end - end - end - end - a = sort(a) - c = sort(c) - for _, v in ipairs(b) do a[#a + 1] = v end - for _, v in ipairs(c) do a[#a + 1] = v end - return a - end -end - --- table.getn -if not table.getn then - table.getn = function(t) - if type(t.n) == "number" then - return t.n - end - local m = 0 - for i, _ in t do - if (type(i) == "number" and i > max) then - m = i - end - end - return m - end -end - --- getn -if not getn then - getn = function(t) - if type(t.n) == "number" then - return t.n - end - local m = 0 - for i, _ in t do - if (type(i) == "number" and i > max) then - m = i - end - end - return m - end -end - --- table.setn -if not table.setn then - table.setn = function(t, n) - setmetatable(t, { - __len = function() - return n - end - }) - end -end - --- table.foreach -if not table.foreach then - table.foreach = function(t, f) - for k, v in pairs(t) do - if (type(f) == "function") then - f(k, v) - end - end - end -end - --- table.foreachi -if not table.foreachi then - table.foreachi = function(t, f) - for k, v in pairs(t) do - if (type(f) == "function") then - if (type(k) == "number") then - f(k, v) - end - end - end - end -end - --- table.maxn -if not table.maxn then - table.maxn = function(t) - local result = 0 - for i, k in ipairs(t) do - if (i > result) then - result = i - end - end - return result - end -end - --- table_ext_solar2d.lua --- Written by Rabia Alhaffar in 11/March/2021 --- Polyfill for some table functions from Corona SDK/Solar2D --- Updated: 27/March/2021 -if CoronaPrototype then - - -- table.indexOf - if not table.indexOf then - table.indexOf = function(arr, elem) - for i = 1, #arr do - if arr[i] == elem then - return i - end - end - end - end - - -- table.copy - if not table.copy then - table.copy = function(...) - local arg = { ... } - local result = {} - if #arg == 1 then - return arg[1] - else - for i = 1, #arg do - for j = 1, #arg[i] do - table.insert(result, arg[i][j]) - end - end - end - return result - end - end - -end - --- table_ext_amulet.lua --- Written by Rabia Alhaffar in 11/March/2021 --- Polyfill for some table functions from Amulet --- Updated: 27/March/2021 -if (type(am) == "table") then - - -- table.search - if not table.search then - table.search = function(arr, elem) - for i = 1, #arr do - if arr[i] == elem then - return i - end - end - end - end - - -- table.clear - if not table.clear then - table.clear = function(t) - for k, v in pairs(t) do - if t[k] then - t[k] = nil - end - end - end - end - - -- table.remove_all - if not table.remove_all then - table.remove_all = function(arr, elem) - for i = 1, #arr do - if arr[i] == elem then - arr[i] = nil - end - end - end - end - - -- table.append - if not table.append then - table.append = function(t1, t2) - for i = 1, #t2 do - table.insert(t1, t2[i]) - end - end - end - - -- table.merge - if not table.merge then - table.merge = function(t1, t2) - for k, v in pairs(t2) do - t1[k] = t2[k] - end - end - end - - -- table.keys - if not table.keys then - table.keys = function(t) - local result = {} - for k in pairs(t) do - table.insert(result, k) - end - end - return result - end - - -- table.values - if not table.values then - table.values = function(t) - local result = {} - for k, v in pairs(t) do - table.insert(result, v) - end - end - return result - end - - -- table.count - if not table.count then - table.count = function(t) - local result = 0 - for k, v in pairs(t) do - if t[k] then - result = result + 1 - end - end - return result - end - end - - -- table.filter - if not table.filter then - table.filter = function(t, f) - local result = {} - for i = 1, #t do - local a = t[i] - local b = t[i + 1] or t[i] - if (f(a, b) == true) then - t[i] = a - t[i + 1] = b - else - t[i] = b - t[i + 1] = a - end - end - return result - end - end - - -- table.tostring - if not table.tostring then - table.tostring = function(t) - local result = "{" - for k, v in pairs(t) do - if assert(type(tonumber(k)) == "number") then - result = result .. v .. "," - else - result = result .. "\"" .. k .. "\"" .. " = " .. v .. "," - end - end - result = result .. "}" - return result - end - end - - -- table.shuffle - if not table.shuffle then - table.shuffle = function(t, r) - math.randomseed(os.time()) - for i = #t, 2, -1 do - local j = r or math.random(i) - t[i], t[j] = t[j], t[i] - end - return t - end - end - -end - --- module: package (Config for require function polyfill) -if package then - if ffi then - if not package.loaddir then - package.loaddir = "lualibs" - end - if not package.config then - if (ffi.os == "Windows") then - package.config = "\\\n;\n?\n!\n-" - else - package.config = "///n;/n?/n!/n-" - end - end - end -end - --- module: os (Requires FFI) -os = require("os") or {} - -if ffi then - if ffi.arch == "x86" then - ffi.cdef([[ - typedef long __time32_t; - typedef __time32_t time_t; - ]]) - elseif ffi.arch == "x64" then - ffi.cdef([[ - typedef __int64 __time64_t; - typedef __time64_t time_t; - ]]) - end - ffi.cdef([[ - typedef long clock_t; - time_t time(time_t *_Time); - char * ctime(const time_t *_Time); - int system(const char *_Command); - void exit(int _Code); - int rename(const char *_OldFilename, const char *_NewFilename); - int remove(const char *_Filename); - char* setlocale(int _Category, const char *_Locale); - char* getenv(const char *_VarName); - double difftime(time_t _Time1, time_t _Time2); - char tmpnam(char *_Buffer); - char *_strdate(char *_Buffer); - clock_t clock(void); - ]]) -end - --- os.time -if not os.time then - if ffi then - os.time = function() - return ffi.C.time(ffi.new("time_t *")) - end - end -end - --- os.execute -if not os.execute then - if ffi then - os.execute = function(cmd) - return (ffi.C.system(cmd) == 0) - end - end -end - --- execute -if not execute then - if ffi then - execute = function(cmd) - return (ffi.C.system(cmd) == 0) - end - end -end - --- os.exit -if not os.exit then - if ffi then - os.exit = function(c) - return ffi.C.exit(c or 0) - end - end -end - --- exit -if not exit then - if ffi then - exit = function(c) - return ffi.C.exit(c or 0) - end - end -end - --- os.rename -if not os.rename then - if ffi then - os.rename = function(o, n) - return (ffi.C.rename(o, n) == 0) - end - end -end - --- rename -if not rename then - if ffi then - rename = function(o, n) - return (ffi.C.rename(o, n) == 0) - end - end -end - --- os.remove -if not os.remove then - if ffi then - os.remove = function(f) - return (ffi.C.remove(f) == 0) - end - end -end - --- remove -if not remove then - if ffi then - remove = function(f) - return (ffi.C.remove(f) == 0) - end - end -end - --- os.setlocale -if not os.setlocale then - if ffi then - os.setlocale = function(v) - return ffi.string(ffi.C.setlocale(v)) - end - end -end - --- setlocale -if not setlocale then - if ffi then - setlocale = function(v) - return ffi.string(ffi.C.setlocale(v)) - end - end -end - --- os.getenv -if not os.getenv then - if ffi then - os.getenv = function(v) - return ffi.string(ffi.C.getenv(v)) - end - end -end - --- getenv -if not getenv then - if ffi then - getenv = function(v) - return ffi.string(ffi.C.getenv(v)) - end - end -end - --- os.difftime -if not os.difftime then - if ffi then - os.difftime = function(t1, t2) - return ffi.C.difftime(t1, t2) - end - end -end - --- os.tmpname -if not os.tmpname then - if ffi then - os.tmpname = function(str) - return ffi.string(ffi.C.tmpnam(str)) - end - end -end - --- os.date -if not os.date == "nil" then - if ffi then - os.date = function(form) - return ffi.string(ffi.C._strdate(form)) - end - end -end - --- date -if not date == "nil" then - if ffi then - date = function(form) - return ffi.string(ffi.C._strdate(form)) - end - end -end - --- os.clock -if not os.clock then - if ffi then - os.clock = function() - return ffi.C.clock() - end - end -end - --- clock -if not clock then - if ffi then - clock = function() - return ffi.C.clock() - end - end -end - --- module: math -math = require("math") or {} - --- Variables --- math.pi -if not math.pi then - math.pi = 3.14159265358979323846 -end - --- PI -if not PI then - PI = 3.14159265358979323846 -end - --- math.huge -if not math.huge then - math.huge = 1 / 0 -end - --- math.mininteger -if not math.mininteger then - math.mininteger = -2147483648 -end - --- math.maxinteger -if not math.maxinteger then - math.maxinteger = 2147483647 -end - --- Functions --- math.sqrt -if not math.sqrt then - if ffi then - ffi.cdef("double sqrt(double);") - math.sqrt = function(n) - return ffi.C.sqrt(n) - end - end -end - --- sqrt -if not sqrt then - if ffi then - ffi.cdef("double sqrt(double);") - sqrt = function(n) - return ffi.C.sqrt(n) - end - end -end - --- math.sinh -if not math.sinh then - if ffi then - ffi.cdef("double sinh(double);") - math.sinh = function(n) - return ffi.C.sinh(n) - end - end -end - --- math.cosh -if not math.cosh then - if ffi then - ffi.cdef("double cosh(double);") - math.cosh = function(n) - return ffi.C.cosh(n) - end - end -end - --- math.tanh -if not math.tanh then - if ffi then - ffi.cdef("double tanh(double);") - math.tanh = function(n) - return ffi.C.tanh(n) - end - end -end - --- math.asin -if not math.asin then - if ffi then - ffi.cdef("double asin(double);") - math.asin = function(n) - return ffi.C.asin(n) - end - else - math.asin = function(n) - return (n + (1 / 2) * (math.pow(n, 3) / 3) + ((1 * 3) / (2 * 4)) * (math.pow(n, 5) / 5) + ((1 * 3 * 5) / (2 * 4 * 6)) * (math.pow(n, 7) / 7)) - end - end -end - --- asin -if not asin then - if ffi then - ffi.cdef("double asin(double);") - asin = function(n) - return ffi.C.asin(n) - end - else - asin = function(n) - return (n + (1 / 2) * (math.pow(n, 3) / 3) + ((1 * 3) / (2 * 4)) * (math.pow(n, 5) / 5) + ((1 * 3 * 5) / (2 * 4 * 6)) * (math.pow(n, 7) / 7)) - end - end -end - --- math.acos -if not math.acos then - if ffi then - ffi.cdef("double acos(double);") - math.acos = function(n) - return ffi.C.acos(n) - end - else - math.acos = function(n) - return (-0.69813170079773212 * n * n - 0.87266462599716477) * n + 1.5707963267948966 - end - end -end - --- acos -if not acos then - if ffi then - ffi.cdef("double acos(double);") - acos = function(n) - return ffi.C.acos(n) - end - else - acos = function(n) - return (-0.69813170079773212 * n * n - 0.87266462599716477) * n + 1.5707963267948966 - end - end -end - --- math.atan -if not math.atan then - if ffi then - math.atan = function(...) - local args = { ... } - if (#args == 1) then - ffi.cdef("double atan(double);") - return ffi.C.atan(args[1]) - elseif (#args == 2) then - ffi.cdef("double atan2(double, double);") - return ffi.C.atan2(args[1], args[2]) - end - end - end -end - --- atan -if not atan then - if ffi then - atan = function(...) - local args = { ... } - if (#args == 1) then - ffi.cdef("double atan(double);") - return ffi.C.atan(args[1]) - elseif (#args == 2) then - ffi.cdef("double atan2(double, double);") - return ffi.C.atan2(args[1], args[2]) - end - end - end -end - --- math.atan2 -if not math.atan2 then - if ffi then - ffi.cdef("double atan2(double, double);") - math.atan2 = function(x, y) - return ffi.C.atan2(args[1], args[2]) - end - end -end - --- atan2 -if not atan2 then - if ffi then - ffi.cdef("double atan2(double, double);") - atan2 = function(x, y) - return ffi.C.atan2(args[1], args[2]) - end - end -end - --- math.exp -if not math.exp then - if ffi then - ffi.cdef("double exp(double);") - math.exp = function(n) - return ffi.C.exp(n) - end - end -end - --- exp -if not exp then - if ffi then - ffi.cdef("double exp(double);") - exp = function(n) - return ffi.C.exp(n) - end - end -end - --- math.log -if not math.log then - if ffi then - ffi.cdef("double log(double);") - math.log = function(n) - return ffi.C.log(n) - end - end -end - --- log -if not log then - if ffi then - ffi.cdef("double log(double);") - log = function(n) - return ffi.C.log(n) - end - end -end - --- math.log10 -if not math.log10 then - if ffi then - ffi.cdef("double log10(double);") - math.log10 = function(n) - return ffi.C.log10(n) - end - end -end - --- log10 -if not log10 then - if ffi then - ffi.cdef("double log10(double);") - log10 = function(n) - return ffi.C.log10(n) - end - end -end - --- math.ldexp -if not math.ldexp then - if ffi then - ffi.cdef("double ldexp(double, int);") - math.ldexp = function(x, y) - return ffi.C.ldexp(x, y) - end - end -end - --- ldexp -if not ldexp then - if ffi then - ffi.cdef("double ldexp(double, int);") - ldexp = function(x, y) - return ffi.C.ldexp(x, y) - end - end -end - --- math.frexp -if not math.frexp then - if ffi then - ffi.cdef("double frexp(double, int*);") - math.frexp = function(x, y) - return ffi.C.frexp(x, y) - end - end -end - --- frexp -if not frexp then - if ffi then - ffi.cdef("double frexp(double, int*);") - frexp = function(x, y) - return ffi.C.frexp(x, y) - end - end -end - --- math.modf -if not math.modf then - if ffi then - ffi.cdef("double modf(double, double*);") - math.modf = function(x, y) - return ffi.C.modf(x, y) - end - end -end - --- math.mod -if not math.mod then - if ffi then - ffi.cdef("double fmod(double, double);") - math.mod = function(x, y) - return ffi.C.fmod(x, y) - end - end -end - --- math.fmod -if not math.fmod then - if ffi then - ffi.cdef("double fmod(double, double);") - math.fmod = function(x, y) - return ffi.C.fmod(x, y) - end - end -end - --- mod -if not mod then - if ffi then - ffi.cdef("double fmod(double, double);") - mod = function(x, y) - return ffi.C.fmod(x, y) - end - end -end - --- math.pow -if not math.pow then - if ffi then - ffi.cdef("double pow(double, double);") - math.pow = function(n, p) - return ffi.C.pow(n, p) - end - else - math.pow = function(n, p) - local e = n - if (p == 0) then - return 1 - end - if (p < 0) then - p = p * -1 - end - for c = p, 2, -1 do - e = e * n - end - return e - end - end -end - --- math.abs -if not math.abs then - math.abs = function(n) - if (n < 0) then - return -n - else - return n - end - end -end - --- abs -if not abs then - abs = function(n) - if (n < 0) then - return -n - else - return n - end - end -end - --- math.deg -if not math.deg then - math.deg = function(n) - return n * (180 / math.pi) - end -end - --- deg -if not deg then - deg = function(n) - return n * (180 / math.pi) - end -end - --- math.rad -if not math.rad then - math.rad = function(d) - return d * (math.pi / 180) - end -end - --- rad -if not rad then - rad = function(d) - return d * (math.pi / 180) - end -end - --- math.min -if not math.min then - math.min = function(x, y) - if x < y then - return x - else - return y - end - end -end - --- min -if not min then - min = function(x, y) - if x < y then - return x - else - return y - end - end -end - --- math.max -if not math.max then - math.max = function(x, y) - if x > y then - return x - else - return y - end - end -end - --- max -if not max then - max = function(x, y) - if x > y then - return x - else - return y - end - end -end - --- math.tointeger -if not math.tointeger then - math.tointeger = function(n) - return math.floor(n) - end -end - --- math.hypot -if not math.hypot then - if ffi then - ffi.cdef("double hypot(double, double);") - math.hypot = function(x, y) - return ffi.C.hypot(x, y) - end - else - math.hypot = function(x, y) - return math.sqrt(math.pow(x, 2) + math.pow(y, 2)) - end - end -end - --- math.sin -if not math.sin then - if ffi then - ffi.cdef("double sin(double);") - math.sin = function(n) - return ffi.C.sin(n) - end - end -end - --- sin -if not sin then - if ffi then - ffi.cdef("double sin(double);") - sin = function(n) - return ffi.C.sin(n) - end - end -end - --- math.cos -if not math.cos then - if ffi then - ffi.cdef("double cos(double);") - math.cos = function(n) - return ffi.C.cos(n) - end - else - function fact(a) - if (a == 1) or (a == 0) then - return 1 - end - local e = 1 - for c = a, 1, -1 do - e = e * c - end - return e - end - - function correctRadians(v) - while v > math.pi * 2 do - v = v - math.pi * 2 - end - while v < -math.pi * 2 do - v = v + math.pi * 2 - end - return v - end - - math.cos = function(a, b) - local e = 1 - a = correctRadians(a) - b = b or 10 - for i = 1, b do - e = e + (math.pow(-1, i) * math.pow(a, 2 * i) / fact(2 * i)) - end - return e - end - end -end - --- cos -if not cos then - if ffi then - ffi.cdef("double cos(double);") - cos = function(n) - return ffi.C.cos(n) - end - else - function fact(a) - if (a == 1) or (a == 0) then - return 1 - end - local e = 1 - for c = a, 1, -1 do - e = e * c - end - return e - end - - function correctRadians(v) - while v > math.pi * 2 do - v = v - math.pi * 2 - end - while v < -math.pi * 2 do - v = v + math.pi * 2 - end - return v - end - - cos = function(a, b) - local e = 1 - a = correctRadians(a) - b = b or 10 - for i = 1, b do - e = e + (math.pow(-1, i) * math.pow(a, 2 * i) / fact(2 * i)) - end - return e - end - end -end - --- math.tan -if not math.tan then - if ffi then - ffi.cdef("double tan(double);") - math.tan = function(n) - return ffi.C.tan(n) - end - end -end - --- tan -if not tan then - if ffi then - ffi.cdef("double tan(double);") - tan = function(n) - return ffi.C.tan(n) - end - end -end - --- math.ult -if not math.ult then - if ffi then - math.ult = function(x, y) - return (ffi.cast("unsigned int", x) < ffi.cast("unsigned int", y)) - end - end -end - --- math.ceil -if not math.ceil then - if ffi then - math.ceil = function(n) - ffi.cdef("double ceil(double);") - return ffi.C.ceil(n) - end - end -end - --- ceil -if not ceil then - if ffi then - ceil = function(n) - ffi.cdef("double ceil(double);") - return ffi.C.ceil(n) - end - end -end - --- math.round -if not math.round then - if ffi then - math.round = function(n) - ffi.cdef("double round(double);") - return ffi.C.round(n) - end - end -end - --- round -if not round then - if ffi then - round = function(n) - ffi.cdef("double round(double);") - return ffi.C.round(n) - end - end -end - --- math.floor -if not math.floor then - if ffi then - math.floor = function(n) - ffi.cdef("double floor(double);") - return ffi.C.floor(n) - end - end -end - --- floor -if not floor then - if ffi then - floor = function(n) - ffi.cdef("double floor(double);") - return ffi.C.floor(n) - end - end -end - --- math.randomseed -if not math.randomseed then - if ffi then - ffi.cdef("void srand(unsigned int _Seed);") - math.randomseed = function(n) - ffi.C.srand(n) - end - end -end - --- randomseed -if not randomseed then - if ffi then - ffi.cdef("void srand(unsigned int _Seed);") - randomseed = function(n) - ffi.C.srand(n) - end - end -end - --- math.random -if not math.random then - if ffi then - ffi.cdef("int rand(void);") - math.random = function(...) - local pownum = 100000 - local n = { ... } - if (#n == 0) then - return (ffi.C.rand() / pownum) - elseif (#n == 1) then - local num = (n[1] * (n[1] - 2)) - local result = math.floor((ffi.C.rand() / pownum) * num) - if (result > n[1]) then - return n[1] - end - return result - elseif (#n == 2) then - local num1 = (n[1] * (n[1] - 2)) - local num2 = (n[2] * (n[2] - 2)) - local result = math.floor((ffi.C.rand() / pownum) * (num2 - num1) + num1) - if (result > n[2]) then - return n[2] - end - if (result < n[1]) then - return n[1] - end - return result - end - end - end -end - --- random -if not random then - if ffi then - ffi.cdef("int rand(void);") - random = function(...) - local pownum = 100000 - local n = { ... } - if (#n == 0) then - return (ffi.C.rand() / pownum) - elseif (#n == 1) then - local num = (n[1] * (n[1] - 2)) - local result = math.floor((ffi.C.rand() / pownum) * num) - if (result > n[1]) then - return n[1] - end - return result - elseif (#n == 2) then - local num1 = (n[1] * (n[1] - 2)) - local num2 = (n[2] * (n[2] - 2)) - local result = math.floor((ffi.C.rand() / pownum) * (num2 - num1) + num1) - if (result > n[2]) then - return n[2] - end - if (result < n[1]) then - return n[1] - end - return result - end - end - end -end - --- module: bit32 -bit32 = bit32 or {} - -bit32.bits = 32 -bit32.powtab = { 1 } - -for b = 1, bit32.bits - 1 do - bit32.powtab[#bit32.powtab + 1] = math.pow(2, b) -end - --- Functions --- bit32.band -if not bit32.band then - bit32.band = function(a, b) - local result = 0 - for x = 1, bit32.bits do - result = result + result - if (a < 0) then - if (b < 0) then - result = result + 1 - end - end - a = a + a - b = b + b - end - return result - end -end - --- bit32.bor -if not bit32.bor then - bit32.bor = function(a, b) - local result = 0 - for x = 1, bit32.bits do - result = result + result - if (a < 0) then - result = result + 1 - elseif (b < 0) then - result = result + 1 - end - a = a + a - b = b + b - end - return result - end -end - --- bit32.bnot -if not bit32.bnot then - bit32.bnot = function(x) - return bit32.bxor(x, math.pow((bit32.bits or math.floor(math.log(x, 2))), 2) - 1) - end -end - --- bit32.lshift -if not bit32.lshift then - bit32.lshift = function(a, n) - if (n > bit32.bits) then - a = 0 - else - a = a * bit32.powtab[n] - end - return a - end -end - --- bit32.rshift -if not bit32.rshift then - bit32.rshift = function(a, n) - if (n > bit32.bits) then - a = 0 - elseif (n > 0) then - if (a < 0) then - a = a - bit32.powtab[#bit32.powtab] - a = a / bit32.powtab[n] - a = a + bit32.powtab[bit32.bits - n] - else - a = a / bit32.powtab[n] - end - end - return a - end -end - --- bit32.arshift -if not bit32.arshift then - bit32.arshift = function(a, n) - if (n >= bit32.bits) then - if (a < 0) then - a = -1 - else - a = 0 - end - elseif (n > 0) then - if (a < 0) then - a = a - bit32.powtab[#bit32.powtab] - a = a / bit32.powtab[n] - a = a - bit32.powtab[bit32.bits - n] - else - a = a / bit32.powtab[n] - end - end - return a - end -end - --- bit32.bxor -if not bit32.bxor then - bit32.bxor = function(a, b) - local result = 0 - for x = 1, bit32.bits, 1 do - result = result + result - if (a < 0) then - if (b >= 0) then - result = result + 1 - end - elseif (b < 0) then - result = result + 1 - end - a = a + a - b = b + b - end - return result - end -end - --- bit32.btest -if not bit32.btest then - bit32.btest = function(a, b) - return (bit32.band(a, b) ~= 0) - end -end - --- bit32.lrotate -if not bit32.lrotate then - bit32.lrotate = function(a, b) - local bits = bit32.band(b, bit32.bits - 1) - a = bit32.band(a, 0xffffffff) - a = bit32.bor(bit32.lshift(a, b), bit32.rshift(a, ((bit32.bits - 1) - b))) - return bit32.band(n, 0xffffffff) - end -end - --- bit32.rrotate -if not bit32.rrotate then - bit32.rrotate = function(a, b) - return bit32.lrotate(a, -b) - end -end - --- bit32.extract -if not bit32.extract then - bit32.extract = function(a, b, c) - c = c or 1 - return bit32.band(bit32.rshift(a, b, c), math.pow(b, 2) - 1) - end -end - --- bit32.replace -if not bit32.replace then - bit32.replace = function(a, b, c, d) - d = d or 1 - local mask1 = math.pow(d, 2) -1 - b = bit32.band(b, mask1) - local mask = bit32.bnot(bit32.lshift(mask1, c)) - return bit32.band(n, mask) + bit32.lshift(b, c) - end -end - --- module: bit -bit = bit or {} - -bit.bits = 32 -bit.powtab = { 1 } - -for b = 1, bit.bits - 1 do - bit.powtab[#bit.powtab + 1] = math.pow(2, b) -end - --- Functions --- bit.band -if not bit.band then - bit.band = function(a, b) - local result = 0 - for x = 1, bit.bits do - result = result + result - if (a < 0) then - if (b < 0) then - result = result + 1 - end - end - a = a + a - b = b + b - end - return result - end -end - --- bit.bor -if not bit.bor then - bit.bor = function(a, b) - local result = 0 - for x = 1, bit.bits do - result = result + result - if (a < 0) then - result = result + 1 - elseif (b < 0) then - result = result + 1 - end - a = a + a - b = b + b - end - return result - end -end - --- bit.bnot -if not bit.bnot then - bit.bnot = function(x) - return bit.bxor(x, math.pow((bit.bits or math.floor(math.log(x, 2))), 2) - 1) - end -end - --- bit.lshift -if not bit.lshift then - bit.lshift = function(a, n) - if (n > bit.bits) then - a = 0 - else - a = a * bit.powtab[n] - end - return a - end -end - --- bit.rshift -if not bit.rshift then - bit.rshift = function(a, n) - if (n > bit.bits) then - a = 0 - elseif (n > 0) then - if (a < 0) then - a = a - bit.powtab[#bit.powtab] - a = a / bit.powtab[n] - a = a + bit.powtab[bit.bits - n] - else - a = a / bit.powtab[n] - end - end - return a - end -end - --- bit.arshift -if not bit.arshift then - bit.arshift = function(a, n) - if (n >= bit.bits) then - if (a < 0) then - a = -1 - else - a = 0 - end - elseif (n > 0) then - if (a < 0) then - a = a - bit.powtab[#bit.powtab] - a = a / bit.powtab[n] - a = a - bit.powtab[bit.bits - n] - else - a = a / bit.powtab[n] - end - end - return a - end -end - --- bit.bxor -if not bit.bxor then - bit.bxor = function(a, b) - local result = 0 - for x = 1, bit.bits, 1 do - result = result + result - if (a < 0) then - if (b >= 0) then - result = result + 1 - end - elseif (b < 0) then - result = result + 1 - end - a = a + a - b = b + b - end - return result - end -end - --- bit.rol -if not bit.rol then - bit.rol = function(a, b) - local bits = bit.band(b, bit.bits - 1) - a = bit.band(a,0xffffffff) - a = bit.bor(bit.lshift(a, b), bit.rshift(a, ((bit.bits - 1) - b))) - return bit.band(n, 0xffffffff) - end -end - --- bit.ror -if not bit.ror then - bit.ror = function(a, b) - return bit.rol(a, -b) - end -end - --- bit.bswap -if not bit.bswap then - bit.bswap = function(n) - local a = bit.band(n, 0xff) - n = bit.rshift(n, 8) - local b = bit.band(n, 0xff) - n = bit.rshift(n, 8) - local c = bit.band(n, 0xff) - n = bit.rshift(n, 8) - local d = bit.band(n, 0xff) - return bit.lshift(bit.lshift(bit.lshift(a, 8) + b, 8) + c, 8) + d - end -end - --- bit.tobit -if not bit.tobit then - bit.tobit = function(n) - local MOD = 2^32 - n = n % MOD - if (n >= 0x80000000) then - n = n - MOD - end - return n - end -end - --- bit.tohex -if not bit.tohex then - bit.tohex = function(x, n) - n = n or 8 - local up - if n <= 0 then - if n == 0 then - return '' - end - up = true - n = -n - end - x = bit.band(x, 16^n-1) - return ('%0'..n..(up and 'X' or 'x')):format(x) - end -end - --- module: io -io = require("io") or {} - -if not _INPUT then - _INPUT = io.stdin -end - -if not _OUTPUT then - _OUTPUT = io.stdout -end - -if not _STDIN then - _STDIN = io.stdin -end - -if not _STDOUT then - _STDOUT = io.stdout -end - -if not _STDERR then - _STDERR = io.stderr -end - --- Used by io.input and io.output, And works as usable file with IO functions lol -io.__DEFAULT__INPUT__FILE__ = nil -io.__DEFAULT__OUTPUT__FILE__ = nil - -if ffi then - ffi.cdef([[ - struct _iobuf { - char *_ptr; - int _cnt; - char *_base; - int _flag; - int _file; - int _charbuf; - int _bufsiz; - char *_tmpfname; - }; - typedef struct _iobuf FILE; - typedef struct SExIO_Stream { - FILE *f; /* stream (NULL for incompletely created streams) */ - } SExIO_Stream; - ]]) -end - --- Native file type -_FILE = {} - -function _FILE:new(f, m, s) - o = {} - setmetatable(o, self) - self.__index = self - self.__FILE = f - self.__MODE = m - self.__STATE = "file" - self.__SRC = s - return o -end - -function _FILE:close() - if ffi then - ffi.cdef("int fclose(FILE *_File);") - local result = (ffi.C.fclose(self.__FILE) == 0) - if result then - self.__STATE = "closed file" - end - end -end - -function _FILE:flush() - if ffi then - ffi.cdef("int fflush(FILE *_File);") - return (ffi.C.flush(self.__FILE) == 0) - end -end - -function _FILE:seek(w, o) - if ffi then - ffi.cdef("int fseek(FILE *stream, long int offset, int whence);") - if (w == "set") then - return ffi.C.fseek(self.__FILE, o, 0) - elseif (w == "cur") then - return ffi.C.fseek(self.__FILE, o, 1) - elseif (w == "end") then - return ffi.C.fseek(self.__FILE, o, 2) - else - return ffi.C.fseek(self.__FILE, o, w) - end - end -end - -function _FILE:read(t) - if (t == "*all" or t == "*a") then - while not cast("bool", ffi.C.feof(f)) do - local content = "" - local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f))) - if (ch ~= nil) then - content = content .. ch - end - end - elseif (t == "*line" or t == "*l") then - if not cast("bool", ffi.C.feof(f)) then - local line = "" - while not cast("bool", ffi.C.feof(f)) do - local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f))) - if (ch == "\n") then - break - else - line = line .. ch - end - end - return line - end - elseif (t == "*number" or t == "*n") then - local line = "" - while not cast("bool", ffi.C.feof(f)) do - local ch = tonumber(ffi.string(ffi.cast("char", ffi.C.fgetc(f)))) - if not ch then - break - else - line = line .. ch - end - end - return line - elseif (type(t) == "number") then - if not cast("bool", ffi.C.feof(f)) then - local line = ffi.new("char[?]", t) - return ffi.string(ffi.C.fgets(line, t, f)) - end - end -end - -function _FILE:write(...) - if ffi then - ffi.cdef("int fprintf(FILE *stream, const char *format, ...);") - local args = { ... } - if (#args == 0) then - args[1] = f - end - local form = args[1] - table.remove(args, 1) - if (#args == 0) then - ffi.C.fprintf(f.__FILE, form) - else - ffi.C.fprintf(f.__FILE, form, table.unpack(args)) - end - end -end - -function _FILE:setvbuf(m, s) - if ffi then - ffi.cdef("int setvbuf(FILE *stream, char *buffer, int mode, size_t size);") - if (m == "no") then - return (ffi.C.setvbuf(self.__FILE, nil, 0x0004, s) == 0) - elseif (m == "full") then - return (ffi.C.setvbuf(self.__FILE, nil, 0x0000, s) == 0) - elseif (m == "line") then - return (ffi.C.setvbuf(self.__FILE, nil, 0x0040, s) == 0) - end - end -end - -function _FILE:lines() - if ffi then - local lines = {} - local line = "" - while not cast("bool", ffi.C.feof(self.__FILE)) do - local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(self.__FILE))) - if (ch == "\n") then - lines[#lines + 1] = line - line = "" - else - line = line .. ch - end - end - return ipairs(lines) - end -end - --- Functions and Variables --- io.tmpfile -if not io.tmpfile then - io.tmpfile = function() - if ffi then - ffi.cdef("FILE *tmpfile(void);") - return _FILE:new(ffi.C.tmpfile(), nil, nil) - end - end -end - --- tmpfile -if not tmpfile then - tmpfile = function() - if ffi then - ffi.cdef("FILE *tmpfile(void);") - return _FILE:new(ffi.C.tmpfile(), nil, nil) - end - end -end - --- io.open -if not io.open then - if ffi then - io.open = function(s, m) - ffi.cdef("FILE *fopen(const char *_Filename,const char *_Mode);") - return _FILE:new(ffi.C.fopen(s, m), m, s) - end - end -end - --- openfile -if not openfile then - if ffi then - openfile = function(s, m) - ffi.cdef("FILE *fopen(const char *_Filename,const char *_Mode);") - return _FILE:new(ffi.C.fopen(s, m), m, s) - end - end -end - --- io.write -if not io.write then - if ffi then - io.write = function(f, ...) - ffi.cdef("int fprintf(FILE *stream, const char *format, ...);") - local args = { ... } - if ((#args == 0) and (io.__DEFAULT__OUTPUT__FILE__)) then - args[1] = f - return (ffi.C.fprintf(io.__DEFAULT__OUTPUT__FILE__, args[1]) == 0) - elseif (f.__FILE) then - local form = args[1] - table.remove(args, 1) - return (ffi.C.fprintf(f.__FILE, form, table.unpack(args)) == 0) - end - end - end -end - --- write -if not write then - if ffi then - write = function(f, ...) - ffi.cdef("int fprintf(FILE *stream, const char *format, ...);") - local args = { ... } - if ((#args == 0) and (io.__DEFAULT__OUTPUT__FILE__)) then - args[1] = f - return (ffi.C.fprintf(io.__DEFAULT__OUTPUT__FILE__, args[1]) == 0) - elseif (f.__FILE) then - local form = args[1] - table.remove(args, 1) - return (ffi.C.fprintf(f.__FILE, form, table.unpack(args)) == 0) - end - end - end -end - --- io.seek -if not io.seek then - if ffi then - io.seek = function(f, w, o) - ffi.cdef("int fseek(FILE *stream, long int offset, int whence);") - if (w == "set") then - return ffi.C.fseek(f, o, 0) - elseif (w == "cur") then - return ffi.C.fseek(f, o, 1) - elseif (w == "end") then - return ffi.C.fseek(f, o, 2) - else - return ffi.C.fseek(f, o, w) - end - end - end -end - --- seek -if not seek then - if ffi then - seek = function(f, w, o) - ffi.cdef("int fseek(FILE *stream, long int offset, int whence);") - if (w == "set") then - return ffi.C.fseek(f, o, 0) - elseif (w == "cur") then - return ffi.C.fseek(f, o, 1) - elseif (w == "end") then - return ffi.C.fseek(f, o, 2) - else - return ffi.C.fseek(f, o, w) - end - end - end -end - --- io.read -if not io.read then - if ffi then - io.read = function(f, t) - ffi.cdef([[ - char *fgets(char *str, int n, FILE *stream); - int fgetc(FILE *stream); - int feof(FILE *stream); - int scanf(const char *format, ...); - ]]) - if t and f then - if (t == "*all" or t == "*a") then - while not cast("bool", ffi.C.feof(f)) do - local content = "" - local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f))) - if (ch ~= nil) then - content = content .. ch - end - end - elseif (t == "*line" or t == "*l") then - if not cast("bool", ffi.C.feof(f)) then - local line = "" - while not cast("bool", ffi.C.feof(f)) do - local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f))) - if (ch == "\n") then - break - else - line = line .. ch - end - end - return line - end - elseif (t == "*number" or t == "*n") then - local line = "" - while not cast("bool", ffi.C.feof(f)) do - local ch = tonumber(ffi.string(ffi.cast("char", ffi.C.fgetc(f)))) - if not ch then - break - else - line = line .. ch - end - end - return line - elseif (type(t) == "number") then - if not cast("bool", ffi.C.feof(f)) then - local line = ffi.new("char[?]", t) - return ffi.string(ffi.C.fgets(line, t, f)) - end - elseif io.__DEFAULT__INPUT__FILE__ then - --if not cast("bool", ffi.C.feof(io.__DEFAULT__INPUT__FILE__)) then - --local line = ffi.new("char[?]", 512) - local line = "" - while not cast("bool", ffi.C.feof(io.__DEFAULT__INPUT__FILE__)) do - local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(io.__DEFAULT__INPUT__FILE__))) - if (ch == "\n") then - break - else - line = line .. ch - end - end - return line - --return ffi.string(ffi.C.fgets(line, 512, io.__DEFAULT__INPUT__FILE__)) - else - local input = ffi.new("char[?]", 512) - local execution_code = ffi.C.scanf("%s\0", input) - return input, (execution_code == 0) - end - end - end - end -end - --- read -if not read then - if ffi then - read = function(f, t) - ffi.cdef([[ - char *fgets(char *str, int n, FILE *stream); - int fgetc(FILE *stream); - int feof(FILE *stream); - int scanf(const char *format, ...); - ]]) - if t and f then - if (t == "*all" or t == "*a") then - while not cast("bool", ffi.C.feof(f)) do - local content = "" - local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f))) - if (ch ~= nil) then - content = content .. ch - end - end - elseif (t == "*line" or t == "*l") then - if not cast("bool", ffi.C.feof(f)) then - local line = "" - while not cast("bool", ffi.C.feof(f)) do - local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f))) - if (ch == "\n") then - break - else - line = line .. ch - end - end - return line - end - elseif (t == "*number" or t == "*n") then - local line = "" - while not cast("bool", ffi.C.feof(f)) do - local ch = tonumber(ffi.string(ffi.cast("char", ffi.C.fgetc(f)))) - if not ch then - break - else - line = line .. ch - end - end - return line - elseif (type(t) == "number") then - if not cast("bool", ffi.C.feof(f)) then - local line = ffi.new("char[?]", t) - return ffi.string(ffi.C.fgets(line, t, f)) - end - elseif io.__DEFAULT__INPUT__FILE__ then - --if not cast("bool", ffi.C.feof(io.__DEFAULT__INPUT__FILE__)) then - --local line = ffi.new("char[?]", 512) - local line = "" - while not cast("bool", ffi.C.feof(io.__DEFAULT__INPUT__FILE__)) do - local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(io.__DEFAULT__INPUT__FILE__))) - if (ch == "\n") then - break - else - line = line .. ch - end - end - return line - --return ffi.string(ffi.C.fgets(line, 512, io.__DEFAULT__INPUT__FILE__)) - else - local input = ffi.new("char[?]", 512) - local execution_code = ffi.C.scanf("%s\0", input) - return input, (execution_code == 0) - end - end - end - end -end - --- io.close -if not io.close then - if ffi then - io.close = function(f) - if f and (f.__FILE or f.__STATE) then - ffi.cdef("int fclose(FILE *_File);") - local result = (ffi.C.fclose(f.__FILE) == 0) - if result then - f.__STATE = "closed file" - end - end - end - end -end - --- closefile -if not closefile then - if ffi then - closefile = function(f) - if f and (f.__FILE or f.__STATE) then - ffi.cdef("int fclose(FILE *_File);") - local result = (ffi.C.fclose(f.__FILE) == 0) - if result then - f.__STATE = "closed file" - end - end - end - end -end - --- io.flush -if not io.flush then - if ffi then - io.flush = function(f) - ffi.cdef("int fflush(FILE *_File);") - return (ffi.C.fflush(f or io.stdout) == 0) - end - end -end - --- flush -if not flush then - if ffi then - flush = function(f) - ffi.cdef("int fflush(FILE *_File);") - return (ffi.C.fflush(f or io.stdout) == 0) - end - end -end - --- io.type -if not io.type then - io.type = function(f) - if f and f.__STATE and ffi.istype("FILE", f) then - return f.__STATE - else - return nil - end - end -end - --- io.input -if not io.input then - io.input = function(f) - if f and (f.__FILE or f.__STATE) then - if (f.__FILE or f.__MODE or f.__STATE) then - io.__DEFAULT__INPUT__FILE__ = f - end - end - end -end - --- readfrom -if not readfrom then - readfrom = function(f) - if f and (f.__FILE or f.__STATE) then - if (f.__FILE or f.__MODE or f.__STATE) then - io.__DEFAULT__OUTPUT__FILE__ = f - end - end - end -end - --- io.output -if not io.output then - io.output = function(f) - if f and (f.__FILE or f.__STATE) then - if (f.__FILE or f.__MODE or f.__STATE) then - io.__DEFAULT__OUTPUT__FILE__ = f - end - end - end -end - --- writeto -if not writeto then - writeto = function(f) - if f and (f.__FILE or f.__STATE) then - if (f.__FILE or f.__MODE or f.__STATE) then - io.__DEFAULT__OUTPUT__FILE__ = f - end - end - end -end - --- appendto -if not appendto then - appendto = function(f) - if f and (f.__FILE or f.__STATE) then - if (f.__FILE or f.__MODE or f.__STATE) then - io.__DEFAULT__OUTPUT__FILE__ = f - end - end - end -end - --- io.popen -if not io.popen then - if ffi then - io.popen = function(c, m) - ffi.cdef("FILE *_popen(const char *_Command, const char *_Mode);") - return _FILE:new(ffi.C._popen(c, m), m, nil) - end - end -end - --- io.lines -if not io.lines then - if ffi then - io.lines = function(filename) - local lines = {} - local line = "" - local file = nil - if (not filename) and io.__DEFAULT__INPUT__FILE__ and io.__DEFAULT__INPUT__FILE__.__FILE then - filename = io.__DEFAULT__INPUT__FILE__ - file = io.__DEFAULT__INPUT__FILE__.__FILE - else - file = io.open(filename, "r") - end - while not cast("bool", ffi.C.feof(file)) do - local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(file))) - if (ch == "\n") then - lines[#lines + 1] = line - line = "" - else - line = line .. ch - end - end - return ipairs(lines) - end - end -end - --- io.stdin -if not io.stdin then - if ffi then - io.stdin = _FILE:new(io.open("stdin", "w"), "w", "stdin") - end -end - --- io.stdout -if not io.stdout then - if ffi then - io.stdout = _FILE:new(io.open("stdout", "w"), "w", "stdout") - end -end - --- io.stderr -if not io.stderr then - if ffi then - io.stderr = _FILE:new(io.open("stderr", "w"), "w", "stderr") - end -end - --- module: string --- Functions -string = require("string") or {} - -string.chars = {} -string.chars["a"] = 97 -string.chars["b"] = 98 -string.chars["c"] = 99 -string.chars["d"] = 100 -string.chars["e"] = 101 -string.chars["f"] = 102 -string.chars["g"] = 103 -string.chars["h"] = 104 -string.chars["i"] = 105 -string.chars["j"] = 106 -string.chars["k"] = 107 -string.chars["l"] = 108 -string.chars["m"] = 109 -string.chars["n"] = 110 -string.chars["o"] = 111 -string.chars["p"] = 112 -string.chars["q"] = 113 -string.chars["r"] = 114 -string.chars["s"] = 115 -string.chars["t"] = 116 -string.chars["u"] = 117 -string.chars["v"] = 118 -string.chars["w"] = 119 -string.chars["x"] = 120 -string.chars["y"] = 121 -string.chars["z"] = 122 -string.chars["0"] = 48 -string.chars["1"] = 49 -string.chars["2"] = 50 -string.chars["3"] = 51 -string.chars["4"] = 52 -string.chars["5"] = 53 -string.chars["6"] = 54 -string.chars["7"] = 55 -string.chars["8"] = 56 -string.chars["9"] = 57 -string.chars["!"] = 33 -string.chars["@"] = 64 -string.chars["#"] = 35 -string.chars["$"] = 36 -string.chars["%"] = 37 -string.chars["^"] = 94 -string.chars["&"] = 38 -string.chars["*"] = 42 -string.chars["("] = 40 -string.chars[")"] = 41 -string.chars["-"] = 45 -string.chars["+"] = 43 -string.chars["_"] = 95 -string.chars["="] = 61 -string.chars["{"] = 123 -string.chars["}"] = 125 -string.chars["["] = 91 -string.chars["]"] = 93 -string.chars[":"] = 58 -string.chars["'"] = 39 -string.chars["\""] = 34 -string.chars[";"] = 95 -string.chars["/"] = 47 -string.chars["`"] = 96 -string.chars["~"] = 126 -string.chars["|"] = 124 -string.chars["\\"] = 92 -string.chars[","] = 44 -string.chars["."] = 46 -string.chars["<"] = 60 -string.chars[">"] = 62 -string.chars["?"] = 63 - --- string.split -if not string.split then - string.split = function(s, sep) - local result = {} - local line = "" - for i = 1, #s do - if (string.char(string.byte(s, i)) == sep) then - result[#result + 1] = line - line = "" - else - line = line .. string.char(string.byte(s, i)) - end - end - return result - end -end - --- string.rep -if not string.rep then - string.rep = function(s, n, sep) - local str = "" - local sp = sep or "" - for i = 1, n, 1 do - if (i == n) then - sp = "" - end - str = str .. s .. sp - end - return str - end -end - --- strrep -if not strrep then - strrep = function(s, n, sep) - local str = "" - local sp = sep or "" - for i = 1, n, 1 do - if (i == n) then - sp = "" - end - str = str .. s .. sp - end - return str - end -end - --- string.len -if not string.len then - string.len = function(s) - if not ffi then - return #n - else - ffi.cdef("size_t strlen(const char *_Str);") - return ffi.cast("int", ffi.C.strlen(s)) - end - end -end - --- strlen -if not strlen then - strlen = function(s) - if not ffi then - return #n - else - ffi.cdef("size_t strlen(const char *_Str);") - return ffi.cast("int", ffi.C.strlen(s)) - end - end -end - --- string.byte -if not string.byte then - if (type(ffi) == "string") then - string.byte = function(s, i) - i = i or 1 - local strarr = ffi.new("char[?]", #s) - ffi.copy(strarr, s) - return ffi.cast("int", strarr[i]) - end - end -end - --- strbyte -if not strbyte then - if (type(ffi) == "string") then - strbyte = function(s, i) - i = i or 1 - local strarr = ffi.new("char[?]", #s) - ffi.copy(strarr, s) - return ffi.cast("int", strarr[i]) - end - end -end - --- string.char -if not string.char then - string.char = function(...) - local args = { ... } - local str = "" - for i = 1, #args do - for k, v in pairs(string.chars) do - if (v == args[i]) then - str = str .. k - end - end - end - return str - end -end - --- strchar -if not strchar then - strchar = function(...) - local args = { ... } - local str = "" - for i = 1, #args do - for k, v in pairs(string.chars) do - if (v == args[i]) then - str = str .. k - end - end - end - return str - end -end - --- string.upper -if not string.upper then - if ffi then - string.upper = function(s) - ffi.cdef("int toupper(int _C);") - local result = {} - local t = ffi.new("char[?]", #s) - ffi.copy(t, s) - for i = 1, #s, 1 do - result[i] = ffi.C.toupper(string.char(ffi.cast("int", t[i]))) - end - return table.concat(result, "") - end - end -end - --- strupper -if not strupper then - if ffi then - strupper = function(s) - ffi.cdef("int toupper(int _C);") - local result = {} - local t = ffi.new("char[?]", #s) - ffi.copy(t, s) - for i = 1, #s, 1 do - result[i] = ffi.C.toupper(string.char(ffi.cast("int", t[i]))) - end - return table.concat(result, "") - end - end -end - --- string.lower -if not string.lower then - if ffi then - string.lower = function(s) - ffi.cdef("int tolower(int _C);") - local result = {} - local t = ffi.new("char[?]", #s) - ffi.copy(t, s) - for i = 1, #s, 1 do - result[i] = ffi.C.tolower(string.char(ffi.cast("int", t[i]))) - end - return table.concat(result, "") - end - end -end - --- strlower -if not strlower then - if ffi then - string.lower = function(s) - ffi.cdef("int tolower(int _C);") - local result = {} - local t = ffi.new("char[?]", #s) - ffi.copy(t, s) - for i = 1, #s, 1 do - result[i] = ffi.C.tolower(string.char(ffi.cast("int", t[i]))) - end - return table.concat(result, "") - end - end -end - --- string.pack -if not string.pack then - if ffi then - string.pack = function(f, ...) - local packtype = string.char(string.byte(f, 1)) - local arrtype = "" - local arrsize = 0 - if packtype == "i" then - arrtype = "int" - arrsize = 2 - elseif packtype == "f" then - arrtype = "float" - arrsize = 4 - elseif packtype == "d" then - arrtype = "double" - arrsize = 8 - elseif packtype == "c" then - arrtype = "char" -- char could be int? - arrsize = 1 - end - local occurences = string.match(args[1], packtype) - local args = { ... } - return ffi.string(ffi.new(arrtype.."[?]", #args, args), arrsize * #args) - end - end -end - --- string.unpack -if not string.unpack then - if ffi then - string.unpack = function(f, s, o) - local packtype = string.char(string.byte(f, 1)) - local arrtype = "" - local arrsize = 0 - if packtype == "i" then - arrtype = "int" - arrsize = 2 - elseif packtype == "f" then - arrtype = "float" - arrsize = 4 - elseif packtype == "d" then - arrtype = "double" - arrsize = 8 - elseif packtype == "c" then - arrtype = "char" -- char could be int? - arrsize = 1 - end - local str = ffi.cast(arrtype .. "*", ffi.new("char[?]", #str, str)) - local t = {} - for i = o, #str / arrsize do - t[#t + 1] = str[#t] - end - return table.concat(t) - end - end -end - --- string.packsize -if not string.packsize then - if ffi then - string.packsize = function(str) - if str[1] then - return #str - end - end - end -end - --- string.sub -if not string.sub then - string.sub = function(s, f, t) - t = t or #s - local result = "" - for i = f, t do - result = result .. string.char(string.byte(s, i)) - end - return result - end -end - --- strsub -if not strsub then - strsub = function(s, f, t) - t = t or #s - local result = "" - for i = f, t do - result = result .. string.char(string.byte(s, i)) - end - return result - end -end - --- string.format -if not string.format then - if ffi then - string.format = function(...) - ffi.cdef("int sprintf(char *str, const char *format, ...);") - local args = { ... } - local str = "" - ffi.C.sprintf(str, table.unpack(args)) - return ffi.string(str) - end - end -end - --- format -if not format then - if ffi then - format = function(...) - ffi.cdef("int sprintf(char *str, const char *format, ...);") - local args = { ... } - local str = "" - ffi.C.sprintf(str, table.unpack(args)) - return ffi.string(str) - end - end -end - --- string.match -if not string.match then - if ffi then - string.match = function(s1, s2, init) - ffi.cdef("char* strstr(const char*, const char*);") - init = init or 0 - local occurences = 0 - local count = 0 - local ptr = s1 - local lastfind = nil - while (ffi.C.strstr(ptr, s2) ~= nil) do - lastfind = ffi.C.strstr(ptr, s2) - ptr = lastfind + 1 - if (occurences >= init) then - count = count + 1 - end - occurences = occurences + 1 - end - if (occurences > 1) then - return (occurences * #s2) - 1, #s2 - else - return occurences, #s2 - end - end - end -end - --- string.gmatch -if not string.gmatch then - if ffi then - string.gmatch = function(s1, s2) - ffi.cdef("char* strstr(const char*, const char*);") - local occurences = {} - local ptr = s1 - local lastfind = nil - while (ffi.C.strstr(ptr, s2) ~= nil) do - lastfind = ffi.C.strstr(ptr, s2) - ptr = lastfind + 1 - occurences[#occurences + 1] = lastfind - end - return ipairs(occurences) - end - end -end - --- string.find -if not string.find then - if ffi then - string.find = function(s1, s2, init) - ffi.cdef("char* strstr(const char*, const char*);") - init = init or 0 - local occurences = 0 - local count = 0 - local ptr = s1 - local lastfind = nil - while (ffi.C.strstr(ptr, s2) ~= nil) do - lastfind = ffi.C.strstr(ptr, s2) - ptr = lastfind + 1 - if (occurences >= init) then - count = count + 1 - end - occurences = occurences + 1 - end - return occurences, #s2 - end - end -end - --- strfind -if not strfind then - if ffi then - strfind = function(s1, s2, init) - ffi.cdef("char* strstr(const char*, const char*);") - init = init or 0 - local occurences = 0 - local count = 0 - local ptr = s1 - local lastfind = nil - while (ffi.C.strstr(ptr, s2) ~= nil) do - lastfind = ffi.C.strstr(ptr, s2) - ptr = lastfind + 1 - if (occurences >= init) then - count = count + 1 - end - occurences = occurences + 1 - end - return occurences, #s2 - end - end -end - --- string.gfind -if not string.gfind then - if ffi then - string.gfind = function(s1, s2) - ffi.cdef("char* strstr(const char*, const char*);") - local occurences = {} - local ptr = s1 - local lastfind = nil - while (ffi.C.strstr(ptr, s2) ~= nil) do - lastfind = strstr(ptr, s2) - ptr = lastfind + 1 - occurences[#occurences + 1] = lastfind - end - return ipairs(occurences) - end - end -end - -return polyfill From 6d45cf978afe21c31e8e33dc41bf54fb67aa2171 Mon Sep 17 00:00:00 2001 From: ParticleG Date: Wed, 14 Jun 2023 17:32:26 +0800 Subject: [PATCH 09/14] =?UTF-8?q?=E6=A1=86=E6=9E=B6=E8=B7=9F=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Zframework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zframework b/Zframework index 6d9b1439..599f9639 160000 --- a/Zframework +++ b/Zframework @@ -1 +1 @@ -Subproject commit 6d9b1439eb348bbb618746516d86538b5f3fb8df +Subproject commit 599f96392c63e682edab75327ebbbe36439f1fa6 From 2ff2fd19404a0197a6fb91af5ce45c703c40d8cc Mon Sep 17 00:00:00 2001 From: ParticleG Date: Wed, 14 Jun 2023 17:52:23 +0800 Subject: [PATCH 10/14] =?UTF-8?q?=E6=A1=86=E6=9E=B6=E8=B7=9F=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Zframework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zframework b/Zframework index 599f9639..fca356f8 160000 --- a/Zframework +++ b/Zframework @@ -1 +1 @@ -Subproject commit 599f96392c63e682edab75327ebbbe36439f1fa6 +Subproject commit fca356f8a57432004a9e016bb486125833945f45 From c583769cf320d9746756ddafda521250881d7d4e Mon Sep 17 00:00:00 2001 From: ParticleG Date: Wed, 14 Jun 2023 18:06:38 +0800 Subject: [PATCH 11/14] =?UTF-8?q?=E6=A1=86=E6=9E=B6=E8=B7=9F=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Zframework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zframework b/Zframework index fca356f8..8747f1ef 160000 --- a/Zframework +++ b/Zframework @@ -1 +1 @@ -Subproject commit fca356f8a57432004a9e016bb486125833945f45 +Subproject commit 8747f1ef22f9b4c176589ca469edd4014eb7a392 From 4a81d8beb019ce831ddf5390da3d4c56d1f7e6f8 Mon Sep 17 00:00:00 2001 From: ParticleG Date: Wed, 14 Jun 2023 23:42:07 +0800 Subject: [PATCH 12/14] =?UTF-8?q?=E6=A1=86=E6=9E=B6=E8=B7=9F=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Zframework | 2 +- parts/gameFuncs.lua | 2 +- parts/gameTables.lua | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Zframework b/Zframework index 8747f1ef..9a7be7d4 160000 --- a/Zframework +++ b/Zframework @@ -1 +1 @@ -Subproject commit 8747f1ef22f9b4c176589ca469edd4014eb7a392 +Subproject commit 9a7be7d45fb9349e30a96e66423e2d3fa1776279 diff --git a/parts/gameFuncs.lua b/parts/gameFuncs.lua index a79828d1..aefff5f6 100644 --- a/parts/gameFuncs.lua +++ b/parts/gameFuncs.lua @@ -981,7 +981,7 @@ do-- function resetGameData(args) GAME.replaying=true else GAME.frameStart=args:find'n' and 0 or 180-SETTING.reTime*60 - GAME.seed=seed or math.random(1046101471,2662622626) + GAME.seed=seed or math.random(1046101471) GAME.pauseTime=0 GAME.pauseCount=0 GAME.saved=false diff --git a/parts/gameTables.lua b/parts/gameTables.lua index f8000a95..cee2bc22 100644 --- a/parts/gameTables.lua +++ b/parts/gameTables.lua @@ -652,7 +652,7 @@ do-- Userdata tables showSpike=true, highCam=true, nextPos=true, - fullscreen=true, + fullscreen=SYSTEM~='Web', portrait=false, msaa=0, bg='on', From e7fc5a676eeb24c9869fb83a78d3503c3095745c Mon Sep 17 00:00:00 2001 From: MrZ_26 <1046101471@qq.com> Date: Thu, 15 Jun 2023 00:12:45 +0800 Subject: [PATCH 13/14] =?UTF-8?q?=E6=A1=86=E6=9E=B6=E8=B7=9F=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Zframework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zframework b/Zframework index 9a7be7d4..4a3433ac 160000 --- a/Zframework +++ b/Zframework @@ -1 +1 @@ -Subproject commit 9a7be7d45fb9349e30a96e66423e2d3fa1776279 +Subproject commit 4a3433ac94622a7adbe4f55a62dc17162652d967 From 96bf30fcab06990be6d4010f2cf5578181d40ec6 Mon Sep 17 00:00:00 2001 From: MrZ_26 <1046101471@qq.com> Date: Thu, 15 Jun 2023 01:15:39 +0800 Subject: [PATCH 14/14] =?UTF-8?q?=E7=8E=A9=E5=AE=B6=E6=AD=BB=E4=BA=A1?= =?UTF-8?q?=E5=90=8E=E4=B8=8D=E5=86=8D=E5=8D=A0=E7=94=A8=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=92=8C=E7=BB=98=E5=88=B6=E8=B5=84=E6=BA=90=20=E6=A1=86?= =?UTF-8?q?=E6=9E=B6=E8=B7=9F=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Zframework | 2 +- parts/player/player.lua | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Zframework b/Zframework index 4a3433ac..4aa87c61 160000 --- a/Zframework +++ b/Zframework @@ -1 +1 @@ -Subproject commit 4a3433ac94622a7adbe4f55a62dc17162652d967 +Subproject commit 4aa87c6147c259b6ad2aff918c5b956f531e00e5 diff --git a/parts/player/player.lua b/parts/player/player.lua index 748c72d0..40380251 100644 --- a/parts/player/player.lua +++ b/parts/player/player.lua @@ -613,6 +613,7 @@ do-- function Player:dropPosition(x,y,size) vy=vy+.0626 self:setPosition(x,y,size) if y>2600 then + table.remove(PLAYERS,TABLE.find(PLAYERS,self)) return true end end