mirror of
https://github.com/clockworkpi/PicoCalc.git
synced 2026-03-23 20:42:38 +01:00
update PicoCalc SD
This commit is contained in:
260
Bin/PicoCalc SD/lua/asteroids.lua
Normal file
260
Bin/PicoCalc SD/lua/asteroids.lua
Normal file
@@ -0,0 +1,260 @@
|
||||
-- asteroids game
|
||||
-- written by maple "mavica" syrup <maple@maple.pet>
|
||||
|
||||
local poly_ship = {{0, -10}, {5, 5}, {0, 0}, {-5, 5}, {0, -10}}
|
||||
local poly_thrust = {{-2.5, 2,5}, {0, 4}, {2.5, 2.5}}
|
||||
local poly_shot = {{0, 0}, {0, -5}}
|
||||
local poly_rock = {{-1,0},{-0.8,-0.6},{-0.4,-0.5},
|
||||
{0,-1},{0.5,-0.9},{0.3,-0.4},{0.8,-0.5},
|
||||
{1,0},{0.7,0.4},{0.7,0.6},{0.3,0.8},{0,0.7},
|
||||
{-0.3,0.9},{-0.7,0.8},{-0.7,0.5},{-1,0}}
|
||||
|
||||
local bg = colors.fromRGB(0,0,0)
|
||||
local fg = colors.fromRGB(0,255,0)
|
||||
local width = 320
|
||||
local height = 320
|
||||
|
||||
local max_shots = 5
|
||||
local shot_speed = 7
|
||||
local rock_speed = 0.6
|
||||
local rock_size = 30
|
||||
local rock_step = 10
|
||||
|
||||
local player = {
|
||||
x=width/2,
|
||||
y=height/2,
|
||||
accel = 0.06,
|
||||
vx=0,
|
||||
vy=0,
|
||||
ang=0,
|
||||
cdown=0,
|
||||
inv=0
|
||||
}
|
||||
|
||||
local shots = {}
|
||||
local rocks = {}
|
||||
local score = 0
|
||||
local lives = 3
|
||||
|
||||
local last_frame = 0
|
||||
local game_over = false
|
||||
|
||||
local function sign(number)
|
||||
return (number > 0 and 1) or (number == 0 and 0) or -1
|
||||
end
|
||||
|
||||
local function distance(x1, y1, x2, y2)
|
||||
return math.sqrt((x2-x1)^2+(y2-y1)^2)
|
||||
end
|
||||
|
||||
local function draw_rotated(shape, x, y, ang, scale, color)
|
||||
processed = {}
|
||||
|
||||
local sin = math.sin(ang) * scale
|
||||
local cos = math.cos(ang) * scale
|
||||
|
||||
for _,v in pairs(shape) do
|
||||
local px = x + v[1] * cos - v[2] * sin
|
||||
local py = y + v[1] * sin + v[2] * cos
|
||||
table.insert(processed,math.floor(px+0.5))
|
||||
table.insert(processed,math.floor(py+0.5))
|
||||
end
|
||||
|
||||
draw.polygon(processed, color)
|
||||
end
|
||||
|
||||
local shot_meta = {
|
||||
erase = function(self)
|
||||
draw_rotated(poly_shot, self.x, self.y, self.ang, 1, bg)
|
||||
end,
|
||||
update = function(self, k)
|
||||
self.x = self.x + self.vx
|
||||
self.y = self.y + self.vy
|
||||
|
||||
if self.x > width or self.x < 0 or self.y > height or self.y < 0 then
|
||||
self:erase()
|
||||
table.remove(shots,k)
|
||||
else
|
||||
for rockid,rock in pairs(rocks) do
|
||||
if distance(self.x, self.y, rock.x, rock.y) < rock.scale then
|
||||
rock:hit(rockid,self,k)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
draw = function(self)
|
||||
draw_rotated(poly_shot, self.x, self.y, self.ang, 1, fg)
|
||||
end
|
||||
}
|
||||
|
||||
local rock_meta = {} --hoist
|
||||
|
||||
local rock_create = function(x, y, ang, size)
|
||||
rock = {
|
||||
x = x,
|
||||
y = y,
|
||||
ang = ang,
|
||||
vx = math.sin(ang) * rock_speed,
|
||||
vy = -math.cos(ang) * rock_speed,
|
||||
scale = size
|
||||
}
|
||||
setmetatable(rock, { __index = rock_meta })
|
||||
table.insert(rocks, rock)
|
||||
end
|
||||
|
||||
local function level_init()
|
||||
for i=1,4 do
|
||||
rock_create(math.random(30,width-30), math.random(30,height-30), math.random()*6.28, 30)
|
||||
end
|
||||
player.inv = 50
|
||||
end
|
||||
|
||||
rock_meta = {
|
||||
erase = function(self)
|
||||
draw_rotated(poly_rock, self.x, self.y, self.ang, self.scale, bg)
|
||||
end,
|
||||
update = function(self, k)
|
||||
self.x = (self.x + self.vx) % width
|
||||
self.y = (self.y + self.vy) % height
|
||||
|
||||
if player.inv == 0 and distance(self.x, self.y, player.x, player.y) < self.scale then
|
||||
player:hit()
|
||||
end
|
||||
end,
|
||||
hit = function(self, k, shot, sk)
|
||||
sound.playPitch(1, 0.5, sound.drums.snare2)
|
||||
self:erase()
|
||||
score = score + ((rock_size + rock_step) - self.scale)
|
||||
rock_speed = rock_speed + 0.06
|
||||
if self.scale > rock_step then
|
||||
rock_create(self.x, self.y, shot.ang - math.random()*3.14, self.scale-rock_step)
|
||||
rock_create(self.x, self.y, shot.ang + math.random()*3.14, self.scale-rock_step)
|
||||
end
|
||||
table.remove(rocks, k)
|
||||
table.remove(shots, sk)
|
||||
if #rocks == 0 then
|
||||
rock_speed = rock_speed - 0.6
|
||||
score = score + 500
|
||||
level_init()
|
||||
end
|
||||
end,
|
||||
draw = function(self)
|
||||
draw_rotated(poly_rock, self.x, self.y, self.ang, self.scale, fg)
|
||||
end
|
||||
}
|
||||
|
||||
function player:fire()
|
||||
if self.cdown == 0 and #shots < max_shots then
|
||||
sound.playPitch(1, 2, sound.drums.tom)
|
||||
shot = {
|
||||
x = self.x,
|
||||
y = self.y,
|
||||
ang = self.ang,
|
||||
vx = math.sin(self.ang) * shot_speed,
|
||||
vy = -math.cos(self.ang) * shot_speed,
|
||||
}
|
||||
setmetatable(shot, { __index = shot_meta })
|
||||
table.insert(shots, shot)
|
||||
self.cdown = 8
|
||||
end
|
||||
end
|
||||
|
||||
function player:erase()
|
||||
draw_rotated(poly_ship, self.x, self.y, self.ang, 1, bg)
|
||||
draw_rotated(poly_thrust, self.x, self.y, self.ang, 1, bg)
|
||||
end
|
||||
|
||||
function player:update()
|
||||
local angle_d = (keys.getState(keys.right) and 0.15 or 0) - (keys.getState(keys.left) and 0.15 or 0)
|
||||
|
||||
self.ang = self.ang + angle_d
|
||||
if keys.getState(keys.up) then
|
||||
self.vx = (self.vx + math.sin(self.ang) * self.accel)
|
||||
self.vy = (self.vy - math.cos(self.ang) * self.accel)
|
||||
elseif keys.getState(keys.down) then
|
||||
self.vx = (self.vx - sign(self.vx) * self.accel)
|
||||
self.vy = (self.vy - sign(self.vy) * self.accel)
|
||||
end
|
||||
self.x = (self.x + self.vx) % width
|
||||
self.y = (self.y + self.vy) % height
|
||||
|
||||
if self.cdown > 0 then
|
||||
self.cdown = self.cdown - 1
|
||||
else
|
||||
if keys.getState(keys.enter) then
|
||||
self:fire()
|
||||
end
|
||||
end
|
||||
|
||||
if self.inv > 0 then self.inv = self.inv - 1 end
|
||||
end
|
||||
|
||||
function player:hit()
|
||||
sound.playPitch(1, 0.4, sound.drums.snare1)
|
||||
if lives == 0 then game_over = true return end
|
||||
lives = lives - 1
|
||||
self.x = width/2
|
||||
self.y = height/2
|
||||
self.vx = 0
|
||||
self.vy = 0
|
||||
self.ang = 0
|
||||
self.inv = 50
|
||||
end
|
||||
|
||||
function player:draw()
|
||||
if math.floor(self.inv / 3) % 2 == 0 then
|
||||
draw_rotated(poly_ship, self.x, self.y, self.ang, 1, fg)
|
||||
end
|
||||
if keys.getState(keys.up) then
|
||||
draw_rotated(poly_thrust, self.x, self.y, self.ang, 1, fg)
|
||||
end
|
||||
end
|
||||
|
||||
local function hud_draw()
|
||||
draw.text(15,15," ",fg,bg)
|
||||
draw.text(15,15,score,fg,bg)
|
||||
for i = 0, 3 do
|
||||
local color = i < lives and fg or bg
|
||||
draw_rotated(poly_ship, width - 20 - 20*i, 20, 0, 1, color)
|
||||
end
|
||||
end
|
||||
|
||||
term.clear()
|
||||
--draw.enableBuffer(true)
|
||||
draw.rectFill(0, 0, width, height, bg)
|
||||
level_init()
|
||||
|
||||
while true do
|
||||
if keys.getState(keys.esc) or game_over then break end
|
||||
|
||||
local now = os.clock()
|
||||
if now >= last_frame + 0.05 then
|
||||
last_frame = now
|
||||
|
||||
-- erase
|
||||
player:erase()
|
||||
for _,v in pairs(shots) do v:erase() end
|
||||
for _,v in pairs(rocks) do v:erase() end
|
||||
|
||||
-- move player
|
||||
player:update()
|
||||
for k,v in pairs(shots) do v:update(k) end
|
||||
for k,v in pairs(rocks) do v:update(k) end
|
||||
|
||||
--draw.clear()
|
||||
hud_draw()
|
||||
player:draw()
|
||||
for _,v in pairs(shots) do v:draw() end
|
||||
for _,v in pairs(rocks) do v:draw() end
|
||||
--draw.blitBuffer()
|
||||
|
||||
collectgarbage()
|
||||
end
|
||||
end
|
||||
|
||||
draw.enableBuffer(false)
|
||||
if game_over then
|
||||
term.clear()
|
||||
print("game over!")
|
||||
print("final score: "..score)
|
||||
end
|
||||
BIN
Bin/PicoCalc SD/lua/boxworld.bmp
Normal file
BIN
Bin/PicoCalc SD/lua/boxworld.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
448
Bin/PicoCalc SD/lua/boxworld.lua
Normal file
448
Bin/PicoCalc SD/lua/boxworld.lua
Normal file
@@ -0,0 +1,448 @@
|
||||
-- BOXWORLD
|
||||
-- original game and sprites by Jeng-Long Jiang, 1992
|
||||
-- picocalc lua conversion by maple "mavica" syrup, 2025
|
||||
|
||||
local sprite_size = 20
|
||||
local sprites = draw.loadBMPSprites("lua/boxworld.bmp", sprite_size, sprite_size)
|
||||
|
||||
local fg,bg = colors.fromRGB(255,255,255),colors.fromRGB(0,0,0)
|
||||
local screen = nil
|
||||
local quit = false
|
||||
|
||||
local function switch_screen(to)
|
||||
screen = to
|
||||
if screen.entry then screen.entry() end
|
||||
end
|
||||
|
||||
local music = {
|
||||
tick = 0.10,
|
||||
instrument = sound.instrument(sound.presets.square),
|
||||
notes = {
|
||||
c = 0,
|
||||
C = 1,
|
||||
d = 2,
|
||||
D = 3,
|
||||
e = 4,
|
||||
f = 5,
|
||||
F = 6,
|
||||
g = 7,
|
||||
G = 8,
|
||||
a = 9,
|
||||
A = 10,
|
||||
b = 11
|
||||
},
|
||||
tracks = {
|
||||
intro = {
|
||||
"l2o3el1<el2gl1el2>cl1<el2>el3dl1c<bafl3>c<bl2al1dl2fl1el2gl1fl2b>c",
|
||||
"l3o1cga>cel2dl3c<l4bl3fa>cl2<a>c"
|
||||
},
|
||||
victory = {
|
||||
"l2o2el1Gl2al3bl1>dl2ee",
|
||||
"l3o1aGel1gl2de"
|
||||
}
|
||||
},
|
||||
playing = nil
|
||||
}
|
||||
music.instrument.decay = 250
|
||||
|
||||
function music.perform()
|
||||
if not music.playing then return end
|
||||
local done_playing = true
|
||||
for k,v in pairs(music.playing) do
|
||||
local ch = music.channels[k]
|
||||
local track = music.playing[k]
|
||||
if ch.cursor <= #track then done_playing = false end
|
||||
if ch.timer > 0 then ch.timer = ch.timer - 1 end
|
||||
if ch.timer == 0 then
|
||||
while ch.cursor <= #track do
|
||||
local input = string.sub(track, ch.cursor, ch.cursor)
|
||||
ch.cursor = ch.cursor + 1
|
||||
if input == 'l' then
|
||||
input = string.sub(track, ch.cursor, ch.cursor)
|
||||
ch.cursor = ch.cursor + 1
|
||||
ch.length = tonumber(input)
|
||||
elseif input == 'o' then
|
||||
input = string.sub(track, ch.cursor, ch.cursor)
|
||||
ch.cursor = ch.cursor + 1
|
||||
ch.octave = tonumber(input)
|
||||
elseif input == '<' then
|
||||
ch.octave = ch.octave - 1
|
||||
elseif input == '>' then
|
||||
ch.octave = ch.octave + 1
|
||||
elseif music.notes[input] then
|
||||
ch.timer = ch.length
|
||||
sound.play(k-1, music.notes[input] + (ch.octave+2) * 12, music.instrument)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if done_playing then music.playing = nil sys.stopTimer() end
|
||||
end
|
||||
|
||||
function music.play(track)
|
||||
music.playing = track
|
||||
music.channels = {}
|
||||
for k,v in pairs(track) do
|
||||
music.channels[k] = {}
|
||||
music.channels[k].cursor = 1
|
||||
music.channels[k].length = 4
|
||||
music.channels[k].octave = 3
|
||||
music.channels[k].timer = 0
|
||||
end
|
||||
sys.repeatTimer(music.tick * 1000, music.perform)
|
||||
end
|
||||
|
||||
local game = {
|
||||
level = 1,
|
||||
levelstrings = {
|
||||
"00111\n00131\n00121111\n11142431\n13246111\n111141\n000131\n000111\n",
|
||||
"11111\n16221\n124410111\n124210131\n111211131\n011222231\n012221221\n012221111\n011111\n",
|
||||
"01111111\n0122222111\n1141112221\n1262422421\n1233124211\n113312221\n011111111\n",
|
||||
"01111\n11221\n16421\n114211\n112421\n134221\n133531\n111111\n",
|
||||
"011111\n0162111\n0124221\n11121211\n13121221\n13422121\n13222421\n11111111\n",
|
||||
"0001111111\n1111222221\n1222311121\n12121222211\n12124241321\n12122522121\n12314242121\n1122221212111\n0121113222261\n0122222112221\n0111111111111\n",
|
||||
"0001111111\n0011221261\n0012221221\n0014242421\n0012411221\n1112421211\n133333221\n111111111\n",
|
||||
"000111111\n011122221\n1132411211\n1334242261\n1332424211\n111111221\n000001111\n",
|
||||
"0111111111\n0122112221\n0122242221\n0142111241\n0121333121\n11213331211\n12422422421\n12222212621\n11111111111\n",
|
||||
"00111111\n00122221\n11144421\n16243321\n12433311\n1111221\n0001111\n",
|
||||
"011110011111\n112210012221\n124211114221\n122433332421\n112222126211\n01111111111\n",
|
||||
"0011111\n1112261\n12243211\n12234321\n11125421\n00122211\n0011111\n",
|
||||
"001111\n001331\n0112311\n0122431\n11242211\n12214421\n12262221\n11111111\n",
|
||||
"11111111\n12212221\n12433421\n16435211\n12433421\n12212221\n11111111\n",
|
||||
"0111111\n11222211\n12424421\n13333331\n12442421\n11126111\n001111\n",
|
||||
"00111111\n0012222111\n0012422221\n1112421121\n1333242221\n1333414211\n1111212421\n0001226221\n0001111111\n",
|
||||
"111111\n122221\n1244411\n122133111\n112233421\n012622221\n011111111\n",
|
||||
"0011111111\n0012221321\n0112243331\n0122421531\n1121141211\n1222422421\n1222122221\n1111111621\n0000001111\n",
|
||||
"01111111\n01333321\n1113334111\n1224142421\n1244221421\n1222212221\n1111262111\n00011111\n",
|
||||
"1111111\n1334331\n1331331\n1244421\n1224221\n1244421\n1221621\n1111111\n",
|
||||
"000111111\n000123331\n111133331\n12211142111\n12424224421\n16242422221\n12221112221\n11111011111\n",
|
||||
"11111111\n12222221\n12144221\n12333121\n113334211\n012112421\n014224221\n012212261\n011111111\n",
|
||||
"0011111\n1112221111\n1222424221\n1242224261\n1114411111\n00122331\n00133331\n00111111\n",
|
||||
"11111100011111\n12222111012231\n12242421013331\n12122421112231\n12244422242631\n11122422412231\n00122414213331\n00112222212231\n00011111111111\n",
|
||||
"00000111111\n01111132221\n01221331121\n01224332221\n01221231211\n11121141221\n12422224421\n12141221221\n16221111111\n11111\n",
|
||||
"0111111111\n0122211221111\n0124222222221\n0114111211221\n0122112521211\n012433333321\n112111232121\n122222411141\n122212222461\n111114121111\n000012221\n000011111\n",
|
||||
"000000111111111\n000000122222221\n000000121212121\n000000122424121\n111111122242221\n133122112424121\n133222112424221\n133122112111111\n133121242421\n133222224221\n122111262111\n1111011111\n",
|
||||
"00001111\n11111221\n1224242101111111\n1222422101535351\n1124242111353531\n0142422122535351\n0164242222353511\n0142422122535351\n1124242111353531\n1222422101535351\n1224242101111111\n11111221\n00001111\n",
|
||||
"11111111\n13333331\n122421211\n124212421\n114242421\n012262221\n011111111\n",
|
||||
"001111111111\n111222322221\n122211411221\n126432323411\n11241141121\n01222232221\n01111111111\n",
|
||||
"000111111\n111132261\n122444221\n131131131\n122242221\n122431211\n11112221\n00011111\n",
|
||||
"0111111\n0132331\n0132431\n11122411\n12422421\n12141121\n12226221\n11111111\n",
|
||||
"0000111111\n001112222111\n00122214222111\n00122242224421\n00124421422221\n00112224222421\n11111121411111\n1336214221\n1313322411\n133334121\n133332221\n111111111\n",
|
||||
"111111111111111\n122222212222221\n124214212411421\n121224212222221\n122211414114421\n121212333212221\n124223212342121\n124164333121221\n122223212322421\n121134111432121\n121243333321121\n122222222222221\n111111111111111\n",
|
||||
"111111111\n122211221\n121242421\n122531221\n112136311\n1141115111\n1222222221\n1222112121\n1111112221\n0000011111\n",
|
||||
"11111111\n12222221\n1244222111\n12242444211111\n112112333222211\n012161333111421\n012124333222221\n112124333421211\n12211111211121\n12222224222421\n11111111111221\n00000000001111\n",
|
||||
"00011111\n00012621\n00014441\n11112221\n122231411\n124343231\n122131311\n11111111\n",
|
||||
"111111111111\n133321222221\n133221211221\n133222221221\n133221241121\n133321424221\n111111224421\n011224244221\n016244422121\n011242112221\n001222222221\n001111111111\n",
|
||||
"111111111\n122222221\n122424241\n112141121\n0123323311\n0113323321\n00121141211\n00142424221\n00122222261\n00111111111\n",
|
||||
"111110000001111\n162211111111221\n112422222224221\n012121221111221\n012242221111411\n01421121242421\n11242241222221\n12221222222121\n12221111141111\n1111122212221\n0000133322421\n0000133331221\n0000133331111\n0000111111\n",
|
||||
"0000011111\n0111112221\n0123324121\n0121352221\n1125314211\n124224221\n122211261\n111111111\n",
|
||||
"1111101111111\n1222111221221\n1242222242621\n1121411311221\n0122333532421\n0124121312121\n0112222422221\n0012211111111\n001111\n",
|
||||
"000000000111\n0000111111611\n00001333314211\n00001333312421\n00001333324221\n00001233312221\n111111211111211\n124242224221221\n122224422242421\n111242424221111\n001122242421\n000122111111\n0001111\n",
|
||||
"00011111\n0111222111\n1122642421\n12211211211\n12431342221\n12131512221\n12433322111\n111412111\n0012221\n0011111\n",
|
||||
"0000001111\n000000122111111\n000000122221221\n000000124422221\n111111141221221\n122132332111411\n122131534222221\n122131351212221\n124433331211111\n12642121121\n12444122221\n12222111111\n111111\n",
|
||||
"1111\n122111\n12422111\n1242422111\n124242422111\n124242422221\n1242422122211\n1242211244421\n16211112222211\n11210134444431\n012111333333311\n012223555555531\n011113333333331\n000011111111111\n",
|
||||
"1111111\n12612211111\n12442242221\n12213114121\n11413332221\n11233311411\n12211311221\n12242242221\n12212221221\n11111111111\n",
|
||||
"00011111\n00012621\n00012421\n00014341\n011134311\n11234343111\n12243434221\n12222322221\n11111111111\n",
|
||||
"1111111111111\n1224242435331\n1242424253331\n1224242435331\n1242424253331\n1224242435331\n1242424253331\n1224242435331\n1242424253331\n1224242435331\n1642424253331\n1111111111111\n",
|
||||
"00000000000001\n00000000000011\n00000000000111\n000000000012221\n000111111112121\n001242424242221\n01121313131641\n111333333322211\n01121212121411\n001242424242221\n000111111112121\n000000000012221\n00000000000111\n00000000000011\n",
|
||||
"1111111\n122342111\n123434221\n154343621\n123434211\n12234221\n11111111\n",
|
||||
"00000000011111\n00000000012221\n1111111111252111\n1222222222232221\n1244445555433361\n1222222222232221\n1111111111252111\n00000000012221\n00000000011111\n",
|
||||
"000001111\n1111112211111\n1642222422421\n1411124212121\n1221221242221\n1241222212111\n122421412221\n133333333321\n111111112221\n000000011111\n",
|
||||
"0111111111\n0122211221111\n0124222222221\n0114111211221\n0122113421211\n012433333321\n112111322121\n122222411141\n122212222461\n111114121111\n000012221\n000011111\n",
|
||||
"11111111111\n12222122221\n12464444421\n12222222221\n11111211111\n00013221\n00013221\n00013331\n00013221\n00011111\n",
|
||||
"0011111\n0012621\n0012421\n111232111\n122252221\n125555521\n122252221\n111454111\n0012321\n0012521\n0012321\n0011111\n",
|
||||
"11111111111111\n13222222222221\n13424242424221\n13111111111221\n13135242334511\n1312424253461\n1313224233441\n1311111111131\n1322222222221\n1314141414141\n1322222222221\n1111111111111\n",
|
||||
"111111111111\n13322122222111\n13322124224221\n13322141111221\n13322226211221\n13322121224211\n11111121142421\n00124224242421\n00122221222221\n00111111111111\n",
|
||||
"00000001111\n11111111221111\n12221133333221\n12242211333121\n11224221112121\n01212422122221\n01221242212221\n01222124221221\n01222212421211\n0111122124221\n0000112212421\n0000011612221\n0000001111111\n",
|
||||
"11110000001111\n13311111111331\n15353333353531\n12424242424241\n14242464242421\n12424242424241\n14242424242421\n13535333335351\n13311111111331\n11110000001111\n",
|
||||
"000011111\n000112221111\n000123352421\n111121312221\n122223531611\n12141141121\n12222242421\n11221222111\n011111111\n",
|
||||
"111111\n122221\n124221111\n124533521\n125335421\n111122421\n000126221\n000111111\n",
|
||||
"00011111\n111132211\n124343221\n164121421\n124323221\n111141421\n001323221\n001111111\n",
|
||||
"111111111111\n122223332421\n124445552461\n122223332421\n111111111111\n",
|
||||
"1111111111\n1122222221\n1222141421\n1244223431\n1261113331\n1111111111\n",
|
||||
"01111\n012211111\n114211221\n122464221\n122211421\n1113112111\n0133342421\n0113322221\n0011111111\n",
|
||||
"1111101111\n1333101221111\n1333111224221\n133331124224111\n113333112224221\n111333211242421\n121122221224221\n1221121211121111\n1242121422422221\n1224262422224221\n1222124244242111\n12211111122111\n121100001111\n111\n",
|
||||
"1111111\n1323231\n1244421\n1346431\n1244421\n1323231\n1111111\n",
|
||||
"0000001111\n1111111221\n1222224221\n1222411641\n1141333121\n0124333221\n01213231211\n01222121421\n01422422221\n01221111111\n01111\n",
|
||||
"000111111111\n000122212221\n000122222221\n111115111211\n12223332221\n121215111411\n124222242221\n111116212221\n000011111111\n",
|
||||
"11111\n13331011111\n13331112221\n133332224411111\n1333322122122211\n1331411112141221\n1124221222224421\n1224126242441221\n1242424212224211\n122212242112221\n111111222111111\n0000011111\n",
|
||||
"111111111111111\n111312222221111\n113312422421221\n133312112421221\n133333221442221\n113333422221421\n111121111111221\n122242222222211\n122421224124211\n124111242124421\n122261221122221\n111111111111111\n",
|
||||
"000000011111111\n000000012212221\n011111112443331\n012222222213331\n012111111413331\n112122222213331\n122121424211111\n12124242421\n12622421221\n11111424421\n00001222221\n00001111111\n",
|
||||
"000000011111\n001111112221\n111222232421\n124221431411\n122122631221\n112111132221\n012422151111\n01211213221\n01222223121\n01114222221\n00012211111\n0001111\n",
|
||||
"00001111\n111112211111\n122224222421\n122414112221\n111213532111\n0012333261\n0011214111\n00012221\n00011111\n",
|
||||
"00011111111\n11112222321\n12242424321\n12231111311\n1243424261\n1223221111\n1111111\n",
|
||||
"0011111\n0012221\n11143411111\n12223242221\n12114112621\n12223211111\n1112321\n0012221\n0011111\n",
|
||||
"011111\n01262111111\n01213352221\n01233312221\n11411242421\n12221411111\n122242221\n111112121\n000012221\n000011111\n",
|
||||
"00000111111\n000111222211\n000122211221\n011141122121\n112222233121\n122414153121\n12446213512111\n12244213312221\n11222213342221\n01114113212111\n000122111221\n000112222211\n00001111111\n",
|
||||
"000001111111\n000001221221\n000001224421\n111111241221\n1333111212211\n1322122421221\n1322224242421\n1322122421221\n1333111212211\n111111242221\n000001621221\n000001111111\n",
|
||||
"0000000000111111\n0000000000122221\n1111100011121121\n1332111112422121\n1332222242224121\n1332211211222121\n1332112421424121\n1332122222422121\n1332122421114221\n1332124242242111\n111211212422221\n001222216112421\n001111111112211\n00000000001111\n",
|
||||
"00000001\n0000011111\n000111262111\n000122424221\n000125353521\n0011234243211\n01112535352111\n111122424221111\n000111111221\n00001100011\n",
|
||||
"011111111111111\n0126252525212211\n0141225252212221\n0121252525222221\n0121225252211211\n012125252521121\n012122525221121\n012125252521121\n012122525221121\n0121252325211211\n1121111111111221\n1222222222222221\n1222111111111221\n1111100000001111\n",
|
||||
"01111111111111\n01222212211221\n014442124422411\n012422122333321\n012242214311321\n012212412333311\n114242214311321\n124224264333321\n122211122111111\n1111101111\n",
|
||||
"00000111111111\n00000122222221\n00000122414121\n01111112212421\n01222124224221\n11242222211121\n12221411112221\n12222421112111\n1111133261211\n0001333424421\n0001333122221\n0001333111111\n00011111\n",
|
||||
"1111000001111\n122111111133111\n124242422133331\n124222442155531\n124242422133531\n122424242153531\n1124242423535311\n1224242423535361\n1224242421535311\n124242422133531\n124222442155531\n124242422133331\n122111111133111\n1111000001111\n",
|
||||
"00000011111\n11111112221\n12221132221\n122413322111\n1122333144211111\n0124313422222221\n0124111411212421\n0122212222244121\n0114412114142221\n0133324624222111\n01333141222111\n013332211111\n01111111\n",
|
||||
"0111100111111\n0122111122221\n1152225255221\n1242522225121\n1232221112221\n1111112221611\n1252325225521\n1222122212221\n1152225214121\n0122111112221\n0111100011111\n",
|
||||
"0111111111\n0122212221\n0124444421\n1124242421\n1242262221\n12421111211\n12213333321\n11223333321\n01111111111\n",
|
||||
"0001111111\n0001222221\n00012424211\n000111113311111\n111111335322421\n122464333314421\n122242141112221\n111112222222111\n0000111221111\n0000001221\n0000001111\n",
|
||||
"11111\n1222111111\n1242332421\n1142334461\n0122332421\n0111111111\n",
|
||||
"0011111\n001222111111\n111413222221\n124233312421\n162431542221\n111122221111\n000111111\n",
|
||||
"000011111\n111112221\n122242621\n122421311111\n114211311221111\n012233333241221\n012411311221421\n012221311222221\n011124211111211\n000121422222421\n000122221112221\n000111111011111\n",
|
||||
"1111111\n1225221\n1263421\n1243221\n1535551\n1225221\n1245421\n1223221\n1111111\n",
|
||||
"00111111111\n00122221221\n11121422421111\n1224221133122111\n1212242133424221\n1244224133221221\n1122122333142221\n0142621333124221\n0122221333422211\n012114211122211\n01222422222111\n012211111111\n01111\n",
|
||||
"0001111111111\n1111333333221\n1222333331221\n1221333333211\n112111141141\n16422424222111\n12442222112221\n12122441122121\n12224221244221\n12242242221421\n11112221242421\n00012221222221\n00011111111111\n",
|
||||
"000000111111111\n000000122222221\n000000142444221\n000000122212421\n000000122246421\n000011142421211\n00001222414121\n11111212212221\n13332212412111\n133333222121\n133333124121\n111111112221\n000000011111\n",
|
||||
"0111110111111\n0122211122221\n1124242142141\n12242624224211\n12122112133331\n12211242131131\n11224222233331\n01244214133331\n01222122214211\n0111112422221\n0000011112211\n000000001111\n",
|
||||
"1111\n1221\n1221111111111\n1222211222221\n1331222244121\n133221122242111\n133122114124221\n133222126424221\n133122124242221\n123222124242111\n1221221222111\n12212222111\n111111111\n",
|
||||
"00000000011111\n000000001222221\n0000000122411221\n0000001221222421\n1001001212212121\n0101001242422421\n0011111112141221\n001224242222221\n00163342553111\n000133333311111\n0000111111111111\n"
|
||||
},
|
||||
anim_timer = 0,
|
||||
player_flip = 0,
|
||||
player_sprites = {
|
||||
U = {7, 8},
|
||||
D = {5, 6},
|
||||
L = {11, 12},
|
||||
R = {9, 10},
|
||||
W = {13, 13}
|
||||
}
|
||||
}
|
||||
game.push_sound = sound.instrument(sound.drums.tom)
|
||||
game.push_sound.volume = 0.5
|
||||
game.push_sound.decay = 150
|
||||
game.push_sound.sustain = 0
|
||||
|
||||
local title = {}
|
||||
|
||||
function title.input()
|
||||
local state, _, code = keys.poll()
|
||||
|
||||
if state == keys.states.pressed then
|
||||
if code == keys.left then
|
||||
game.level = ((game.level - 2) % #game.levelstrings) + 1
|
||||
screen.redraw = true
|
||||
elseif code == keys.right then
|
||||
game.level = ((game.level) % #game.levelstrings) + 1
|
||||
screen.redraw = true
|
||||
elseif code == keys.enter then
|
||||
switch_screen(game)
|
||||
elseif code == keys.esc then
|
||||
quit = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function title.entry()
|
||||
draw.enableBuffer(false)
|
||||
music.play(music.tracks.intro)
|
||||
draw.clear()
|
||||
screen.redraw = true
|
||||
end
|
||||
|
||||
function title.draw()
|
||||
-- boxworld logo
|
||||
for j = 0, 1 do
|
||||
for i = 0, 6 do
|
||||
sprites:blit(160 - 70 + i * sprite_size, 80 + j * sprite_size, 14 + i + j * 7)
|
||||
end
|
||||
end
|
||||
|
||||
draw.text(160, 140, "Original by Jeng-Long Jiang, 1992",fg,bg,draw.align_center)
|
||||
draw.text(160, 160, "Reprogram by maple \"mavica\" syrup, 2025",fg,bg,draw.align_center)
|
||||
draw.text(160, 180, "Select level",fg,bg,draw.align_center)
|
||||
draw.text(160, 190, " < " .. game.level .. " > ",fg,bg,draw.align_center)
|
||||
end
|
||||
|
||||
function game.entry()
|
||||
-- load level
|
||||
game.leveltable = {}
|
||||
local row = {}
|
||||
local longest = 0
|
||||
local str = game.levelstrings[game.level]
|
||||
for i = 1, #str do
|
||||
if str:sub(i,i) == '\n' then
|
||||
table.insert(game.leveltable, row)
|
||||
if #row > longest then longest = #row end
|
||||
row = {}
|
||||
elseif str:sub(i,i) == '6' then -- player
|
||||
game.player_pos = {#row + 1, #game.leveltable + 1}
|
||||
game.player_direction = "D"
|
||||
table.insert(row, '2') -- empty floor under player
|
||||
else
|
||||
table.insert(row, str:sub(i,i))
|
||||
end
|
||||
end
|
||||
game.draw_offset = {140 - longest/2*sprite_size, 140 - #game.leveltable/2*sprite_size}
|
||||
game.moves = {}
|
||||
collectgarbage()
|
||||
|
||||
draw.enableBuffer(1)
|
||||
draw.clear()
|
||||
screen.redraw = true
|
||||
end
|
||||
|
||||
function game.draw()
|
||||
for j = 1, #game.leveltable do
|
||||
local row = game.leveltable[j]
|
||||
for i = 1, #row do
|
||||
local pos = {game.draw_offset[1] + i * sprite_size, game.draw_offset[2] + j * sprite_size}
|
||||
if row[i] == "1" then -- wall
|
||||
sprites:blit(pos[1], pos[2], 0)
|
||||
elseif row[i] == "2" then -- floor
|
||||
sprites:blit(pos[1], pos[2], 1)
|
||||
elseif row[i] == "3" then -- floor with goal
|
||||
sprites:blit(pos[1], pos[2], 1)
|
||||
sprites:blit(pos[1], pos[2], 4)
|
||||
elseif row[i] == "4" then -- box
|
||||
sprites:blit(pos[1], pos[2], 2)
|
||||
elseif row[i] == "5" then -- box on goal
|
||||
sprites:blit(pos[1], pos[2], 3)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local pos = {
|
||||
game.draw_offset[1] + game.player_pos[1] * sprite_size,
|
||||
game.draw_offset[2] + game.player_pos[2] * sprite_size
|
||||
}
|
||||
sprites:blit(pos[1], pos[2], game.player_sprites[game.player_direction][game.player_flip+1])
|
||||
|
||||
if game.player_direction == "W" then
|
||||
draw.text(160, 160, "You win !!!",fg,bg,draw.align_center)
|
||||
draw.text(160, 170, "Press ENTER for next level",fg,bg,draw.align_center)
|
||||
end
|
||||
|
||||
draw.text(0, 300, "Box World! #" .. game.level .. " - Moves: " .. #game.moves .. " ")
|
||||
draw.text(0, 310, "(U)ndo, (R)estart, (ESC) Quit")
|
||||
|
||||
draw.blitBuffer()
|
||||
end
|
||||
|
||||
function game.check_win()
|
||||
for j = 1, #game.leveltable do
|
||||
local row = game.leveltable[j]
|
||||
for i = 1, #row do
|
||||
if row[i] == "4" then -- box not on goal
|
||||
return false -- quit as soon as found any
|
||||
end
|
||||
end
|
||||
end
|
||||
-- didn't quit? must mean we won
|
||||
game.player_direction = "W"
|
||||
music.play(music.tracks.victory)
|
||||
end
|
||||
|
||||
function game.process_push(code)
|
||||
if game.player_direction == "W" then return end -- don't move if we've already won
|
||||
local ahead, ahead2
|
||||
if code == keys.up then
|
||||
game.player_direction = "U"
|
||||
ahead = {game.player_pos[1], game.player_pos[2]-1}
|
||||
ahead2 = {game.player_pos[1], game.player_pos[2]-2}
|
||||
elseif code == keys.down then
|
||||
game.player_direction = "D"
|
||||
ahead = {game.player_pos[1], game.player_pos[2]+1}
|
||||
ahead2 = {game.player_pos[1], game.player_pos[2]+2}
|
||||
elseif code == keys.left then
|
||||
game.player_direction = "L"
|
||||
ahead = {game.player_pos[1]-1, game.player_pos[2]}
|
||||
ahead2 = {game.player_pos[1]-2, game.player_pos[2]}
|
||||
elseif code == keys.right then
|
||||
game.player_direction = "R"
|
||||
ahead = {game.player_pos[1]+1, game.player_pos[2]}
|
||||
ahead2 = {game.player_pos[1]+2, game.player_pos[2]}
|
||||
end
|
||||
|
||||
local whats_ahead = game.leveltable[ahead[2]]
|
||||
if whats_ahead ~= nil then whats_ahead = whats_ahead[ahead[1]] end
|
||||
local whats_ahead2 = game.leveltable[ahead2[2]]
|
||||
if whats_ahead2 ~= nil then whats_ahead2 = whats_ahead2[ahead2[1]] end
|
||||
|
||||
if whats_ahead == '2' or whats_ahead == '3' then -- ahead is floor or empty goal
|
||||
game.player_pos = ahead
|
||||
table.insert(game.moves, string.lower(game.player_direction))
|
||||
elseif whats_ahead == '4' or whats_ahead == '5' then -- ahead is box, whether or not on a goal
|
||||
if whats_ahead2 == '2' or whats_ahead2 == '3' then -- box pushed onto floor or goal
|
||||
sound.playPitch(2,1,game.push_sound)
|
||||
local box_leaves = whats_ahead == '4' and '2' or '3'
|
||||
local box_becomes = whats_ahead2 == '2' and '4' or '5'
|
||||
game.player_pos = ahead
|
||||
game.leveltable[ahead[2]][ahead[1]] = box_leaves
|
||||
game.leveltable[ahead2[2]][ahead2[1]] = box_becomes
|
||||
table.insert(game.moves, game.player_direction)
|
||||
game.check_win()
|
||||
end
|
||||
end
|
||||
screen.redraw = true
|
||||
end
|
||||
|
||||
function game.process_undo()
|
||||
if #game.moves < 1 then return false end
|
||||
|
||||
local return_to, pushed
|
||||
local move = table.remove(game.moves)
|
||||
game.player_direction = string.upper(move)
|
||||
|
||||
if string.upper(move) == 'D' then
|
||||
return_to = {game.player_pos[1], game.player_pos[2]-1}
|
||||
pushed = {game.player_pos[1], game.player_pos[2]+1}
|
||||
elseif string.upper(move) == 'U' then
|
||||
return_to = {game.player_pos[1], game.player_pos[2]+1}
|
||||
pushed = {game.player_pos[1], game.player_pos[2]-1}
|
||||
elseif string.upper(move) == 'R' then
|
||||
return_to = {game.player_pos[1]-1, game.player_pos[2]}
|
||||
pushed = {game.player_pos[1]+1, game.player_pos[2]}
|
||||
elseif string.upper(move) == 'L' then
|
||||
return_to = {game.player_pos[1]+1, game.player_pos[2]}
|
||||
pushed = {game.player_pos[1]-1, game.player_pos[2]}
|
||||
end
|
||||
|
||||
if move == string.upper(move) then -- if move was recorded upper means we moved a box
|
||||
local what_box_became = game.leveltable[pushed[2]][pushed[1]]
|
||||
local box_leaves = what_box_became == '4' and '2' or '3'
|
||||
local box_becomes = game.leveltable[game.player_pos[2]][game.player_pos[1]] == '2' and '4' or '5'
|
||||
game.leveltable[pushed[2]][pushed[1]] = box_leaves
|
||||
game.leveltable[game.player_pos[2]][game.player_pos[1]] = box_becomes
|
||||
end
|
||||
game.player_pos = return_to
|
||||
|
||||
screen.redraw = true
|
||||
end
|
||||
|
||||
function game.input()
|
||||
local state, _, code = keys.poll()
|
||||
|
||||
if state == keys.states.pressed then
|
||||
if code == keys.up or code == keys.down or code == keys.left or code == keys.right then
|
||||
game.process_push(code)
|
||||
elseif code == 'u' then
|
||||
game.process_undo()
|
||||
elseif code == 'r' then
|
||||
game.entry()
|
||||
elseif code == keys.esc then
|
||||
switch_screen(title)
|
||||
elseif game.player_direction == "W" and code == keys.enter then
|
||||
-- go to next level when won and pressed enter
|
||||
game.level = ((game.level) % #game.levelstrings) + 1
|
||||
game.entry()
|
||||
end
|
||||
end
|
||||
collectgarbage()
|
||||
end
|
||||
|
||||
function game.update(now)
|
||||
if game.player_direction ~= 'W' and now > game.anim_timer then
|
||||
game.player_flip = (game.player_flip + 1) % 2
|
||||
game.anim_timer = now + 1
|
||||
screen.redraw = true
|
||||
end
|
||||
end
|
||||
|
||||
switch_screen(title)
|
||||
while true do
|
||||
now = os.clock()
|
||||
if screen.input then screen.input() end
|
||||
if quit then break end
|
||||
if screen.update then screen.update(now) end
|
||||
if screen.redraw and screen.draw then screen.draw() screen.redraw = false end
|
||||
end
|
||||
74
Bin/PicoCalc SD/lua/browser.lua
Normal file
74
Bin/PicoCalc SD/lua/browser.lua
Normal file
@@ -0,0 +1,74 @@
|
||||
local current_dir = "/"
|
||||
local cursor_y = 1
|
||||
local width, height = term.getSize()
|
||||
|
||||
function string:endswith(suffix)
|
||||
return self:sub(-#suffix) == suffix
|
||||
end
|
||||
|
||||
term.clear()
|
||||
while true do
|
||||
local dir = fs.list(current_dir)
|
||||
term.setCursorPos(1,1)
|
||||
|
||||
table.sort(dir, function(a, b) return string.upper(a.name) < string.upper(b.name) end)
|
||||
local folders = {}
|
||||
local files = {}
|
||||
for _,v in pairs(dir) do
|
||||
if v.isDir then table.insert(folders, v)
|
||||
else table.insert(files, v) end
|
||||
end
|
||||
table.sort(files, function(a, b) return a.name < b.name end)
|
||||
dir = folders
|
||||
for _,v in ipairs(files) do
|
||||
table.insert(dir, v)
|
||||
end
|
||||
|
||||
if current_dir > "/" then
|
||||
table.insert(dir, 1, {name="..", isDir=true})
|
||||
end
|
||||
|
||||
local off = 0
|
||||
if #dir > height-2 then
|
||||
off = math.floor(cursor_y / #dir * (#dir - height + 3))
|
||||
end
|
||||
|
||||
for y = 1, height - 2 do
|
||||
local yoff = y + off
|
||||
local v = dir[yoff]
|
||||
if v then
|
||||
local str = ""
|
||||
if v.isDir then str = str .. "\27[93m"
|
||||
elseif v.name:endswith(".lua") then str = str .. "\27[96m"
|
||||
else str = str .. "\27[97m" end
|
||||
if yoff == cursor_y then str = str .. "\27[7m" end
|
||||
term.write(str .. v.name .. "\27[m\27[K\n")
|
||||
else
|
||||
term.write("\27[K\n")
|
||||
end
|
||||
end
|
||||
|
||||
term.write("\n\27[93mCurrent directory: " .. current_dir .. "\27[m\27[K")
|
||||
|
||||
local state, _, code = keys.wait(true, true)
|
||||
|
||||
if code == keys.up then
|
||||
cursor_y = ((cursor_y - 2) % #dir) + 1
|
||||
elseif code == keys.down then
|
||||
cursor_y = ((cursor_y) % #dir) + 1
|
||||
elseif code == keys.enter then
|
||||
if dir[cursor_y].isDir then
|
||||
if dir[cursor_y].name == ".." then
|
||||
current_dir = current_dir:match("(.*/).*/") or '/'
|
||||
else
|
||||
current_dir = current_dir .. dir[cursor_y].name .. '/'
|
||||
end
|
||||
cursor_y = 1
|
||||
elseif dir[cursor_y].name:endswith(".lua") then
|
||||
edit(current_dir .. dir[cursor_y].name)
|
||||
end
|
||||
elseif code == keys.esc then
|
||||
break
|
||||
end
|
||||
end
|
||||
term.clear()
|
||||
50
Bin/PicoCalc SD/lua/bubble.lua
Normal file
50
Bin/PicoCalc SD/lua/bubble.lua
Normal file
@@ -0,0 +1,50 @@
|
||||
-- Bubble Universe
|
||||
-- inspired by https://forum.clockworkpi.com/t/bubble-universe/19907
|
||||
|
||||
local w = 320
|
||||
local w2 = w/2
|
||||
local rad = 70
|
||||
local n = 20
|
||||
local nc = 120
|
||||
local step = 2
|
||||
local r = math.pi*2/n
|
||||
local x,y,t = 0,0,6
|
||||
local u,v,px,py
|
||||
|
||||
local res = 100
|
||||
|
||||
local sint = {}
|
||||
for i = 1, math.floor(math.pi*2*res) do
|
||||
sint[i] = math.sin(i/res)
|
||||
end
|
||||
|
||||
local function fsin(i)
|
||||
return sint[(math.floor(i*res)%#sint)+1]
|
||||
end
|
||||
|
||||
local function fcos(i)
|
||||
return sint[((math.floor((math.pi/2-i)*res))%#sint)+1]
|
||||
end
|
||||
|
||||
draw.enableBuffer(2)
|
||||
while true do
|
||||
if keys.getState(keys.esc) then break end
|
||||
draw.clear()
|
||||
for i = 0, n-1 do
|
||||
for c = 0, nc-1, step do
|
||||
u = fsin(i+y)+fsin(r*i+x)
|
||||
v = fcos(i+y)+fcos(r*i+x)
|
||||
x = u + t
|
||||
y = v
|
||||
px = u * rad + w2
|
||||
py = y * rad + w2
|
||||
draw.point(px, py,
|
||||
--draw.rectFill(px, py, 2, 2,
|
||||
colors.fromRGB(math.floor(63+i/n*192),
|
||||
math.floor(63+c/nc*192),168))
|
||||
end
|
||||
end
|
||||
t=t+0.02
|
||||
draw.blitBuffer()
|
||||
end
|
||||
draw.enableBuffer(false)
|
||||
107
Bin/PicoCalc SD/lua/mandelbrot.lua
Normal file
107
Bin/PicoCalc SD/lua/mandelbrot.lua
Normal file
@@ -0,0 +1,107 @@
|
||||
-- partially adapted from https://bisqwit.iki.fi/jutut/kuvat/programming_examples/mandelbrotbtrace.pdf
|
||||
-- arrow keys, 9 and 0 to control view, escape to quit
|
||||
|
||||
local maxIter = 64
|
||||
local chunk = 8
|
||||
local center = {-1,0}
|
||||
local radius = 1
|
||||
local minX, maxX, minY, maxY
|
||||
local wid, hei = 320, 320
|
||||
|
||||
local function iterate(zr, zi, max)
|
||||
local cnt, r, i, r2, i2, ri
|
||||
cnt = 0
|
||||
r,i = zr,zi
|
||||
while cnt < max do
|
||||
r2 = r*r; i2 = i*i
|
||||
if r2+i2 >= 4 then break end
|
||||
ri = r*i
|
||||
i = ri+ri + zi
|
||||
r = r2-i2 + zr
|
||||
cnt = cnt + 1
|
||||
end
|
||||
return cnt
|
||||
end
|
||||
|
||||
local function is_control_key()
|
||||
local state, _, code = keys.peek()
|
||||
if state == keys.states.pressed then
|
||||
if code == keys.up
|
||||
or code == keys.down
|
||||
or code == keys.left
|
||||
or code == keys.right
|
||||
or code == '9'
|
||||
or code == '0'
|
||||
or code == '['
|
||||
or code == ']'
|
||||
or code == keys.esc then
|
||||
return true
|
||||
end
|
||||
end
|
||||
keys.flush()
|
||||
return false
|
||||
end
|
||||
|
||||
local function drawScanlineMandelbrot(max)
|
||||
local zr, zi, cnt, clr
|
||||
local st = chunk
|
||||
local proc = {}
|
||||
local stepR = (maxX - minX) / wid
|
||||
local stepI = (maxY - minY) / hei
|
||||
while st >= 1 do
|
||||
for y = 0, hei - 1, st do
|
||||
zi = minY + y * stepI
|
||||
if proc[(y % (st*2))] then goto next end
|
||||
for x = 0, wid - 1 do
|
||||
zr = minX + x * stepR
|
||||
cnt = iterate(zr, zi, max)
|
||||
if cnt == max then clr = 0
|
||||
else
|
||||
cnt = math.floor(cnt/max*255)
|
||||
clr = colors.fromHSV((-cnt-32)%256,255,127+math.floor(cnt/2))
|
||||
end
|
||||
draw.line(x, y, x, y+st-1, clr)
|
||||
if is_control_key() then return end
|
||||
end
|
||||
::next::
|
||||
end
|
||||
proc[st%chunk] = true
|
||||
st = math.floor(st/2)
|
||||
end
|
||||
end
|
||||
|
||||
while true do
|
||||
minX, maxX, minY, maxY = center[1]-radius, center[1]+radius, center[2]-radius, center[2]+radius
|
||||
drawScanlineMandelbrot(maxIter)
|
||||
while true do
|
||||
local _, _, code = keys.wait(false, true)
|
||||
if code == keys.up then
|
||||
center[2] = center[2] - radius * 0.25
|
||||
break
|
||||
elseif code == keys.down then
|
||||
center[2] = center[2] + radius * 0.25
|
||||
break
|
||||
elseif code == keys.left then
|
||||
center[1] = center[1] - radius * 0.25
|
||||
break
|
||||
elseif code == keys.right then
|
||||
center[1] = center[1] + radius * 0.25
|
||||
break
|
||||
elseif code == '9' then
|
||||
radius = radius * 4
|
||||
break
|
||||
elseif code == '0' then
|
||||
radius = radius * 0.25
|
||||
break
|
||||
elseif code == '[' then
|
||||
maxIter = maxIter - 10
|
||||
break
|
||||
elseif code == ']' then
|
||||
maxIter = maxIter + 10
|
||||
break
|
||||
elseif code == keys.esc then
|
||||
goto exit
|
||||
end
|
||||
end
|
||||
end
|
||||
::exit::
|
||||
84
Bin/PicoCalc SD/lua/piano.lua
Normal file
84
Bin/PicoCalc SD/lua/piano.lua
Normal file
@@ -0,0 +1,84 @@
|
||||
-- kalimba / piano demo
|
||||
-- written by maple "mavica" syrup <maple@maple.pet>
|
||||
|
||||
local pkeys = {}
|
||||
|
||||
local keymap = {
|
||||
"5","6","4","7","3","8","2","9",
|
||||
"t","y","r","u","e","i","w","o",
|
||||
"g","h","f","j","d","k","s","l",
|
||||
"b","n","v","m","c",",","x","."
|
||||
}
|
||||
|
||||
local qwertymap = {
|
||||
"2","3","4","5","6","7","8","9",
|
||||
"w","e","r","t","y","u","i","o",
|
||||
"s","d","f","g","h","j","k","l",
|
||||
"x","c","v","b","n","m",",","."
|
||||
}
|
||||
|
||||
for k,v in pairs(keymap) do
|
||||
pkeys[v] = k - 1
|
||||
end
|
||||
|
||||
local last = nil
|
||||
local ch = 0
|
||||
local octave = 3
|
||||
|
||||
local inst_num = 0
|
||||
local insts = {}
|
||||
local inst_names = {}
|
||||
|
||||
for k,v in pairs(sound.presets) do
|
||||
table.insert(insts, v)
|
||||
table.insert(inst_names, k)
|
||||
end
|
||||
|
||||
local function noteString(note)
|
||||
local notes = {"C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-", "G#", "A-", "A#", "B-"}
|
||||
return notes[(note % 12)+1] .. math.floor(note / 12)
|
||||
end
|
||||
|
||||
local function redraw()
|
||||
term.setCursorPos(1,1)
|
||||
term.write("Piano / Kalimba demo\n\n")
|
||||
for j = 0, 24, 8 do
|
||||
for i = 1, 8 do
|
||||
if qwertymap[i+j] == last then term.write("\27[7m") end
|
||||
term.write(qwertymap[i+j].."\27[m ")
|
||||
end
|
||||
term.write("\n")
|
||||
end
|
||||
term.write("\n")
|
||||
if pkeys[last] then term.write(noteString(pkeys[last] + octave * 12)) end
|
||||
term.write("\n\n")
|
||||
term.write("Octave: " .. octave .. " | Instrument: " .. inst_names[inst_num+1] .. "\n\x1b[K")
|
||||
term.write("/ \\ - Change octave\n[ ] - Change instrument\nEsc - Quit\n")
|
||||
end
|
||||
|
||||
term.clear()
|
||||
while true do
|
||||
redraw()
|
||||
|
||||
local state, _, code = keys.wait(false, false)
|
||||
|
||||
if state == keys.states.pressed and code ~= last then
|
||||
if pkeys[code] then
|
||||
last = code
|
||||
sound.play(ch, pkeys[code] + octave * 12, insts[inst_num+1])
|
||||
ch = (ch+1) % 4
|
||||
elseif code == "[" then
|
||||
inst_num = (inst_num - 1) % #insts
|
||||
elseif code == "]" then
|
||||
inst_num = (inst_num + 1) % #insts
|
||||
elseif code == "/" and octave > 0 then
|
||||
octave = (octave - 1)
|
||||
elseif code == "\\" and octave < 6 then
|
||||
octave = (octave + 1)
|
||||
elseif code == keys.esc then
|
||||
break
|
||||
end
|
||||
elseif state == keys.states.released then
|
||||
last = nil
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user