chalwheel: added chart list and difficulty icons

This commit is contained in:
Hersi 2021-11-21 03:17:22 +01:00
parent be96b53510
commit b4b4f07b82
1 changed files with 97 additions and 228 deletions

View File

@ -91,6 +91,19 @@ local passStates = {
local scoreNumber = Numbers.load_number_image("score_num") local scoreNumber = Numbers.load_number_image("score_num")
local difficultyLabelImages = {
gfx.CreateSkinImage("diff/1 novice.png", 0),
gfx.CreateSkinImage("diff/2 advanced.png", 0),
gfx.CreateSkinImage("diff/3 exhaust.png", 0),
gfx.CreateSkinImage("diff/4 maximum.png", 0),
gfx.CreateSkinImage("diff/5 infinite.png", 0),
gfx.CreateSkinImage("diff/6 gravity.png", 0),
gfx.CreateSkinImage("diff/7 heavenly.png", 0),
gfx.CreateSkinImage("diff/8 vivid.png", 0)
}
local difficultyLabelText = { "NOV", "ADV", "EXH", "MXM", "INF", "GRV", "HVN", "VVD" }
gfx.LoadSkinFont("divlit_custom.ttf") gfx.LoadSkinFont("divlit_custom.ttf")
gfx.LoadSkinFont("dfmarugoth.ttf"); gfx.LoadSkinFont("dfmarugoth.ttf");
@ -200,16 +213,18 @@ check_or_create_cache = function(challenge)
end end
draw_challenge = function(challenge, x, y, w, h, selected) draw_challenge = function(challenge, x, y, w, h, selected)
if not challenge then return end if not challenge then
return
end
check_or_create_cache(challenge) check_or_create_cache(challenge)
local _draw_card_bg = function () local _draw_card_bg = function()
gfx.BeginPath() gfx.BeginPath()
gfx.ImageRect(x, y, w, h, challengeCardBG, 1, 0) gfx.ImageRect(x, y, w, h, challengeCardBG, 1, 0)
end end
local _draw_info = function () local _draw_info = function()
local stateLabel = challengeCache[challenge.id]["pass_state"] local stateLabel = challengeCache[challenge.id]["pass_state"]
local stateLabelWidth, stateLabelHeight = gfx.ImageSize(stateLabel) local stateLabelWidth, stateLabelHeight = gfx.ImageSize(stateLabel)
local stateLabelAspect = stateLabelWidth / stateLabelHeight local stateLabelAspect = stateLabelWidth / stateLabelHeight
@ -220,31 +235,29 @@ draw_challenge = function(challenge, x, y, w, h, selected)
local stateOffsetY = y + h / 16 local stateOffsetY = y + h / 16
local titleMargin = 6 local titleMargin = 6
local titleMaxWidth = 3/5 * w local titleMaxWidth = 3 / 5 * w
local titleCenterX = x + w - titleMargin - titleMaxWidth/2 --align right local titleCenterX = x + w - titleMargin - titleMaxWidth / 2 -- align right
local titleOffsetY = y + 1/11 * h --align baseline local titleOffsetY = y + 1 / 11 * h -- align baseline
if not selected then if not selected then
stateWidth = stateWidth * 0.9 stateWidth = stateWidth * 0.9
stateHeight = stateHeight * 0.9 stateHeight = stateHeight * 0.9
stateOffsetY = y + h / 32 stateOffsetY = y + h / 32
titleMaxWidth = 6/9 * w titleMaxWidth = 6 / 9 * w
titleCenterX = x + w - titleMargin - titleMaxWidth/2 --align right titleCenterX = x + w - titleMargin - titleMaxWidth / 2 -- align right
titleOffsetY = y + titleMargin/2 --align baseline titleOffsetY = y + titleMargin / 2 -- align baseline
end end
gfx.BeginPath() gfx.BeginPath()
gfx.ImageRect(stateOffsetX, stateOffsetY, stateWidth, stateHeight, stateLabel, 1, 0) gfx.ImageRect(stateOffsetX, stateOffsetY, stateWidth, stateHeight, stateLabel, 1, 0)
--testBox(stateOffsetX, stateOffsetY, stateWidth, stateHeight)
gfx.FontFace("divlit_custom.ttf") gfx.FontFace("divlit_custom.ttf")
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER | gfx.TEXT_ALIGN_BASELINE) gfx.TextAlign(gfx.TEXT_ALIGN_CENTER | gfx.TEXT_ALIGN_BASELINE)
gfx.DrawLabel(challengeCache[challenge.id]["title"], titleCenterX, titleOffsetY, titleMaxWidth) gfx.DrawLabel(challengeCache[challenge.id]["title"], titleCenterX, titleOffsetY, titleMaxWidth)
--testBox(titleOffsetX, titleOffsetY, math.min(titleLabelWidth, titleMaxWidth), titleLabelHeight)
end end
local _draw_jacket = function () local _draw_jacket = function()
local size = h * 0.68 local size = h * 0.68
local offsetX = x + w / 32 local offsetX = x + w / 32
local offsetY = y + h - size - h * 0.05 local offsetY = y + h - size - h * 0.05
@ -259,10 +272,10 @@ draw_challenge = function(challenge, x, y, w, h, selected)
gfx.ImageRect(offsetX, offsetY, size, size, challengeCache[challenge.id]["jackets"][1], 1, 0) gfx.ImageRect(offsetX, offsetY, size, size, challengeCache[challenge.id]["jackets"][1], 1, 0)
end end
local _draw_stats = function () local _draw_stats = function()
local textSizeCorrection = h / gfx.ImageSize(scoreNumber[1]) local textSizeCorrection = h / gfx.ImageSize(scoreNumber[1])
local percentOffsetX = x + 6/12 * w local percentOffsetX = x + 6 / 12 * w
local percentOffsetY = y + 0.87 * h local percentOffsetY = y + 0.87 * h
local percentSize = 0.17 * textSizeCorrection local percentSize = 0.17 * textSizeCorrection
@ -278,8 +291,8 @@ draw_challenge = function(challenge, x, y, w, h, selected)
local score = challengeCache[challenge.id]["total_score"] local score = challengeCache[challenge.id]["total_score"]
if selected then if selected then
percentOffsetX = x + 11/24 * w percentOffsetX = x + 11 / 24 * w
percentOffsetY = y + 49/64 * h percentOffsetY = y + 49 / 64 * h
percentSize = 0.12 * textSizeCorrection percentSize = 0.12 * textSizeCorrection
scoreUpperOffsetX = x + w * 0.63 scoreUpperOffsetX = x + w * 0.63
@ -291,17 +304,52 @@ draw_challenge = function(challenge, x, y, w, h, selected)
end end
Numbers.draw_number(percentOffsetX, percentOffsetY, 1, percent, 3, scoreNumber, true, percentSize, 1) Numbers.draw_number(percentOffsetX, percentOffsetY, 1, percent, 3, scoreNumber, true, percentSize, 1)
-- TODO: Missing percentage character
if selected then if selected then
Numbers.draw_number(scoreUpperOffsetX, scoreUpperOffsetY, 1, scoreUpper, 4, scoreNumber, true, scoreUpperSize, 1) Numbers.draw_number(
scoreUpperOffsetX, scoreUpperOffsetY, 1, scoreUpper, 4, scoreNumber, true, scoreUpperSize, 1
)
Numbers.draw_number(scoreOffsetX, scoreOffsetY, 1, score, 4, scoreNumber, true, scoreSize, 1) Numbers.draw_number(scoreOffsetX, scoreOffsetY, 1, score, 4, scoreNumber, true, scoreSize, 1)
else else
Numbers.draw_number(scoreOffsetX, scoreOffsetY, 1, score, 8, scoreNumber, true, scoreSize, 1) Numbers.draw_number(scoreOffsetX, scoreOffsetY, 1, score, 8, scoreNumber, true, scoreSize, 1)
end end
end end
local _draw_chart = function () local _draw_charts = function()
local diffIconHeight = 0.124 * h
local diffIconWidth = 140 / 31 * diffIconHeight -- only scaling, no stretching textures
-- diffIconWidth = 0.8 * diffIconWidth -- okay, maybe a little squishing must be done
local paddingY = 0.18 * h
local offsetX = x + 0.252 * w
local offsetY = y + 0.246 * h
local titleMargin = 6
local titleMaxWidth = 6 / 9 * w
local titleCenterX = x + w - titleMargin - titleMaxWidth / 2 -- align right
if selected then
diffIconHeight = h / 12
diffIconWidth = 140 / 31 * diffIconHeight -- only scaling, no stretching textures
-- diffIconWidth = 0.8 * diffIconWidth -- okay, maybe a little squishing must be done
paddingY = 0.122 * h
offsetX = x + 0.268 * w
offsetY = y + 0.256 * h
titleMaxWidth = 3 / 5 * w
titleCenterX = x + w - titleMargin - titleMaxWidth / 2 -- align right
end
for i, chart in ipairs(challengeCache[challenge.id]["charts"]) do
local ypos = offsetY + paddingY * (i - 1)
draw_diff_icon(chart, offsetX, ypos, diffIconWidth, diffIconHeight, selected)
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER | gfx.TEXT_ALIGN_MIDDLE)
gfx.DrawLabel(chart.title, titleCenterX, ypos + diffIconHeight / 2, titleMaxWidth)
end
end end
if not selected then if not selected then
@ -311,218 +359,39 @@ draw_challenge = function(challenge, x, y, w, h, selected)
_draw_info() _draw_info()
_draw_jacket() _draw_jacket()
_draw_stats() _draw_stats()
_draw_charts()
--[[
-- set up padding and margins
local xPadding = math.floor(w / 16)
local yPadding = math.floor(h / 32)
local xMargin = math.floor(w / 16)
local yMargin = math.floor(h / 32)
local width = (w - (xMargin * 2))
local height = (h - (yMargin * 2))
local xpos = x + xMargin
local ypos = y + yMargin
-- Border
-- local diff = song.difficulties[selectedDiff]
-- gfx.BeginPath()
-- gfx.RoundedRectVarying(xpos,ypos,width,height,yPadding,yPadding,yPadding,yPadding)
-- gfx.FillColor(30,30,30,100)
-- gfx.StrokeColor(0,128,255)
-- gfx.StrokeWidth(1)
-- gfx.Fill()
-- gfx.Stroke()
-- jacket should take up 1/3 of height, always be square, and be centered
local imageSize = math.floor((height / 2) * 2) - 10
local imageXPos = x + xMargin + xPadding
local imageYPos = y + yMargin + yPadding
local square_size = math.ceil(math.sqrt(#challenge.charts))
local origImageSize = imageSize
imageSize = math.floor(imageSize / square_size)
local bottom_off = math.ceil((square_size - #challenge.charts))
local img_row = 0;
local img_col = 0;
for i, chart in ipairs(challenge.charts) do
if challengeCache[challenge.id]["jackets"][i] == jacketFallback then
challengeCache[challenge.id]["jackets"][i] = gfx.LoadImageJob(chart.jacketPath, jacketFallback, 200, 200)
end
gfx.BeginPath()
local xoff = img_col * imageSize
if math.ceil(i / square_size) == square_size then
xoff = xoff
end
gfx.ImageRect(
imageXPos, imageYPos + (img_row / 200 * imageSize), imageSize * 1.19, imageSize * 1.19,
challengeCache[challenge.id]["jackets"][i], 1, 0
)
img_col = img_col + 1
if img_col >= square_size then
img_row = img_row + 1
img_col = 0
end
end
local num_img_rows = img_row + 1
if img_col == 0 then
num_img_rows = img_row
end
if challengeCache[challenge.id][selectedDiff] then
gfx.BeginPath()
-- gfx.ImageRect(imageXPos, y+yMargin+yPadding, imageSize, imageSize, songCache[song.id][selectedDiff], 1, 0)
end
local gradeImg = nil
for i, v in ipairs(grades) do
if v.max > challenge.bestScore then
gfx.BeginPath()
gradeImg = v.image
break
end
end
if scrollmul < 0 then
scrollmulOffset = scrollmulOffset - scrollmul
scrollmul = 0
end
local descw, desch = gfx.LabelSize(challengeCache[challenge.id]["desc"])
local boxh, boxw = 0, 0
local starty, startx = 0, 0
gfx.FontSize(40)
gfx.TextAlign(gfx.TEXT_ALIGN_TOP + gfx.TEXT_ALIGN_MIDDLE)
starty = y + yMargin + yPadding
startx = xpos + xPadding + origImageSize + 10
gfx.DrawLabel(challengeCache[challenge.id]["title"], 295, 845, width - origImageSize - 30)
gfx.FontSize(30)
-- Scroll box info
starty = starty + 50
boxh = height - starty
boxw = width - startx - 200
-- gfx.DrawLabel(songCache[song.id]["artist"], xpos+xPadding+imageSize+3, y+yMargin+yPadding + 45, width-imageSize-20)
-- gfx.DrawLabel(songCache[song.id]["artist"], xpos+xPadding+imageSize+3, y+yMargin+yPadding + 45, width-imageSize-20)
-- gfx.FontSize(20)
-- gfx.DrawLabel(songCache[song.id]["bpm"], xpos+xPadding+imageSize+3, y+yMargin+yPadding + 85, width-imageSize-20)
-- gfx.FastText(string.format("Effector: %s", diff.effector), xpos+xPadding+imageSize+3, y+yMargin+yPadding + 115)
if challenge.topBadge ~= 0 then
gfx.BeginPath()
gfx.ImageRect(978, 1026.5, 50, 50, badges[challenge.topBadge], 1, 0)
local iar = 0
if gradeImg ~= nil then
gfx.BeginPath()
local iw, ih = gfx.ImageSize(gradeImg)
iar = iw / ih
gfx.ImageRect(961 - iar * 50, 1026.5, iar * 50, 50, gradeImg, 1, 0)
end
gfx.TextAlign(gfx.TEXT_ALIGN_RIGHT + gfx.TEXT_ALIGN_MIDDLE)
gfx.DrawLabel(challengeCache[challenge.id]["percent"], 595, 1045, 200)
end
-- Render desc scrolling box
do
-- gfx.BeginPath()
-- gfx.Rect(startx, starty, boxw, boxh)
-- gfx.FillColor(50,50,50)
-- gfx.Fill()
local overBottom = desch - 100 * scrollmul - boxh
if overBottom < 0 and scrollmul > 0 then
local scrollend = (desch - boxh) / 100
if scrollend < 0 then
scrollend = 0
end
scrollmulOffset = scrollmulOffset - (scrollmul - scrollend)
scrollmul = scrollend
end
-- Draw scroll bar
if desch > boxh then
gfx.BeginPath()
local barStart = (100 * scrollmul) / desch -- Start percent of visible desc
local barh = (boxh / desch) * boxh
gfx.Rect(startx + boxw - 5, starty + (barStart * boxh) // 1, 5, barh // 1)
gfx.FillColor(20, 20, 20)
gfx.Fill()
end
gfx.BeginPath()
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE)
gfx.DrawLabel(challengeCache[challenge.id]["desc"], 600, 942)
end
-- if aspectRatio == "PortraitWidescreen" then
-- draw_scores(diff, xpos+xPadding+imageSize+3, (height/3)*2, width-imageSize-20, (height/3)-yPadding)
-- else
-- draw_scores(diff, xpos, (height/6)*5, width, (height/6))
-- end
--]]
gfx.ForceRender() gfx.ForceRender()
end end
draw_diff_icon = function(diff, x, y, w, h, selected, deltaTime) draw_diff_icon = function(diff, x, y, w, h)
local shrinkX = w / 4 -- cut out the transparent part of the diff background image
local shrinkY = h / 4 local boxWidth = 140 / 122 * w
if selected then local boxHeight = 31 / 27 * h
gfx.FontSize(h / 2) local boxOffsetX = x - (boxWidth - w) / 2
shrinkX = w / 6 local boxOffsetY = y - (boxHeight - h) / 2
shrinkY = h / 6
else
gfx.FontSize(math.floor(h / 3))
end
gfx.BeginPath()
gfx.RoundedRectVarying(x + shrinkX, y + shrinkY, w - shrinkX * 2, h - shrinkY * 2, 0, 0, 0, 0)
gfx.FillColor(15, 15, 15)
gfx.StrokeColor(table.unpack(diffColors[diff.difficulty + 1]))
gfx.StrokeWidth(2)
gfx.Fill()
gfx.Stroke()
gfx.FillColor(255, 255, 255)
gfx.TextAlign(gfx.TEXT_ALIGN_MIDDLE + gfx.TEXT_ALIGN_CENTER)
gfx.FastText(tostring(diff.level), x + (w / 2), y + (h / 2))
-- gfx.BeginPath()
-- DiffRectangle.render(deltaTime, 183, 2.5, 10, songCache[song.id][selectedDiff],tostring(diff.level));
end
draw_diffs = function(diffs, x, y, w, h) local labelOffsetX = w / 12
local diffWidth = w / 2.5 local labelTextOffsetY = h / 12
local diffHeight = w / 2.5
local diffCount = #diffs
gfx.Scissor(x, y, w, h)
for i = math.max(selectedDiff - 2, 1), math.max(selectedDiff - 1, 1) do
local diff = diffs[i]
local xpos = x + ((w / 2 - diffWidth / 2) + (selectedDiff - i + doffset) * (-0.8 * diffWidth))
if i ~= selectedDiff then
draw_diff_icon(diff, xpos, y, diffWidth, diffHeight, false)
end
end
-- after selected
for i = math.min(selectedDiff + 2, diffCount), selectedDiff + 1, -1 do
local diff = diffs[i]
local xpos = x + ((w / 2 - diffWidth / 2) + (selectedDiff - i + doffset) * (-0.8 * diffWidth))
if i ~= selectedDiff then
draw_diff_icon(diff, xpos, y, diffWidth, diffHeight, false)
end
end
local diff = diffs[selectedDiff]
local xpos = x + ((w / 2 - diffWidth / 2) + (doffset) * (-0.8 * diffWidth))
draw_diff_icon(diff, xpos, y, diffWidth, diffHeight, true)
gfx.BeginPath() gfx.BeginPath()
gfx.FillColor(0, 128, 255)
gfx.Rect(x, y + 10, 2, diffHeight - h / 6) gfx.ImageRect(boxOffsetX, boxOffsetY, boxWidth, boxHeight, difficultyLabelImages[diff.difficulty + 1], 1, 0)
gfx.Fill()
gfx.BeginPath() gfx.FontFace("dfmarugoth.ttf")
gfx.Rect(x + w - 2, y + 10, 2, diffHeight - h / 6) gfx.FontSize(math.floor(0.6 * h))
gfx.Fill() gfx.TextAlign(gfx.TEXT_ALIGN_LEFT | gfx.TEXT_ALIGN_MIDDLE)
gfx.ResetScissor() gfx.FastText(difficultyLabelText[diff.difficulty + 1], x + labelOffsetX, y + (h / 2) - labelTextOffsetY)
draw_cursor(x + w / 2, y + diffHeight / 2, timer * math.pi, diffHeight / 1.5) gfx.FontSize(math.floor(0.8 * h))
gfx.TextAlign(gfx.TEXT_ALIGN_RIGHT | gfx.TEXT_ALIGN_MIDDLE)
gfx.FastText(tostring(diff.level), x + w - labelOffsetX, y + (h / 2) - labelTextOffsetY)
end end
draw_selected = function(challenge, x, y, w, h) draw_selected = function(challenge, x, y, w, h)
if not challenge then return end if not challenge then
return
end
check_or_create_cache(challenge) check_or_create_cache(challenge)
@ -542,7 +411,7 @@ draw_chalwheel = function(x, y, w, h)
local selectedWidth = math.floor(w * 0.944) local selectedWidth = math.floor(w * 0.944)
local selectedHeight = math.floor((selectedWidth / selectedChallengeAspect) * portraitAspectCorrection) local selectedHeight = math.floor((selectedWidth / selectedChallengeAspect) * portraitAspectCorrection)
local offsetX = w / 2 - width / 2 --center local offsetX = w / 2 - width / 2 -- center
local centerY = h / 2 - height / 2 local centerY = h / 2 - height / 2
local selectedOffsetX = w / 2 - selectedWidth / 2 local selectedOffsetX = w / 2 - selectedWidth / 2
local selectedCenterY = h / 2 - selectedHeight / 2 local selectedCenterY = h / 2 - selectedHeight / 2
@ -556,7 +425,7 @@ draw_chalwheel = function(x, y, w, h)
if not (current == 0) then if not (current == 0) then
local challenge = chalwheel.challenges[i] local challenge = chalwheel.challenges[i]
local xpos = x + offsetX local xpos = x + offsetX
--local offsetY = current * (height - (wheelSize / 2 * (current * aspectFloat))) -- local offsetY = current * (height - (wheelSize / 2 * (current * aspectFloat)))
local offsetY = math.abs(current) * (height + margin) + (selectedHeight - height) / 2 local offsetY = math.abs(current) * (height + margin) + (selectedHeight - height) / 2
local ypos = y + centerY local ypos = y + centerY
if current < 0 then if current < 0 then