diff --git a/scripts/songselect/chalwheel.lua b/scripts/songselect/chalwheel.lua index 3bf5933..b56a24c 100644 --- a/scripts/songselect/chalwheel.lua +++ b/scripts/songselect/chalwheel.lua @@ -91,6 +91,19 @@ local passStates = { 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("dfmarugoth.ttf"); @@ -200,16 +213,18 @@ check_or_create_cache = function(challenge) end 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) - local _draw_card_bg = function () + local _draw_card_bg = function() gfx.BeginPath() gfx.ImageRect(x, y, w, h, challengeCardBG, 1, 0) end - local _draw_info = function () + local _draw_info = function() local stateLabel = challengeCache[challenge.id]["pass_state"] local stateLabelWidth, stateLabelHeight = gfx.ImageSize(stateLabel) local stateLabelAspect = stateLabelWidth / stateLabelHeight @@ -220,31 +235,29 @@ draw_challenge = function(challenge, x, y, w, h, selected) local stateOffsetY = y + h / 16 local titleMargin = 6 - local titleMaxWidth = 3/5 * w - local titleCenterX = x + w - titleMargin - titleMaxWidth/2 --align right - local titleOffsetY = y + 1/11 * h --align baseline + local titleMaxWidth = 3 / 5 * w + local titleCenterX = x + w - titleMargin - titleMaxWidth / 2 -- align right + local titleOffsetY = y + 1 / 11 * h -- align baseline if not selected then stateWidth = stateWidth * 0.9 stateHeight = stateHeight * 0.9 stateOffsetY = y + h / 32 - titleMaxWidth = 6/9 * w - titleCenterX = x + w - titleMargin - titleMaxWidth/2 --align right - titleOffsetY = y + titleMargin/2 --align baseline + titleMaxWidth = 6 / 9 * w + titleCenterX = x + w - titleMargin - titleMaxWidth / 2 -- align right + titleOffsetY = y + titleMargin / 2 -- align baseline end gfx.BeginPath() gfx.ImageRect(stateOffsetX, stateOffsetY, stateWidth, stateHeight, stateLabel, 1, 0) - --testBox(stateOffsetX, stateOffsetY, stateWidth, stateHeight) gfx.FontFace("divlit_custom.ttf") gfx.TextAlign(gfx.TEXT_ALIGN_CENTER | gfx.TEXT_ALIGN_BASELINE) gfx.DrawLabel(challengeCache[challenge.id]["title"], titleCenterX, titleOffsetY, titleMaxWidth) - --testBox(titleOffsetX, titleOffsetY, math.min(titleLabelWidth, titleMaxWidth), titleLabelHeight) end - local _draw_jacket = function () + local _draw_jacket = function() local size = h * 0.68 local offsetX = x + w / 32 local offsetY = y + h - size - h * 0.05 @@ -254,15 +267,15 @@ draw_challenge = function(challenge, x, y, w, h, selected) offsetX = x + w * 0.058 offsetY = y + h - size - h * 0.066 end - + gfx.BeginPath() gfx.ImageRect(offsetX, offsetY, size, size, challengeCache[challenge.id]["jackets"][1], 1, 0) end - local _draw_stats = function () + local _draw_stats = function() 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 percentSize = 0.17 * textSizeCorrection @@ -272,16 +285,16 @@ draw_challenge = function(challenge, x, y, w, h, selected) local scoreOffsetY = y + h * 0.9 local scoreUpperSize = 0.2 * textSizeCorrection local scoreSize = 0.125 * textSizeCorrection - + local percent = challengeCache[challenge.id]["percent"] local scoreUpper = math.floor(challengeCache[challenge.id]["total_score"] / 10000) local score = challengeCache[challenge.id]["total_score"] if selected then - percentOffsetX = x + 11/24 * w - percentOffsetY = y + 49/64 * h + percentOffsetX = x + 11 / 24 * w + percentOffsetY = y + 49 / 64 * h percentSize = 0.12 * textSizeCorrection - + scoreUpperOffsetX = x + w * 0.63 scoreUpperOffsetY = y + h * 0.82 scoreOffsetX = x + w * 0.755 @@ -291,17 +304,52 @@ draw_challenge = function(challenge, x, y, w, h, selected) end Numbers.draw_number(percentOffsetX, percentOffsetY, 1, percent, 3, scoreNumber, true, percentSize, 1) + -- TODO: Missing percentage character 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) else Numbers.draw_number(scoreOffsetX, scoreOffsetY, 1, score, 8, scoreNumber, true, scoreSize, 1) 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 if not selected then @@ -311,218 +359,39 @@ draw_challenge = function(challenge, x, y, w, h, selected) _draw_info() _draw_jacket() _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() end -draw_diff_icon = function(diff, x, y, w, h, selected, deltaTime) - local shrinkX = w / 4 - local shrinkY = h / 4 - if selected then - gfx.FontSize(h / 2) - shrinkX = w / 6 - 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_diff_icon = function(diff, x, y, w, h) + -- cut out the transparent part of the diff background image + local boxWidth = 140 / 122 * w + local boxHeight = 31 / 27 * h + local boxOffsetX = x - (boxWidth - w) / 2 + local boxOffsetY = y - (boxHeight - h) / 2 -draw_diffs = function(diffs, x, y, w, h) - local diffWidth = w / 2.5 - 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 + local labelOffsetX = w / 12 + local labelTextOffsetY = h / 12 - -- 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.FillColor(0, 128, 255) - gfx.Rect(x, y + 10, 2, diffHeight - h / 6) - gfx.Fill() - gfx.BeginPath() - gfx.Rect(x + w - 2, y + 10, 2, diffHeight - h / 6) - gfx.Fill() - gfx.ResetScissor() - draw_cursor(x + w / 2, y + diffHeight / 2, timer * math.pi, diffHeight / 1.5) + + gfx.ImageRect(boxOffsetX, boxOffsetY, boxWidth, boxHeight, difficultyLabelImages[diff.difficulty + 1], 1, 0) + + gfx.FontFace("dfmarugoth.ttf") + gfx.FontSize(math.floor(0.6 * h)) + gfx.TextAlign(gfx.TEXT_ALIGN_LEFT | gfx.TEXT_ALIGN_MIDDLE) + gfx.FastText(difficultyLabelText[diff.difficulty + 1], x + labelOffsetX, y + (h / 2) - labelTextOffsetY) + 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 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) @@ -542,7 +411,7 @@ draw_chalwheel = function(x, y, w, h) local selectedWidth = math.floor(w * 0.944) 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 selectedOffsetX = w / 2 - selectedWidth / 2 local selectedCenterY = h / 2 - selectedHeight / 2 @@ -556,7 +425,7 @@ draw_chalwheel = function(x, y, w, h) if not (current == 0) then local challenge = chalwheel.challenges[i] 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 ypos = y + centerY if current < 0 then @@ -578,7 +447,7 @@ draw_legend_pane = function(x, y, w, h, obj) local xpos = x + 5 local ypos = y local imageSize = h - + gfx.BeginPath() gfx.TextAlign(gfx.TEXT_ALIGN_MIDDLE + gfx.TEXT_ALIGN_LEFT) gfx.ImageRect(x, y, imageSize, imageSize, obj.image, 1, 0) @@ -629,7 +498,7 @@ draw_search = function(x, y, w, h) gfx.StrokeWidth(1) gfx.Fill() gfx.Stroke() - + gfx.BeginPath(); gfx.LoadSkinFont("dfmarugoth.ttf"); gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE);