Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 13 additions & 31 deletions source/funkin/Conductor.hx
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,6 @@ class Conductor
*/
var songPositionDelta(default, null):Float = 0;

var prevTimestamp:Float = 0;
var prevTime:Float = 0;

/**
* Beats per minute of the current song at the current time.
*/
Expand Down Expand Up @@ -421,16 +418,7 @@ class Conductor
*/
public function update(?songPos:Float, applyOffsets:Bool = true, forceDispatch:Bool = false):Void
{
var currentTime:Float = (FlxG.sound.music != null) ? FlxG.sound.music.time : 0.0;
var currentLength:Float = (FlxG.sound.music != null) ? FlxG.sound.music.length : 0.0;

if (songPos == null)
{
songPos = currentTime;
}

// Take into account instrumental and file format song offsets.
songPos += applyOffsets ? (combinedOffset) : 0;
if (songPos == null) songPos = (FlxG.sound.music != null) ? FlxG.sound.music.time : 0.0;

var oldMeasure:Float = this.currentMeasure;
var oldBeat:Float = this.currentBeat;
Expand All @@ -439,11 +427,16 @@ class Conductor
// If the song is playing, limit the song position to the length of the song or beginning of the song.
if (FlxG.sound.music != null && FlxG.sound.music.playing)
{
this.songPosition = Math.min(this.combinedOffset, 0).clamp(songPos, currentLength);
this.songPositionDelta += FlxG.elapsed * 1000 * FlxG.sound.music.pitch;
// Take into account instrumental and file format song offsets.
songPos += applyOffsets ? (combinedOffset * FlxG.sound.music.pitch) : 0;

this.songPosition = Math.min(this.combinedOffset, 0).clamp(songPos, FlxG.sound.music.length);
}
else
{
// Take into account instrumental and file format song offsets.
songPos += applyOffsets ? (combinedOffset) : 0;

this.songPosition = songPos;
}

Expand Down Expand Up @@ -502,17 +495,6 @@ class Conductor
this.onMeasureHit.dispatch();
}

// only update the timestamp if songPosition actually changed
// which it doesn't do every frame!
if (prevTime != this.songPosition)
{
this.songPositionDelta = 0;

// Update the timestamp for use in-between frames
prevTime = this.songPosition;
prevTimestamp = Std.int(Timer.stamp() * 1000);
}

if (this == Conductor.instance) @:privateAccess SongSequence.update.dispatch();
}

Expand All @@ -522,7 +504,7 @@ class Conductor
*/
public function getTimeWithDelta():Float
{
return this.songPosition + this.songPositionDelta;
return this.songPosition;
}

/**
Expand All @@ -536,10 +518,10 @@ class Conductor
public function getTimeWithDiff(?soundToCheck:FlxSound):Float
{
if (soundToCheck == null) soundToCheck = FlxG.sound.music;

@:privateAccess
this.songPosition = soundToCheck._channel.position;
return this.songPosition;
return soundToCheck.getActualTime();
//@:privateAccess
//this.songPosition = soundToCheck.getActualTime();
//return this.songPosition;
}

/**
Expand Down
85 changes: 3 additions & 82 deletions source/funkin/FunkinMemory.hx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ class FunkinMemory
static var currentCachedTextures:Map<String, FlxGraphic> = [];
static var previousCachedTextures:Map<String, FlxGraphic> = [];

static var permanentCachedSounds:Map<String, Sound> = [];
static var currentCachedSounds:Map<String, Sound> = [];
static var previousCachedSounds:Map<String, Sound> = [];

static var purgeFilter:Array<String> = ["/week", "/characters", "/charSelect", "/results"];

/**
Expand Down Expand Up @@ -102,8 +98,6 @@ class FunkinMemory
{
preparePurgeTextureCache();
purgeTextureCache();
preparePurgeSoundCache();
purgeSoundCache();
#if (cpp || neko || hl)
if (callGarbageCollector) funkin.util.MemoryUtil.collect(true);
#end
Expand Down Expand Up @@ -331,21 +325,7 @@ class FunkinMemory
*/
public static function cacheSound(key:String):Void
{
if (currentCachedSounds.exists(key)) return;

if (previousCachedSounds.exists(key))
{
// Move the texture from the previous cache to the current cache.
var sound:Null<Sound> = previousCachedSounds.get(key);
previousCachedSounds.remove(key);
if (sound != null) currentCachedSounds.set(key, sound);
return;
}

var sound:Null<Sound> = Assets.getSound(key, true);
if (sound == null) return;
else
currentCachedSounds.set(key, sound);
flixel.sound.FlxSoundData.fromAssetKey(key);
}

/**
Expand All @@ -354,64 +334,8 @@ class FunkinMemory
*/
public static function permanentCacheSound(key:String):Void
{
if (permanentCachedSounds.exists(key)) return;

var sound:Null<Sound> = Assets.getSound(key, true);
if (sound == null) return;
else
permanentCachedSounds.set(key, sound);

if (sound != null) currentCachedSounds.set(key, sound);
}

/**
* Prepares the cache for purging unused sounds.
*/
public static function preparePurgeSoundCache():Void
{
previousCachedSounds = currentCachedSounds.copy();

for (key in previousCachedSounds.keys())
{
if (permanentCachedSounds.exists(key))
{
previousCachedSounds.remove(key);
}
}

currentCachedSounds = permanentCachedSounds.copy();
}

/**
* Purges unused sounds from the cache.
*/
public static inline function purgeSoundCache():Void
{
for (key in previousCachedSounds.keys())
{
if (permanentCachedSounds.exists(key))
{
previousCachedSounds.remove(key);
continue;
}

var sound:Null<Sound> = previousCachedSounds.get(key);
if (sound != null)
{
Assets.cache.removeSound(key);
previousCachedSounds.remove(key);
}
}
Assets.cache.clear("songs");
Assets.cache.clear("music");
// Felt lazy.
var key = Paths.music("freakyMenu/freakyMenu");
var sound:Null<Sound> = Assets.getSound(key, true);
if (sound != null)
{
permanentCachedSounds.set(key, sound);
currentCachedSounds.set(key, sound);
}
var soundData = flixel.sound.FlxSoundData.fromAssetKey(key);
if (soundData != null) soundData.persist = true;
}

///// MISC /////
Expand Down Expand Up @@ -445,9 +369,6 @@ class FunkinMemory
if (currentCachedTextures.exists(key)) currentCachedTextures.remove(key);
Assets.cache.clear(key);
}

preparePurgeSoundCache();
purgeSoundCache();
}

/**
Expand Down
86 changes: 64 additions & 22 deletions source/funkin/Paths.hx
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,23 @@ class Paths implements ConsoleClass
return parts[0];
}

static function getPath(file:String, type:AssetType, library:Null<String>):String
public static function fixPathExtension(path:String, defaultExtension:String):String
{
return if (path.lastIndexOf(".") == -1) '${path}.$defaultExtension'; else path;
}

public static function normalizePath(path:String, ?defaultExtension:String):String
{
return if (defaultExtension == null) Path.normalize(path); else fixPathExtension(Path.normalize(path), defaultExtension);
}

public static function getPath(file:String, type:AssetType, ?library:String):String
{
if (library != null) return getLibraryPath(file, library);

if (currentLevel != null)
{
var levelPath:String = getLibraryPathForce(file, currentLevel);
var levelPath:String = getLibraryPath(file, currentLevel);
if (Assets.exists(levelPath, type)) return levelPath;
}

Expand Down Expand Up @@ -84,47 +94,74 @@ class Paths implements ConsoleClass

public static function txt(key:String, ?library:String):String
{
return getPath('data/$key.txt', TEXT, library);
return getPath(normalizePath('data/$key', 'txt'), TEXT, library);
}

public static function frag(key:String, ?library:String):String
{
return getPath('shaders/$key.frag', TEXT, library);
return getPath(normalizePath('shaders/$key', 'frag'), TEXT, library);
}

public static function vert(key:String, ?library:String):String
{
return getPath('shaders/$key.vert', TEXT, library);
return getPath(normalizePath('shaders/$key', 'vert'), TEXT, library);
}

public static function xml(key:String, ?library:String):String
{
return getPath('data/$key.xml', TEXT, library);
return getPath(normalizePath('data/$key', 'xml'), TEXT, library);
}

public static function json(key:String, ?library:String):String
{
return getPath('data/$key.json', TEXT, library);
return getPath(normalizePath('data/$key', 'json'), TEXT, library);
}

public static function srt(key:String, ?library:String, ?directory:String = "data/"):String
public static function srt(key:String, ?library:String, ?directory:String = "data"):String
{
return getPath('$directory$key.srt', TEXT, library);
return getPath(normalizePath('${directory}/$key', 'srt'), TEXT, library);
}

public static function sound(key:String, ?library:String):String
public static function sound(key:String, ?library:String, ?directory:String = 'sounds', ?extension:String):String
{
return getPath('sounds/$key.${Constants.EXT_SOUND}', SOUND, library);
var normalizedPath = Path.normalize((directory == '' ? '' : directory + '/') + key);
if (extension != null) return getPath(fixPathExtension(normalizedPath, extension), SOUND, library);

// Attempt to find the sound by looping through the supported file formats.
var path:String;
for (extension in Constants.EXT_SOUNDS)
{
// no need to check if its exists in MUSIC type, as Openfl/Lime AssetLibrary have the same returns for SOUND and MUSIC internally.
if (library != null)
{
path = getLibraryPath(fixPathExtension(normalizedPath, extension), library);
if (Assets.exists(path, SOUND)/* || Assets.exists(path, MUSIC)*/) return path;
}
else
{
if (currentLevel != null)
{
path = getLibraryPath(fixPathExtension(normalizedPath, extension), currentLevel);
if (Assets.exists(path, SOUND)/* || Assets.exists(path, MUSIC)*/) return path;
}

path = getLibraryPathForce(fixPathExtension(normalizedPath, extension), 'shared');
if (Assets.exists(path, SOUND)/* || Assets.exists(path, MUSIC)*/) return path;
}
}

if (library != null) return getLibraryPath(fixPathExtension(normalizedPath, Constants.EXT_SOUND), library);
else return getPreloadPath(fixPathExtension(normalizedPath, Constants.EXT_SOUND));
}

public static function soundRandom(key:String, min:Int, max:Int, ?library:String):String
public static function soundRandom(key:String, min:Int, max:Int, ?library:String, ?extension:String):String
{
return sound(key + FlxG.random.int(min, max), library);
return sound(key + FlxG.random.int(min, max), library, null, extension);
}

public static function music(key:String, ?library:String):String
public static function music(key:String, ?library:String, ?extension:String):String
{
return getPath('music/$key.${Constants.EXT_SOUND}', MUSIC, library);
return sound(key, library, 'music', extension);
}

public static function videos(key:String, ?library:String):String
Expand All @@ -139,24 +176,29 @@ class Paths implements ConsoleClass
return getPath('videos/$key.${Constants.EXT_VIDEO}', BINARY, library ?? 'videos');
}

public static function voices(song:String, ?suffix:String = ''):String
public static function song(key:String, ?extension:String):String
{
if (suffix == null) suffix = ''; // no suffix, for a sorta backwards compatibility with older-ish voice files
// For web platform that haven't loaded the library "songs" yet.
if (Assets.getLibrary("songs") != null) return sound(key, 'songs', '', extension);
else return getLibraryPathForce(normalizePath(key, extension ?? Constants.EXT_SOUND), 'songs');
}

return 'songs:assets/songs/${song.toLowerCase()}/Voices$suffix.${Constants.EXT_SOUND}';
public static function voices(song:String, ?suffix:String = '', ?extension:String):String
{
if (suffix == null) suffix = ''; // no suffix, for a sorta backwards compatibility with older-ish voice files
return Paths.song('${song.toLowerCase()}/Voices$suffix', extension);
}

/**
* Gets the path to an `Inst.mp3/ogg` song instrumental from songs:assets/songs/`song`/
* @param song name of the song to get instrumental for
* @param suffix any suffix to add to end of song name, used for `-erect` variants usually
* @param withExtension if it should return with the audio file extension `.mp3` or `.ogg`.
* @param extension The audio file extension of the track. If empty, it'll attempt to find a supported audio file format.
* @return String
*/
public static function inst(song:String, ?suffix:String = '', withExtension:Bool = true):String
public static function inst(song:String, ?suffix:String = '', ?extension:String):String
{
var ext:String = withExtension ? '.${Constants.EXT_SOUND}' : '';
return 'songs:assets/songs/${song.toLowerCase()}/Inst$suffix$ext';
return Paths.song('${song.toLowerCase()}/Inst$suffix', extension);
}

public static function image(key:String, ?library:String):String
Expand Down
Loading
Loading