This commit is contained in:
lifestorm
2024-08-04 23:54:45 +03:00
parent 0e770b2b49
commit df294d03aa
7526 changed files with 4011945 additions and 15 deletions

View File

@@ -0,0 +1,216 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
-- Piano renderer
local Piano = {
keys = {},
whiteCount = 0,
transpose = 0,
noteMin = 0,
noteMax = 128,
w = 16,
keyW = 22
}
MKeyboard.piano = Piano
local keyNameOverride = {
[KEY_SEMICOLON] = ";"
}
local function GetButtonName( button )
return language.GetPhrase( keyNameOverride[button] or input.GetKeyName( button ) or "NONE" )
end
function Piano:SetLayout( layout )
self.keys = {}
self.whiteCount = 0
for _, key in ipairs( layout ) do
self.keys[#self.keys + 1] = {
button = key[1],
altButton = key[5],
label = GetButtonName( key[1] ),
note = key[2],
isBlack = key[3],
needsShift = key[4],
isPressed = false
}
if not key[3] then
self.whiteCount = self.whiteCount + 1
end
end
self.w = self.keyW * self.whiteCount
end
--- Set the note limits. Keys with notes
--- outside this range will be grayed out.
function Piano:SetNoteRange( min, max )
self.noteMin, self.noteMax = min, max
end
--- Find the normal and shifted keys linked to this button.
function Piano:FindKeys( button )
local normal, shifted
for _, key in ipairs( self.keys ) do
if key.button == button or key.altButton == button then
if key.needsShift then
shifted = key
else
normal = key
end
end
end
return normal, shifted
end
--- Find the key linked to this note.
function Piano:FindKeyByNote( note )
for _, key in ipairs( self.keys ) do
if key.note == note then
return key
end
end
end
--- Press the key linked to this note.
function Piano:PressNote( note, velocity, instrument, color, automated )
local key = self:FindKeyByNote( note )
if key then
key.color = color
key.isPressed = true
end
self.OnNoteOn( note, velocity, instrument, automated )
end
--- Release the key linked to this note.
function Piano:ReleaseNote( note )
local key = self:FindKeyByNote( note )
if key then
key.color = nil
key.isPressed = false
end
end
--- Releases all notes.
function Piano:ReleaseAllNotes()
for _, key in ipairs( self.keys ) do
key.color = nil
key.isPressed = false
end
end
--- Press the key linked to this button.
function Piano:PressButton( button, velocity, instrument, color )
velocity = velocity or 127
local normal, shifted = self:FindKeys( button )
if input.IsShiftDown() then
if shifted then
shifted.color = color
shifted.isPressed = true
self.OnNoteOn( shifted.note + self.transpose, velocity, instrument )
end
else
if normal then
normal.color = color
normal.isPressed = true
self.OnNoteOn( normal.note + self.transpose, velocity, instrument )
end
end
end
--- Release the key linked to this button.
function Piano:ReleaseButton( button )
-- Always release both normal and shifted keys, to handle a key that was
-- pressed with shift previously but does not have shift pressed now.
local normal, shifted = self:FindKeys( button )
if normal and normal.isPressed then
normal.color = nil
normal.isPressed = false
end
if shifted and shifted.isPressed then
shifted.color = nil
shifted.isPressed = false
end
end
local SetColor = surface.SetDrawColor
local DrawRect = surface.DrawRect
local DrawRoundedBox = draw.RoundedBoxEx
local DrawText = draw.SimpleText
local COLOR_WHITE = Color( 255, 255, 255 )
local COLOR_BLACK = Color( 0, 0, 0 )
local ALIGN_CENTER = TEXT_ALIGN_CENTER
local ALIGN_BOTTOM = TEXT_ALIGN_BOTTOM
local settings = MKeyboard.settings
function Piano:Draw( x, y, h )
local min, max = self.noteMin, self.noteMax
local transpose = self.transpose
local labels = settings.drawKeyLabels
local w = self.keyW
local labelY = y + h - 4
local blackLabelY = y + ( h * 0.6 ) - 4
local blackW = w * 0.7
local note, deferKey
for _, key in ipairs( self.keys ) do
note = key.note + transpose
if note < min or note > max then
-- empty space
if not key.isBlack then
x = x + w
end
elseif key.isBlack then
-- draw it on top of the next one
deferKey = key
else
SetColor( key.color or COLOR_WHITE )
DrawRect( x, y, w - 1, h )
if labels then
DrawText( key.label, "MKeyboard_Key", x + w * 0.5, labelY, COLOR_BLACK, ALIGN_CENTER, ALIGN_BOTTOM )
end
if deferKey then
DrawRoundedBox( 4, x - blackW * 0.5, y, blackW, h * 0.6, deferKey.color or COLOR_BLACK, false, false, true, true )
if labels then
DrawText( deferKey.label, "MKeyboard_Key", x, blackLabelY, COLOR_WHITE, ALIGN_CENTER, ALIGN_BOTTOM )
end
deferKey = nil
end
x = x + w
end
end
end