diff --git a/Docs/Changelog_language.txt b/Docs/Changelog_language.txt index 9a62f54f9c..c9eba36c29 100644 --- a/Docs/Changelog_language.txt +++ b/Docs/Changelog_language.txt @@ -19,7 +19,7 @@ This means that three strings were added to the "ScreenDebugOverlay" section, 2015/05/05 ---------- * [ScreenGameplay] SkipSongText - +* [SongManager] Sanity checking groups... 2015/04/23 ---------- diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 98c8672735..5f83c3f2ea 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -2043,6 +2043,7 @@ Loading songs...=Loading songs... Reloading...=Reloading... Unloading songs...=Unloading songs... Unloading courses...=Unloading courses... +Sanity checking groups...=Sanity checking groups... The folder "%s" appears to be a song folder. All song folders must reside in a group folder. For example, "Songs/Originals/My Song".=The folder "%s" appears to be a song folder. All song folders must reside in a group folder. For example, "Songs/Originals/My Song" will contain the music file (MP3, OGG...), the steps file (.sm, .dwi, .ksf...) and other related files. [SongUtil] diff --git a/src/NoteDisplay.cpp b/src/NoteDisplay.cpp index a74ef39324..c8887255f8 100644 --- a/src/NoteDisplay.cpp +++ b/src/NoteDisplay.cpp @@ -729,10 +729,17 @@ struct StripBuffer int Free() const { return size - Used(); } }; +enum hold_part_type +{ + hpt_top, + hpt_body, + hpt_bottom, +}; + void NoteDisplay::DrawHoldPart(vector &vpSpr, const NoteFieldRenderArgs& field_args, const NoteColumnRenderArgs& column_args, - const draw_hold_part_args& part_args, bool glow) + const draw_hold_part_args& part_args, bool glow, int part_type) { ASSERT(!vpSpr.empty()); @@ -744,36 +751,46 @@ void NoteDisplay::DrawHoldPart(vector &vpSpr, if(part_args.flip_texture_vertically) swap(rect.top, rect.bottom); const float fFrameWidth = pSprite->GetUnzoomedWidth(); - const float fFrameHeight = pSprite->GetUnzoomedHeight() * ae_zoom; + const float unzoomed_frame_height= pSprite->GetUnzoomedHeight(); /* Only draw the section that's within the range specified. If a hold note is * very long, don't process or draw the part outside of the range. Don't change * part_args.y_top or part_args.y_bottom; they need to be left alone to calculate texture coordinates. */ const float y_start_pos = max(part_args.y_top, part_args.y_start_pos); - const float y_end_pos = min(part_args.y_bottom, part_args.y_end_pos); + float y_end_pos = min(part_args.y_bottom, part_args.y_end_pos); const float color_scale= glow ? 1 : part_args.color_scale; + if(part_type == hpt_body) + { + // Overshoot to cover up the seam between body and bottom. + // It's not fully gone, but the bg doesn't peak through. + y_end_pos+= 1; + } // top to bottom bool bAllAreTransparent = true; bool bLast = false; float fAddToTexCoord = 0; - if(!part_args.anchor_to_top) + // The caps should always use the full texture. + if(part_type == hpt_body) { - float tex_coord_bottom= SCALE(part_args.y_bottom - part_args.y_top, - 0, fFrameHeight, rect.top, rect.bottom); - float want_tex_coord_bottom = ceilf(tex_coord_bottom - 0.0001f); - fAddToTexCoord = want_tex_coord_bottom - tex_coord_bottom; - } + if(!part_args.anchor_to_top) + { + float tex_coord_bottom= SCALE(part_args.y_bottom - part_args.y_top, + 0, unzoomed_frame_height, rect.top, rect.bottom); + float want_tex_coord_bottom = ceilf(tex_coord_bottom - 0.0001f); + fAddToTexCoord = want_tex_coord_bottom - tex_coord_bottom; + } - if(part_args.wrapping) - { - /* For very large hold notes, shift the texture coordinates to be near 0, so we - * don't send very large values to the renderer. */ - const float fDistFromTop = y_start_pos - part_args.y_top; - float fTexCoordTop = SCALE(fDistFromTop, 0, fFrameHeight, rect.top, rect.bottom); - fTexCoordTop += fAddToTexCoord; - fAddToTexCoord -= floorf(fTexCoordTop); + if(part_args.wrapping) + { + /* For very large hold notes, shift the texture coordinates to be near 0, so we + * don't send very large values to the renderer. */ + const float fDistFromTop = y_start_pos - part_args.y_top; + float fTexCoordTop = SCALE(fDistFromTop, 0, unzoomed_frame_height, rect.top, rect.bottom); + fTexCoordTop += fAddToTexCoord; + fAddToTexCoord -= floorf(fTexCoordTop); + } } DISPLAY->ClearAllTextures(); @@ -937,8 +954,8 @@ void NoteDisplay::DrawHoldPart(vector &vpSpr, const RageVector3 right_vert(center_vert.x - render_left.x, center_vert.y - render_left.y, center_vert.z - render_left.z); - const float fDistFromTop = fY - part_args.y_top; - float fTexCoordTop = SCALE(fDistFromTop, 0, fFrameHeight, rect.top, rect.bottom); + const float fDistFromTop = (fY - y_start_pos) / ae_zoom; + float fTexCoordTop = SCALE(fDistFromTop, 0, unzoomed_frame_height, rect.top, rect.bottom); fTexCoordTop += fAddToTexCoord; const float fAlpha = ArrowGetAlphaOrGlow(glow, m_pPlayerState, column_args.column, fYOffset, part_args.percent_fade_to_fail, m_fYReverseOffsetPixels, field_args.draw_pixels_before_targets, field_args.fade_before_targets); @@ -994,19 +1011,19 @@ void NoteDisplay::DrawHoldBodyInternal(vector& sprite_top, part_args.top_beat= top_beat; part_args.bottom_beat= top_beat; part_args.wrapping= false; - DrawHoldPart(sprite_top, field_args, column_args, part_args, glow); + DrawHoldPart(sprite_top, field_args, column_args, part_args, glow, hpt_top); // Draw the body part_args.y_top= y_head; part_args.y_bottom= y_tail; part_args.bottom_beat= bottom_beat; part_args.wrapping= true; - DrawHoldPart(sprite_body, field_args, column_args, part_args, glow); + DrawHoldPart(sprite_body, field_args, column_args, part_args, glow, hpt_body); // Draw the bottom cap part_args.y_top= y_tail; part_args.y_bottom= tail_plus_bottom; part_args.top_beat= bottom_beat; part_args.y_start_pos= max(part_args.y_start_pos, y_head); - DrawHoldPart(sprite_bottom, field_args, column_args, part_args, glow); + DrawHoldPart(sprite_bottom, field_args, column_args, part_args, glow, hpt_bottom); } void NoteDisplay::DrawHoldBody(const TapNote& tn, @@ -1067,8 +1084,9 @@ void NoteDisplay::DrawHoldBody(const TapNote& tn, y_tail += cache->m_iStopDrawingHoldBodyOffsetFromTail; } - const float frame_height_top= pSpriteTop->GetUnzoomedHeight(); - const float frame_height_bottom= pSpriteBottom->GetUnzoomedHeight(); + float ae_zoom= ArrowEffects::GetZoom(m_pPlayerState); + const float frame_height_top= pSpriteTop->GetUnzoomedHeight() * ae_zoom; + const float frame_height_bottom= pSpriteBottom->GetUnzoomedHeight() * ae_zoom; part_args.y_start_pos= ArrowEffects::GetYPos(column_args.column, field_args.draw_pixels_after_targets, m_fYReverseOffsetPixels); diff --git a/src/NoteDisplay.h b/src/NoteDisplay.h index 2727dfbfd1..ce9dd0a2bd 100644 --- a/src/NoteDisplay.h +++ b/src/NoteDisplay.h @@ -246,7 +246,7 @@ private: void DrawHoldPart(vector &vpSpr, const NoteFieldRenderArgs& field_args, const NoteColumnRenderArgs& column_args, - const draw_hold_part_args& part_args, bool glow); + const draw_hold_part_args& part_args, bool glow, int part_type); void DrawHoldBodyInternal(vector& sprite_top, vector& sprite_body, vector& sprite_bottom, const NoteFieldRenderArgs& field_args, diff --git a/src/SongManager.cpp b/src/SongManager.cpp index 85b0d7ab6e..bf6d3f27ed 100644 --- a/src/SongManager.cpp +++ b/src/SongManager.cpp @@ -107,6 +107,7 @@ void SongManager::InitAll( LoadingWindow *ld ) static LocalizedString RELOADING ( "SongManager", "Reloading..." ); static LocalizedString UNLOADING_SONGS ( "SongManager", "Unloading songs..." ); static LocalizedString UNLOADING_COURSES ( "SongManager", "Unloading courses..." ); +static LocalizedString SANITY_CHECKING_GROUPS("SongManager", "Sanity checking groups..."); void SongManager::Reload( bool bAllowFastLoad, LoadingWindow *ld ) { @@ -278,9 +279,21 @@ void SongManager::LoadStepManiaSongDir( RString sDir, LoadingWindow *ld ) groupIndex = 0; songCount = 0; + if(ld) + { + ld->SetIndeterminate(false); + ld->SetTotalWork(arrayGroupDirs.size()); + } + int sanity_index= 0; FOREACH_CONST( RString, arrayGroupDirs, s ) // foreach dir in /Songs/ { RString sGroupDirName = *s; + if(ld) + { + ld->SetProgress(sanity_index); + ld->SetText(SANITY_CHECKING_GROUPS.GetValue() + ssprintf("\n%s", + Basename(sGroupDirName).c_str())); + } // TODO: If this check fails, log a warning instead of crashing. SanityCheckGroupDir(sDir+sGroupDirName);