im back bitches (for a little) wip

Co-Authored-By: Ne_Eo <NeeEoo@users.noreply.github.com>
This commit is contained in:
⍚~Nex
2024-08-16 20:09:51 +02:00
co-authored by Ne_Eo
parent de0a02dd50
commit c6a42bb661
12 changed files with 298 additions and 105 deletions
+2 -2
View File
@@ -45,13 +45,13 @@
<group name="Pause">
<group name="PauseOptions">
<!-- These are actually the only strings that dont require an english translation, you can still translate them though
<!-- These are actually the only strings that dont require an english translation, you can still translate them though -->
<str id="pause.resume">Resume</str>
<str id="pause.restartSong">Restart Song</str>
<str id="pause.changeControls">Change Controls</str>
<str id="pause.changeOptions">Change Options</str>
<str id="pause.exitToMenu">Exit to menu</str>
<str id="pause.exitToCharter">Exit to charter</str> -->
<str id="pause.exitToCharter">Exit to charter</str>
</group>
<str id="pause.deathCounter">Blue balled: {0}</str>
+115
View File
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="utf-8" ?>
<language>
<group name="OptionsMenu">
<str id="optionsMenu.header.title">Options Menu</str>
<str id="optionsMenu.header.desc">Select a category to continue.</str>
<str id="optionsTree.controls-name">Controls</str>
<str id="optionsTree.controls-desc">Change Controls for Player 1 and Player 2!</str>
<str id="optionsTree.gameplay-name">Gameplay &gt;</str>
<str id="optionsTree.gameplay-desc">Change Gameplay options such as Downscroll, Scroll Speed, Naughtyness...</str>
<str id="optionsTree.appearance-name">Appearance &gt;</str>
<str id="optionsTree.appearance-desc">Change Appearance options such as Flashing menus...</str>
<str id="optionsTree.miscellaneous-name">Miscellaneous &gt;</str>
<str id="optionsTree.miscellaneous-desc">Use this menu to reset save data or engine settings.</str>
<!-- cant have debug here -->
</group>
<group name="AppearanceOptions" prefix="AppearanceOptions">
<str id="framerate-name">Framerate</str>
<str id="framerate-desc">Pretty self explanatory, isn't it?</str>
<str id="antialiasing-name">Antialiasing</str>
<str id="antialiasing-desc">If unchecked, will disable antialiasing on every sprite. Can boost performances at the cost of sharper, more pixely sprites.</str>
<str id="colorHealthBar-name">Colored Healthbar</str>
<str id="colorHealthBar-desc">If unchecked, the game will use the orginal red/green health bar from the week 6 fnf game.</str>
<str id="week6PixelPerfect-name">Pixel Perfect Effect</str>
<str id="week6PixelPerfect-desc">If checked, Week 6 will have a pixel perfect effect to it enabled, aligning every pixel on the screen.</str>
<str id="gameplayShaders-name">Gameplay Shaders</str>
<str id="gameplayShaders-desc">If unchecked, gameplay shaders (visual effects like Thorns's Chromatic Aberration) wont be loaded; this may be helpful on weak devices.</str>
<str id="flashingMenu-name">Flashing Menu</str>
<str id="flashingMenu-desc">If unchecked, will disable menu flashing when you select an option in the Main Menu, and other flashes will be slower.</str>
<str id="lowMemoryMode-name">Low Memory Mode</str>
<str id="lowMemoryMode-desc">If checked, will disable certain background elements in stages to reduce memory usage.</str>
<str id="gpuOnlyBitmaps-name">VRAM-Only Sprites</str>
<str id="gpuOnlyBitmaps-desc">If checked, will only store the bitmaps in the GPU, freeing a LOT of memory (EXPERIMENTAL). Turning this off will consume a lot of memory, especially on bigger sprites. If you aren't sure, leave this on.</str>
<str id="autoPause-name">Auto Pause</str>
<str id="autoPause-desc">If checked, switching windows will pause the game.</str>
</group>
<group name="GameplayOptions" prefix="GameplayOptions">
<str id="downscroll-name">Downscroll</str>
<str id="downscroll-desc">If checked, notes will go from up to down instead of down to up, as if they're falling.</str>
<str id="ghostTapping-name">Ghost Tapping</str>
<str id="ghostTapping-desc">If unchecked, trying to hit any strum that have no note that can be hit will cause a miss.</str>
<str id="songOffset-name">Song Offset</str>
<str id="songOffset-desc">Changes the offset that songs should start with.</str>
<str id="naughtyness-name">Naughtyness</str>
<str id="naughtyness-desc">If unchecked, will censor the Week 7 cutscenes.</str>
<str id="camZoomOnBeat-name">Camera Zoom on Beat</str>
<str id="camZoomOnBeat-desc">If unchecked, will stop the camera from zooming in every 4 beats</str>
</group>
<group name="MiscOptions" prefix="MiscOptions">
<str id="language-name">Language</str>
<str id="language-desc">The language that the engine currently uses (the default one is {0}).</str>
<str id="forceCrash-name">Force Crash</str>
<str id="forceCrash-desc">Select this option to force a crash.</str>
<str id="betaUpdates-name">Enable Nightly Updates</str>
<str id="betaUpdates-desc">If checked, will also include nightly builds in the update checking.</str>
<str id="checkForUpdates-name">Check for Updates</str>
<str id="checkForUpdates-desc">Select this option to check for new engine updates.</str>
<str id="checkForUpdates-noUpdateFound">No update found.</str>
<str id="resetSaveData-name">Reset Save Data</str>
<str id="resetSaveData-desc">Select this option to reset save data. This will remove all of your highscores.</str>
</group>
<group name="DebugOptions" prefix="DebugOptions">
<str id="title">Debug Options</str>
<str id="desc">Use this menu to enable or disable debug options.</str>
<str id="showConsole-name">Show Console</str>
<str id="showConsole-desc">Select this to show the debug console, which contains log information about the game.</str>
<str id="editorSFX-name">Editor SFXs</str>
<str id="editorSFX-desc">If checked, will play sound effects when working on editors (ex: will play sfxs when checking checkboxes...)</str>
<str id="editorPrettyPrint-name">Pretty Print</str>
<str id="editorPrettyPrint-desc">If checked, the saved files from the editor will be formatted to be easily viewable (does not apply to xmls...)</str>
<str id="intensiveBlur-name">Intensive Blur</str>
<str id="intensiveBlur-desc">If checked, will use more intensive blur that may be laggier but look better.</str>
<str id="charterAutoSaves-name">Editor Autosaves</str>
<str id="charterAutoSaves-desc">If checked, this will autosave your files in the editor, with the settings listed below.</str>
<str id="charterAutoSaveTime-name">Autosaving Time</str>
<str id="charterAutoSaveTime-desc">This controls how often the editor will autosave your file (in seconds...)</str>
<str id="charterAutoSaveWarningTime-name">Save Warning Time</str>
<str id="charterAutoSaveWarningTime-desc">This controls how long the editor will warn you before it autosaves (in seconds..., 0 to disable)</str>
<str id="charterAutoSavesSeperateFolder-name">Autosaves Folder</str>
<str id="charterAutoSavesSeperateFolder-desc">If checked, this will autosave your file in a seperate folder with a time stamp instead of overriding your current file. (song/autosaves/)</str>
</group>
</language>
+6 -2
View File
@@ -1,3 +1,7 @@
name="English"
credits="Codename Engine"
version="0.0.1"
credits="Codename Engine Devs"
version="0.0.1"
; Shows missing ID:s as {id} and prints in the console Missing Translation IDs: id
; otherwhise uses the other languages (based on the chosen order) for the missing translations
showMissingIds="true"
+45 -10
View File
@@ -61,6 +61,8 @@ final class TranslationUtil
*/
public static var foundLanguages:Array<String> = [];
public static var showMissingIds:Bool = false;
// Private
private static inline var LANG_FOLDER:String = "languages";
private static var langConfigs:Map<String, IniMap> = [];
@@ -98,6 +100,8 @@ final class TranslationUtil
config = getConfig(name);
stringMap = loadLanguage(name);
showMissingIds = config.get("showMissingIds").getDefault("false") == "true";
#end
}
@@ -115,13 +119,31 @@ final class TranslationUtil
public static inline function translateDiff(?id:String, ?params:Array<Dynamic>):String
return get("diff." + id.toLowerCase(), params, id);
public static inline function exists(id:String):Bool
#if TRANSLATIONS_SUPPORT
return stringMap.exists(id);
#else
return false;
#end
public static function getUnformatted(id:String, ?def:String):IFormatInfo
{
#if TRANSLATIONS_SUPPORT
if (stringMap.exists(id)) return stringMap.get(id);
#end
if(def != null) id = def;
return FormatUtil.get(id);
if(def != null)
return FormatUtil.get(def);
return FormatUtil.getStr("{" + id + "}");
/*if(curLanguage == DEFAULT_LANGUAGE) {
return FormatUtil.getStr("{" + id + "}");
} else {
}
return FormatUtil.get(showMissingIds ? "{" + id + "}" : id);*/
}
/**
@@ -187,13 +209,16 @@ final class TranslationUtil
FormatUtil.clear(); // Clean up the format cache
var mainPath:String = translationsMain(lang);
var leMap:Map<String, IFormatInfo> = [];
var translations = [];
function parseXml(xml:Access) {
var translations:Array<TranslationPair> = [];
function parseXml(xml:Access, prefix:String = "") {
for(node in xml.elements) {
if (node.name == "group") // Cosmetic name
parseXml(node);
parseXml(node, prefix + (node.has.prefix ? node.att.prefix : ""));
else if(["text", "trans", "lang", "string", "str"].contains(node.name))
translations.push(node);
translations.push({
prefix: prefix,
node: node
});
}
}
@@ -220,18 +245,22 @@ final class TranslationUtil
parseXml(langNode);
}
for(node in translations) {
for(pair in translations) {
var node = pair.node;
if (!node.has.id) {
Logs.warn('A <${node.name}> node requires an ID attribute.', "Language");
continue;
}
var prefix = pair.prefix;
if(leMap.exists(node.att.id)) continue;
var id = prefix + node.att.id;
if(leMap.exists(id)) continue;
var value:String = node.has.string ? node.att.string : node.innerData;
if(node.getAtt("notrim").getDefault("true") != "true") value = value.trim();
value = value.replace("\\n", "\n").replace("\r", ""); // remove stupid windows line breaks and convert newline literals to newlines
leMap.set(node.att.id, FormatUtil.get(value));
//Logs.trace("Added " + node.att.id + " -> `" + value + "`", "Language");
leMap.set(id, FormatUtil.get(value));
//Logs.trace("Added " + id + " -> `" + value + "`", "Language");
}
return leMap;
@@ -288,4 +317,10 @@ final class TranslationUtil
@:noCompletion private static function get_isLanguageLoaded():Bool
return Lambda.count(stringMap) > 0;
}
@:structInit
class TranslationPair {
public var prefix:String;
public var node:Access;
}
@@ -7,6 +7,7 @@ package funkin.backend.utils.translations;
*/
class FormatUtil {
private static var cache:Map<String, IFormatInfo> = new Map();
private static var cacheStr:Map<String, IFormatInfo> = new Map();
public static function get(id:String):IFormatInfo {
if (cache.exists(id))
@@ -18,8 +19,18 @@ class FormatUtil {
return fi;
}
public static function getStr(id:String):IFormatInfo {
if (cacheStr.exists(id))
return cacheStr.get(id);
var fi:IFormatInfo = new StrFormatInfo(id);
cacheStr.set(id, fi);
return fi;
}
public inline static function clear() {
cache.clear();
cacheStr.clear();
}
}
+18 -17
View File
@@ -26,46 +26,47 @@ class DebugOptions extends TreeMenu {
class DebugOptionsScreen extends OptionsScreen {
public override function new() {
super("Debug Options", "Use this menu to change debug options.");
prefix = "DebugOptions";
super(translate("title"), translate("desc"), prefix);
#if windows
add(new TextOption(
"Show Console",
"Select this to show the debug console, which contains log information about the game.",
getName("showConsole"),
getDesc("showConsole"),
function() {
NativeAPI.allocConsole();
}));
#end
add(new Checkbox(
"Editor SFXs",
"If checked, will play sound effects when working on editors (ex: will play sfxs when checking checkboxes...)",
getName("editorSFX"),
getDesc("editorSFX"),
"editorSFX"));
add(new Checkbox(
"Pretty Print",
"If checked, the saved files from the editor will be formatted to be easily viewable (does not apply to xmls...)",
getName("editorPrettyPrint"),
getDesc("editorPrettyPrint"),
"editorPrettyPrint"));
add(new Checkbox(
"Intensive Blur",
"If checked, will use more intensive blur that may be laggier but look better.",
getName("intensiveBlur"),
getDesc("intensiveBlur"),
"intensiveBlur"));
add(new Checkbox(
"Editor Autosaves",
"If checked, this will autosave your files in the editor, with the settings listed below.",
getName("charterAutoSaves"),
getDesc("charterAutoSaves"),
"charterAutoSaves"));
add(new NumOption(
"Autosaving Time",
"This controls how often the editor will autosave your file (in seconds...)",
getName("charterAutoSaveTime"),
getDesc("charterAutoSaveTime"),
60, 60*10, 30,
"charterAutoSaveTime"
));
add(new NumOption(
"Save Warning Time",
"This controls how long the editor will warn you before it autosaves (in seconds..., 0 to disable)",
getName("charterAutoSaveWarningTime"),
getDesc("charterAutoSaveWarningTime"),
0, 15, 1,
"charterAutoSaveWarningTime"
));
add(new Checkbox(
"Autosaves Folder",
"If checked, this will autosave your file in a seperate folder with a time stamp instead of overriding your current file. (song/autosaves/)",
getName("charterAutoSavesSeperateFolder"),
getDesc("charterAutoSavesSeperateFolder"),
"charterAutoSavesSeperateFolder"));
}
}
+8
View File
@@ -9,26 +9,33 @@ class EditorPicker extends MusicBeatSubstate {
public var options:Array<Editor> = [
{
name: "Chart Editor",
id: "charter",
iconID: 0,
state: funkin.editors.charter.CharterSelection
},
{
name: "Character Editor",
id: "character",
iconID: 1,
state: funkin.editors.character.CharacterSelection
},
{
name: "Stage Editor",
id: "stage",
iconID: 2,
state: null
},
#if (debug || debug_ui)
{
name: "UI Debug State",
id: "ui-debug",
iconID: 3,
state: UIDebugState
},
#end
{
name: "Debug Options",
id: "debug-options",
iconID: 4,
state: DebugOptions
}
@@ -143,6 +150,7 @@ class EditorPicker extends MusicBeatSubstate {
typedef Editor = {
var name:String;
var id:String;
var iconID:Int;
var state:Class<MusicBeatState>;
}
+30 -24
View File
@@ -9,25 +9,25 @@ import haxe.xml.Access;
class OptionsMenu extends TreeMenu {
public static var mainOptions:Array<OptionCategory> = [
{
name: 'Controls',
desc: 'Change Controls for Player 1 and Player 2!',
{ // name and desc are actually the translations ids! - Nex
name: 'optionsTree.controls-name',
desc: 'optionsTree.controls-desc',
state: null,
substate: funkin.options.keybinds.KeybindsOptions
},
{
name: 'Gameplay >',
desc: 'Change Gameplay options such as Downscroll, Scroll Speed, Naughtyness...',
name: 'optionsTree.gameplay-name',
desc: 'optionsTree.gameplay-desc',
state: GameplayOptions
},
{
name: 'Appearance >',
desc: 'Change Appearance options such as Flashing menus...',
name: 'optionsTree.appearance-name',
desc: 'optionsTree.appearance-desc',
state: AppearanceOptions
},
{
name: 'Miscellaneous >',
desc: 'Use this menu to reset save data or engine settings.',
name: 'optionsTree.miscellaneous-name',
desc: 'optionsTree.miscellaneous-desc',
state: MiscOptions
}
];
@@ -48,23 +48,29 @@ class OptionsMenu extends TreeMenu {
bg.antialiasing = true;
add(bg);
main = new OptionsScreen("Options", "Select a category to continue.", [for(o in mainOptions) new TextOption(o.name, o.desc, function() {
if (o.substate != null) {
persistentUpdate = false;
persistentDraw = true;
if (o.substate is MusicBeatSubstate) {
openSubState(o.substate);
main = new OptionsScreen(TU.translate("optionsMenu.header.title"), TU.translate("optionsMenu.header.desc"), [for(o in mainOptions) {
var name = o.name;
var desc = o.desc;
if(TU.exists(name)) name = TU.translate(name);
if(TU.exists(desc)) desc = TU.translate(desc);
new TextOption(name, desc, function() {
if (o.substate != null) {
persistentUpdate = false;
persistentDraw = true;
if (o.substate is MusicBeatSubstate) {
openSubState(o.substate);
} else {
openSubState(Type.createInstance(o.substate, [name, desc]));
}
} else {
openSubState(Type.createInstance(o.substate, []));
if (o.state is OptionsScreen) {
optionsTree.add(o.state);
} else {
optionsTree.add(Type.createInstance(o.state, [name, desc]));
}
}
} else {
if (o.state is OptionsScreen) {
optionsTree.add(o.state);
} else {
optionsTree.add(Type.createInstance(o.state, []));
}
}
})]);
});
}]);
var xmlPath = Paths.xml("config/options");
for(source in [funkin.backend.assets.AssetSource.SOURCE, funkin.backend.assets.AssetSource.MODS]) {
+13 -1
View File
@@ -14,11 +14,23 @@ class OptionsScreen extends FlxTypedSpriteGroup<OptionType> {
public var name:String;
public var desc:String;
public var prefix:String = "";
public function new(name:String, desc:String, ?options:Array<OptionType>) {
public function getName(name:String, ?args:Array<Dynamic>):String {
return TU.translate(prefix + name + "-name", args);
}
public function getDesc(name:String, ?args:Array<Dynamic>):String {
return TU.translate(prefix + name + "-desc", args);
}
public function translate(name:String, ?args:Array<Dynamic>):String {
return TU.translate(prefix + name, args);
}
public function new(name:String, desc:String, ?prefix:String, ?options:Array<OptionType>) {
super();
this.name = name;
this.desc = desc;
if (prefix != null) this.prefix = prefix;
if (options != null) for(o in options) add(o);
}
@@ -1,51 +1,51 @@
package funkin.options.categories;
class AppearanceOptions extends OptionsScreen {
public override function new() {
super("Appearance", "Change Appearance options such as Flashing menus...");
public override function new(title:String, desc:String) {
super(title, desc, "AppearanceOptions");
add(new NumOption(
"Framerate",
"Pretty self explanatory, isn't it?",
getName("framerate"),
getDesc("framerate"),
30, // minimum
240, // maximum
10, // change
"framerate", // save name or smth
__changeFPS)); // callback
add(new Checkbox(
"Antialiasing",
"If unchecked, will disable antialiasing on every sprite. Can boost performances at the cost of sharper, more pixely sprites.",
getName("antialiasing"),
getDesc("antialiasing"),
"antialiasing"));
add(new Checkbox(
"Colored Healthbar",
"If unchecked, the game will use the orginal red/green health bar from the week 6 fnf game.",
getName("colorHealthBar"),
getDesc("colorHealthBar"),
"colorHealthBar"));
add(new Checkbox(
"Pixel Perfect Effect",
"If checked, Week 6 will have a pixel perfect effect to it enabled, aligning every pixel on the screen.",
getName("week6PixelPerfect"),
getDesc("week6PixelPerfect"),
"week6PixelPerfect"));
add(new Checkbox(
"Gameplay Shaders",
"If unchecked, gameplay shaders (visual effects like Thorns's Chromatic Aberration) wont be loaded; this may be helpful on weak devices.",
getName("gameplayShaders"),
getDesc("gameplayShaders"),
"gameplayShaders"));
add(new Checkbox(
"Flashing Menu",
"If unchecked, will disable menu flashing when you select an option in the Main Menu, and other flashes will be slower.",
getName("flashingMenu"),
getDesc("flashingMenu"),
"flashingMenu"));
add(new Checkbox(
"Low Memory Mode",
"If checked, will disable certain background elements in stages to reduce memory usage.",
getName("lowMemoryMode"),
getDesc("lowMemoryMode"),
"lowMemoryMode"));
#if sys
if (!Main.forceGPUOnlyBitmapsOff) {
add(new Checkbox(
"VRAM-Only Sprites",
"If checked, will only store the bitmaps in the GPU, freeing a LOT of memory (EXPERIMENTAL). Turning this off will consume a lot of memory, especially on bigger sprites. If you aren't sure, leave this on.",
getName("gpuOnlyBitmaps"),
getDesc("gpuOnlyBitmaps"),
"gpuOnlyBitmaps"));
}
#end
add(new Checkbox(
"Auto Pause",
"If checked, switching windows will pause the game.",
getName("autoPause"),
getDesc("autoPause"),
"autoPause"));
}
@@ -8,31 +8,31 @@ class GameplayOptions extends OptionsScreen {
var offsetSetting:NumOption;
public override function new() {
super("Gameplay", 'Change Gameplay options such as Downscroll, Scroll Speed, Naughtyness...');
public override function new(title:String, desc:String) {
super(title, desc, "GameplayOptions");
add(new Checkbox(
"Downscroll",
"If checked, notes will go from up to down instead of down to up, as if they're falling.",
getName("downscroll"),
getDesc("downscroll"),
"downscroll"));
add(new Checkbox(
"Ghost Tapping",
"If unchecked, trying to hit any strum that have no note that can be hit will cause a miss.",
getName("ghostTapping"),
getDesc("ghostTapping"),
"ghostTapping"));
add(offsetSetting = new NumOption(
"Song Offset",
"Changes the offset that songs should start with.",
getName("songOffset"),
getDesc("songOffset"),
-999, // minimum
999, // maximum
1, // change
"songOffset", // save name or smth
__changeOffset)); // callback
add(new Checkbox(
"Naughtyness",
"If unchecked, will censor the Week 7 cutscenes.",
getName("naughtyness"),
getDesc("naughtyness"),
"naughtyness"));
add(new Checkbox(
"Camera Zoom on Beat",
"If unchecked, will stop the camera from zooming in every 4 beats",
getName("camZoomOnBeat"),
getDesc("camZoomOnBeat"),
"camZoomOnBeat"));
}
+18 -17
View File
@@ -2,54 +2,55 @@ package funkin.options.categories;
class MiscOptions extends OptionsScreen {
public override function new() {
super("Miscellaneous", "Use this menu to reset save data or engine settings.");
public override function new(title:String, desc:String) {
super(title, desc, "MiscOptions");
{ // Language Option
var lanArray:Array<String> = TranslationUtil.foundLanguages;
// TODO: add credits based on the config file
add(new ArrayOption(
"Language",
'The language that the engine currently uses (the default one is ${TranslationUtil.DEFAULT_LANGUAGE}).',
getName("language"),
getDesc("language", [TranslationUtil.DEFAULT_LANGUAGE]),
[for(lan in lanArray) lan.split("/").first()],
[for(lan in lanArray) lan.split("/").last()], "language",
[for(lan in lanArray) lan.split("/").last()],
"language",
function(path:String) {
TranslationUtil.setLanguage(path);
parent.remove(this);
// Reload the current screen
// todo add parent.reload();
this.clear();
parent.add(new MiscOptions());
parent.add(new MiscOptions(title, desc));
}));
}
add(new TextOption(
"Force Crash",
"Select this option to force a crash.",
getName("forceCrash"),
getDesc("forceCrash"),
() -> { throw new haxe.Exception("Forced crash."); }
));
#if UPDATE_CHECKING
add(new Checkbox(
"Enable Nightly Updates",
"If checked, will also include nightly builds in the update checking.",
"betaUpdates"));,
getName("betaUpdates"),
getDesc("betaUpdates"),
"betaUpdates"));
add(new TextOption(
"Check for Updates",
"Select this option to check for new engine updates.",
getName("checkForUpdates"),
getDesc("checkForUpdates"),
function() {
var report = funkin.backend.system.updating.UpdateUtil.checkForUpdates();
if (report.newUpdate) {
FlxG.switchState(new funkin.backend.system.updating.UpdateAvailableScreen(report));
} else {
CoolUtil.playMenuSFX(CANCEL);
updateDescText("No update found.");
updateDescText(TU.translate(prefix + "checkForUpdates-noUpdateFound"));
}
}));,
}));
#end
add(new TextOption(
"Reset Save Data",
"Select this option to reset save data. This will remove all of your highscores.",
getName("resetSaveData"),
getDesc("resetSaveData"),
function() {
// TODO: SAVE DATA RESETTING
}));