Merge branch 'master' into kade-github/new-offsets

This commit is contained in:
kade-github
2025-06-28 13:55:32 -07:00
21 changed files with 666 additions and 79 deletions
+3 -10
View File
@@ -55,13 +55,6 @@
"ref": "b9118f47f43a66bc0e5fbfcfd9903f0425e918ee",
"url": "https://github.com/FunkinCrew/flixel-addons"
},
{
"name": "flixel-text-input",
"type": "git",
"dir": null,
"ref": "951a0103a17bfa55eed86703ce50b4fb0d7590bc",
"url": "https://github.com/FunkinCrew/flixel-text-input"
},
{
"name": "flxanimate",
"type": "git",
@@ -97,14 +90,14 @@
"name": "haxeui-core",
"type": "git",
"dir": null,
"ref": "07fc7aa8098deaea633b0726d01f83eb4ef8a832",
"ref": "47ee9f5fa02d422e186e844f87e68220cabfcc5b",
"url": "https://github.com/haxeui/haxeui-core"
},
{
"name": "haxeui-flixel",
"type": "git",
"dir": null,
"ref": "b899a4c7d7318c5ff2b1bb645fbc73728fad1ac9",
"ref": "100f2c96beab619cfe72c567a058c41c71e3e998",
"url": "https://github.com/haxeui/haxeui-flixel"
},
{
@@ -177,7 +170,7 @@
"name": "lime",
"type": "git",
"dir": null,
"ref": "71c0f93e91c10975426d7518b826c1584a4f4b73",
"ref": "045ede0363120ff0425529a4902e4da44fd6d293",
"url": "https://github.com/FunkinCrew/lime-mobile"
},
{
-1
View File
@@ -1036,7 +1036,6 @@ class Project extends HXProject
// addHaxelib('flixel-ui'); // UI framework (DEPRECATED)
addHaxelib('haxeui-core'); // UI framework
addHaxelib('haxeui-flixel'); // Integrate HaxeUI with Flixel
addHaxelib('flixel-text-input'); // Improved text field rendering for HaxeUI
addHaxelib('polymod'); // Modding framework
addHaxelib('flxanimate'); // Texture atlas rendering
@@ -31,7 +31,6 @@ class PreciseInputHandler
static function handleHintDown(hint:FunkinHint):Void
{
final timestamp:Int64 = PreciseInputManager.getCurrentTimestamp();
@:privateAccess
if (hint.input?.justPressed ?? false)
{
@@ -48,7 +47,6 @@ class PreciseInputHandler
static function handleHintUp(hint:FunkinHint):Void
{
final timestamp:Int64 = PreciseInputManager.getCurrentTimestamp();
@:privateAccess
if (hint.input?.justReleased ?? false)
{
@@ -290,6 +290,7 @@ class ControlsSchemeMenu extends MusicBeatSubState
});
}
#if FEATURE_TOUCH_CONTROLS
/**
* Handles touch dragging.
*/
@@ -344,7 +345,7 @@ class ControlsSchemeMenu extends MusicBeatSubState
if (TouchUtil.pressed && dragDistance != 0)
{
final showcasesTargetX:Float = originX + dragDistance * 10;
hitboxShowcases.x = MathUtil.smoothLerp(hitboxShowcases.x, showcasesTargetX, elapsed, 0.5);
hitboxShowcases.x = MathUtil.smoothLerpPrecision(hitboxShowcases.x, showcasesTargetX, elapsed, 0.5);
final minShowcasesX:Float = -1500 * availableSchemes.length;
hitboxShowcases.x = FlxMath.bound(hitboxShowcases.x, minShowcasesX, 400);
@@ -355,7 +356,8 @@ class ControlsSchemeMenu extends MusicBeatSubState
}
else
{
hitboxShowcases.x = MathUtil.smoothLerp(hitboxShowcases.x, (-1500 * currentIndex) + (-1500 / (availableSchemes.length + 1) * currentIndex), elapsed, 0.5);
hitboxShowcases.x = MathUtil.smoothLerpPrecision(hitboxShowcases.x, (-1500 * currentIndex) + (-1500 / (availableSchemes.length + 1) * currentIndex), elapsed, 0.5);
}
#end
}
}
@@ -110,7 +110,7 @@ class HitboxShowcase extends FlxSpriteGroup
{
super.update(elapsed);
alpha = MathUtil.smoothLerp(alpha, HITBOX_SHOWCASE_ALPHA[selected ? 1 : 0], elapsed, 0.2);
alpha = MathUtil.smoothLerpPrecision(alpha, HITBOX_SHOWCASE_ALPHA[selected ? 1 : 0], elapsed, 0.2);
}
function get_selected():Bool
+2
View File
@@ -630,6 +630,7 @@ class PauseSubState extends MusicBeatSubState
changeSelection(1);
}
#if FEATURE_TOUCH_CONTROLS
if (!SwipeUtil.justSwipedAny && !justOpened && currentMenuEntries.length > 0)
{
for (i in 0...menuEntryText.members.length)
@@ -649,6 +650,7 @@ class PauseSubState extends MusicBeatSubState
break;
}
}
#end
if (controls.ACCEPT && currentMenuEntries.length > 0)
{
+11 -1
View File
@@ -620,6 +620,12 @@ class PlayState extends MusicBeatSubState
return FlxG?.sound?.music?.length;
}
/**
* The threshold for resyncing the song.
* If the vocals deviate from the instrumental by more than this amount, then `resyncVocals()` will be called.
*/
static final RESYNC_THRESHOLD:Float = 30;
// TODO: Refactor or document
var generatedMusic:Bool = false;
@@ -1690,7 +1696,9 @@ class PlayState extends MusicBeatSubState
}
if (!startingSong
&& (Math.abs(FlxG.sound.music.time - correctSync) > 30 || Math.abs(playerVoicesError) > 30 || Math.abs(opponentVoicesError) > 30))
&& (Math.abs(FlxG.sound.music.time - correctSync) > RESYNC_THRESHOLD
|| Math.abs(playerVoicesError) > RESYNC_THRESHOLD
|| Math.abs(opponentVoicesError) > RESYNC_THRESHOLD))
{
trace("VOCALS NEED RESYNC");
if (vocals != null)
@@ -2368,6 +2376,8 @@ class PlayState extends MusicBeatSubState
#if FEATURE_NEWGROUNDS
Events.logStartSong(currentSong.id, currentVariation);
#end
resyncVocals();
}
/**
-1
View File
@@ -199,7 +199,6 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
if (includeScript && SongRegistry.instance.isScriptedEntry(songId))
{
var songClassName:Null<String> = SongRegistry.instance.getScriptedEntryClassName(songId);
@:privateAccess
if (songClassName != null) result = SongRegistry.instance.createScriptedEntry(songClassName);
}
@@ -785,12 +785,14 @@ class CharSelectSubState extends MusicBeatSubState
mobileAccept = false;
if (controls.UI_UP_R || controls.UI_DOWN_R || controls.UI_LEFT_R || controls.UI_RIGHT_R || TouchUtil.justReleased) selectSound.pitch = 1;
if (controls.UI_UP_R || controls.UI_DOWN_R || controls.UI_LEFT_R || controls.UI_RIGHT_R #if FEATURE_TOUCH_CONTROLS || TouchUtil.justReleased #end)
selectSound.pitch = 1;
syncAudio(elapsed);
if (allowInput && !pressedSelect)
{
#if FEATURE_TOUCH_CONTROLS
if (TouchUtil.pressed || TouchUtil.justReleased)
{
for (i => hitbox in grpHitboxes.members)
@@ -821,6 +823,7 @@ class CharSelectSubState extends MusicBeatSubState
{
mobileAccept = true;
}
#end
//
if (controls.UI_UP) holdTmrUp += elapsed;
@@ -912,7 +915,7 @@ class CharSelectSubState extends MusicBeatSubState
{
curChar = availableChars.get(getCurrentSelected());
if (allowInput && pressedSelect && (controls.BACK || (mobileDeny && TouchUtil.justReleased)))
if (allowInput && pressedSelect && (controls.BACK #if FEATURE_TOUCH_CONTROLS || (mobileDeny && TouchUtil.justReleased) #end))
{
mobileDeny = false;
cursorConfirmed.visible = false;
@@ -968,7 +971,9 @@ class CharSelectSubState extends MusicBeatSubState
goToFreeplay();
});
}
#if FEATURE_TOUCH_CONTROLS
else if (pressedSelect && TouchUtil.justReleased) mobileDeny = true;
#end
mobileAccept = false;
}
+115 -29
View File
@@ -7,6 +7,8 @@ import flixel.FlxSprite;
import funkin.ui.mainmenu.MainMenuState;
import flixel.group.FlxSpriteGroup;
import funkin.util.TouchUtil;
import funkin.ui.credits.CreditsData.CreditsDataRole;
import funkin.ui.credits.CreditsData.CreditsDataMember;
/**
* The state used to display the credits scroll.
@@ -77,6 +79,9 @@ class CreditsState extends MusicBeatState
var scrollPaused:Bool = false;
var backersToBuild:Array<String>;
var entriesToBuild:Array<CreditsEntry>;
public function new()
{
super();
@@ -86,6 +91,22 @@ class CreditsState extends MusicBeatState
{
super.create();
backersToBuild = CreditsDataHandler.fetchBackerEntries();
entriesToBuild = [];
for (entry in CreditsDataHandler.CREDITS_DATA.entries)
{
entriesToBuild.push(
{
data: entry,
lineIndexToBuild: 0,
backerIndexToBuild: 0,
hasBuiltHeader: (entry.header == null),
hasBuiltBody: (entry.body.length == 0),
hasBuiltBackers: (!entry.appendBackers || backersToBuild.length == 0)
});
}
// Background
var bg = new FlxSprite(Paths.image('menuDesat'));
bg.scrollFactor.x = 0;
@@ -105,7 +126,7 @@ class CreditsState extends MusicBeatState
creditsGroup.x = Math.max(funkin.ui.FullScreenScaleMode.gameNotchSize.x, SCREEN_PAD);
creditsGroup.y = STARTING_HEIGHT;
buildCreditsGroup();
// buildCreditsGroup();
add(creditsGroup);
@@ -124,39 +145,44 @@ class CreditsState extends MusicBeatState
#end
}
function buildCreditsGroup():Void
var creditsLineY:Float = 0;
function buildCreditsEntryLine(entry:CreditsEntry):Void
{
var y:Float = 0;
for (entry in CreditsDataHandler.CREDITS_DATA.entries)
if (!entry.hasBuiltHeader)
{
if (entry.header != null)
{
var header = buildCreditsLine(entry.header, y, true, CreditsSide.Left);
header.bold = true;
creditsGroup.add(header);
y += CREDITS_HEADER_FONT_SIZE + (header.textField.numLines * CREDITS_HEADER_FONT_SIZE);
}
var header:FlxText = buildCreditsLine(entry.data.header, creditsLineY, true, CreditsSide.Left);
creditsLineY += CREDITS_HEADER_FONT_SIZE + (header.textField.numLines * CREDITS_HEADER_FONT_SIZE);
entry.hasBuiltHeader = true;
return;
}
for (line in entry?.body ?? [])
{
var entry = buildCreditsLine(line.line, y, false, CreditsSide.Left);
creditsGroup.add(entry);
y += CREDITS_FONT_SIZE * entry.textField.numLines;
}
if (!entry.hasBuiltBody)
{
var lineData:CreditsDataMember = entry.data.body[entry.lineIndexToBuild];
var line:FlxText = buildCreditsLine(lineData.line, creditsLineY, false, CreditsSide.Left);
creditsLineY += CREDITS_FONT_SIZE * line.textField.numLines;
entry.lineIndexToBuild++;
if (entry.appendBackers)
if (entry.lineIndexToBuild >= entry.data.body.length)
{
var backers = CreditsDataHandler.fetchBackerEntries();
for (backer in backers)
{
creditsGroup.add(buildCreditsLine(backer, y, false, CreditsSide.Left));
y += CREDITS_FONT_SIZE;
}
entry.hasBuiltBody = true;
}
return;
}
// Padding between each role.
y += CREDITS_FONT_SIZE * 2.5;
if (!entry.hasBuiltBackers)
{
var backer:String = backersToBuild[entry.backerIndexToBuild];
creditsGroup.add(buildCreditsLine(backer, creditsLineY, false, CreditsSide.Left));
creditsLineY += CREDITS_FONT_SIZE;
entry.backerIndexToBuild++;
if (entry.backerIndexToBuild >= backersToBuild.length)
{
entry.hasBuiltBackers = true;
}
return;
}
}
@@ -169,16 +195,66 @@ class CreditsState extends MusicBeatState
var width = (side == CreditsSide.Center) ? FULL_WIDTH : (FULL_WIDTH / 2);
var size = header ? CREDITS_HEADER_FONT_SIZE : CREDITS_FONT_SIZE;
var creditsLine:FlxText = new FlxText(xPos, yPos, width, text);
// using a cast since creditsGroup is FlxSpriteGroup
// we could also do FlxTypedSpriteGroup<FlxText>
var creditsLine:FlxText = cast(creditsGroup.recycle(() -> new FlxText()), FlxText);
creditsLine.x = xPos + creditsGroup.x;
creditsLine.y = yPos + creditsGroup.y;
creditsLine.fieldWidth = width;
creditsLine.text = text;
creditsLine.bold = header;
creditsLine.setFormat(CREDITS_FONT, size, CREDITS_FONT_COLOR, FlxTextAlign.LEFT, FlxTextBorderStyle.OUTLINE, CREDITS_FONT_STROKE_COLOR, true);
return creditsLine;
}
function killOffScreenLines():Void
{
creditsGroup.forEachExists(function(creditsLine:FlxSprite) {
if (creditsLine.y + creditsLine.height <= 0)
{
creditsLine.kill();
trace("killed line");
}
});
}
function buildNextLine():Void
{
// no more entriesToBuild
if (entriesToBuild.length == 0)
{
return;
}
// line is off-screen
if (creditsGroup.y + creditsLineY >= FlxG.height)
{
return;
}
var entry:CreditsEntry = entriesToBuild[0];
buildCreditsEntryLine(entry);
// check if everything has been built
if (!entry.hasBuiltHeader || !entry.hasBuiltBody || !entry.hasBuiltBackers)
{
return;
}
entriesToBuild.shift();
// offset that each entry has
creditsLineY += CREDITS_FONT_SIZE * 2.5;
}
public override function update(elapsed:Float):Void
{
super.update(elapsed);
killOffScreenLines();
buildNextLine();
if (!scrollPaused)
{
// TODO: Replace with whatever the special note button is.
@@ -206,7 +282,7 @@ class CreditsState extends MusicBeatState
function hasEnded():Bool
{
return creditsGroup.y < -creditsGroup.height;
return creditsGroup.getFirstExisting() == null && entriesToBuild.length == 0;
}
function exit():Void
@@ -226,3 +302,13 @@ enum CreditsSide
Center;
Right;
}
typedef CreditsEntry =
{
var data:CreditsDataRole;
var lineIndexToBuild:Int;
var backerIndexToBuild:Int;
var hasBuiltHeader:Bool;
var hasBuiltBody:Bool;
var hasBuiltBackers:Bool;
}
@@ -118,7 +118,7 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox
if (valid)
{
chartEditorState.currentSongNoteStyle = event.data.id;
chartEditorState.currentSongNoteStyle = event.data.id;
}
};
var startingValueNoteStyle = ChartEditorDropdowns.populateDropdownWithNoteStyles(inputNoteStyle, chartEditorState.currentSongMetadata.playData.noteStyle);
@@ -0,0 +1,500 @@
package funkin.ui.debug.latency;
import funkin.data.notestyle.NoteStyleRegistry;
import flixel.FlxSprite;
import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.math.FlxMath;
import funkin.ui.MusicBeatSubState;
import flixel.sound.FlxSound;
import flixel.text.FlxText;
import flixel.util.FlxColor;
import funkin.input.PreciseInputManager;
import funkin.play.notes.Strumline;
import funkin.data.song.SongData.SongNoteData;
#if mobile
import funkin.util.TouchUtil;
import funkin.mobile.ui.FunkinHitbox;
import funkin.play.notes.NoteDirection;
import funkin.graphics.FunkinSprite;
#end
import haxe.Timer;
import flixel.FlxCamera;
class LatencyState extends MusicBeatSubState
{
var visualOffsetText:FlxText;
#if mobile
var visualOffsetLeftArrow:FlxText;
var visualOffsetRightArrow:FlxText;
#end
var offsetText:FlxText;
#if mobile
var offsetLeftArrow:FlxText;
var offsetRightArrow:FlxText;
#end
var helpText:FlxText;
var noteGrp:Array<SongNoteData> = [];
var strumLine:Strumline;
var blocks:FlxTypedGroup<FlxSprite>;
var songPosVis:FlxSprite;
var songVisFollowVideo:FlxSprite;
var songVisFollowAudio:FlxSprite;
var beatTrail:FlxSprite;
var diffGrp:FlxTypedGroup<FlxText>;
var offsetsPerBeat:Array<Null<Int>> = [];
var swagSong:HomemadeMusic;
var previousVolume:Float;
var stateCamera:FlxCamera;
/**
* A local conductor instance for this testing class, in-case we are in a PlayState
* because I'm too lazy to set the old variables for conductor stuff !
*/
var localConductor:Conductor;
// stores values of what the previous persistent draw/update stuff was, example if opened
// from pause menu, we want to NOT draw persistently, but then resume drawing once closed
var prevPersistentDraw:Bool;
var prevPersistentUpdate:Bool;
override function create()
{
super.create();
prevPersistentDraw = FlxG.state.persistentDraw;
prevPersistentUpdate = FlxG.state.persistentUpdate;
FlxG.state.persistentDraw = false;
FlxG.state.persistentUpdate = false;
localConductor = new Conductor();
conductorInUse = localConductor;
stateCamera = new FlxCamera(0, 0, FlxG.width, FlxG.height);
stateCamera.bgColor = FlxColor.BLACK;
FlxG.cameras.add(stateCamera);
var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK);
add(bg);
if (FlxG.sound.music != null)
{
previousVolume = FlxG.sound.music.volume;
FlxG.sound.music.volume = 0; // only want to mute the volume, incase we are coming from pause menu
}
else
previousVolume = 1; // defaults to 1 if no music is playing 🤔 also fuck it, emoji in code comment
swagSong = new HomemadeMusic();
swagSong.loadEmbedded(Paths.sound('soundTest'), true);
swagSong.looped = true;
swagSong.play();
FlxG.sound.list.add(swagSong);
PreciseInputManager.instance.onInputPressed.add(preciseInputPressed);
PreciseInputManager.instance.onInputReleased.add(preciseInputReleased);
localConductor.forceBPM(60);
Conductor.instance.forceBPM(60);
diffGrp = new FlxTypedGroup<FlxText>();
add(diffGrp);
for (beat in 0...Math.floor(swagSong.length / (localConductor.stepLengthMs * 2)))
{
var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * (localConductor.stepLengthMs * 2)), FlxG.height - 15);
beatTick.makeGraphic(2, 15);
beatTick.alpha = 0.3;
add(beatTick);
var offsetTxt:FlxText = new FlxText(songPosToX(beat * (localConductor.stepLengthMs * 2)), FlxG.height - 26, 0, "");
offsetTxt.alpha = 0.5;
diffGrp.add(offsetTxt);
offsetsPerBeat.push(null);
}
songVisFollowAudio = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.YELLOW);
add(songVisFollowAudio);
songVisFollowVideo = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.BLUE);
add(songVisFollowVideo);
songPosVis = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.RED);
add(songPosVis);
beatTrail = new FlxSprite(0, songPosVis.y).makeGraphic(2, 20, FlxColor.PURPLE);
beatTrail.alpha = 0.7;
add(beatTrail);
blocks = new FlxTypedGroup<FlxSprite>();
add(blocks);
for (i in 0...8)
{
var block = new FlxSprite(2, ((FlxG.height / 8) + 2) * i).makeGraphic(Std.int(FlxG.height / 8), Std.int((FlxG.height / 8) - 4));
block.alpha = 0.1;
blocks.add(block);
}
var strumlineBG:FlxSprite = new FlxSprite();
add(strumlineBG);
strumLine = new Strumline(NoteStyleRegistry.instance.fetchDefault(), true);
strumLine.conductorInUse = localConductor;
strumLine.screenCenter();
add(strumLine);
strumlineBG.x = strumLine.x;
strumlineBG.makeGraphic(Std.int(strumLine.width), FlxG.height, 0xFFFFFFFF);
strumlineBG.alpha = 0.1;
visualOffsetText = new FlxText();
visualOffsetText.setFormat(Paths.font("vcr.ttf"), 20);
visualOffsetText.x = (FlxG.height / 8) + 10;
visualOffsetText.y = 10;
visualOffsetText.fieldWidth = strumLine.x - visualOffsetText.x - 10;
add(visualOffsetText);
#if mobile
visualOffsetLeftArrow = new FlxText();
visualOffsetLeftArrow.setFormat(Paths.font("vcr.ttf"), 60);
visualOffsetLeftArrow.text = "<";
visualOffsetLeftArrow.x = visualOffsetText.x;
visualOffsetLeftArrow.y = visualOffsetText.y * 4;
add(visualOffsetLeftArrow);
visualOffsetRightArrow = new FlxText();
visualOffsetRightArrow.setFormat(Paths.font("vcr.ttf"), 60);
visualOffsetRightArrow.text = ">";
visualOffsetRightArrow.x = visualOffsetLeftArrow.x * 2;
visualOffsetRightArrow.y = visualOffsetLeftArrow.y;
add(visualOffsetRightArrow);
#end
offsetText = new FlxText();
offsetText.setFormat(Paths.font("vcr.ttf"), 20);
offsetText.x = strumLine.x + strumLine.width + 10;
offsetText.y = 10;
offsetText.fieldWidth = FlxG.width - offsetText.x - 10;
add(offsetText);
#if mobile
offsetLeftArrow = new FlxText();
offsetLeftArrow.setFormat(Paths.font("vcr.ttf"), 60);
offsetLeftArrow.text = "<";
offsetLeftArrow.x = offsetText.x;
offsetLeftArrow.y = offsetText.y * 9;
add(offsetLeftArrow);
offsetRightArrow = new FlxText();
offsetRightArrow.setFormat(Paths.font("vcr.ttf"), 60);
offsetRightArrow.text = ">";
offsetRightArrow.x = offsetLeftArrow.x * 1.2;
offsetRightArrow.y = offsetLeftArrow.y;
add(offsetRightArrow);
#end
helpText = new FlxText();
helpText.setFormat(Paths.font("vcr.ttf"), 20 #if mobile * 3 #end);
helpText.text = #if mobile "Back" #else "Press BACK to return to options menu" #end;
helpText.x = FlxG.width - helpText.width #if mobile * 1.5 #end;
helpText.y = FlxG.height - (helpText.height * 2) - 2;
add(helpText);
#if mobile
addHitbox(true, true, FunkinHitboxControlSchemes.FourLanes, [NoteDirection.DOWN], [0xFF00FFFF]);
hitbox.forEachAlive(function(hint:FunkinHint) {
@:privateAccess
if (hint.label != null) hint.label.visible = false;
for (text in [
helpText,
visualOffsetLeftArrow,
visualOffsetRightArrow,
offsetLeftArrow,
offsetRightArrow
])
hint.deadZones.push(cast(text, FunkinSprite));
});
#end
regenNoteData();
}
function preciseInputPressed(event:PreciseInputEvent)
{
generateBeatStuff(event);
strumLine.pressKey(event.noteDirection);
strumLine.playPress(event.noteDirection);
}
function preciseInputReleased(event:PreciseInputEvent)
{
strumLine.playStatic(event.noteDirection);
strumLine.releaseKey(event.noteDirection);
}
override public function destroy():Void
{
cleanup();
super.destroy();
}
function cleanup():Void
{
PreciseInputManager.instance.onInputPressed.remove(preciseInputPressed);
PreciseInputManager.instance.onInputReleased.remove(preciseInputReleased);
if (FlxG.sound.music != null)
{
FlxG.sound.music.volume = previousVolume;
}
swagSong.stop();
FlxG.sound.list.remove(swagSong);
FlxG.cameras.remove(stateCamera);
FlxG.state.persistentDraw = prevPersistentDraw;
FlxG.state.persistentUpdate = prevPersistentUpdate;
}
function regenNoteData()
{
for (i in 0...32)
{
var note:SongNoteData = new SongNoteData((localConductor.stepLengthMs * 2) * i, 1);
noteGrp.push(note);
}
strumLine.applyNoteData(noteGrp);
}
override function stepHit():Bool
{
if (localConductor.currentStep % 4 == 2)
{
blocks.members[((localConductor.currentBeat % 8) + 1) % 8].alpha = 0.5;
}
return super.stepHit();
}
override function beatHit():Bool
{
if (localConductor.currentBeat % 8 == 0) blocks.forEach(blok -> {
blok.alpha = 0.1;
});
blocks.members[localConductor.currentBeat % 8].alpha = 1;
// block.visible = !block.visible;
return super.beatHit();
}
override function update(elapsed:Float)
{
/* trace("1: " + swagSong.frfrTime);
@:privateAccess
trace(FlxG.sound.music._channel.position);
*/
localConductor.update(swagSong.time, false);
// localConductor.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp;
songPosVis.x = songPosToX(localConductor.songPosition);
songVisFollowAudio.x = songPosToX(localConductor.songPosition - localConductor.audioVisualOffset);
songVisFollowVideo.x = songPosToX(localConductor.songPosition - localConductor.inputOffset);
visualOffsetText.text = "Visual Offset: " + localConductor.audioVisualOffset + "ms";
#if !mobile
visualOffsetText.text += "\n\nYou can press SPACE+Left/Right to change this value.";
visualOffsetText.text += "\n\nYou can hold SHIFT to step 1ms at a time";
#end
#if mobile
offsetText.text = "INPUT Offset: " + localConductor.inputOffset + "ms";
#else
offsetText.text = "INPUT Offset (Left/Right to change): " + localConductor.inputOffset + "ms";
offsetText.text += "\n\nYou can hold SHIFT to step 1ms at a time";
#end
var avgOffsetInput:Float = 0;
var loopInd:Int = 0;
for (offsetThing in offsetsPerBeat)
{
if (offsetThing == null) continue;
avgOffsetInput += offsetThing;
loopInd++;
}
avgOffsetInput /= loopInd;
offsetText.text += "\n\nEstimated average input offset needed: " + avgOffsetInput;
var multiply:Int = 10;
if (FlxG.keys.pressed.SHIFT || FlxG.onMobile) multiply = 1;
#if mobile
handleSelectionInputMobile(multiply);
#else
handleSelectionInput(multiply);
#end
if (controls.BACK #if mobile || (TouchUtil.pressAction(helpText)) #end)
{
// close();
cleanup();
FlxG.switchState(() -> new funkin.ui.options.OptionsState());
}
super.update(elapsed);
}
function handleSelectionInput(multiply:Int)
{
if (FlxG.keys.pressed.CONTROL || FlxG.keys.pressed.SPACE)
{
if (FlxG.keys.justPressed.RIGHT)
{
localConductor.audioVisualOffset += 1 * multiply;
}
if (FlxG.keys.justPressed.LEFT)
{
localConductor.audioVisualOffset -= 1 * multiply;
}
}
else
{
if (FlxG.keys.anyJustPressed([LEFT, RIGHT]))
{
if (FlxG.keys.justPressed.RIGHT)
{
localConductor.inputOffset += 1 * multiply;
}
if (FlxG.keys.justPressed.LEFT)
{
localConductor.inputOffset -= 1 * multiply;
}
// reset the average, so you don't need to wait a full loop to start getting averages
// also reset each text member
offsetsPerBeat = [];
diffGrp.forEach(memb -> memb.text = "");
}
}
}
#if mobile
function handleSelectionInputMobile(multiply:Int)
{
final touchPressCheck:Bool = TouchUtil.justPressed
|| TouchUtil.pressed
&& TouchUtil.touch != null
&& TouchUtil.touch.ticksDeltaSincePress >= 200;
if (TouchUtil.overlapsComplex(visualOffsetRightArrow) && touchPressCheck)
{
cleanup();
FlxG.switchState(() -> new funkin.ui.options.OptionsState());
localConductor.audioVisualOffset += 1 * multiply;
}
if (TouchUtil.overlapsComplex(visualOffsetLeftArrow) && touchPressCheck)
{
localConductor.audioVisualOffset -= 1 * multiply;
}
if ((TouchUtil.overlapsComplex(offsetRightArrow) || TouchUtil.overlapsComplex(offsetLeftArrow)) && touchPressCheck)
{
if (TouchUtil.overlapsComplex(offsetRightArrow) && touchPressCheck)
{
localConductor.inputOffset += 1 * multiply;
}
if (TouchUtil.overlapsComplex(offsetLeftArrow) && touchPressCheck)
{
localConductor.inputOffset -= 1 * multiply;
}
// reset the average, so you don't need to wait a full loop to start getting averages
// also reset each text member
offsetsPerBeat = [];
diffGrp.forEach(memb -> memb.text = "");
}
}
#end
function generateBeatStuff(event:PreciseInputEvent)
{
// localConductor.update(swagSong.getTimeWithDiff());
var inputLatencyMs:Float = haxe.Int64.toInt(PreciseInputManager.getCurrentTimestamp() - event.timestamp) / 1000.0 / 1000.0;
// trace("input latency: " + inputLatencyMs + "ms");
// trace("cur timestamp: " + PreciseInputManager.getCurrentTimestamp() + "ns");
// trace("event timestamp: " + event.timestamp + "ns");
// trace("songtime: " + localConductor.getTimeWithDiff(swagSong) + "ms");
var closestBeat:Int = Math.round(localConductor.getTimeWithDiff(swagSong) / (localConductor.stepLengthMs * 2)) % diffGrp.members.length;
var getDiff:Float = localConductor.getTimeWithDiff(swagSong) - (closestBeat * (localConductor.stepLengthMs * 2));
// getDiff -= localConductor.inputOffset;
getDiff -= inputLatencyMs;
getDiff -= localConductor.audioVisualOffset;
// lil fix for end of song
if (closestBeat == 0 && getDiff >= localConductor.stepLengthMs * 2) getDiff -= swagSong.length;
beatTrail.x = songPosVis.x;
diffGrp.members[closestBeat].text = getDiff + "ms";
offsetsPerBeat[closestBeat] = Math.round(getDiff);
}
function songPosToX(pos:Float):Float
{
return FlxMath.remapToRange(pos, 0, swagSong.length, 0, FlxG.width);
}
}
class HomemadeMusic extends FlxSound
{
public var prevTimestamp:Int = 0;
public function new()
{
super();
}
var prevTime:Float = 0;
override function update(elapsed:Float)
{
super.update(elapsed);
if (prevTime != time)
{
prevTime = time;
prevTimestamp = Std.int(Timer.stamp() * 1000);
}
}
public function getTimeWithDiff():Float
{
return time + (Std.int(Timer.stamp() * 1000) - prevTimestamp);
}
}
@@ -1260,14 +1260,13 @@ class StageEditorState extends UIState
if (exitConfirmDialog == null)
{
exitConfirmDialog = Dialogs.messageBox("You are about to leave the Editor without Saving.\n\nAre you sure? ", "Leave Editor",
MessageBoxType.TYPE_YESNO, true,
function(btn:DialogButton) {
MessageBoxType.TYPE_YESNO, true, function(btn:DialogButton) {
exitConfirmDialog = null;
if (btn == DialogButton.YES)
{
saved = true;
onMenuItemClick("exit");
}
if (btn == DialogButton.YES)
{
saved = true;
onMenuItemClick("exit");
}
});
}
@@ -114,7 +114,7 @@ class StageEditorObjectAnimsToolbox extends StageEditorDefaultToolbox
objAnims.selectedIndex = objAnims.dataSource.size - 1;
}
this.onDialogClosed = onClose;
}
@@ -121,7 +121,7 @@ class StageEditorObjectPropertiesToolbox extends StageEditorDefaultToolbox
linkedObj.color = FlxColor.fromString(_.value) ?? 0xFFFFFFFF;
}
}
this.onDialogClosed = onClose;
}
@@ -51,7 +51,7 @@ class StageEditorStageToolbox extends StageEditorDefaultToolbox
}
refresh();
this.onDialogClosed = onClose;
}
@@ -21,7 +21,6 @@ class FreeplayStyle implements IRegistryEntry<FreeplayStyleData>
* The full data for a freeplay style.
*/
// public final _data:FreeplayStyleData;
public function new(id:String)
{
this.id = id;
+6 -2
View File
@@ -107,6 +107,7 @@ class LetterSort extends FlxSpriteGroup
if (inputEnabled)
{
#if FEATURE_TOUCH_CONTROLS
if (TouchUtil.pressAction())
{
for (index => letter in letterHitboxes)
@@ -132,12 +133,15 @@ class LetterSort extends FlxSpriteGroup
break;
}
}
#end
@:privateAccess
{
if (controls.FREEPLAY_LEFT || (TouchUtil.overlaps(swipeBounds, instance.funnyCam) && SwipeUtil.swipeLeft)) changeSelection(-1);
if (controls.FREEPLAY_LEFT #if FEATURE_TOUCH_CONTROLS
|| (TouchUtil.overlaps(swipeBounds, instance.funnyCam) && SwipeUtil.swipeLeft) #end) changeSelection(-1);
if (controls.FREEPLAY_RIGHT || (TouchUtil.overlaps(swipeBounds, instance.funnyCam) && SwipeUtil.swipeRight)) changeSelection(1);
if (controls.FREEPLAY_RIGHT #if FEATURE_TOUCH_CONTROLS
|| (TouchUtil.overlaps(swipeBounds, instance.funnyCam) && SwipeUtil.swipeRight) #end) changeSelection(1);
}
}
}
+2 -2
View File
@@ -456,8 +456,8 @@ class MainMenuState extends MusicBeatState
gyroPan.add(FlxG.gyroscope.pitch * -1.25, FlxG.gyroscope.roll * -1.25);
// our pseudo damping
gyroPan.x = MathUtil.smoothLerp(gyroPan.x, 0, elapsed, 2.5);
gyroPan.y = MathUtil.smoothLerp(gyroPan.y, 0, elapsed, 2.5);
gyroPan.x = MathUtil.smoothLerpPrecision(gyroPan.x, 0, elapsed, 2.5);
gyroPan.y = MathUtil.smoothLerpPrecision(gyroPan.y, 0, elapsed, 2.5);
// how far away from bg mid do we want to pan via gyroPan
camFollow.x = bg.getGraphicMidpoint().x - gyroPan.x;
+4 -2
View File
@@ -391,7 +391,7 @@ class StoryMenuState extends MusicBeatState
changeDifficulty(-1);
}
if (controls.UI_RIGHT || TouchUtil.overlaps(rightDifficultyArrow))
if (controls.UI_RIGHT #if FEATURE_TOUCH_CONTROLS || TouchUtil.overlaps(rightDifficultyArrow) #end)
{
rightDifficultyArrow.animation.play('press');
}
@@ -400,7 +400,7 @@ class StoryMenuState extends MusicBeatState
rightDifficultyArrow.animation.play('idle');
}
if (controls.UI_LEFT || TouchUtil.overlaps(leftDifficultyArrow))
if (controls.UI_LEFT #if FEATURE_TOUCH_CONTROLS || TouchUtil.overlaps(leftDifficultyArrow) #end)
{
leftDifficultyArrow.animation.play('press');
}
@@ -415,6 +415,7 @@ class StoryMenuState extends MusicBeatState
selectLevel();
}
#if FEATURE_TOUCH_CONTROLS
if (TouchUtil.justReleased && !TouchUtil.overlaps(leftDifficultyArrow) && !SwipeUtil.justSwipedAny)
{
for (i in 0...levelTitles.members.length)
@@ -427,6 +428,7 @@ class StoryMenuState extends MusicBeatState
(item == selectedItem) ? selectLevel() : changeLevel(i - levelList.indexOf(currentLevelId));
}
}
#end
}
if (controls.BACK) goBack();
+1 -12
View File
@@ -68,11 +68,9 @@ class TouchUtil
*/
public static function overlaps(?object:FlxBasic, ?camera:FlxCamera):Bool
{
#if FEATURE_TOUCH_CONTROLS
if (object == null || touch == null) return false;
return touch.overlaps(object, camera ?? object.camera);
#end
return false;
}
@@ -87,14 +85,12 @@ class TouchUtil
*/
public static function overlapsComplex(?object:FlxObject, ?camera:FlxCamera):Bool
{
#if FEATURE_TOUCH_CONTROLS
if (object == null || touch == null) return false;
if (camera == null) camera = object.cameras[0];
@:privateAccess
return object.overlapsPoint(touch.getWorldPosition(camera, object._point), true, camera);
#end
return false;
}
@@ -111,7 +107,6 @@ class TouchUtil
*/
public static function overlapsComplexPoint(?object:FlxObject, point:FlxPoint, ?inScreenSpace:Bool = false, ?camera:FlxCamera):Bool
{
#if FEATURE_TOUCH_CONTROLS
if (object == null || point == null) return false;
if (camera == null) camera = object.cameras[0];
@@ -123,7 +118,6 @@ class TouchUtil
}
point.putWeak();
#end
return false;
}
@@ -137,7 +131,6 @@ class TouchUtil
*/
public static function pressAction(?object:FlxBasic, ?camera:FlxCamera, useOverlapsComplex:Bool = true):Bool
{
#if FEATURE_TOUCH_CONTROLS
if (TouchUtil.touch == null || (TouchUtil.touch != null && TouchUtil.touch.ticksDeltaSincePress > 200)) return false;
if (object == null && camera == null)
@@ -149,7 +142,6 @@ class TouchUtil
final overlapsObject:Bool = useOverlapsComplex ? overlapsComplex(cast(object, FlxObject), camera) : overlaps(object, camera);
return justReleased && overlapsObject;
}
#end
return false;
}
@@ -189,13 +181,10 @@ class TouchUtil
}
#else
@:noCompletion
inline static function get_touch():FlxMouse
static function get_touch():FlxMouse
{
#if FEATURE_TOUCH_CONTROLS
FlxG.mouse.visible = true;
return FlxG.mouse;
#end
return null;
}
#end
}