Title Screen (#454)

* Barebones title screen prefab added

* logo and stuff

* cool

* Added sfx to title screen

* The logo now bops to the beat

* epic reveal

* Fixed something

* put some of the stuff into the main menu

* other logo bop

* Implemented logobop2 and starbop

* added scrolling bg, tweaked positioning and wip splash text for play button

* more menu

* ooops

* Expand implemented

* cool

* Made stars spawn in in the opening

* make UI elements look nicer on different aspect ratios

* add sound while hovering over logo

* add settings menu to title screen

make the title screen properly play after the opening

* swap out title screen hover sound

remove the old config path warning

* every button works, some play mode fixes

* fix issues with beataction/multisound and pausing

* fix dropdown menus not working in certain screens

* fix particles rotating when camera controls are used

* touch style pause menu items only trigger if cursor is over an item

* various changes

make playback (unpausing) more reliable
only apply changes to advanced audio settings on launch
fix title screen visuals
add opening music
continue past opening by pressing a key
update credits

* almost forgot this

* lol

* initial flow mems

* user-taggable fonts in textboxes

* alt materials for kurokane

* assets prep

* plan out judgement screen layout

change sound encodings

* start sequencing judgement

* judgement screen sequence

* full game loop

* fix major issue with pooled sound objects

rebalance ranking audio
fix issues with some effects in play mode

* new graphics

* particles

* make certain uses of the beat never go below 0

fix loop of superb music

* make markers non clamped

lockstep frees rendertextures when unloading

* lockstep creates its own rendertextures

swapped button order on title screen
added null checks to animation helpers
disabled controller auto-search for now

* enable particles on OK rank

* play mode info panel

* let play mode handle its own fade out

* fix that alignment bug in controller settings

* more safety here

* Update PauseMenu.cs

* settable (one-liner) rating screen text

* address minigame loading crashes

* don't do this twice

* wav converter for mp3

* Update Minigames.cs

* don't double-embed the converted audio

* studio dance bugfixing spree

* import redone sprites for studio dance

* update jukebox

prep epilogue screen

* epilogue screen

* studio dance inkling shuffle test

* new studio dance choreo system

* markers upgrade

* fix deleting volume changes and markers

prep category markers

* Update Editor.unity

* new rating / epilogue settings look

* update to use new tooltip system

mark certain editor components as blocking

* finish category system

* dedicated tempo / volume marker dialogs

* swing prep

* open properties dialog if mapper hasn't opened it prior for this chart

fix memory copy bug when making new chart

* fix ctrl + s

* return to title screen button

* make graphy work everywhere

studio dance selector
membillion mems

* make sure riq cache is clear when loading chart

* lol

* fix the stupid

* bring back tempo and volume change scrolling

* new look for panels

* adjust alignment

* round tooltip

* alignment of chart property prefab

* change scale factor of mem

* adjust open captions material

no dotted BG in results commentary (only epilogue)
bugfix for tempo / volume scroll

* format line 2 of judgement a bit better

update font

* oops

* adjust look of judgement score bar

* new rating bar

* judgement size adjustment

* fix timing window scaling with song pitch

* proper clamping in dialogs

better sync conductor to dsptime (experiment)

* disable timeline pitch change when song is paused

enable perfect challenge if no marker is set to do so

* new app icon

* timing window values are actually double now

* improve deferred timekeep even more

* re-generate font atlases

new app icon in credits

* default epilogue images

* more timing window adjustment

* fix timing display when pitched

* use proper terminology here

* new logo on titlescreen

* remove wip from play

update credits

* adjust spacing of play mode panel

* redo button spacing

* can pass title screen with any controller

fix issues with controller auto-search

* button scale fixes

* controller title screen nav

* remove song genre from properties editor

* disable circle cursor when not using touch style

* proper selection graphic

remove refs
re-add heart to the opening

* controller support in opening

---------

Co-authored-by: ev <85412919+evdial@users.noreply.github.com>
Co-authored-by: minenice55 <star.elementa@gmail.com>
Co-authored-by: ThatZeoMan <67521686+ThatZeoMan@users.noreply.github.com>
This commit is contained in:
Rapandrasmus
2023-12-26 06:22:51 +01:00
committed by GitHub
parent 8d8c275e66
commit 98835c3936
1314 changed files with 194146 additions and 11622 deletions

View File

@ -49,6 +49,7 @@ namespace HeavenStudio
double absTime, absTimeAdjust;
double dspSizeSeconds;
double dspMargin = 128 / 44100.0;
bool deferTimeKeeping = false;
// the dspTime we started at
private double dspStart;
@ -85,6 +86,7 @@ namespace HeavenStudio
private float timelinePitch = 1f;
private float minigamePitch = 1f;
public float SongPitch { get => isPaused ? 0f : (timelinePitch * minigamePitch); }
public float TimelinePitch { get => timelinePitch; }
private float musicScheduledPitch = 1f;
private double musicScheduledTime = 0;
@ -94,6 +96,7 @@ namespace HeavenStudio
public void SetTimelinePitch(float pitch)
{
if (isPaused) return;
if (pitch != 0 && pitch * minigamePitch != SongPitch)
{
Debug.Log("added pitch change " + pitch * minigamePitch + " at" + absTime);
@ -119,7 +122,7 @@ namespace HeavenStudio
public void SetMinigamePitch(float pitch, double beat)
{
BeatAction.New( this,
BeatAction.New(this,
new List<BeatAction.Action> {
new BeatAction.Action(beat, delegate {
SetMinigamePitch(pitch);
@ -164,7 +167,11 @@ namespace HeavenStudio
{
if (isPlaying) return;
if (!isPaused)
if (isPaused)
{
Util.SoundByte.UnpauseOneShots();
}
else
{
AudioConfiguration config = AudioSettings.GetConfiguration();
dspSizeSeconds = config.dspBufferSize / (double)config.sampleRate;
@ -176,7 +183,7 @@ namespace HeavenStudio
SetMinigameVolume(1f);
}
var chart = GameManager.instance.Beatmap;
RiqBeatmap chart = GameManager.instance.Beatmap;
double offset = chart.data.offset;
double dspTime = AudioSettings.dspTime;
@ -190,56 +197,78 @@ namespace HeavenStudio
double musicStartDelay = -offset - startPos;
if (musicStartDelay > 0)
{
musicScheduledTime = dspTime + musicStartDelay / SongPitch;
dspStart = dspTime;
musicScheduledTime = dspTime + (musicStartDelay / SongPitch) + 2*dspSizeSeconds;
dspStart = dspTime + 2*dspSizeSeconds;
}
else
{
musicScheduledTime = dspTime + dspMargin;
dspStart = dspTime + dspMargin;
musicScheduledTime = dspTime + 2*dspSizeSeconds;
dspStart = dspTime + 2*dspSizeSeconds;
}
musicScheduledPitch = SongPitch;
musicSource.PlayScheduled(musicScheduledTime);
Debug.Log($"playback scheduled for dsptime {dspStart}");
}
if (musicSource.clip == null)
{
dspStart = dspTime;
}
songPosBeat = GetBeatFromSongPos(time);
songPosBeat = beat;
startBeat = songPosBeat;
_metronomeTally = 0;
startTime = DateTime.Now;
absTimeAdjust = 0;
deferTimeKeeping = (musicSource.clip != null);
isPlaying = true;
isPaused = false;
}
void OnAudioFilterRead(float[] data, int channels)
{
if (!deferTimeKeeping) return;
// don't actually do anything with the data
// wait until we get a dsp update before starting to keep time
double dsp = AudioSettings.dspTime;
if (dsp >= dspStart - dspSizeSeconds)
{
deferTimeKeeping = false;
Debug.Log($"dsptime: {dsp}, deferred timekeeping for {DateTime.Now - startTime} seconds (delta dsp {dsp - dspStart})");
startTime += TimeSpan.FromSeconds(dsp - dspStart);
absTimeAdjust = 0;
dspStart = dsp;
}
}
public void Pause()
{
if (!isPlaying) return;
isPlaying = false;
isPaused = true;
deferTimeKeeping = false;
musicSource.Pause();
musicSource.Stop();
Util.SoundByte.PauseOneShots();
}
public void Stop(double time)
public void Stop(double beat)
{
if (absTimeAdjust != 0)
{
Debug.Log($"Last playthrough had a dsp (audio) drift of {absTimeAdjust}.\nConsider increasing audio buffer size if audio distortion was present.");
}
this.time = time;
songPosBeat = beat;
time = GetSongPosFromBeat(beat);
songPos = time;
songPosBeat = 0;
absTimeAdjust = 0;
isPlaying = false;
isPaused = false;
deferTimeKeeping = false;
musicSource.Stop();
}
@ -343,7 +372,8 @@ namespace HeavenStudio
{
if (isPlaying)
{
if (AudioSettings.dspTime < musicScheduledTime && musicScheduledPitch != SongPitch)
double dsp = AudioSettings.dspTime;
if (dsp < musicScheduledTime && musicScheduledPitch != SongPitch)
{
if (SongPitch == 0f)
{
@ -355,30 +385,33 @@ namespace HeavenStudio
musicSource.UnPause();
musicScheduledPitch = SongPitch;
musicScheduledTime = (AudioSettings.dspTime + (-GameManager.instance.Beatmap.data.offset - songPositionAsDouble) / (double)SongPitch);
musicScheduledTime = (dsp + (-GameManager.instance.Beatmap.data.offset - songPositionAsDouble) / (double)SongPitch);
musicSource.SetScheduledStartTime(musicScheduledTime);
}
}
absTime = (DateTime.Now - startTime).TotalSeconds;
//dspTime to sync with audio thread in case of drift
dspTime = AudioSettings.dspTime - dspStart;
if (Math.Abs(absTime + absTimeAdjust - dspTime) > dspMargin)
if (!deferTimeKeeping)
{
int i = 0;
while (Math.Abs(absTime + absTimeAdjust - dspTime) > dspMargin)
absTime = (DateTime.Now - startTime).TotalSeconds;
//dspTime to sync with audio thread in case of drift
dspTime = dsp - dspStart;
if (Math.Abs(absTime + absTimeAdjust - dspTime) > dspMargin)
{
i++;
absTimeAdjust = (dspTime - absTime + absTimeAdjust) * 0.5;
if (i > 8) break;
int i = 0;
while (Math.Abs(absTime + absTimeAdjust - dspTime) > dspMargin)
{
i++;
absTimeAdjust = (dspTime - absTime + absTimeAdjust) * 0.5;
if (i > 8) break;
}
}
time = MapTimeToPitchChanges(absTime + absTimeAdjust);
songPos = startPos + time;
songPosBeat = GetBeatFromSongPos(songPos);
}
time = MapTimeToPitchChanges(absTime + absTimeAdjust);
songPos = startPos + time;
songPosBeat = GetBeatFromSongPos(songPos);
}
}
@ -439,44 +472,41 @@ namespace HeavenStudio
return result;
}
public float GetLoopPositionFromBeat(float beatOffset, float length)
public float GetLoopPositionFromBeat(float beatOffset, float length, bool beatClamp = true)
{
return Mathf.Repeat((songPositionInBeats / length) + beatOffset, 1);
float beat = songPositionInBeats;
if (beatClamp)
{
beat = Mathf.Max(beat, 0);
}
return Mathf.Repeat((beat / length) + beatOffset, 1);
}
public float GetPositionFromBeat(double startBeat, double length)
public float GetPositionFromBeat(double startBeat, double length, bool beatClamp = true)
{
float a = Mathp.Normalize(songPositionInBeats, (float)startBeat, (float)(startBeat + length));
float beat = songPositionInBeats;
if (beatClamp)
{
beat = Mathf.Max(beat, 0);
}
float a = Mathp.Normalize(beat, (float)startBeat, (float)(startBeat + length));
return a;
}
public float GetBeatFromPosition(float position, float startBeat, float length)
{
return Mathp.DeNormalize(position, (float)startBeat, (float)(startBeat + length));
}
public float GetPositionFromMargin(float targetBeat, float margin)
{
return GetPositionFromBeat(targetBeat - margin, margin);
}
public float GetBeatFromPositionAndMargin(float position, float targetBeat, float margin)
{
return GetBeatFromPosition(position, targetBeat - margin, margin);
}
private List<RiqEntity> GetSortedTempoChanges()
{
GameManager.instance.SortEventsList();
return GameManager.instance.Beatmap.TempoChanges;
}
public float GetBpmAtBeat(double beat)
public float GetBpmAtBeat(double beat, out float swingRatio)
{
swingRatio = 0.5f;
var chart = GameManager.instance.Beatmap;
if (chart.TempoChanges.Count == 0)
return 120f;
float bpm = chart.TempoChanges[0]["tempo"];
swingRatio = chart.TempoChanges[0]["swing"] + 0.5f;
foreach (RiqEntity t in chart.TempoChanges)
{
@ -485,11 +515,42 @@ namespace HeavenStudio
break;
}
bpm = t["tempo"];
swingRatio = t["swing"] + 0.5f;
}
return bpm;
}
public float GetBpmAtBeat(double beat)
{
return GetBpmAtBeat(beat, out _);
}
public float GetSwingRatioAtBeat(double beat)
{
float swingRatio;
GetBpmAtBeat(beat, out swingRatio);
return swingRatio;
}
public double GetSwungBeat(double beat, float ratio)
{
return beat + GetSwingOffset(beat, ratio);
}
public double GetSwingOffset(double beatFrac, float ratio)
{
beatFrac %= 1;
if (beatFrac <= 0.5)
{
return 0.5 / ratio * beatFrac;
}
else
{
return 0.5 + (0.5 / (1f - ratio) * (beatFrac - ratio));
}
}
public double GetSongPosFromBeat(double beat)
{
var chart = GameManager.instance.Beatmap;