mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-12-10 22:17:05 +00:00
Compare commits
15 commits
758f712eb5
...
620ec071a7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
620ec071a7 | ||
|
|
7202043189 | ||
|
|
f0253fc46f | ||
|
|
7cb6bb201e | ||
|
|
3d659bc0c9 | ||
|
|
be487ad36d | ||
|
|
658af405bf | ||
|
|
d0183594cc | ||
|
|
22e43f564a | ||
|
|
c03b70bfce | ||
|
|
a0ee6ece21 | ||
|
|
552e8e035f | ||
|
|
93bb397da1 | ||
|
|
1a4db118ed | ||
|
|
cc644676b3 |
2
assets
2
assets
|
|
@ -1 +1 @@
|
|||
Subproject commit 1a961f111381eb3bfc452166c4e4b5a18b409781
|
||||
Subproject commit b43892631e064771b057a8b00271dc20fab8478c
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
"colorprofile": "cl",
|
||||
"custom": [
|
||||
{
|
||||
"asset": "asset/shared/images/resultScreen/results-pico/resultsPERFECT/spritemap1.png",
|
||||
"asset": "asset/shared/images/resultScreen/results-pico/resultsGOOD/spritemap1.png",
|
||||
"blocksize": "4x4"
|
||||
},
|
||||
{
|
||||
|
|
@ -14,11 +14,7 @@
|
|||
"blocksize": "4x4"
|
||||
},
|
||||
{
|
||||
"asset": "asset/shared/images/resultScreen/results-pico/resultsGOOD/spritemap1.png",
|
||||
"blocksize": "4x4"
|
||||
},
|
||||
{
|
||||
"asset": "assets/shared/images/resultScreen/results-bf/resultsEXCELLENT/spritemap1.png",
|
||||
"asset": "asset/shared/images/resultScreen/results-pico/resultsPERFECT/spritemap1.png",
|
||||
"blocksize": "4x4"
|
||||
},
|
||||
{
|
||||
|
|
@ -41,6 +37,10 @@
|
|||
"asset": "assets/preload/images/alphabet.png",
|
||||
"blocksize": "4x4"
|
||||
},
|
||||
{
|
||||
"asset": "assets/preload/images/charSelect/gfChill/spritemap1.png",
|
||||
"blocksize": "6x6"
|
||||
},
|
||||
{
|
||||
"asset": "assets/shared/images/NOTE_hold_assets.png",
|
||||
"blocksize": "4x4"
|
||||
|
|
@ -81,6 +81,10 @@
|
|||
"asset": "assets/shared/images/notes.png",
|
||||
"blocksize": "4x4"
|
||||
},
|
||||
{
|
||||
"asset": "assets/shared/images/resultScreen/results-bf/resultsEXCELLENT/spritemap1.png",
|
||||
"blocksize": "4x4"
|
||||
},
|
||||
{
|
||||
"asset": "assets/week1/image/erect/bg.png",
|
||||
"blocksize": "8x8"
|
||||
|
|
|
|||
21
source/funkin/external/windows/WinAPI.hx
vendored
21
source/funkin/external/windows/WinAPI.hx
vendored
|
|
@ -11,38 +11,32 @@ extern class WinAPI
|
|||
/**
|
||||
* Shows a message box with an error icon.
|
||||
*
|
||||
* @param handle A handle to the parent window.
|
||||
* @param message The message to display.
|
||||
* @param title The title of the message box.
|
||||
*/
|
||||
@:native('WINAPI_ShowError')
|
||||
static function showError(message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void;
|
||||
static function showError(handle:cpp.RawPointer<cpp.Void>, message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void;
|
||||
|
||||
/**
|
||||
* Shows a message box with a warning icon.
|
||||
*
|
||||
* @param handle A handle to the parent window.
|
||||
* @param message The message to display.
|
||||
* @param title The title of the message box.
|
||||
*/
|
||||
@:native('WINAPI_ShowWarning')
|
||||
static function showWarning(message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void;
|
||||
static function showWarning(handle:cpp.RawPointer<cpp.Void>, message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void;
|
||||
|
||||
/**
|
||||
* Shows a message box with an information icon.
|
||||
*
|
||||
* @param handle A handle to the parent window.
|
||||
* @param message The message to display.
|
||||
* @param title The title of the message box.
|
||||
*/
|
||||
@:native('WINAPI_ShowInformation')
|
||||
static function showInformation(message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void;
|
||||
|
||||
/**
|
||||
* Shows a message box with a question icon.
|
||||
*
|
||||
* @param message The message to display.
|
||||
* @param title The title of the message box.
|
||||
*/
|
||||
@:native('WINAPI_ShowQuestion')
|
||||
static function showQuestion(message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void;
|
||||
static function showInformation(handle:cpp.RawPointer<cpp.Void>, message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void;
|
||||
|
||||
/**
|
||||
* Disables the "Report to Microsoft" dialog that appears when the application crashes.
|
||||
|
|
@ -67,10 +61,11 @@ extern class WinAPI
|
|||
/**
|
||||
* Sets the dark mode for the active window.
|
||||
*
|
||||
* @param handle A handle to the parent window.
|
||||
* @param enable Whether to enable or disable dark mode.
|
||||
*/
|
||||
@:native('WINAPI_SetDarkMode')
|
||||
static function setDarkMode(enable:Bool):Void;
|
||||
static function setDarkMode(handle:cpp.RawPointer<cpp.Void>, enable:Bool):Void;
|
||||
|
||||
/**
|
||||
* Checks if the system is using dark mode.
|
||||
|
|
|
|||
|
|
@ -3,34 +3,29 @@
|
|||
/**
|
||||
* Shows an error message box.
|
||||
*
|
||||
* @param handle A handle to the parent window
|
||||
* @param message The error message to display
|
||||
* @param title The title of the message box
|
||||
*/
|
||||
void WINAPI_ShowError(const char *message, const char *title);
|
||||
void WINAPI_ShowError(void* handle, const char *message, const char *title);
|
||||
|
||||
/**
|
||||
* Shows a warning message box.
|
||||
*
|
||||
* @param handle A handle to the parent window
|
||||
* @param message The warning message to display
|
||||
* @param title The title of the message box
|
||||
*/
|
||||
void WINAPI_ShowWarning(const char *message, const char *title);
|
||||
void WINAPI_ShowWarning(void* handle, const char *message, const char *title);
|
||||
|
||||
/**
|
||||
* Shows an information message box.
|
||||
*
|
||||
* @param handle A handle to the parent window
|
||||
* @param message The information message to display
|
||||
* @param title The title of the message box
|
||||
*/
|
||||
void WINAPI_ShowInformation(const char *message, const char *title);
|
||||
|
||||
/**
|
||||
* Shows a question message box with OK/Cancel buttons.
|
||||
*
|
||||
* @param message The question message to display
|
||||
* @param title The title of the message box
|
||||
*/
|
||||
void WINAPI_ShowQuestion(const char *message, const char *title);
|
||||
void WINAPI_ShowInformation(void* handle, const char *message, const char *title);
|
||||
|
||||
/**
|
||||
* Disables Windows error reporting dialogs.
|
||||
|
|
@ -52,11 +47,12 @@ void WINAPI_DisableWindowsGhosting();
|
|||
size_t WINAPI_GetProcessMemoryWorkingSetSize();
|
||||
|
||||
/**
|
||||
* Sets dark mode for the active window.
|
||||
* Sets dark mode on a window
|
||||
* @param handle A handle to the parent window.
|
||||
*
|
||||
* @param enable True to enable dark mode, false to disable
|
||||
*/
|
||||
void WINAPI_SetDarkMode(bool enable);
|
||||
void WINAPI_SetDarkMode(void* handle, bool enable);
|
||||
|
||||
/**
|
||||
* Checks if the system is using dark mode.
|
||||
|
|
|
|||
|
|
@ -11,25 +11,36 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void WINAPI_ShowError(const char *message, const char *title)
|
||||
void WINAPI_ShowError(void* handle, const char *message, const char *title)
|
||||
{
|
||||
MessageBox(GetActiveWindow(), message, title, MB_OK | MB_ICONERROR);
|
||||
HWND hwnd = (HWND)handle;
|
||||
|
||||
if (!IsWindow(hwnd))
|
||||
hwnd = nullptr;
|
||||
|
||||
MessageBox(hwnd, message, title, MB_OK | MB_ICONERROR);
|
||||
}
|
||||
|
||||
void WINAPI_ShowWarning(const char *message, const char *title)
|
||||
void WINAPI_ShowWarning(void* handle, const char *message, const char *title)
|
||||
{
|
||||
MessageBox(GetActiveWindow(), message, title, MB_OK | MB_ICONWARNING);
|
||||
HWND hwnd = (HWND)handle;
|
||||
|
||||
if (!IsWindow(hwnd))
|
||||
hwnd = nullptr;
|
||||
|
||||
MessageBox(hwnd, message, title, MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
|
||||
void WINAPI_ShowInformation(const char *message, const char *title)
|
||||
void WINAPI_ShowInformation(void* handle, const char *message, const char *title)
|
||||
{
|
||||
MessageBox(GetActiveWindow(), message, title, MB_OK | MB_ICONINFORMATION);
|
||||
HWND hwnd = (HWND)handle;
|
||||
|
||||
if (!IsWindow(hwnd))
|
||||
hwnd = nullptr;
|
||||
|
||||
MessageBox(hwnd, message, title, MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
|
||||
void WINAPI_ShowQuestion(const char *message, const char *title)
|
||||
{
|
||||
MessageBox(GetActiveWindow(), message, title, MB_OKCANCEL | MB_ICONQUESTION);
|
||||
}
|
||||
|
||||
void WINAPI_DisableErrorReporting()
|
||||
{
|
||||
|
|
@ -51,16 +62,19 @@ size_t WINAPI_GetProcessMemoryWorkingSetSize()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void WINAPI_SetDarkMode(bool enable)
|
||||
void WINAPI_SetDarkMode(void* handle, bool enable)
|
||||
{
|
||||
HWND window = GetActiveWindow();
|
||||
HWND hwnd = (HWND)handle;
|
||||
|
||||
if (!IsWindow(hwnd))
|
||||
return;
|
||||
|
||||
int darkMode = enable ? 1 : 0;
|
||||
|
||||
if (DwmSetWindowAttribute(window, 20, &darkMode, sizeof(darkMode)) != S_OK)
|
||||
DwmSetWindowAttribute(window, 19, &darkMode, sizeof(darkMode));
|
||||
if (DwmSetWindowAttribute(hwnd, 20, &darkMode, sizeof(darkMode)) != S_OK)
|
||||
DwmSetWindowAttribute(hwnd, 19, &darkMode, sizeof(darkMode));
|
||||
|
||||
UpdateWindow(window);
|
||||
UpdateWindow(hwnd);
|
||||
}
|
||||
|
||||
bool WINAPI_IsSystemDarkMode()
|
||||
|
|
|
|||
|
|
@ -121,6 +121,11 @@ typedef PlayStateParams =
|
|||
* @default `false`
|
||||
*/
|
||||
?botPlayMode:Bool,
|
||||
/**
|
||||
* Whether the results screen should show up before returning to the chart editor.
|
||||
* @default `false`
|
||||
*/
|
||||
?playtestResults:Bool,
|
||||
/**
|
||||
* Whether the song should be in minimal mode.
|
||||
* @default `false`
|
||||
|
|
@ -362,6 +367,11 @@ class PlayState extends MusicBeatSubState
|
|||
*/
|
||||
public var isBotPlayMode:Bool = false;
|
||||
|
||||
/**
|
||||
* Whether the results screen should show up before returning to the chart editor.
|
||||
*/
|
||||
public var isPlaytestResults:Bool = false;
|
||||
|
||||
/**
|
||||
* Whether the player has dropped below zero health,
|
||||
* and we are just waiting for an animation to play out before transitioning.
|
||||
|
|
@ -723,6 +733,7 @@ class PlayState extends MusicBeatSubState
|
|||
if (params.targetInstrumental != null) currentInstrumental = params.targetInstrumental;
|
||||
isPracticeMode = params.practiceMode ?? false;
|
||||
isBotPlayMode = params.botPlayMode ?? false;
|
||||
isPlaytestResults = params.playtestResults ?? false;
|
||||
isMinimalMode = params.minimalMode ?? false;
|
||||
startTimestamp = params.startTimestamp ?? 0.0;
|
||||
playbackRate = params.playbackRate ?? 1.0;
|
||||
|
|
@ -837,6 +848,7 @@ class PlayState extends MusicBeatSubState
|
|||
var pre:Float = (Conductor.instance.beatLengthMs * -5) + startTimestamp;
|
||||
|
||||
trace('Attempting to start at ' + pre);
|
||||
trace('startTimestamp ${startTimestamp}');
|
||||
|
||||
Conductor.instance.update(pre);
|
||||
|
||||
|
|
@ -1071,7 +1083,7 @@ class PlayState extends MusicBeatSubState
|
|||
opponentStrumline.clean();
|
||||
|
||||
// Delete all notes and reset the arrays.
|
||||
regenNoteData();
|
||||
regenNoteData(startTimestamp);
|
||||
|
||||
// Reset camera zooming
|
||||
cameraBopIntensity = Constants.DEFAULT_BOP_INTENSITY;
|
||||
|
|
@ -2388,7 +2400,7 @@ class PlayState extends MusicBeatSubState
|
|||
}
|
||||
}
|
||||
|
||||
regenNoteData();
|
||||
regenNoteData(startTimestamp);
|
||||
|
||||
var event:ScriptEvent = new ScriptEvent(CREATE, false);
|
||||
ScriptEventDispatcher.callEvent(currentSong, event);
|
||||
|
|
@ -3598,7 +3610,21 @@ class PlayState extends MusicBeatSubState
|
|||
{
|
||||
if (isSubState)
|
||||
{
|
||||
this.close();
|
||||
if (isPlaytestResults)
|
||||
{
|
||||
var talliesToUse:Tallies = PlayStatePlaylist.isStoryMode ? Highscore.talliesLevel : Highscore.tallies;
|
||||
var clearPercentFloat = talliesToUse.totalNotes == 0 ? 0.0 : (talliesToUse.sick + talliesToUse.good) / talliesToUse.totalNotes * 100;
|
||||
/*
|
||||
Only move to the score screen if more than 30% of the song was successfully hit.
|
||||
While that might sound like a low clear percent, consider the fact that some songs are hard,
|
||||
and the user might be only playtesting one third or half the song.
|
||||
*/
|
||||
if (clearPercentFloat >= 30) moveToResultsScreen(false, prevScoreData);
|
||||
else
|
||||
this.close();
|
||||
}
|
||||
else
|
||||
this.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import funkin.ui.MusicBeatSubState;
|
|||
import funkin.ui.story.StoryMenuState;
|
||||
import funkin.util.HapticUtil;
|
||||
import funkin.graphics.ScriptedFunkinSprite;
|
||||
import funkin.ui.debug.charting.ChartEditorState;
|
||||
#if FEATURE_NEWGROUNDS
|
||||
import funkin.api.newgrounds.Medals;
|
||||
#end
|
||||
|
|
@ -93,6 +94,11 @@ class ResultState extends MusicBeatSubState
|
|||
|
||||
var introMusicAudio:Null<FunkinSound> = null;
|
||||
|
||||
/**
|
||||
* The music playing in the background of the state.
|
||||
*/
|
||||
var resultsMusic:Null<FunkinSound> = null;
|
||||
|
||||
var rankBg:FunkinSprite;
|
||||
final cameraBG:FunkinCamera;
|
||||
final cameraScroll:FunkinCamera;
|
||||
|
|
@ -102,6 +108,15 @@ class ResultState extends MusicBeatSubState
|
|||
|
||||
var busy:Bool = false;
|
||||
|
||||
public var isChartingMode(get, never):Bool;
|
||||
|
||||
function get_isChartingMode():Bool
|
||||
{
|
||||
if (PlayState.instance != null) return PlayState.instance.isChartingMode;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public function new(params:ResultsStateParams)
|
||||
{
|
||||
super();
|
||||
|
|
@ -487,22 +502,34 @@ class ResultState extends MusicBeatSubState
|
|||
// Play the intro music.
|
||||
introMusicAudio = FunkinSound.load(introMusic, 1.0, false, true, true, () -> {
|
||||
introMusicAudio = null;
|
||||
if (!isChartingMode) // Don't override the music and cause problems on the chart editor
|
||||
FunkinSound.playMusic(getMusicPath(playerCharacter, rank),
|
||||
{
|
||||
startingVolume: 1.0,
|
||||
overrideExisting: true,
|
||||
restartTrack: true
|
||||
});
|
||||
else // Play the results music as a looped sound instead (that we cancel before closing and returning to the chart editor)
|
||||
{
|
||||
resultsMusic = FunkinSound.load(Paths.music(getMusicPath(playerCharacter, rank) + '/' + getMusicPath(playerCharacter, rank)), 1.0, true, false,
|
||||
true);
|
||||
false; // Why is this necessary for this to work?
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
FunkinSound.playMusic(getMusicPath(playerCharacter, rank),
|
||||
if (!isChartingMode) FunkinSound.playMusic(getMusicPath(playerCharacter, rank),
|
||||
{
|
||||
startingVolume: 1.0,
|
||||
overrideExisting: true,
|
||||
restartTrack: true
|
||||
});
|
||||
else
|
||||
{
|
||||
resultsMusic = FunkinSound.load(Paths.music(getMusicPath(playerCharacter, rank) + '/' + getMusicPath(playerCharacter, rank)), 1.0, true, false, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -780,6 +807,7 @@ class ResultState extends MusicBeatSubState
|
|||
if (_parentState is funkin.ui.debug.results.ResultsDebugSubState)
|
||||
{
|
||||
if (introMusicAudio != null)
|
||||
|
||||
{
|
||||
introMusicAudio.stop();
|
||||
introMusicAudio.destroy();
|
||||
|
|
@ -793,16 +821,18 @@ class ResultState extends MusicBeatSubState
|
|||
introMusicAudio.onComplete = null;
|
||||
|
||||
FlxTween.tween(introMusicAudio, {volume: 0}, 0.8,
|
||||
|
||||
{
|
||||
onComplete: _ -> {
|
||||
if (introMusicAudio != null)
|
||||
onComplete: _ -> {
|
||||
if (introMusicAudio != null)
|
||||
|
||||
{
|
||||
introMusicAudio.stop();
|
||||
introMusicAudio.destroy();
|
||||
introMusicAudio = null;
|
||||
introMusicAudio.stop();
|
||||
introMusicAudio.destroy();
|
||||
introMusicAudio = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
FlxTween.tween(introMusicAudio, {pitch: 3}, 0.1,
|
||||
{
|
||||
onComplete: _ -> {
|
||||
|
|
@ -893,6 +923,16 @@ class ResultState extends MusicBeatSubState
|
|||
trace('THE RANK IS Higher.....');
|
||||
|
||||
shouldTween = true;
|
||||
if (isChartingMode)
|
||||
{
|
||||
PlayState.instance?.close();
|
||||
FlxTimer.globalManager.clear();
|
||||
FlxTween.globalManager.clear();
|
||||
if (introMusicAudio != null) introMusicAudio.stop();
|
||||
if (resultsMusic != null) resultsMusic.stop();
|
||||
this.close();
|
||||
return;
|
||||
}
|
||||
targetState = FreeplayState.build(
|
||||
{
|
||||
{
|
||||
|
|
@ -910,6 +950,16 @@ class ResultState extends MusicBeatSubState
|
|||
}
|
||||
else
|
||||
{
|
||||
if (isChartingMode)
|
||||
{
|
||||
PlayState.instance?.close();
|
||||
FlxTimer.globalManager.clear();
|
||||
FlxTween.globalManager.clear();
|
||||
if (introMusicAudio != null) introMusicAudio.stop();
|
||||
if (resultsMusic != null) resultsMusic.stop();
|
||||
this.close();
|
||||
return;
|
||||
}
|
||||
shouldTween = false;
|
||||
shouldUseSubstate = true;
|
||||
targetStateFactory = () -> new StickerSubState(
|
||||
|
|
|
|||
|
|
@ -55,11 +55,17 @@ class SetHealthIconSongEvent extends SongEvent
|
|||
switch (data?.value?.char ?? 0)
|
||||
{
|
||||
case 0:
|
||||
trace('Applying Player health icon via song event: ${healthIconData.id}');
|
||||
PlayState.instance.iconP1.configure(healthIconData);
|
||||
if (PlayState.instance.iconP1 != null)
|
||||
{
|
||||
trace('Applying Player health icon via song event: ${healthIconData.id}');
|
||||
PlayState.instance.iconP1.configure(healthIconData);
|
||||
}
|
||||
case 1:
|
||||
trace('Applying Opponent health icon via song event: ${healthIconData.id}');
|
||||
PlayState.instance.iconP2.configure(healthIconData);
|
||||
if (PlayState.instance.iconP2 != null)
|
||||
{
|
||||
trace('Applying Opponent health icon via song event: ${healthIconData.id}');
|
||||
PlayState.instance.iconP2.configure(healthIconData);
|
||||
}
|
||||
default:
|
||||
trace(' WARNING '.bold().bg_yellow() + ' Unknown character index: ' + data.value.char);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class Save implements ConsoleClass
|
|||
@:nullSafety(Off)
|
||||
public function new(?data:RawSaveData)
|
||||
{
|
||||
this.data = data ?? Save.getDefaultData();
|
||||
this.data = data ??= Save.getDefaultData();
|
||||
// Build macro will inject SaveProperty initialization here automatically
|
||||
|
||||
// Make sure the verison number is up to date before we flush.
|
||||
|
|
|
|||
|
|
@ -603,6 +603,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
|||
*/
|
||||
var playtestBotPlayMode:Bool = false;
|
||||
|
||||
/**
|
||||
* If true, after playtesting a chart the results screen will show your score.
|
||||
*/
|
||||
var playtestShowResults:Bool = false;
|
||||
|
||||
/**
|
||||
* Enables or disables the "debugger" popup that appears when you run into a flixel error.
|
||||
*/
|
||||
|
|
@ -6260,6 +6265,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
|||
targetVariation: selectedVariation,
|
||||
practiceMode: playtestPracticeMode,
|
||||
botPlayMode: playtestBotPlayMode,
|
||||
playtestResults: playtestShowResults,
|
||||
minimalMode: minimal,
|
||||
startTimestamp: startTimestamp,
|
||||
playbackRate: playbackRate,
|
||||
|
|
|
|||
|
|
@ -188,71 +188,71 @@ class ChartEditorAudioHandler
|
|||
|
||||
if (state.audioVocalTrackGroup == null) state.audioVocalTrackGroup = new VoicesGroup();
|
||||
|
||||
if (vocalTrack != null)
|
||||
// early return
|
||||
if (vocalTrack == null) return false;
|
||||
|
||||
switch (charType)
|
||||
{
|
||||
switch (charType)
|
||||
{
|
||||
case BF:
|
||||
state.audioVocalTrackGroup.addPlayerVoice(vocalTrack);
|
||||
case BF:
|
||||
state.audioVocalTrackGroup.addPlayerVoice(vocalTrack);
|
||||
|
||||
var waveformData:Null<WaveformData> = vocalTrack.waveformData;
|
||||
var waveformData:Null<WaveformData> = vocalTrack.waveformData;
|
||||
|
||||
if (waveformData != null)
|
||||
{
|
||||
var duration:Float = Conductor.instance.getStepTimeInMs(16) * 0.001;
|
||||
var waveformSprite:WaveformSprite = new WaveformSprite(waveformData, VERTICAL, FlxColor.WHITE);
|
||||
waveformSprite.x = 840;
|
||||
waveformSprite.y = Math.max(state.gridTiledSprite?.y ?? 0.0, ChartEditorState.GRID_INITIAL_Y_POS - ChartEditorState.GRID_TOP_PAD);
|
||||
waveformSprite.height = (ChartEditorState.GRID_SIZE) * 16;
|
||||
waveformSprite.width = (ChartEditorState.GRID_SIZE) * 2;
|
||||
waveformSprite.time = 0;
|
||||
waveformSprite.duration = duration;
|
||||
state.audioWaveforms.add(waveformSprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
trace(' WARNING '.bold().bg_yellow() + ' Failed to parse waveform data for vocal track.');
|
||||
}
|
||||
if (waveformData != null)
|
||||
{
|
||||
var waveformSprite:WaveformSprite = initWaveformSprite(waveformData, state);
|
||||
waveformSprite.x = 840;
|
||||
state.audioWaveforms.add(waveformSprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
trace(' WARNING '.bold().bg_yellow() + ' Failed to parse waveform data for vocal track.');
|
||||
}
|
||||
|
||||
state.audioVocalTrackGroup.playerVoicesOffset = state.currentVocalOffsetPlayer;
|
||||
return true;
|
||||
case DAD:
|
||||
state.audioVocalTrackGroup.addOpponentVoice(vocalTrack);
|
||||
state.audioVocalTrackGroup.playerVoicesOffset = state.currentVocalOffsetPlayer;
|
||||
return true;
|
||||
case DAD:
|
||||
state.audioVocalTrackGroup.addOpponentVoice(vocalTrack);
|
||||
|
||||
var waveformData:Null<WaveformData> = vocalTrack.waveformData;
|
||||
var waveformData:Null<WaveformData> = vocalTrack.waveformData;
|
||||
|
||||
if (waveformData != null)
|
||||
{
|
||||
var duration:Float = Conductor.instance.getStepTimeInMs(16) * 0.001;
|
||||
var waveformSprite:WaveformSprite = new WaveformSprite(waveformData, VERTICAL, FlxColor.WHITE);
|
||||
waveformSprite.x = 360;
|
||||
waveformSprite.y = Math.max(state.gridTiledSprite?.y ?? 0.0, ChartEditorState.GRID_INITIAL_Y_POS - ChartEditorState.GRID_TOP_PAD);
|
||||
waveformSprite.height = (ChartEditorState.GRID_SIZE) * 16;
|
||||
waveformSprite.width = (ChartEditorState.GRID_SIZE) * 2;
|
||||
waveformSprite.time = 0;
|
||||
waveformSprite.duration = duration;
|
||||
state.audioWaveforms.add(waveformSprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
trace(' WARNING '.bold().bg_yellow() + ' Failed to parse waveform data for vocal track.');
|
||||
}
|
||||
if (waveformData != null)
|
||||
{
|
||||
var waveformSprite:WaveformSprite = initWaveformSprite(waveformData, state);
|
||||
waveformSprite.x = 360;
|
||||
state.audioWaveforms.add(waveformSprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
trace(' WARNING '.bold().bg_yellow() + ' Failed to parse waveform data for vocal track.');
|
||||
}
|
||||
|
||||
state.audioVocalTrackGroup.opponentVoicesOffset = state.currentVocalOffsetOpponent;
|
||||
state.audioVocalTrackGroup.opponentVoicesOffset = state.currentVocalOffsetOpponent;
|
||||
|
||||
return true;
|
||||
case OTHER:
|
||||
state.audioVocalTrackGroup.add(vocalTrack);
|
||||
// TODO: Add offset for other characters.
|
||||
return true;
|
||||
default:
|
||||
// Do nothing.
|
||||
}
|
||||
return true;
|
||||
case OTHER:
|
||||
state.audioVocalTrackGroup.add(vocalTrack);
|
||||
// TODO: Add offset for other characters.
|
||||
return true;
|
||||
default:
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// initializes a waveform sprite with buncho non-charType specific things
|
||||
static function initWaveformSprite(waveformData:WaveformData, state:ChartEditorState):WaveformSprite
|
||||
{
|
||||
var waveformSprite:WaveformSprite = new WaveformSprite(waveformData, VERTICAL, FlxColor.WHITE);
|
||||
waveformSprite.y = Math.max(state.gridTiledSprite?.y ?? 0.0, ChartEditorState.GRID_INITIAL_Y_POS - ChartEditorState.GRID_TOP_PAD);
|
||||
waveformSprite.height = (ChartEditorState.GRID_SIZE) * 16;
|
||||
waveformSprite.width = (ChartEditorState.GRID_SIZE) * 2;
|
||||
waveformSprite.time = 0;
|
||||
waveformSprite.duration = Conductor.instance.getStepTimeInMs(16) * 0.001;
|
||||
return waveformSprite;
|
||||
}
|
||||
|
||||
public static function stopExistingVocals(state:ChartEditorState):Void
|
||||
{
|
||||
state.audioVocalTrackGroup.clear();
|
||||
|
|
|
|||
|
|
@ -280,6 +280,16 @@ class ChartEditorToolboxHandler
|
|||
state.playtestBotPlayMode = checkboxBotPlay.selected;
|
||||
};
|
||||
|
||||
var checkboxShowResults:Null<CheckBox> = toolbox.findComponent('playtestShowResultsCheckbox', CheckBox);
|
||||
if (checkboxShowResults == null)
|
||||
throw 'ChartEditorToolboxHandler.buildToolboxPlaytestPropertiesLayout() - Could not find playtestShowResultsCheckbox component.';
|
||||
|
||||
checkboxShowResults.selected = state.playtestShowResults;
|
||||
|
||||
checkboxShowResults.onClick = _ -> {
|
||||
state.playtestShowResults = checkboxShowResults.selected;
|
||||
};
|
||||
|
||||
var checkboxSongScripts:Null<CheckBox> = toolbox.findComponent('playtestSongScriptsCheckbox', CheckBox);
|
||||
|
||||
if (checkboxSongScripts == null)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import flixel.util.FlxTimer;
|
|||
@:nullSafety
|
||||
class FreeplayFlames extends FlxSpriteGroup
|
||||
{
|
||||
var flameX(default, set):Float = (FlxG.width - 363) - funkin.ui.FullScreenScaleMode.gameNotchSize.x;
|
||||
var flameY(default, set):Float = 103;
|
||||
var flameX(default, set):Float = (FlxG.width - 367) - funkin.ui.FullScreenScaleMode.gameNotchSize.x;
|
||||
var flameY(default, set):Float = 91;
|
||||
var flameSpreadX(default, set):Float = 29;
|
||||
var flameSpreadY(default, set):Float = 6;
|
||||
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
*/
|
||||
var currentVariation:String = Constants.DEFAULT_VARIATION;
|
||||
|
||||
public var fp:FreeplayScore;
|
||||
var fpScoreDisplay:FreeplayScore;
|
||||
|
||||
var txtCompletion:AtlasText;
|
||||
var lerpCompletion:Float = 0;
|
||||
|
|
@ -330,7 +330,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
|
||||
// We build a bunch of sprites BEFORE create() so we can guarantee they aren't null later on.
|
||||
albumRoll = new AlbumRoll();
|
||||
fp = new FreeplayScore(FlxG.width - (FullScreenScaleMode.gameNotchSize.x + 353), 60, 7, 100, styleData);
|
||||
fpScoreDisplay = new FreeplayScore(FlxG.width - (FullScreenScaleMode.gameNotchSize.x + 353), 60, 7, 100, styleData);
|
||||
rankCamera = new FunkinCamera('rankCamera', 0, 0, FlxG.width, FlxG.height);
|
||||
funnyCam = new FunkinCamera('freeplayFunny', 0, 0, FlxG.width, FlxG.height);
|
||||
grpCapsules = new FlxTypedGroup<SongMenuItem>();
|
||||
|
|
@ -629,8 +629,8 @@ class FreeplayState extends MusicBeatSubState
|
|||
tmr.time = FlxG.random.float(20, 60);
|
||||
}, 0);
|
||||
|
||||
fp.visible = false;
|
||||
add(fp);
|
||||
fpScoreDisplay.visible = false;
|
||||
add(fpScoreDisplay);
|
||||
|
||||
var clearBoxSprite:FlxSprite = new FlxSprite(FlxG.width - (FullScreenScaleMode.gameNotchSize.x + 115), 65).loadGraphic(Paths.image('freeplay/clearBox'));
|
||||
clearBoxSprite.visible = false;
|
||||
|
|
@ -687,13 +687,13 @@ class FreeplayState extends MusicBeatSubState
|
|||
}
|
||||
};
|
||||
|
||||
exitMovers.set([fp, txtCompletion, fnfHighscoreSpr, clearBoxSprite],
|
||||
exitMovers.set([fpScoreDisplay, txtCompletion, fnfHighscoreSpr, clearBoxSprite],
|
||||
{
|
||||
x: FlxG.width,
|
||||
speed: 0.3
|
||||
});
|
||||
|
||||
exitMoversCharSel.set([fp, txtCompletion, fnfHighscoreSpr, clearBoxSprite],
|
||||
exitMoversCharSel.set([fpScoreDisplay, txtCompletion, fnfHighscoreSpr, clearBoxSprite],
|
||||
{
|
||||
y: -270,
|
||||
speed: 0.8,
|
||||
|
|
@ -781,8 +781,8 @@ class FreeplayState extends MusicBeatSubState
|
|||
freeplayTxtBg.visible = true;
|
||||
if (freeplayArrow != null) freeplayArrow.visible = true;
|
||||
ostName.visible = true;
|
||||
fp.visible = true;
|
||||
fp.updateScore(0);
|
||||
fpScoreDisplay.visible = true;
|
||||
fpScoreDisplay.updateScore(0);
|
||||
|
||||
clearBoxSprite.visible = true;
|
||||
txtCompletion.visible = true;
|
||||
|
|
@ -995,7 +995,6 @@ class FreeplayState extends MusicBeatSubState
|
|||
if (tempSong == null) continue;
|
||||
|
||||
var funnyMenu:SongMenuItem = grpCapsules.recycle(SongMenuItem);
|
||||
|
||||
funnyMenu.initPosition(FlxG.width, 0);
|
||||
funnyMenu.initData(tempSong, styleData, i + 1);
|
||||
funnyMenu.onConfirm = function() {
|
||||
|
|
@ -1702,7 +1701,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
lerpCompletion = intendedCompletion;
|
||||
}
|
||||
|
||||
fp.updateScore(Std.int(lerpScore));
|
||||
fpScoreDisplay.updateScore(Std.int(lerpScore));
|
||||
|
||||
// sets the text of the completion percentage. Perhaps eventually we may want to generalize this,
|
||||
// but for now we can just clamp the values between 0 and 100.
|
||||
|
|
|
|||
|
|
@ -95,21 +95,12 @@ class WindowUtil
|
|||
*/
|
||||
public static final windowExit:FlxTypedSignal<Int->Void> = new FlxTypedSignal<Int->Void>();
|
||||
|
||||
/**
|
||||
* Has `initWindowEvents()` been called already?
|
||||
* This is to prevent multiple instances of the same function.
|
||||
*/
|
||||
private static var _initializedWindowEvents:Bool = false;
|
||||
|
||||
/**
|
||||
* Wires up FlxSignals that happen based on window activity.
|
||||
* For example, we can run a callback when the window is closed.
|
||||
*/
|
||||
public static function initWindowEvents():Void
|
||||
{
|
||||
if (_initializedWindowEvents) return; // Fix that annoying
|
||||
// onUpdate is called every frame just before rendering.
|
||||
|
||||
// onExit is called when the game window is closed.
|
||||
openfl.Lib.current.stage.application.onExit.add(function(exitCode:Int) {
|
||||
windowExit.dispatch(exitCode);
|
||||
|
|
@ -144,7 +135,6 @@ class WindowUtil
|
|||
}
|
||||
});
|
||||
#end
|
||||
_initializedWindowEvents = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -164,7 +154,11 @@ class WindowUtil
|
|||
public static function showError(name:String, desc:String):Void
|
||||
{
|
||||
#if (windows && cpp)
|
||||
funkin.external.windows.WinAPI.showError(desc, name);
|
||||
final handleVal:Float = lime.app.Application.current.window.nativeHandle;
|
||||
|
||||
final handlePtr:cpp.RawPointer<cpp.Void> = untyped __cpp__('(void*)(uintptr_t){0}', handleVal);
|
||||
|
||||
funkin.external.windows.WinAPI.showError(handlePtr, desc, name);
|
||||
#else
|
||||
lime.app.Application.current.window.alert(desc, name);
|
||||
#end
|
||||
|
|
@ -178,7 +172,11 @@ class WindowUtil
|
|||
public static function showWarning(name:String, desc:String):Void
|
||||
{
|
||||
#if (windows && cpp)
|
||||
funkin.external.windows.WinAPI.showWarning(desc, name);
|
||||
final handleVal:Float = lime.app.Application.current.window.nativeHandle;
|
||||
|
||||
final handlePtr:cpp.RawPointer<cpp.Void> = untyped __cpp__('(void*)(uintptr_t){0}', handleVal);
|
||||
|
||||
funkin.external.windows.WinAPI.showWarning(handlePtr, desc, name);
|
||||
#else
|
||||
lime.app.Application.current.window.alert(desc, name);
|
||||
#end
|
||||
|
|
@ -192,23 +190,30 @@ class WindowUtil
|
|||
public static function showInformation(name:String, desc:String):Void
|
||||
{
|
||||
#if (windows && cpp)
|
||||
funkin.external.windows.WinAPI.showInformation(desc, name);
|
||||
final handleVal:Float = lime.app.Application.current.window.nativeHandle;
|
||||
|
||||
final handlePtr:cpp.RawPointer<cpp.Void> = untyped __cpp__('(void*)(uintptr_t){0}', handleVal);
|
||||
|
||||
funkin.external.windows.WinAPI.showInformation(handlePtr, desc, name);
|
||||
#else
|
||||
lime.app.Application.current.window.alert(desc, name);
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a question dialog with a question icon and OK/Cancel buttons.
|
||||
* @param name The title of the dialog window.
|
||||
* @param desc The question message to display.
|
||||
* Sets the dark mode appearance for the specified window.
|
||||
*
|
||||
* @param window The window instance to modify.
|
||||
* @param value Whether to enable (`true`) or disable (`false`) dark mode.
|
||||
*/
|
||||
public static function showQuestion(name:String, desc:String):Void
|
||||
public static function setDarkMode(window:lime.ui.Window, value:Bool):Void
|
||||
{
|
||||
#if (windows && cpp)
|
||||
funkin.external.windows.WinAPI.showQuestion(desc, name);
|
||||
#else
|
||||
lime.app.Application.current.window.alert(desc, name);
|
||||
final handleVal:Float = window.nativeHandle;
|
||||
|
||||
final handlePtr:cpp.RawPointer<cpp.Void> = untyped __cpp__('(void*)(uintptr_t){0}', handleVal);
|
||||
|
||||
funkin.external.windows.WinAPI.setDarkMode(handlePtr, value);
|
||||
#end
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ import hxgamemode.GamemodeClient;
|
|||
class ApplicationIcon extends lime.graphics.Image {}
|
||||
#end
|
||||
|
||||
#if (windows && cpp)
|
||||
using funkin.util.WindowUtil;
|
||||
#end
|
||||
|
||||
@:access(lime.app.Application)
|
||||
@:access(lime.system.System)
|
||||
@:access(openfl.display.Stage)
|
||||
|
|
@ -21,8 +25,24 @@ class ApplicationIcon extends lime.graphics.Image {}
|
|||
class ApplicationMain
|
||||
{
|
||||
#if !macro
|
||||
public static function main()
|
||||
|
||||
#if (windows && cpp)
|
||||
public static var systemDarkMode:Bool = false;
|
||||
#end
|
||||
|
||||
public static function main():Void
|
||||
{
|
||||
#if (windows && cpp)
|
||||
// Disable the Windows "ghosting" effect that dims unresponsive windows.
|
||||
funkin.external.windows.WinAPI.disableWindowsGhosting();
|
||||
|
||||
// Disable Windows error reporting (avoids sending bug reports to Microsoft).
|
||||
funkin.external.windows.WinAPI.disableErrorReporting();
|
||||
|
||||
// Whether the system is currently using dark mode.
|
||||
systemDarkMode = funkin.external.windows.WinAPI.isSystemDarkMode();
|
||||
#end
|
||||
|
||||
lime.system.System.__registerEntryPoint("::APP_FILE::", create);
|
||||
|
||||
#if (js && html5)
|
||||
|
|
@ -36,6 +56,10 @@ class ApplicationMain
|
|||
|
||||
public static function create(config):Void
|
||||
{
|
||||
#if linux
|
||||
GamemodeClient.request_start();
|
||||
#end
|
||||
|
||||
final appMeta:Map<String, String> = [];
|
||||
|
||||
appMeta.set("build", "::meta.buildNumber::");
|
||||
|
|
@ -52,12 +76,20 @@ class ApplicationMain
|
|||
|
||||
var app = new openfl.display.Application(appMeta);
|
||||
|
||||
#if linux
|
||||
#if ((windows && cpp) || linux)
|
||||
app.onCreateWindow.add(function(window:lime.ui.Window):Void
|
||||
{
|
||||
#if (windows && cpp)
|
||||
if (systemDarkMode)
|
||||
{
|
||||
window.setDarkMode(systemDarkMode);
|
||||
}
|
||||
#end
|
||||
|
||||
#if linux
|
||||
window.setIcon(new ApplicationIcon());
|
||||
#end
|
||||
});
|
||||
GamemodeClient.request_start();
|
||||
#end
|
||||
|
||||
#if !disable_preloader_assets
|
||||
|
|
@ -128,20 +160,6 @@ class ApplicationMain
|
|||
app.window.frameRate = ::WIN_FPS::;
|
||||
#end
|
||||
|
||||
#if (windows && cpp)
|
||||
// Disable the Windows "ghosting" effect that dims unresponsive windows.
|
||||
funkin.external.windows.WinAPI.disableWindowsGhosting();
|
||||
|
||||
// Disable Windows error reporting (avoids sending bug reports to Microsoft).
|
||||
funkin.external.windows.WinAPI.disableErrorReporting();
|
||||
|
||||
// Enable dark mode if the system theme is set to dark.
|
||||
if (funkin.external.windows.WinAPI.isSystemDarkMode())
|
||||
{
|
||||
funkin.external.windows.WinAPI.setDarkMode(true);
|
||||
}
|
||||
#end
|
||||
|
||||
var preloader = getPreloader();
|
||||
app.preloader.onProgress.add (function(loaded, total)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue