From 8326bb0bf4524d0538491448a5068fda6e4c08e7 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 28 Mar 2018 14:52:01 -0300 Subject: [PATCH 1/7] Rename solution from Stepmania to Etterna --- CMake/CPackSetup.cmake | 18 +++++++++--------- CMakeLists.txt | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CMake/CPackSetup.cmake b/CMake/CPackSetup.cmake index 9e11f8abf2..de3aca0f15 100644 --- a/CMake/CPackSetup.cmake +++ b/CMake/CPackSetup.cmake @@ -5,29 +5,29 @@ else() endif() set(CPACK_PACKAGE_NAME "${SM_EXE_NAME}") -set(CPACK_PACKAGE_VENDOR "StepMania") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Rhythm Game Simulator") +set(CPACK_PACKAGE_VENDOR "Etterna") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Rhythm Game Simulator For Keyboard") set(CPACK_PACKAGE_VERSION_MAJOR "${SM_VERSION_MAJOR}") set(CPACK_PACKAGE_VERSION_MINOR "${SM_VERSION_MINOR}") set(CPACK_PACKAGE_VERSION_PATCH "${SM_VERSION_PATCH}") set(CPACK_PACKAGE_VERSION "${SM_VERSION_TRADITIONAL}") -set(CPACK_NSIS_HELP_LINK "https://github.com/stepmania/stepmania/issues") +set(CPACK_NSIS_HELP_LINK "https://github.com/etternagame/etterna/issues") set(CPACK_NSIS_PACKAGE_NAME "${SM_EXE_NAME} ${NSIS_VERSION_FINAL}") -set(CPACK_NSIS_URL_INFO_ABOUT "http://www.stepmania.com/") +set(CPACK_NSIS_URL_INFO_ABOUT "https://etternaonline.com/") set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) set(CPACK_RESOURCE_FILE_README "${SM_ROOT_DIR}/README.md") set(CPACK_RESOURCE_FILE_LICENSE "${SM_CMAKE_DIR}/license_install.txt") set(CPACK_PACKAGE_EXECUTABLES - "${SM_EXE_NAME}" "StepMania ${SM_VERSION_MAJOR}" + "${SM_EXE_NAME}" "Etterna ${SM_VERSION_MAJOR}" ) set(CPACK_NSIS_MUI_ICON "${SM_INSTALLER_DIR}/install.ico") set(CPACK_NSIS_MUI_UNIICON "${SM_INSTALLER_DIR}/uninstall.ico") set(CPACK_NSIS_COMPRESSOR "/SOLID lzma") # Custom items for nsis go here. -set(CPACK_SM_NSIS_REPOSITORY "https://github.com/stepmania/stepmania") +set(CPACK_SM_NSIS_REPOSITORY "https://github.com/etternagame/etterna/") set(CPACK_SM_NSIS_ROOT_DIR "${SM_ROOT_DIR}") -set(CPACK_SM_NSIS_PRODUCT_ID "StepMania ${SM_VERSION_MAJOR}.${SM_VERSION_MINOR}") +set(CPACK_SM_NSIS_PRODUCT_ID "Etterna ${SM_VERSION_MAJOR}.${SM_VERSION_MINOR}") set(CPACK_SM_NSIS_PRODUCT_VERSION "${SM_VERSION_TRADITIONAL}.0") set(CPACK_SM_NSIS_HEADER_BITMAP "${SM_INSTALLER_DIR}/header-ett.bmp") set(CPACK_SM_NSIS_WELCOME_BITMAP "${SM_INSTALLER_DIR}/welcome-ett.bmp") @@ -44,8 +44,8 @@ if(WIN32) # This is currently done to maintain backwards compatibility. # However, removing these two will allow for multiple versions of StepMania # to be installed relatively cleanly. - set(CPACK_PACKAGE_INSTALL_DIRECTORY "StepMania ${SM_VERSION_MAJOR}") - set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "StepMania ${SM_VERSION_MAJOR}") + set(CPACK_PACKAGE_INSTALL_DIRECTORY "Etterna ${SM_VERSION_MAJOR}") + set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "Etterna ${SM_VERSION_MAJOR}") set(CPACK_NSIS_EXECUTABLES_DIRECTORY "Program") set(CPACK_NSIS_INSTALL_ROOT "C:\\\\Games") endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 183fc9bb73..3524c231ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.2.0) -project(StepMania) +project(Etterna) include (StepmaniaCore.cmake) From 21a5b195d3cc576f4e8332fa5dccae818a70cd6a Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 28 Mar 2018 17:28:32 -0300 Subject: [PATCH 2/7] ETTPC wife%, SSRs and rate update messages --- .../ScreenNetEvaluation decorations.lua | 482 ++++++------------ Themes/Til Death/Scripts/02 Branches.lua | 66 ++- Themes/Til Death/metrics.ini | 44 +- Themes/_fallback/Scripts/02 Branches.lua | 83 ++- Themes/_fallback/metrics.ini | 32 +- src/NetworkSyncManager.cpp | 8 +- src/ScreenNetSelectMusic.cpp | 11 +- src/ScreenSelectMusic.cpp | 1 + src/SongOptions.cpp | 26 +- 9 files changed, 359 insertions(+), 394 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenNetEvaluation decorations.lua b/Themes/Til Death/BGAnimations/ScreenNetEvaluation decorations.lua index cf8a7cf175..77d9faa0cf 100644 --- a/Themes/Til Death/BGAnimations/ScreenNetEvaluation decorations.lua +++ b/Themes/Til Death/BGAnimations/ScreenNetEvaluation decorations.lua @@ -1,7 +1,10 @@ local t = Def.ActorFrame{} +local enabledCustomWindows = playerConfig:get_data(pn_to_profile_slot(PLAYER_1)).CustomEvaluationWindowTimings PROFILEMAN:SaveProfile(PLAYER_1) +local customWindows = timingWindowConfig:get_data().customWindows + local scoreType = themeConfig:get_data().global.DefaultScoreType if GAMESTATE:GetNumPlayersEnabled() == 1 and themeConfig:get_data().eval.ScoreBoardEnabled then @@ -9,71 +12,26 @@ if GAMESTATE:GetNumPlayersEnabled() == 1 and themeConfig:get_data().eval.ScoreBo end -local dummyX1P = SCREEN_CENTER_X -local dummyX = dummyX1P -local dummyY1P = SCREEN_CENTER_Y -local dummyY = dummyY1P -local songY1P = dummyY-95 -local rateX = capWideScale(SCREEN_CENTER_X-295,SCREEN_CENTER_X) -local rateY = capWideScale(45,180) - -if not IsUsingWideScreen() == true then -songY1P = dummyY-125 -end; - -if IsUsingWideScreen() == true then -songY1P = SCREEN_CENTER_Y-110 -dummyX = SCREEN_CENTER_X -end; - ---Hacky way of fixing these ratios outside of 16:9 and 4:3. -Misterkister ---Redundant, but w/e. -Misterkister - ---16:10 ratio. -Misterkister -if round(GetScreenAspectRatio(),5) == 1.6 then - -songY1P = dummyY-118 -rateX = SCREEN_CENTER_X -rateY = SCREEN_CENTER_Y-67 - -end; - ---5:4 ratio. -Misterkister -if round(GetScreenAspectRatio(),5) == 1.25 then - -rateX = SCREEN_CENTER_X-280 - -end - ---8:3 ratio targeted. -Misterkister -if round(GetScreenAspectRatio(),5) > 1.77778 then - -songY1P = dummyY-115 -rateY = SCREEN_CENTER_Y-63 - -end - t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) - self:xy(dummyX,songY1P+30):zoom(0.4):maxwidth(400/0.4) - end; + self:xy(SCREEN_CENTER_X,capWideScale(135,150)):zoom(0.4):maxwidth(400/0.4) + end, BeginCommand=function(self) self:queuecommand("Set") - end; + end, SetCommand=function(self) if GAMESTATE:IsCourseMode() then self:settext(GAMESTATE:GetCurrentCourse():GetDisplayFullTitle().." // "..GAMESTATE:GetCurrentCourse():GetScripter()) else self:settext(GAMESTATE:GetCurrentSong():GetDisplayMainTitle().." // "..GAMESTATE:GetCurrentSong():GetDisplayArtist()) - end; - end; -}; - + end + end +} -- Rate String t[#t+1] = LoadFont("Common normal")..{ InitCommand=function(self) - self:xy(rateX,rateY):zoom(0.5):halign(0.5) + self:xy(SCREEN_CENTER_X,capWideScale(145,160)):zoom(0.5):halign(0.5) end, BeginCommand=function(self) if getCurRateString() == "1x" then @@ -130,84 +88,18 @@ local pssP1 = STATSMAN:GetCurStageStats():GetPlayerStageStats(PLAYER_1) local frameX = 20 local frameY = 140 local frameWidth = SCREEN_CENTER_X-120 -local SMOX = SCREEN_CENTER_X -local SMOY = SCREEN_CENTER_Y -local smoframeX = frameX+320 -local smoframeY = frameY+50 -local comboX = SMOX+250 -local titleX = SMOX -local titleY = SMOY -local zoomlength = frameWidth+200 -local zoomheight = 110 - - -if IsUsingWideScreen() == true then -SMOX = SCREEN_CENTER_X-30 -SMOY = SCREEN_CENTER_Y-40 -end; - -if not IsUsingWideScreen() == true then -smoframeX = frameX+210 -SMOX = SCREEN_CENTER_X-30 -SMOY = SCREEN_CENTER_Y-40 -comboX = SMOX+160 -end; - ---Hacky way of fixing these ratios outside of 16:9 and 4:3. -Misterkister - ---16:10 ratio. -Misterkister -if round(GetScreenAspectRatio(),5) == 1.6 then - -smoframeX = frameX+275 -smoframeY = frameY+40 -comboX = SMOX+200 -titleX = SCREEN_CENTER_X-70 -titleY = SCREEN_CENTER_Y-40 -zoomheight = 120 - -end; - ---5:4 ratio. -Misterkister -if round(GetScreenAspectRatio(),5) == 1.25 then - -titleX = SCREEN_CENTER_X-32 -titleY = SCREEN_CENTER_Y-40 -smoframeX = frameX+190 - -end - ---8:3 ratio targeted. -Misterkister -if round(GetScreenAspectRatio(),5) > 1.77778 then - -smoframeX = frameX+530 -titleX = SCREEN_CENTER_X-32 -titleY = SCREEN_CENTER_Y-40 -comboX = SMOX+250 - -end - ---Had to fix this for 4:3 and 16:9. -Misterkister -if round(GetScreenAspectRatio(),5) == 1.77778 then - -titleY = SCREEN_CENTER_Y-40 -titleX = SCREEN_CENTER_X-32 - -end - -if round(GetScreenAspectRatio(),5) == 1.33333 then - -titleX = SCREEN_CENTER_X-32 -titleY = SCREEN_CENTER_Y-40 - -end - function scoreBoard(pn,position) - local judge = GetTimingDifficulty() + + local customWindow + local judge = enabledCustomWindows and 0 or GetTimingDifficulty() local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats(pn) local score = SCOREMAN:GetMostRecentScore() + local dvt = pss:GetOffsetVector() + local totalTaps = pss:GetTotalTaps() local smallest,largest local devianceTable + local t = Def.ActorFrame{ BeginCommand=function(self) if position == 1 then @@ -224,28 +116,21 @@ function scoreBoard(pn,position) end end, } - - t[#t+1] = Def.Quad{ InitCommand=function(self) self:xy(frameX-5,frameY):zoomto(frameWidth+10,220):halign(0):valign(0):diffuse(color("#333333CC")) - end; - } - t[#t+1] = Def.Quad{ - InitCommand=function(self) - self:xy(smoframeX,smoframeY):zoomto(zoomlength,zoomheight):halign(0):valign(0):diffuse(color("#333333CC")) - end; - } + end, + }; t[#t+1] = Def.Quad{ InitCommand=function(self) self:xy(frameX,frameY+30):zoomto(frameWidth,2):halign(0):diffuse(getMainColor('highlight')):diffusealpha(0.5) - end; - } + end, + }; t[#t+1] = Def.Quad{ InitCommand=function(self) self:xy(frameX,frameY+55):zoomto(frameWidth,2):halign(0):diffuse(getMainColor('highlight')):diffusealpha(0.5) - end; - } + end, + }; t[#t+1] = LoadFont("Common Large")..{ InitCommand=function(self) @@ -259,8 +144,7 @@ function scoreBoard(pn,position) self:settextf("%5.2f", meter) self:diffuse(ByMSD(meter)) end, - } - + }; t[#t+1] = LoadFont("Common Large")..{ InitCommand=function(self) self:xy(frameWidth+frameX,frameY+32):zoom(0.5):halign(1):valign(0):maxwidth(200) @@ -274,7 +158,7 @@ function scoreBoard(pn,position) self:settextf("%5.2f", meter) self:diffuse(ByMSD(meter)) end, - } + }; t[#t+1] = LoadFont("Common Large") .. { InitCommand=function(self) self:xy(frameWidth+frameX,frameY+7):zoom(0.5):halign(1):valign(0):maxwidth(200) @@ -288,189 +172,52 @@ function scoreBoard(pn,position) self:settext(getShortDifficulty(diff)) self:diffuse(getDifficultyColor(GetCustomDifficulty(steps:GetStepsType(),steps:GetDifficulty()))) end - } - - t[#t+1] = LoadFont("Common Normal")..{ - InitCommand=function(self) - self:zoom(0.5):x(titleX):y(titleY) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - if IsNetSMOnline() == true then - if round(GetScreenAspectRatio(),5) == 1.6 then - self:settext("SMO") - else - self:settext("StepMania Online") - end; - else - self:settext("Offline") - end - end; - } - - t[#t+1] = LoadFont("Common Normal")..{ - InitCommand=function(self) - self:zoom(0.5):x(SMOX-34):y(SMOY+15) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - if IsNetSMOnline() == true then - self:settext("Grade:") - else - self:settext("") - end - end; - } - t[#t+1] = LoadFont("Common Normal")..{ - InitCommand=function(self) - self:zoom(0.5):x(SMOX-22):y(SMOY+33) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - if IsNetSMOnline() == true then - self:settext("Marvelous:") - else - self:settext("") - end - end; - } - t[#t+1] = LoadFont("Common Normal")..{ - InitCommand=function(self) - self:zoom(0.5):x(SMOX-31):y(SMOY+51) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - if IsNetSMOnline() == true then - self:settext("Perfect:") - else - self:settext("") - end - end; - } - t[#t+1] = LoadFont("Common Normal")..{ - InitCommand=function(self) - self:zoom(0.5):x(SMOX-37):y(SMOY+69) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - if IsNetSMOnline() == true then - self:settext("Great:") - else - self:settext("") - end - end; - } - t[#t+1] = LoadFont("Common Normal")..{ - InitCommand=function(self) - self:zoom(0.5):x(SMOX+157):y(SMOY+33) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - if IsNetSMOnline() == true then - self:settext("Good:") - else - self:settext("") - end - end; - } - t[#t+1] = LoadFont("Common Normal")..{ - InitCommand=function(self) - self:zoom(0.5):x(SMOX+153):y(SMOY+51) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - if IsNetSMOnline() == true then - self:settext("Bad:") - else - self:settext("") - end - end; - } - t[#t+1] = LoadFont("Common Normal")..{ - InitCommand=function(self) - self:zoom(0.5):x(SMOX+153):y(SMOY+69) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - if IsNetSMOnline() == true then - self:settext("Miss:") - else - self:settext("") - end - end; - } - t[#t+1] = LoadFont("Common Normal")..{ - InitCommand=function(self) - self:zoom(0.5):x(comboX):y(SMOY+10) - end; - BeginCommand=function(self) - self:queuecommand("Set") - end; - SetCommand=function(self) - if IsNetSMOnline() == true then - self:settext("Combo:") - else - self:settext("") - end - end; - } + }; - if ShowStandardDecoration("StepsDisplay") then - for pn in ivalues(PlayerNumber) do - local t2 = Def.StepsDisplay { - InitCommand=function(self) - self:Load("StepsDisplayEvaluation",pn):SetFromGameState(pn) - end; - } - t[#t+1] = StandardDecorationFromTable( "StepsDisplay" .. ToEnumShortString(pn), t2 ) - end - end - -- Wife percent t[#t+1] = LoadFont("Common Large")..{ InitCommand=function(self) - self:xy(frameX+5,frameY+9):zoom(0.45):halign(0):valign(0):maxwidth(capWideScale(280,320)) + self:xy(frameX+5,frameY+9):zoom(0.45):halign(0):valign(0):maxwidth(capWideScale(320,360)) end, BeginCommand=function(self) self:queuecommand("Set") end, - ScoreChangedMessageCommand = function(self) self:queuecommand("Set"); end, SetCommand=function(self) self:diffuse(getGradeColor(score:GetWifeGrade())) self:settextf("%05.2f%% (%s)",notShit.floor(score:GetWifeScore()*10000)/100, "Wife") end, + ScoreChangedMessageCommand = function(self) self:queuecommand("Set"); end, CodeMessageCommand=function(self,params) - if params.Name == "PrevJudge" and judge > 1 then + local totalHolds = pss:GetRadarPossible():GetValue("RadarCategory_Holds") + pss:GetRadarPossible():GetValue("RadarCategory_Rolls") + local holdsHit = score:GetRadarValues():GetValue("RadarCategory_Holds") + score:GetRadarValues():GetValue("RadarCategory_Rolls") + local minesHit = pss:GetRadarPossible():GetValue("RadarCategory_Mines") - score:GetRadarValues():GetValue("RadarCategory_Mines") + if enabledCustomWindows then + if params.Name == "PrevJudge" then + judge = judge < 2 and #customWindows or judge - 1 + customWindow = timingWindowConfig:get_data()[customWindows[judge]] + self:settextf("%05.2f%% (%s)", getRescoredCustomPercentage(dvt, customWindow, totalHolds, holdsHit, minesHit, totalTaps), customWindow.name) + elseif params.Name == "NextJudge" then + judge = judge == #customWindows and 1 or judge + 1 + customWindow = timingWindowConfig:get_data()[customWindows[judge]] + self:settextf("%05.2f%% (%s)", getRescoredCustomPercentage(dvt, customWindow, totalHolds, holdsHit, minesHit, totalTaps), customWindow.name) + end + elseif params.Name == "PrevJudge" and judge > 1 then judge = judge - 1 - self:settextf("%05.2f%% (%s)", notShit.floor(score:RescoreToWifeJudge(judge)*10000)/100, "Wife J"..judge) + self:settextf("%05.2f%% (%s)", getRescoredWifeJudge(dvt, judge, totalHolds - holdsHit, minesHit, totalTaps), "Wife J"..judge) elseif params.Name == "NextJudge" and judge < 9 then judge = judge + 1 if judge == 9 then - self:settextf("%05.2f%% (%s)", notShit.floor(score:RescoreToWifeJudge(judge)*10000)/100, "Wife Justice") + self:settextf("%05.2f%% (%s)", getRescoredWifeJudge(dvt, judge, (totalHolds - holdsHit), minesHit, totalTaps), "Wife Justice") else - self:settextf("%05.2f%% (%s)", notShit.floor(score:RescoreToWifeJudge(judge)*10000)/100, "Wife J"..judge) + self:settextf("%05.2f%% (%s)", getRescoredWifeJudge(dvt, judge, (totalHolds - holdsHit), minesHit, totalTaps), "Wife J"..judge) end - + end + if params.Name == "ResetJudge" then + judge = enabledCustomWindows and 0 or GetTimingDifficulty() + self:playcommand("Set") end end, - } - + }; t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) @@ -479,12 +226,12 @@ function scoreBoard(pn,position) BeginCommand=function(self) self:queuecommand("Set") end, - SetCommand=function(self) - self:settext(GAMESTATE:GetPlayerState(PLAYER_1):GetPlayerOptionsString('ModsLevel_Current')) - end, ScoreChangedMessageCommand=function(self) self:settext(SCREENMAN:GetTopScreen():GetOptions() or "") end, + SetCommand=function(self) + self:settext(GAMESTATE:GetPlayerState(PLAYER_1):GetPlayerOptionsString('ModsLevel_Current')) + end } for k,v in ipairs(judges) do @@ -492,7 +239,7 @@ function scoreBoard(pn,position) InitCommand=function(self) self:xy(frameX,frameY+80+((k-1)*22)):zoomto(frameWidth,18):halign(0):diffuse(byJudgment(v)):diffusealpha(0.5) end; - } + }; t[#t+1] = Def.Quad{ InitCommand=function(self) self:xy(frameX,frameY+80+((k-1)*22)):zoomto(0,18):halign(0):diffuse(byJudgment(v)):diffusealpha(0.5) @@ -506,11 +253,18 @@ function scoreBoard(pn,position) end, CodeMessageCommand=function(self,params) if params.Name == "PrevJudge" or params.Name == "NextJudge" then - local rescoreJudges = score:RescoreJudges(judge) - self:zoomx(frameWidth*rescoreJudges[k]/pss:GetTotalTaps()) + if enabledCustomWindows then + self:finishtweening():decelerate(2):zoomx(frameWidth*getRescoredCustomJudge(dvt, customWindow.judgeWindows, k)/totalTaps) + else + local rescoreJudges = getRescoredJudge(dvt, judge, k) + self:finishtweening():decelerate(2):zoomx(frameWidth*rescoreJudges/totalTaps) + end + end + if params.Name == "ResetJudge" then + self:finishtweening():decelerate(2):zoomx(frameWidth*pss:GetPercentageOfTaps(v)) end end, - } + }; t[#t+1] = LoadFont("Common Large")..{ InitCommand=function(self) self:xy(frameX+10,frameY+80+((k-1)*22)):zoom(0.25):halign(0) @@ -520,8 +274,16 @@ function scoreBoard(pn,position) end, SetCommand=function(self) self:settext(getJudgeStrings(v)) - end - } + end, + CodeMessageCommand=function(self,params) + if enabledCustomWindows and (params.Name == "PrevJudge" or params.Name == "NextJudge") then + self:settext(getCustomJudgeString(customWindow.judgeNames, k)) + end + if params.Name == "ResetJudge" then + self:playcommand("Set") + end + end, + }; t[#t+1] = LoadFont("Common Large")..{ InitCommand=function(self) self:xy(frameX+frameWidth-40,frameY+80+((k-1)*22)):zoom(0.25):halign(1) @@ -530,18 +292,22 @@ function scoreBoard(pn,position) self:queuecommand("Set") end, SetCommand=function(self) - self:settext(pss:GetTapNoteScores(v)) - end, - ScoreChangedMessageCommand = function(self) self:settext(score:GetTapNoteScore(v)) end, + ScoreChangedMessageCommand = function(self) self:queuecommand("Set"); end, CodeMessageCommand=function(self,params) if params.Name == "PrevJudge" or params.Name == "NextJudge" then - local rescoreJudges = score:RescoreJudges(judge) - self:settext(rescoreJudges[k]) + if enabledCustomWindows then + self:settext(getRescoredCustomJudge(dvt, customWindow.judgeWindows, k)) + else + self:settext(getRescoredJudge(dvt, judge, k)) + end + end + if params.Name == "ResetJudge" then + self:playcommand("Set") end end, - } + }; t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) self:xy(frameX+frameWidth-38,frameY+80+((k-1)*22)):zoom(0.3):halign(0) @@ -557,25 +323,50 @@ function scoreBoard(pn,position) end, CodeMessageCommand=function(self,params) if params.Name == "PrevJudge" or params.Name == "NextJudge" then - local rescoreJudges = score:RescoreJudges(judge) - self:settextf("(%03.2f%%)",rescoreJudges[k]/pss:GetTotalTaps()*100) + local rescoredJudge + if enabledCustomWindows then + rescoredJudge = getRescoredCustomJudge(dvt, customWindow.judgeWindows, k) + else + rescoredJudge = getRescoredJudge(dvt, judge, k) + end + self:settextf("(%03.2f%%)", rescoredJudge/totalTaps * 100) + end + if params.Name == "ResetJudge" then + self:playcommand("Set") end end, - } + }; end + + t[#t+1] = LoadFont("Common Large")..{ + InitCommand=function(self) + self:xy(frameX+40,frameY*2.49):zoom(0.25):halign(0) + end, + BeginCommand=function(self) + self:queuecommand("Set") + end, + ScoreChangedMessageCommand = function(self) self:queuecommand("Set"); end, + SetCommand=function(self) + if score:GetChordCohesion() == true then + self:settext("Chord Cohesion: Yes") + else + self:settext("Chord Cohesion: No") + end + end + }; local fart = {"Holds", "Mines", "Rolls", "Lifts", "Fakes"} t[#t+1] = Def.Quad{ InitCommand=function(self) self:xy(frameX-5,frameY+230):zoomto(frameWidth/2-10,60):halign(0):valign(0):diffuse(color("#333333CC")) - end; - } + end, + }; for i=1,#fart do - t[#t+1] = LoadFont("Common Normal")..{ + t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) self:xy(frameX,frameY+230+10*i):zoom(0.4):halign(0):settext(fart[i]) - end - } + end, + }; t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) self:xy(frameWidth/2,frameY+230+10*i):zoom(0.4):halign(1) @@ -584,39 +375,40 @@ function scoreBoard(pn,position) self:queuecommand("Set") end, SetCommand=function(self) - self:settextf("%03d/%03d",pss:GetRadarActual():GetValue("RadarCategory_"..fart[i]),pss:GetRadarPossible():GetValue("RadarCategory_"..fart[i])) - end - } + self:settextf("%03d/%03d",score:GetRadarValues():GetValue("RadarCategory_"..fart[i]),pss:GetRadarPossible():GetValue("RadarCategory_"..fart[i])) + end, + ScoreChangedMessageCommand = function(self) self:queuecommand("Set"); end, + }; end -- stats stuff - devianceTable = pss:GetOffsetVector() + local devianceTable = pss:GetOffsetVector() t[#t+1] = Def.Quad{ InitCommand=function(self) self:xy(frameWidth+25,frameY+230):zoomto(frameWidth/2+10,60):halign(1):valign(0):diffuse(color("#333333CC")) - end; - } + end, + }; smallest,largest = wifeRange(devianceTable) local doot = {"Mean", "Mean(Abs)", "Sd", "Smallest", "Largest"} local mcscoot = { function() return wifeMean(devianceTable) end, - function() return ms.tableSum(devianceTable, 1,true)/#devianceTable end, + function() return wifeAbsMean(devianceTable) end, function() return wifeSd(devianceTable) end, - function() smallest end, - function() largest end + function() return smallest end, + function() return largest end, } for i=1,#doot do t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) - self:xy(frameX+capWideScale(get43size(130),160),frameY+230+10*i):zoom(0.4):halign(0):settext(doot[i]) - end - } + self:xy(frameX+capWideScale(get43size(130),160),frameY+230+10*i):zoom(0.4):halign(0):settext(doot[i]) + end, + }; t[#t+1] = LoadFont("Common Normal")..{ InitCommand=function(self) self:xy(frameWidth+20,frameY+230+10*i):zoom(0.4):halign(1):settextf("%5.2fms",mcscoot[i]()) - end - } + end, + }; end return t @@ -636,4 +428,14 @@ end t[#t+1] = LoadActor("offsetplot") -return t +-- Discord thingies +local largeImageTooltip = GetPlayerOrMachineProfile(PLAYER_1):GetDisplayName() .. ": " .. string.format("%5.2f", GetPlayerOrMachineProfile(PLAYER_1):GetPlayerRating()) +local detail = GAMESTATE:GetCurrentSong():GetDisplayMainTitle() .. " " .. string.gsub(getCurRateDisplayString(), "Music", "") .. " [" .. GAMESTATE:GetCurrentSong():GetGroupName() .. "]" +-- truncated to 128 characters(discord hard limit) +detail = #detail < 128 and detail or string.sub(detail, 1, 124) .. "..." +local state = "MSD: " .. string.format("%05.2f", GAMESTATE:GetCurrentSteps(PLAYER_1):GetMSD(getCurRateValue(),1)) .. + " - " .. string.format("%05.2f%%",notShit.floor(pssP1:GetWifeScore()*10000)/100) .. + " " .. THEME:GetString("Grade",ToEnumShortString(SCOREMAN:GetMostRecentScore():GetWifeGrade())) +GAMESTATE:UpdateDiscordPresence(largeImageTooltip, detail, state, 0) + +return t \ No newline at end of file diff --git a/Themes/Til Death/Scripts/02 Branches.lua b/Themes/Til Death/Scripts/02 Branches.lua index be2b756e60..3d2bced131 100644 --- a/Themes/Til Death/Scripts/02 Branches.lua +++ b/Themes/Til Death/Scripts/02 Branches.lua @@ -114,13 +114,21 @@ Branch = { return "ScreenSelectMusic"--"ScreenSelectPlayMode" end, AfterProfileSave = function() - -- Might be a little too broken? -- Midiman if GAMESTATE:IsEventMode() then - return SelectMusicOrCourse() + return "ScreenSelectMusic" + elseif STATSMAN:GetCurStageStats():AllFailed() then + return GameOverOrContinue() + else + return "ScreenSelectMusic" + end + end, + AfterNetProfileSave = function() + if GAMESTATE:IsEventMode() then + return "ScreenNetSelectMusic" elseif STATSMAN:GetCurStageStats():AllFailed() then return GameOverOrContinue() else - return SelectMusicOrCourse() + return "ScreenNetSelectMusic" end end, GetGameInformationScreen = function() @@ -140,10 +148,16 @@ Branch = { end end, BackOutOfPlayerOptions = function() - return SelectMusicOrCourse() + return "ScreenSelectMusic" + end, + BackOutOfNetPlayerOptions = function() + return "ScreenNetSelectMusic" end, BackOutOfStageInformation = function() - return SelectMusicOrCourse() + return "ScreenSelectMusic" + end, + BackOutOfNetStageInformation = function() + return "ScreenNetSelectMusic" end, AfterSelectMusic = function() if SCREENMAN:GetTopScreen():GetGoToOptions() then @@ -179,15 +193,25 @@ Branch = { GameplayScreen = function() return IsRoutine() and "ScreenGameplayShared" or "ScreenGameplay" end, - EvaluationScreen= function() - if IsNetSMOnline() then - return "ScreenNetEvaluation" + AfterGameplay = function() + -- pick an evaluation screen based on settings. + if THEME:GetMetric("ScreenHeartEntry", "HeartEntryEnabled") then + local go_to_heart= false + for i, pn in ipairs(GAMESTATE:GetEnabledPlayers()) do + local profile= PROFILEMAN:GetProfile(pn) + if profile and profile:GetIgnoreStepCountCalories() then + go_to_heart= true + end + end + if go_to_heart then + return "ScreenHeartEntry" + end + return "ScreenEvaluationNormal" else - -- todo: account for courses etc? return "ScreenEvaluationNormal" end end, - AfterGameplay = function() + AfterNetGameplay = function() -- pick an evaluation screen based on settings. if THEME:GetMetric("ScreenHeartEntry", "HeartEntryEnabled") then local go_to_heart= false @@ -200,9 +224,9 @@ Branch = { if go_to_heart then return "ScreenHeartEntry" end - return Branch.EvaluationScreen() + return "ScreenNetEvaluation" else - return Branch.EvaluationScreen() + return "ScreenNetEvaluation" end end, AfterHeartEntry= function() @@ -226,6 +250,24 @@ Branch = { return "ScreenProfileSave" end end, + AfterNetEvaluation = function() + local allFailed = STATSMAN:GetCurStageStats():AllFailed() + local song = GAMESTATE:GetCurrentSong() + + if GAMESTATE:IsEventMode() or stagesLeft >= 1 then + return "ScreenNetProfileSave" + elseif song:IsLong() and maxStages <= 2 and stagesLeft < 1 and allFailed then + return "ScreenProfileSaveSummary" + elseif song:IsMarathon() and maxStages <= 3 and stagesLeft < 1 and allFailed then + return "ScreenProfileSaveSummary" + elseif maxStages >= 2 and stagesLeft < 1 and allFailed then + return "ScreenProfileSaveSummary" + elseif allFailed then + return "ScreenProfileSaveSummary" + else + return "ScreenNetProfileSave" + end + end, AfterSummary = function() return "ScreenProfileSaveSummary" end, diff --git a/Themes/Til Death/metrics.ini b/Themes/Til Death/metrics.ini index 2102bdb9c2..ed3e848bb9 100644 --- a/Themes/Til Death/metrics.ini +++ b/Themes/Til Death/metrics.ini @@ -542,7 +542,7 @@ CodePrevJudge="EffectDown" Class="ScreenNetEvaluation" Fallback="ScreenEvaluationNormal" -NextScreen="ScreenProfileSave" +NextScreen="ScreenNetProfileSave" User1X=SCREEN_CENTER_X*0.35 User1Y=SCREEN_CENTER_Y-160 User1OnCommand= @@ -574,81 +574,81 @@ UserDY=24 UserOnCommand=zoomx,0.0;zoomy,0.0;linear,0.5;zoomx,0.5;zoomy,0.5 UserOffCommand=zoomx,0.5;zoomy,0.5;linear,0.5;zoomx,0.0;zoomy,0.0 -ShowJudgmentLineMaxCombo=true +ShowJudgmentLineMaxCombo=false MaxComboNumberP1X=(capWideScale(get43size(SCREEN_CENTER_X+360),SCREEN_CENTER_X+320)) MaxComboNumberP1Y=(capWideScale(get43size(SCREEN_CENTER_Y+40),SCREEN_CENTER_Y-30)) -MaxComboNumberP1OnCommand=zoom,0.55; +MaxComboNumberP1OnCommand=visible,false;zoom,0.55; MaxComboNumberP1OffCommand= -ShowGradeArea=true +ShowGradeArea=false GradeP1X=(capWideScale(get43size(SCREEN_CENTER_X+90),SCREEN_CENTER_X)) GradeP1Y=(capWideScale(get43size(SCREEN_CENTER_Y+48),SCREEN_CENTER_Y-24)) -GradeP1OnCommand=zoom,0.8; +GradeP1OnCommand=visible,false;zoom,0.8; GradeP1OffCommand= GradeFrameP1X=SCREEN_CENTER_X-220 GradeFrameP1Y=SCREEN_TOP+80 -GradeFrameP1OnCommand= +GradeFrameP1OnCommand=visible,false; GradeFrameP1OffCommand= -ShowJudgmentLineW1=true +ShowJudgmentLineW1=false W1NumberP1X=(capWideScale(get43size(SCREEN_CENTER_X+160),SCREEN_CENTER_X+60)) W1NumberP1Y=(capWideScale(get43size(SCREEN_CENTER_Y+71),SCREEN_CENTER_Y-6)) W1NumberP1OnCommand=zoom,0.55; W1NumberP1OffCommand= -ShowJudgmentLineW2=true +ShowJudgmentLineW2=false W2NumberP1X=(capWideScale(get43size(SCREEN_CENTER_X+160),SCREEN_CENTER_X+60)) W2NumberP1Y=(capWideScale(get43size(SCREEN_CENTER_Y+94),SCREEN_CENTER_Y+12)) -W2NumberP1OnCommand=zoom,0.55; +W2NumberP1OnCommand=visible,false;zoom,0.55; W2NumberP1OffCommand= -ShowJudgmentLineW3=true +ShowJudgmentLineW3=false W3NumberP1X=(capWideScale(get43size(SCREEN_CENTER_X+160),SCREEN_CENTER_X+60)) W3NumberP1Y=(capWideScale(get43size(SCREEN_CENTER_Y+117),SCREEN_CENTER_Y+30)) -W3NumberP1OnCommand=zoom,0.55; +W3NumberP1OnCommand=visible,false;zoom,0.55; W3NumberP1OffCommand= -ShowJudgmentLineW4=true +ShowJudgmentLineW4=false W4NumberP1X=(capWideScale(get43size(SCREEN_CENTER_X+400),SCREEN_CENTER_X+230)) W4NumberP1Y=(capWideScale(get43size(SCREEN_CENTER_Y+71),SCREEN_CENTER_Y-6)) -W4NumberP1OnCommand=zoom,0.55; +W4NumberP1OnCommand=visible,false;zoom,0.55; W4NumberP1OffCommand= -ShowJudgmentLineW5=true +ShowJudgmentLineW5=false W5NumberP1X=(capWideScale(get43size(SCREEN_CENTER_X+400),SCREEN_CENTER_X+230)) W5NumberP1Y=(capWideScale(get43size(SCREEN_CENTER_Y+94),SCREEN_CENTER_Y+12)) -W5NumberP1OnCommand=zoom,0.55; +W5NumberP1OnCommand=visible,false;zoom,0.55; W5NumberP1OffCommand= -ShowJudgmentLineMiss=true +ShowJudgmentLineMiss=false MissNumberP1X=(capWideScale(get43size(SCREEN_CENTER_X+400),SCREEN_CENTER_X+230)) MissNumberP1Y=(capWideScale(get43size(SCREEN_CENTER_Y+117),SCREEN_CENTER_Y+30)) -MissNumberP1OnCommand=zoom,0.55; +MissNumberP1OnCommand=visible,false;zoom,0.55; MissNumberP1OffCommand= PlayerOptionsP1X=(capWideScale(get43size(SCREEN_CENTER_X+270),SCREEN_CENTER_X+130)) PlayerOptionsP1Y=(capWideScale(get43size(SCREEN_CENTER_Y+143),SCREEN_CENTER_Y+48)) -PlayerOptionsP1OnCommand=zoom,0.3;shadowlength,1 +PlayerOptionsP1OnCommand=visible,false;zoom,0.3;shadowlength,1 PlayerOptionsP1OffCommand= PlayerOptionsP2X=SCREEN_CENTER_X-64 PlayerOptionsP2Y=SCREEN_TOP+407 -PlayerOptionsP2OnCommand=zoom,0.3;shadowlength,1 +PlayerOptionsP2OnCommand=visible,false;zoom,0.3;shadowlength,1 PlayerOptionsP2OffCommand= -ShowStepsDisplay=true +ShowStepsDisplay=false #~~~~~~~~~~~~~~~# StepsDisplayP1X=(capWideScale(get43size(SCREEN_CENTER_X+200),SCREEN_CENTER_X+170)) StepsDisplayP1Y=(capWideScale(get43size(SCREEN_CENTER_Y+55),SCREEN_CENTER_Y+18)) -StepsDisplayP1OnCommand= +StepsDisplayP1OnCommand=visible,false; StepsDisplayP1OffCommand= #~~~~~~~~~~~~~~# StepsDisplayP2X=SCREEN_CENTER_X*-5 StepsDisplayP2Y=SCREEN_CENTER_Y*-5 -StepsDisplayP2OnCommand= +StepsDisplayP2OnCommand=visible,false; StepsDisplayP2OffCommand= # detail area diff --git a/Themes/_fallback/Scripts/02 Branches.lua b/Themes/_fallback/Scripts/02 Branches.lua index 4bb227aba8..c717c1f0ec 100644 --- a/Themes/_fallback/Scripts/02 Branches.lua +++ b/Themes/_fallback/Scripts/02 Branches.lua @@ -135,11 +135,21 @@ Branch = { AfterProfileSave = function() -- Might be a little too broken? -- Midiman if GAMESTATE:IsEventMode() then - return SelectMusicOrCourse() + return "ScreenSelectMusic" elseif STATSMAN:GetCurStageStats():AllFailed() then return GameOverOrContinue() else - return SelectMusicOrCourse() + return "ScreenSelectMusic" + end + end, + AfterNetProfileSave = function() + -- Might be a little too broken? -- Midiman + if GAMESTATE:IsEventMode() then + return "ScreenNetSelectMusic" + elseif STATSMAN:GetCurStageStats():AllFailed() then + return GameOverOrContinue() + else + return "ScreenNetSelectMusic" end end, GetGameInformationScreen = function() @@ -148,10 +158,16 @@ Branch = { end, AfterSMOLogin = SMOnlineScreen, BackOutOfPlayerOptions = function() - return SelectMusicOrCourse() + return "ScreenSelectMusic" + end, + BackOutOfNetPlayerOptions = function() + return "ScreenNetSelectMusic" end, BackOutOfStageInformation = function() - return SelectMusicOrCourse() + return "ScreenSelectMusic" + end, + BackOutOfNetStageInformation = function() + return "ScreenNetSelectMusic" end, AfterSelectMusic = function() if SCREENMAN:GetTopScreen():GetGoToOptions() then @@ -185,15 +201,25 @@ Branch = { GameplayScreen = function() return IsRoutine() and "ScreenGameplayShared" or "ScreenGameplay" end, - EvaluationScreen= function() - if IsNetSMOnline() then - return "ScreenNetEvaluation" + AfterGameplay = function() + -- pick an evaluation screen based on settings. + if THEME:GetMetric("ScreenHeartEntry", "HeartEntryEnabled") then + local go_to_heart= false + for i, pn in ipairs(GAMESTATE:GetEnabledPlayers()) do + local profile= PROFILEMAN:GetProfile(pn) + if profile and profile:GetIgnoreStepCountCalories() then + go_to_heart= true + end + end + if go_to_heart then + return "ScreenHeartEntry" + end + return "ScreenEvaluationNormal" else - -- todo: account for courses etc? return "ScreenEvaluationNormal" end end, - AfterGameplay = function() + AfterNetGameplay = function() -- pick an evaluation screen based on settings. if THEME:GetMetric("ScreenHeartEntry", "HeartEntryEnabled") then local go_to_heart= false @@ -206,16 +232,49 @@ Branch = { if go_to_heart then return "ScreenHeartEntry" end - return Branch.EvaluationScreen() + return "ScreenNetEvaluation" else - return Branch.EvaluationScreen() + return "ScreenNetEvaluation" end end, AfterHeartEntry= function() return Branch.EvaluationScreen() end, AfterEvaluation = function() - return "ScreenProfileSave" + local allFailed = STATSMAN:GetCurStageStats():AllFailed() + local song = GAMESTATE:GetCurrentSong() + + if GAMESTATE:IsEventMode() or stagesLeft >= 1 then + return "ScreenProfileSave" + elseif song:IsLong() and maxStages <= 2 and stagesLeft < 1 and allFailed then + return "ScreenProfileSaveSummary" + elseif song:IsMarathon() and maxStages <= 3 and stagesLeft < 1 and allFailed then + return "ScreenProfileSaveSummary" + elseif maxStages >= 2 and stagesLeft < 1 and allFailed then + return "ScreenProfileSaveSummary" + elseif allFailed then + return "ScreenProfileSaveSummary" + else + return "ScreenProfileSave" + end + end, + AfterNetEvaluation = function() + local allFailed = STATSMAN:GetCurStageStats():AllFailed() + local song = GAMESTATE:GetCurrentSong() + + if GAMESTATE:IsEventMode() or stagesLeft >= 1 then + return "ScreenNetProfileSave" + elseif song:IsLong() and maxStages <= 2 and stagesLeft < 1 and allFailed then + return "ScreenProfileSaveSummary" + elseif song:IsMarathon() and maxStages <= 3 and stagesLeft < 1 and allFailed then + return "ScreenProfileSaveSummary" + elseif maxStages >= 2 and stagesLeft < 1 and allFailed then + return "ScreenProfileSaveSummary" + elseif allFailed then + return "ScreenProfileSaveSummary" + else + return "ScreenNetProfileSave" + end end, AfterSummary = function() return "ScreenProfileSaveSummary" diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index b2432fd279..2f4c8f25a5 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -2186,6 +2186,13 @@ TimerSeconds=1 # ScreenBeginCommand= + +[ScreenNetStageInformation] +Class="ScreenSplash" +Fallback="ScreenStageInformation" +NextScreen="ScreenNetGameplay" +PrevScreen=Branch.BackOutOfNetStageInformation() + [ScreenOptions] Fallback="ScreenWithMenuElements" @@ -3095,6 +3102,13 @@ Class="ScreenReloadSongs" Fallback="Screen" NextScreen=Branch.TitleMenu() +[ScreenNetPlayerOptions] +Fallback="ScreenPlayerOptions" +Class="ScreenPlayerOptions" +# +PrevScreen=Branch.BackOutOfNetPlayerOptions() +NextScreen=Branch.SongOptions() + [ScreenPlayerOptions] Fallback="ScreenOptions" Class="ScreenPlayerOptions" @@ -3316,6 +3330,11 @@ ScoreOffCommand= # 05 # B # 05 # C +[ScreenNetGameplay] +Fallback="ScreenGameplay" +Class="ScreenGameplayNormal" +NextScreen=Branch.AfterNetGameplay() +PrevScreen=Branch.BackOutOfNetStageInformation() [ScreenGameplay] Fallback="ScreenWithMenuElementsBlank" Class="ScreenGameplayNormal" @@ -3730,6 +3749,11 @@ TimerSeconds=15 ForceTimer=true ForceTimerWait=true +[ScreenNetProfileSave] +Class="ScreenProfileSave" +Fallback="ScreenProfileSave" +NextScreen=Branch.AfterNetProfileSave() + [ScreenProfileSave] Class="ScreenProfileSave" Fallback="ScreenWithMenuElementsBlank" @@ -4255,11 +4279,11 @@ Users4Command=draworder,2;diffuse,color("1.0,0.5,0.5,1.0") Class="ScreenNetSelectMusic" Fallback="ScreenNetSelectBase" PrevScreen="ScreenNetRoom" -NextScreen="ScreenStageInformation" +NextScreen="ScreenNetStageInformation" DisconnectScreen="ScreenSelectMusic" NoSongsScreen=Branch.TitleMenu() RoomSelectScreen="ScreenNetRoom" -PlayerOptionsScreen="ScreenPlayerOptions" +PlayerOptionsScreen="ScreenNetPlayerOptions" Codes="CodeDetectorOnline" ShowStyleIcon=false @@ -4378,7 +4402,9 @@ Fallback="ScreenNetSelectMusic" [ScreenNetEvaluation] Class="ScreenNetEvaluation" Fallback="ScreenEvaluationNormal" -NextScreen="ScreenProfileSave" +# +NextScreen=Branch.AfterNetEvaluation() +PrevScreen=Branch.AfterNetEvaluation() # these three commands are deprecated: UsersBGWidth=SCREEN_CENTER_X*0.6 diff --git a/src/NetworkSyncManager.cpp b/src/NetworkSyncManager.cpp index ca56aca359..637c2c0467 100644 --- a/src/NetworkSyncManager.cpp +++ b/src/NetworkSyncManager.cpp @@ -582,7 +582,10 @@ void ETTProtocol::Update(NetworkSyncManager* n, float fDeltaTime) hs.SetSSRNormPercent(score.value("ssr_norm", 0)); hs.SetEtternaValid(score.value("valid", 0)); hs.SetModifiers(score.value("mods", "")); - + FOREACH_ENUM(Skillset, ss) + hs.SetSkillsetSSR(ss, score.value(SkillsetToString(ss).c_str() , 0)); + hs.SetSSRNormPercent(score.value("score", 0.0f)); + hs.SetWifeScore(score.value("score", 0.0f)); result.tapScores[0] = score.value("marv", 0); hs.SetTapNoteScore(TNS_W1, score.value("marv", 0)); result.tapScores[1] = score.value("perfect", 0); @@ -1198,6 +1201,9 @@ void ETTProtocol::ReportHighScore(HighScore* hs, PlayerStageStats& pss) payload["great"] = hs->GetTapNoteScore(TNS_W3); payload["perfect"] = hs->GetTapNoteScore(TNS_W2); payload["marv"] = hs->GetTapNoteScore(TNS_W1); + payload["score"] = hs->GetSSRNormPercent(); + FOREACH_ENUM(Skillset, ss) + payload[SkillsetToString(ss).c_str()] = hs->GetSkillsetSSR(ss); payload["datetime"] = string(hs->GetDateTime().GetString().c_str()); payload["hitmine"] = hs->GetTapNoteScore(TNS_HitMine); payload["held"] = hs->GetHoldNoteScore(HNS_Held); diff --git a/src/ScreenNetSelectMusic.cpp b/src/ScreenNetSelectMusic.cpp index 8d0973c8ca..2340ec7182 100644 --- a/src/ScreenNetSelectMusic.cpp +++ b/src/ScreenNetSelectMusic.cpp @@ -68,6 +68,9 @@ void ScreenNetSelectMusic::Init() m_MusicWheel.SetName( "MusicWheel" ); m_MusicWheel.Load( MUSIC_WHEEL_TYPE ); LOAD_ALL_COMMANDS_AND_SET_XY( m_MusicWheel ); + SONGMAN->MakeSongGroupsFromPlaylists(); + SONGMAN->SetFavoritedStatus(PROFILEMAN->GetProfile(PLAYER_1)->FavoritedCharts); + SONGMAN->SetHasGoal(PROFILEMAN->GetProfile(PLAYER_1)->goalmap); m_MusicWheel.BeginScreen(); ON_COMMAND( m_MusicWheel ); this->AddChild( &m_MusicWheel ); @@ -439,8 +442,10 @@ void ScreenNetSelectMusic::HandleScreenMessage( const ScreenMessage SM ) } if (NSMAN->steps != nullptr) m_DC[PLAYER_1] = NSMAN->steps->GetDifficulty(); - if (NSMAN->rate > 0) + if (NSMAN->rate > 0) { GAMESTATE->m_SongOptions.GetPreferred().m_fMusicRate = NSMAN->rate/1000.0; + MESSAGEMAN->Broadcast("CurrentRateChanged"); + } m_MusicWheel.Select(); m_MusicWheel.Move(-1); m_MusicWheel.Move(1); @@ -460,8 +465,10 @@ void ScreenNetSelectMusic::HandleScreenMessage( const ScreenMessage SM ) } if(NSMAN->steps != nullptr) m_DC[PLAYER_1] = NSMAN->steps->GetDifficulty(); - if (NSMAN->rate > 0) + if (NSMAN->rate > 0) { GAMESTATE->m_SongOptions.GetPreferred().m_fMusicRate = NSMAN->rate / 1000.0; + MESSAGEMAN->Broadcast("CurrentRateChanged"); + } m_MusicWheel.Select(); m_MusicWheel.Move(-1); m_MusicWheel.Move(1); diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp index 99b9acab22..a3d25ce7ce 100644 --- a/src/ScreenSelectMusic.cpp +++ b/src/ScreenSelectMusic.cpp @@ -1854,6 +1854,7 @@ class LunaScreenSelectMusic : public Luna GAMESTATE->isplaylistcourse = true; p->GetMusicWheel()->SelectSong(pl.chartlist[0].songptr); GAMESTATE->m_SongOptions.GetPreferred().m_fMusicRate = pl.chartlist[0].rate; + MESSAGEMAN->Broadcast("CurrentRateChanged"); p->SelectCurrent(PLAYER_1); return 1; } diff --git a/src/SongOptions.cpp b/src/SongOptions.cpp index ab3932730f..9b25f01e4c 100644 --- a/src/SongOptions.cpp +++ b/src/SongOptions.cpp @@ -156,6 +156,7 @@ bool SongOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut ) if( mult.Compare(sBit, matches) ) { m_fMusicRate = StringToFloat( matches[0] ); + MESSAGEMAN->Broadcast("CurrentRateChanged"); return true; } @@ -223,8 +224,29 @@ class LunaSongOptions: public Luna BOOL_INTERFACE(RandomBGOnly, RandomBGOnly); BOOL_INTERFACE(SaveScore, SaveScore); BOOL_INTERFACE(SaveReplay, SaveReplay); - FLOAT_INTERFACE(MusicRate, MusicRate, (v > 0.0f && v <= 3.0f)); // Greater than 3 seems to crash frequently, haven't investigated why. -Kyz - + static int MusicRate(T* p, lua_State* L) + { + int original_top = lua_gettop(L); + lua_pushnumber(L, p->m_fMusicRate); + lua_pushnumber(L, p->m_SpeedfMusicRate); + if(lua_isnumber(L, 1) && original_top >= 1) + { + float v= FArg(1); + if(!(v > 0.0f && v <= 3.0f)) + { + luaL_error(L, "Invalid value %f", v); + } + p->m_fMusicRate = v; + } + if(original_top >= 2 && lua_isnumber(L, 2)) + { + p->m_SpeedfMusicRate = FArgGTEZero(L, 2); + } + if (lua_isnumber(L, 1)) + MESSAGEMAN->Broadcast("CurrentRateChanged"); + OPTIONAL_RETURN_SELF(original_top); + return 2; + } LunaSongOptions() { ADD_METHOD(AutosyncSetting); From a075a95f4b4e39746bbb90f3090330550b4b68d1 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 28 Mar 2018 17:33:48 -0300 Subject: [PATCH 3/7] Fix ETTPC offsetplot bug when someone fails early --- Themes/Til Death/BGAnimations/offsetplot.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/Themes/Til Death/BGAnimations/offsetplot.lua b/Themes/Til Death/BGAnimations/offsetplot.lua index a336aed4e0..de613123c7 100644 --- a/Themes/Til Death/BGAnimations/offsetplot.lua +++ b/Themes/Til Death/BGAnimations/offsetplot.lua @@ -162,6 +162,7 @@ o[#o+1] = Def.ActorMultiVertex{ verts[#verts+1] = {{x-dotWidth,y-dotWidth,0}, color} end self:SetVertices(verts) + self:SetDrawState{Mode="DrawMode_Quads", First = 1, Num=#verts} end } From edbe9bade6c59f7284b5de37b1ab0586391c89d8 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 28 Mar 2018 18:02:18 -0300 Subject: [PATCH 4/7] Fix rate display online --- .../ScreenNetSelectMusic decorations/dumbrate.lua | 5 ++++- src/ScreenNetSelectMusic.cpp | 4 ++-- src/ScreenSelectMusic.cpp | 2 +- src/SongOptions.cpp | 11 ++++++----- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Themes/Til Death/BGAnimations/ScreenNetSelectMusic decorations/dumbrate.lua b/Themes/Til Death/BGAnimations/ScreenNetSelectMusic decorations/dumbrate.lua index a5607d599a..6f4972b903 100644 --- a/Themes/Til Death/BGAnimations/ScreenNetSelectMusic decorations/dumbrate.lua +++ b/Themes/Til Death/BGAnimations/ScreenNetSelectMusic decorations/dumbrate.lua @@ -168,7 +168,10 @@ t[#t+1] = LoadFont("Common Large") .. { ChangeMusicRate(rate,params) self:settext(getCurRateDisplayString()) end, - CurrentRateChangedCommand=function(self) + RateChangedMessageCommand=function(self,params) + self:settext(getCurRateDisplayString()) + end, + CurrentRateChangedMessageCommand=function(self) self:queuecommand("set") end } diff --git a/src/ScreenNetSelectMusic.cpp b/src/ScreenNetSelectMusic.cpp index 2340ec7182..0efc1f6ea7 100644 --- a/src/ScreenNetSelectMusic.cpp +++ b/src/ScreenNetSelectMusic.cpp @@ -444,7 +444,7 @@ void ScreenNetSelectMusic::HandleScreenMessage( const ScreenMessage SM ) m_DC[PLAYER_1] = NSMAN->steps->GetDifficulty(); if (NSMAN->rate > 0) { GAMESTATE->m_SongOptions.GetPreferred().m_fMusicRate = NSMAN->rate/1000.0; - MESSAGEMAN->Broadcast("CurrentRateChanged"); + MESSAGEMAN->Broadcast("RateChanged"); } m_MusicWheel.Select(); m_MusicWheel.Move(-1); @@ -467,7 +467,7 @@ void ScreenNetSelectMusic::HandleScreenMessage( const ScreenMessage SM ) m_DC[PLAYER_1] = NSMAN->steps->GetDifficulty(); if (NSMAN->rate > 0) { GAMESTATE->m_SongOptions.GetPreferred().m_fMusicRate = NSMAN->rate / 1000.0; - MESSAGEMAN->Broadcast("CurrentRateChanged"); + MESSAGEMAN->Broadcast("RateChanged"); } m_MusicWheel.Select(); m_MusicWheel.Move(-1); diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp index a3d25ce7ce..ddbace46a5 100644 --- a/src/ScreenSelectMusic.cpp +++ b/src/ScreenSelectMusic.cpp @@ -1854,7 +1854,7 @@ class LunaScreenSelectMusic : public Luna GAMESTATE->isplaylistcourse = true; p->GetMusicWheel()->SelectSong(pl.chartlist[0].songptr); GAMESTATE->m_SongOptions.GetPreferred().m_fMusicRate = pl.chartlist[0].rate; - MESSAGEMAN->Broadcast("CurrentRateChanged"); + MESSAGEMAN->Broadcast("RateChanged"); p->SelectCurrent(PLAYER_1); return 1; } diff --git a/src/SongOptions.cpp b/src/SongOptions.cpp index 9b25f01e4c..1f0cf0e476 100644 --- a/src/SongOptions.cpp +++ b/src/SongOptions.cpp @@ -156,7 +156,7 @@ bool SongOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut ) if( mult.Compare(sBit, matches) ) { m_fMusicRate = StringToFloat( matches[0] ); - MESSAGEMAN->Broadcast("CurrentRateChanged"); + MESSAGEMAN->Broadcast("RateChanged"); return true; } @@ -235,15 +235,16 @@ class LunaSongOptions: public Luna if(!(v > 0.0f && v <= 3.0f)) { luaL_error(L, "Invalid value %f", v); - } - p->m_fMusicRate = v; + } + else { + p->m_fMusicRate = v; + MESSAGEMAN->Broadcast("RateChanged"); + } } if(original_top >= 2 && lua_isnumber(L, 2)) { p->m_SpeedfMusicRate = FArgGTEZero(L, 2); } - if (lua_isnumber(L, 1)) - MESSAGEMAN->Broadcast("CurrentRateChanged"); OPTIONAL_RETURN_SELF(original_top); return 2; } From 9d012b33e476ad47efb59565d8357af90a143089 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 28 Mar 2018 19:24:31 -0300 Subject: [PATCH 5/7] Expose ColorBitmapText to lua, add LoadColorFont --- Themes/_fallback/Scripts/02 ActorDef.lua | 14 + src/BitmapText.cpp | 427 ++++++++++++++++++++++- src/BitmapText.h | 24 ++ src/ScreenNetSelectBase.cpp | 421 ---------------------- src/ScreenNetSelectBase.h | 22 -- 5 files changed, 463 insertions(+), 445 deletions(-) diff --git a/Themes/_fallback/Scripts/02 ActorDef.lua b/Themes/_fallback/Scripts/02 ActorDef.lua index 645a31f857..782bce3a10 100644 --- a/Themes/_fallback/Scripts/02 ActorDef.lua +++ b/Themes/_fallback/Scripts/02 ActorDef.lua @@ -178,6 +178,20 @@ function LoadFont(a, b) } end +function LoadColorFont(a, b) + local sSection = b and a or "" + local sFile = b or a + if sFile == "" or not sFile then + sSection = "Common" + sFile = "normal" + end + local sPath = THEME:GetPathF(sSection, sFile) + return Def.ColorBitmapText { + _Level = 2, + File = sPath + } +end + function WrapInActorFrame( t ) return Def.ActorFrame { children = t } end diff --git a/src/BitmapText.cpp b/src/BitmapText.cpp index bf236f8fa5..8042fb1cf4 100644 --- a/src/BitmapText.cpp +++ b/src/BitmapText.cpp @@ -12,8 +12,8 @@ #include "Foreach.h" #include "PrefsManager.h" -REGISTER_ACTOR_CLASS( BitmapText ); - +REGISTER_ACTOR_CLASS(BitmapText); +REGISTER_ACTOR_CLASS(ColorBitmapText); /* XXX: * We need some kind of font modifier string for metrics. For example, * "valign=top;spacing = x+5,y+2" @@ -1050,6 +1050,429 @@ LUA_REGISTER_DERIVED_CLASS( BitmapText, Actor ) // lua end + +/** ColorBitmapText ***********************************************************/ +void ColorBitmapText::SetText(const RString& _sText, const RString& _sAlternateText, int iWrapWidthPixels) +{ + ASSERT(m_pFont != NULL); + + RString sNewText = StringWillUseAlternate(_sText, _sAlternateText) ? _sAlternateText : _sText; + + if (iWrapWidthPixels == -1) // wrap not specified + iWrapWidthPixels = m_iWrapWidthPixels; + + if (m_sText == sNewText && iWrapWidthPixels == m_iWrapWidthPixels) + return; + m_sText = sNewText; + m_iWrapWidthPixels = iWrapWidthPixels; + + // Set up the first color. + m_vColors.clear(); + ColorChange change; + change.c = RageColor(1, 1, 1, 1); + change.l = 0; + m_vColors.push_back(change); + + m_wTextLines.clear(); + + RString sCurrentLine = ""; + int iLineWidth = 0; + + RString sCurrentWord = ""; + int iWordWidth = 0; + int iGlyphsSoFar = 0; + + for (unsigned i = 0; i < m_sText.length(); i++) + { + int iCharsLeft = m_sText.length() - i - 1; + + // First: Check for the special (color) case. + + if (m_sText.length() > 8 && i < m_sText.length() - 9) + { + RString FirstThree = m_sText.substr(i, 3); + if (FirstThree.CompareNoCase("|c0") == 0 && iCharsLeft > 8) + { + ColorChange cChange; + unsigned int r, g, b; + sscanf(m_sText.substr(i, 9).c_str(), "|%*c0%2x%2x%2x", &r, &g, &b); + cChange.c = RageColor(r / 255.f, g / 255.f, b / 255.f, 1.f); + cChange.l = iGlyphsSoFar; + if (iGlyphsSoFar == 0) + m_vColors[0] = cChange; + else + m_vColors.push_back(cChange); + i += 8; + continue; + } + } + + int iCharLength = min(utf8_get_char_len(m_sText[i]), iCharsLeft + 1); + RString curCharStr = m_sText.substr(i, iCharLength); + wchar_t curChar = utf8_get_char(curCharStr); + i += iCharLength - 1; + int iCharWidth = m_pFont->GetLineWidthInSourcePixels(wstring() + curChar); + + switch (curChar) + { + case L' ': + if ( /* iLineWidth == 0 &&*/ iWordWidth == 0) + break; + sCurrentLine += sCurrentWord + " "; + iLineWidth += iWordWidth + iCharWidth; + sCurrentWord = ""; + iWordWidth = 0; + iGlyphsSoFar++; + break; + case L'\n': + if (iLineWidth + iWordWidth > iWrapWidthPixels) + { + SimpleAddLine(sCurrentLine, iLineWidth); + if (iWordWidth > 0) + iLineWidth = iWordWidth + //Add the width of a space + m_pFont->GetLineWidthInSourcePixels(L" "); + sCurrentLine = sCurrentWord + " "; + iWordWidth = 0; + sCurrentWord = ""; + iGlyphsSoFar++; + } + else + { + SimpleAddLine(sCurrentLine + sCurrentWord, iLineWidth + iWordWidth); + sCurrentLine = ""; iLineWidth = 0; + sCurrentWord = ""; iWordWidth = 0; + } + break; + default: + if (iWordWidth + iCharWidth > iWrapWidthPixels && iLineWidth == 0) + { + SimpleAddLine(sCurrentWord, iWordWidth); + sCurrentWord = curCharStr; iWordWidth = iCharWidth; + } + else if (iWordWidth + iLineWidth + iCharWidth > iWrapWidthPixels) + { + SimpleAddLine(sCurrentLine, iLineWidth); + sCurrentLine = ""; + iLineWidth = 0; + sCurrentWord += curCharStr; + iWordWidth += iCharWidth; + } + else + { + sCurrentWord += curCharStr; + iWordWidth += iCharWidth; + } + iGlyphsSoFar++; + break; + } + } + + if (iWordWidth > 0) + { + sCurrentLine += sCurrentWord; + iLineWidth += iWordWidth; + } + + if (iLineWidth > 0) + SimpleAddLine(sCurrentLine, iLineWidth); + + lines = m_wTextLines.size(); + + BuildChars(); + UpdateBaseZoom(); +} + +void ColorBitmapText::ResetText() +{ + ASSERT(m_pFont != NULL); + + int iWrapWidthPixels = m_iWrapWidthPixels; + + // Set up the first color. + m_vColors.clear(); + ColorChange change; + change.c = RageColor(1, 1, 1, 1); + change.l = 0; + m_vColors.push_back(change); + + m_wTextLines.clear(); + + RString sCurrentLine = ""; + int iLineWidth = 0; + + RString sCurrentWord = ""; + int iWordWidth = 0; + int iGlyphsSoFar = 0; + + for (unsigned i = 0; i < m_sText.length(); i++) + { + int iCharsLeft = m_sText.length() - i - 1; + + // First: Check for the special (color) case. + + if (m_sText.length() > 8 && i < m_sText.length() - 9) + { + RString FirstThree = m_sText.substr(i, 3); + if (FirstThree.CompareNoCase("|c0") == 0 && iCharsLeft > 8) + { + ColorChange cChange; + unsigned int r, g, b; + sscanf(m_sText.substr(i, 9).c_str(), "|%*c0%2x%2x%2x", &r, &g, &b); + cChange.c = RageColor(r / 255.f, g / 255.f, b / 255.f, 1.f); + cChange.l = iGlyphsSoFar; + if (iGlyphsSoFar == 0) + m_vColors[0] = cChange; + else + m_vColors.push_back(cChange); + i += 8; + continue; + } + } + + int iCharLength = min(utf8_get_char_len(m_sText[i]), iCharsLeft + 1); + RString curCharStr = m_sText.substr(i, iCharLength); + wchar_t curChar = utf8_get_char(curCharStr); + i += iCharLength - 1; + int iCharWidth = m_pFont->GetLineWidthInSourcePixels(wstring() + curChar); + + switch (curChar) + { + case L' ': + if ( /* iLineWidth == 0 &&*/ iWordWidth == 0) + break; + sCurrentLine += sCurrentWord + " "; + iLineWidth += iWordWidth + iCharWidth; + sCurrentWord = ""; + iWordWidth = 0; + iGlyphsSoFar++; + break; + case L'\n': + if (iLineWidth + iWordWidth > iWrapWidthPixels) + { + SimpleAddLine(sCurrentLine, iLineWidth); + if (iWordWidth > 0) + iLineWidth = iWordWidth + //Add the width of a space + m_pFont->GetLineWidthInSourcePixels(L" "); + sCurrentLine = sCurrentWord + " "; + iWordWidth = 0; + sCurrentWord = ""; + iGlyphsSoFar++; + } + else + { + SimpleAddLine(sCurrentLine + sCurrentWord, iLineWidth + iWordWidth); + sCurrentLine = ""; iLineWidth = 0; + sCurrentWord = ""; iWordWidth = 0; + } + break; + default: + if (iWordWidth + iCharWidth > iWrapWidthPixels && iLineWidth == 0) + { + SimpleAddLine(sCurrentWord, iWordWidth); + sCurrentWord = curCharStr; iWordWidth = iCharWidth; + } + else if (iWordWidth + iLineWidth + iCharWidth > iWrapWidthPixels) + { + SimpleAddLine(sCurrentLine, iLineWidth); + sCurrentLine = ""; + iLineWidth = 0; + sCurrentWord += curCharStr; + iWordWidth += iCharWidth; + } + else + { + sCurrentWord += curCharStr; + iWordWidth += iCharWidth; + } + iGlyphsSoFar++; + break; + } + } + + if (iWordWidth > 0) + { + sCurrentLine += sCurrentWord; + iLineWidth += iWordWidth; + } + + if (iLineWidth > 0) + SimpleAddLine(sCurrentLine, iLineWidth); + lines = m_wTextLines.size(); + BuildChars(); + UpdateBaseZoom(); +} + +void ColorBitmapText::SetMaxLines(int iNumLines, int iDirection, unsigned int &scroll) +{ + iNumLines = max(0, iNumLines); + iNumLines = min(static_cast(m_wTextLines.size()), iNumLines); + if (iDirection == 0) + { + // Crop all bottom lines + m_wTextLines.resize(iNumLines); + m_iLineWidths.resize(iNumLines); + } + else + { + // Because colors are relative to the beginning, we have to crop them back + unsigned shift = 0; + if (scroll > m_iLineWidths.size() - iNumLines) + scroll = m_iLineWidths.size() - iNumLines; + + for (unsigned i = 0; i < m_wTextLines.size() - iNumLines - scroll; i++) + shift += m_wTextLines[i].length(); + + // When we're cutting out text, we need to maintain the last + // color, so our text at the top doesn't become colorless. + RageColor LastColor; + + for (unsigned i = 0; i < m_vColors.size(); i++) + { + m_vColors[i].l -= shift; + if (m_vColors[i].l < 0) + { + LastColor = m_vColors[i].c; + m_vColors.erase(m_vColors.begin() + i); + i--; + } + } + + // If we already have a color set for the first char + // do not override it. + if (m_vColors.size() > 0 && m_vColors[0].l > 0) + { + ColorChange tmp; + tmp.c = LastColor; + tmp.l = 0; + m_vColors.insert(m_vColors.begin(), tmp); + } + + if (scroll == 0 || m_iLineWidths.size() <= iNumLines || scroll > m_iLineWidths.size() - iNumLines) { + m_wTextLines.erase(m_wTextLines.begin(), m_wTextLines.end() - iNumLines); + m_iLineWidths.erase(m_iLineWidths.begin(), m_iLineWidths.end() - iNumLines); + } + else { + m_wTextLines.erase(m_wTextLines.begin(), m_wTextLines.end() - iNumLines - scroll); + m_iLineWidths.erase(m_iLineWidths.begin(), m_iLineWidths.end() - iNumLines - scroll); + + m_wTextLines.erase(m_wTextLines.end() - scroll, m_wTextLines.end()); + m_iLineWidths.erase(m_iLineWidths.begin(), m_iLineWidths.end()); + } + } + BuildChars(); +} + +void ColorBitmapText::SimpleAddLine(const RString &sAddition, const int iWidthPixels) +{ + m_wTextLines.push_back(RStringToWstring(sAddition)); + m_iLineWidths.push_back(iWidthPixels); +} + +void ColorBitmapText::DrawPrimitives() +{ + Actor::SetGlobalRenderStates(); // set Actor-specified render states + DISPLAY->SetTextureMode(TextureUnit_1, TextureMode_Modulate); + + /* Draw if we're not fully transparent or the zbuffer is enabled */ + if (m_pTempState->diffuse[0].a != 0) + { + // render the shadow + if (m_fShadowLengthX != 0 || m_fShadowLengthY != 0) + { + DISPLAY->PushMatrix(); + DISPLAY->TranslateWorld(m_fShadowLengthX, m_fShadowLengthY, 0); // shift by 5 units + RageColor c = m_ShadowColor; + c.a *= m_pTempState->diffuse[0].a; + for (unsigned i = 0; iPopMatrix(); + } + + // render the diffuse pass + int loc = 0, cur = 0; + RageColor c = m_pTempState->diffuse[0]; + + for (unsigned i = 0; i(m_vColors.size())) + { + if (loc > m_vColors[cur].l) + { + c = m_vColors[cur].c; + cur++; + } + } + for (unsigned j = 0; j<4; j++) + m_aVertices[i + j].c = c; + } + + DrawChars(false); + } + + // render the glow pass + if (m_pTempState->glow.a > 0.0001f) + { + DISPLAY->SetTextureMode(TextureUnit_1, TextureMode_Glow); + + for (unsigned i = 0; iglow; + DrawChars(false); + } +} + +void ColorBitmapText::SetMaxLines(int iNumLines, int iDirection) +{ + iNumLines = max(0, iNumLines); + iNumLines = min(static_cast(m_wTextLines.size()), iNumLines); + if (iDirection == 0) + { + // Crop all bottom lines + m_wTextLines.resize(iNumLines); + m_iLineWidths.resize(iNumLines); + } + else + { + // Because colors are relative to the beginning, we have to crop them back + unsigned shift = 0; + + for (unsigned i = 0; i < m_wTextLines.size() - iNumLines; i++) + shift += m_wTextLines[i].length(); + + // When we're cutting out text, we need to maintain the last + // color, so our text at the top doesn't become colorless. + RageColor LastColor; + + for (unsigned i = 0; i < m_vColors.size(); i++) + { + m_vColors[i].l -= shift; + if (m_vColors[i].l < 0) + { + LastColor = m_vColors[i].c; + m_vColors.erase(m_vColors.begin() + i); + i--; + } + } + + // If we already have a color set for the first char + // do not override it. + if (m_vColors.size() > 0 && m_vColors[0].l > 0) + { + ColorChange tmp; + tmp.c = LastColor; + tmp.l = 0; + m_vColors.insert(m_vColors.begin(), tmp); + } + + m_wTextLines.erase(m_wTextLines.begin(), m_wTextLines.end() - iNumLines); + m_iLineWidths.erase(m_iLineWidths.begin(), m_iLineWidths.end() - iNumLines); + } + BuildChars(); +} + + /* * (c) 2003-2007 Chris Danford, Charles Lohr, Steve Checkoway * All rights reserved. diff --git a/src/BitmapText.h b/src/BitmapText.h index d7c5597296..51a1c09bf0 100644 --- a/src/BitmapText.h +++ b/src/BitmapText.h @@ -146,6 +146,30 @@ class BitmapText : public Actor BMT_TweenState BMT_start; }; + +// With the addition of Attributes to BitmapText, this class may very well be +// redundant. (Leave it in for now, though.) -aj +class ColorBitmapText : public BitmapText +{ +public: + ColorBitmapText * Copy() const; + void SetText(const RString &sText, const RString &sAlternateText = "", int iWrapWidthPixels = -1) override; + void ResetText(); + void DrawPrimitives() override; + int lines = 0; + void SetMaxLines(int iNumLines, int iDirection, unsigned int &scroll); + void SetMaxLines(int iLines, bool bCutBottom = true); //if bCutBottom = false then, it will crop the top + void SimpleAddLine(const RString &sAddition, int iWidthPixels); + void SetMaxLines(int iNumLines, int iDirection); +protected: + struct ColorChange + { + RageColor c; // Color to change to + int l; // Change Location + }; + vector m_vColors; +}; + #endif /** diff --git a/src/ScreenNetSelectBase.cpp b/src/ScreenNetSelectBase.cpp index 8c8aaf1065..78d93f548c 100644 --- a/src/ScreenNetSelectBase.cpp +++ b/src/ScreenNetSelectBase.cpp @@ -283,427 +283,6 @@ void ScreenNetSelectBase::SetInputText(RString text) UpdateTextInput(); return; } -/** ColorBitmapText ***********************************************************/ -void ColorBitmapText::SetText( const RString& _sText, const RString& _sAlternateText, int iWrapWidthPixels ) -{ - ASSERT( m_pFont != NULL ); - - RString sNewText = StringWillUseAlternate(_sText,_sAlternateText) ? _sAlternateText : _sText; - - if( iWrapWidthPixels == -1 ) // wrap not specified - iWrapWidthPixels = m_iWrapWidthPixels; - - if( m_sText == sNewText && iWrapWidthPixels==m_iWrapWidthPixels ) - return; - m_sText = sNewText; - m_iWrapWidthPixels = iWrapWidthPixels; - - // Set up the first color. - m_vColors.clear(); - ColorChange change; - change.c = RageColor (1, 1, 1, 1); - change.l = 0; - m_vColors.push_back( change ); - - m_wTextLines.clear(); - - RString sCurrentLine = ""; - int iLineWidth = 0; - - RString sCurrentWord = ""; - int iWordWidth = 0; - int iGlyphsSoFar = 0; - - for( unsigned i = 0; i < m_sText.length(); i++ ) - { - int iCharsLeft = m_sText.length() - i - 1; - - // First: Check for the special (color) case. - - if( m_sText.length() > 8 && i < m_sText.length() - 9 ) - { - RString FirstThree = m_sText.substr( i, 3 ); - if( FirstThree.CompareNoCase("|c0") == 0 && iCharsLeft > 8 ) - { - ColorChange cChange; - unsigned int r, g, b; - sscanf( m_sText.substr( i, 9 ).c_str(), "|%*c0%2x%2x%2x", &r, &g, &b ); - cChange.c = RageColor( r/255.f, g/255.f, b/255.f, 1.f ); - cChange.l = iGlyphsSoFar; - if( iGlyphsSoFar == 0 ) - m_vColors[0] = cChange; - else - m_vColors.push_back( cChange ); - i+=8; - continue; - } - } - - int iCharLength = min( utf8_get_char_len(m_sText[i]), iCharsLeft + 1 ); - RString curCharStr = m_sText.substr( i, iCharLength ); - wchar_t curChar = utf8_get_char( curCharStr ); - i += iCharLength - 1; - int iCharWidth = m_pFont->GetLineWidthInSourcePixels( wstring() + curChar ); - - switch( curChar ) - { - case L' ': - if( /* iLineWidth == 0 &&*/ iWordWidth == 0 ) - break; - sCurrentLine += sCurrentWord + " "; - iLineWidth += iWordWidth + iCharWidth; - sCurrentWord = ""; - iWordWidth = 0; - iGlyphsSoFar++; - break; - case L'\n': - if( iLineWidth + iWordWidth > iWrapWidthPixels ) - { - SimpleAddLine( sCurrentLine, iLineWidth ); - if( iWordWidth > 0 ) - iLineWidth = iWordWidth + //Add the width of a space - m_pFont->GetLineWidthInSourcePixels( L" " ); - sCurrentLine = sCurrentWord + " "; - iWordWidth = 0; - sCurrentWord = ""; - iGlyphsSoFar++; - } - else - { - SimpleAddLine( sCurrentLine + sCurrentWord, iLineWidth + iWordWidth ); - sCurrentLine = ""; iLineWidth = 0; - sCurrentWord = ""; iWordWidth = 0; - } - break; - default: - if( iWordWidth + iCharWidth > iWrapWidthPixels && iLineWidth == 0 ) - { - SimpleAddLine( sCurrentWord, iWordWidth ); - sCurrentWord = curCharStr; iWordWidth = iCharWidth; - } - else if( iWordWidth + iLineWidth + iCharWidth > iWrapWidthPixels ) - { - SimpleAddLine( sCurrentLine, iLineWidth ); - sCurrentLine = ""; - iLineWidth = 0; - sCurrentWord += curCharStr; - iWordWidth += iCharWidth; - } - else - { - sCurrentWord += curCharStr; - iWordWidth += iCharWidth; - } - iGlyphsSoFar++; - break; - } - } - - if( iWordWidth > 0 ) - { - sCurrentLine += sCurrentWord; - iLineWidth += iWordWidth; - } - - if( iLineWidth > 0 ) - SimpleAddLine( sCurrentLine, iLineWidth ); - - lines = m_wTextLines.size(); - - BuildChars(); - UpdateBaseZoom(); -} - -void ColorBitmapText::ResetText() -{ - ASSERT(m_pFont != NULL); - - int iWrapWidthPixels = m_iWrapWidthPixels; - - // Set up the first color. - m_vColors.clear(); - ColorChange change; - change.c = RageColor(1, 1, 1, 1); - change.l = 0; - m_vColors.push_back(change); - - m_wTextLines.clear(); - - RString sCurrentLine = ""; - int iLineWidth = 0; - - RString sCurrentWord = ""; - int iWordWidth = 0; - int iGlyphsSoFar = 0; - - for (unsigned i = 0; i < m_sText.length(); i++) - { - int iCharsLeft = m_sText.length() - i - 1; - - // First: Check for the special (color) case. - - if (m_sText.length() > 8 && i < m_sText.length() - 9) - { - RString FirstThree = m_sText.substr(i, 3); - if (FirstThree.CompareNoCase("|c0") == 0 && iCharsLeft > 8) - { - ColorChange cChange; - unsigned int r, g, b; - sscanf(m_sText.substr(i, 9).c_str(), "|%*c0%2x%2x%2x", &r, &g, &b); - cChange.c = RageColor(r / 255.f, g / 255.f, b / 255.f, 1.f); - cChange.l = iGlyphsSoFar; - if (iGlyphsSoFar == 0) - m_vColors[0] = cChange; - else - m_vColors.push_back(cChange); - i += 8; - continue; - } - } - - int iCharLength = min(utf8_get_char_len(m_sText[i]), iCharsLeft + 1); - RString curCharStr = m_sText.substr(i, iCharLength); - wchar_t curChar = utf8_get_char(curCharStr); - i += iCharLength - 1; - int iCharWidth = m_pFont->GetLineWidthInSourcePixels(wstring() + curChar); - - switch (curChar) - { - case L' ': - if ( /* iLineWidth == 0 &&*/ iWordWidth == 0) - break; - sCurrentLine += sCurrentWord + " "; - iLineWidth += iWordWidth + iCharWidth; - sCurrentWord = ""; - iWordWidth = 0; - iGlyphsSoFar++; - break; - case L'\n': - if (iLineWidth + iWordWidth > iWrapWidthPixels) - { - SimpleAddLine(sCurrentLine, iLineWidth); - if (iWordWidth > 0) - iLineWidth = iWordWidth + //Add the width of a space - m_pFont->GetLineWidthInSourcePixels(L" "); - sCurrentLine = sCurrentWord + " "; - iWordWidth = 0; - sCurrentWord = ""; - iGlyphsSoFar++; - } - else - { - SimpleAddLine(sCurrentLine + sCurrentWord, iLineWidth + iWordWidth); - sCurrentLine = ""; iLineWidth = 0; - sCurrentWord = ""; iWordWidth = 0; - } - break; - default: - if (iWordWidth + iCharWidth > iWrapWidthPixels && iLineWidth == 0) - { - SimpleAddLine(sCurrentWord, iWordWidth); - sCurrentWord = curCharStr; iWordWidth = iCharWidth; - } - else if (iWordWidth + iLineWidth + iCharWidth > iWrapWidthPixels) - { - SimpleAddLine(sCurrentLine, iLineWidth); - sCurrentLine = ""; - iLineWidth = 0; - sCurrentWord += curCharStr; - iWordWidth += iCharWidth; - } - else - { - sCurrentWord += curCharStr; - iWordWidth += iCharWidth; - } - iGlyphsSoFar++; - break; - } - } - - if (iWordWidth > 0) - { - sCurrentLine += sCurrentWord; - iLineWidth += iWordWidth; - } - - if (iLineWidth > 0) - SimpleAddLine(sCurrentLine, iLineWidth); - lines = m_wTextLines.size(); - BuildChars(); - UpdateBaseZoom(); -} - -void ColorBitmapText::SetMaxLines(int iNumLines, int iDirection, unsigned int &scroll) -{ - iNumLines = max(0, iNumLines); - iNumLines = min(static_cast(m_wTextLines.size()), iNumLines); - if (iDirection == 0) - { - // Crop all bottom lines - m_wTextLines.resize(iNumLines); - m_iLineWidths.resize(iNumLines); - } - else - { - // Because colors are relative to the beginning, we have to crop them back - unsigned shift = 0; - if (scroll > m_iLineWidths.size() - iNumLines) - scroll = m_iLineWidths.size() - iNumLines; - - for (unsigned i = 0; i < m_wTextLines.size() - iNumLines - scroll; i++) - shift += m_wTextLines[i].length(); - - // When we're cutting out text, we need to maintain the last - // color, so our text at the top doesn't become colorless. - RageColor LastColor; - - for (unsigned i = 0; i < m_vColors.size(); i++) - { - m_vColors[i].l -= shift; - if (m_vColors[i].l < 0) - { - LastColor = m_vColors[i].c; - m_vColors.erase(m_vColors.begin() + i); - i--; - } - } - - // If we already have a color set for the first char - // do not override it. - if (m_vColors.size() > 0 && m_vColors[0].l > 0) - { - ColorChange tmp; - tmp.c = LastColor; - tmp.l = 0; - m_vColors.insert(m_vColors.begin(), tmp); - } - - if (scroll == 0 || m_iLineWidths.size() <= iNumLines || scroll > m_iLineWidths.size() - iNumLines) { - m_wTextLines.erase(m_wTextLines.begin(), m_wTextLines.end() - iNumLines); - m_iLineWidths.erase(m_iLineWidths.begin(), m_iLineWidths.end() - iNumLines); - } - else { - m_wTextLines.erase(m_wTextLines.begin(), m_wTextLines.end() - iNumLines - scroll); - m_iLineWidths.erase(m_iLineWidths.begin(), m_iLineWidths.end() - iNumLines - scroll); - - m_wTextLines.erase(m_wTextLines.end() - scroll, m_wTextLines.end()); - m_iLineWidths.erase(m_iLineWidths.begin(), m_iLineWidths.end()); - } - } - BuildChars(); -} - -void ColorBitmapText::SimpleAddLine( const RString &sAddition, const int iWidthPixels) -{ - m_wTextLines.push_back( RStringToWstring( sAddition ) ); - m_iLineWidths.push_back( iWidthPixels ); -} - -void ColorBitmapText::DrawPrimitives( ) -{ - Actor::SetGlobalRenderStates(); // set Actor-specified render states - DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate ); - - /* Draw if we're not fully transparent or the zbuffer is enabled */ - if( m_pTempState->diffuse[0].a != 0 ) - { - // render the shadow - if( m_fShadowLengthX != 0 || m_fShadowLengthY != 0 ) - { - DISPLAY->PushMatrix(); - DISPLAY->TranslateWorld( m_fShadowLengthX, m_fShadowLengthY, 0 ); // shift by 5 units - RageColor c = m_ShadowColor; - c.a *= m_pTempState->diffuse[0].a; - for( unsigned i=0; iPopMatrix(); - } - - // render the diffuse pass - int loc = 0, cur = 0; - RageColor c = m_pTempState->diffuse[0]; - - for( unsigned i=0; i(m_vColors.size()) ) - { - if ( loc > m_vColors[cur].l ) - { - c = m_vColors[cur].c; - cur++; - } - } - for( unsigned j=0; j<4; j++ ) - m_aVertices[i+j].c = c; - } - - DrawChars( false ); - } - - // render the glow pass - if( m_pTempState->glow.a > 0.0001f ) - { - DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow ); - - for( unsigned i=0; iglow; - DrawChars( false ); - } -} - -void ColorBitmapText::SetMaxLines(int iNumLines, int iDirection) -{ - iNumLines = max(0, iNumLines); - iNumLines = min(static_cast(m_wTextLines.size()), iNumLines); - if(iDirection == 0) - { - // Crop all bottom lines - m_wTextLines.resize(iNumLines); - m_iLineWidths.resize(iNumLines); - } - else - { - // Because colors are relative to the beginning, we have to crop them back - unsigned shift = 0; - - for(unsigned i = 0; i < m_wTextLines.size() - iNumLines; i++) - shift += m_wTextLines[i].length(); - - // When we're cutting out text, we need to maintain the last - // color, so our text at the top doesn't become colorless. - RageColor LastColor; - - for(unsigned i = 0; i < m_vColors.size(); i++) - { - m_vColors[i].l -= shift; - if(m_vColors[i].l < 0) - { - LastColor = m_vColors[i].c; - m_vColors.erase(m_vColors.begin() + i); - i--; - } - } - - // If we already have a color set for the first char - // do not override it. - if(m_vColors.size() > 0 && m_vColors[0].l > 0) - { - ColorChange tmp; - tmp.c = LastColor; - tmp.l = 0; - m_vColors.insert(m_vColors.begin(), tmp); - } - - m_wTextLines.erase(m_wTextLines.begin(), m_wTextLines.end() - iNumLines); - m_iLineWidths.erase(m_iLineWidths.begin(), m_iLineWidths.end() - iNumLines); - } - BuildChars(); -} - void ScreenNetSelectBase::SetChatboxVisible(bool visibility) { diff --git a/src/ScreenNetSelectBase.h b/src/ScreenNetSelectBase.h index cefe18e90b..8e73d7f198 100644 --- a/src/ScreenNetSelectBase.h +++ b/src/ScreenNetSelectBase.h @@ -8,28 +8,6 @@ #include "Quad.h" #include "BitmapText.h" -// With the addition of Attributes to BitmapText, this class may very well be -// redundant. (Leave it in for now, though.) -aj -class ColorBitmapText : public BitmapText -{ -public: - void SetText( const RString &sText, const RString &sAlternateText = "", int iWrapWidthPixels = -1 ) override; - void ResetText(); - void DrawPrimitives() override; - int lines=0; - void SetMaxLines(int iNumLines, int iDirection, unsigned int &scroll); - void SetMaxLines( int iLines, bool bCutBottom = true ); //if bCutBottom = false then, it will crop the top - void SimpleAddLine( const RString &sAddition, int iWidthPixels ); - void SetMaxLines( int iNumLines, int iDirection ); -protected: - struct ColorChange - { - RageColor c; // Color to change to - int l; // Change Location - }; - vector m_vColors; -}; - class ScreenNetSelectBase : public ScreenWithMenuElements { From 4e8b9d969b27196eafeec7c5c524b60d35878a9d Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 28 Mar 2018 19:27:37 -0300 Subject: [PATCH 6/7] Rename solution to Etterna in appveyor script --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index a334c70850..bd74eb7b47 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,7 +26,7 @@ before_build: del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" build: - project: C:\etterna\build\StepMania.sln + project: C:\etterna\build\Etterna.sln verbosity: normal after_build: From 6852775b9296568a47ce013247757cea374c6247 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 28 Mar 2018 23:18:36 -0300 Subject: [PATCH 7/7] A couple OpenGL RageDisplay changes --- src/RageDisplay_OGL.cpp | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/RageDisplay_OGL.cpp b/src/RageDisplay_OGL.cpp index 01daa824ca..2256415182 100644 --- a/src/RageDisplay_OGL.cpp +++ b/src/RageDisplay_OGL.cpp @@ -801,17 +801,7 @@ void RageDisplay_Legacy::EndFrame() FrameLimitBeforeVsync(); auto beforePresent = std::chrono::steady_clock::now(); g_pWind->SwapBuffers(); - - // Some would advise against glFinish(), ever. Those people don't realize - // the degree of freedom GL hosts are permitted in queueing commands. - // If left to its own devices, the host could lag behind several frames' worth - // of commands. - // glFlush() only forces the host to not wait to execute all commands - // sent so far; it does NOT block on those commands until they finish. - // glFinish() blocks. We WANT to block. Why? This puts the engine state - // reflected by the next frame as close as possible to the on-screen - // appearance of that frame. - glFinish(); + glFlush(); g_pWind->Update(); @@ -2217,11 +2207,13 @@ unsigned RageDisplay_Legacy::CreateTexture( if (bGenerateMipMaps) { - GLenum error = gluBuild2DMipmaps( - GL_TEXTURE_2D, glTexFormat, - pImg->w, pImg->h, - glImageFormat, glImageType, pImg->pixels ); - ASSERT_M( error == 0, (char *) gluErrorString(error) ); + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + glTexImage2D(GL_TEXTURE_2D, 0, glTexFormat, pImg->w, pImg->h, 0, glImageFormat, glImageType, pImg->pixels); + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) + { + ASSERT_M(err == 0, (char *)gluErrorString(err)); + } } else {