diff --git a/assets/data/stages/mall.xml b/assets/data/stages/mall.xml
index 3552cf27..3565f1be 100644
--- a/assets/data/stages/mall.xml
+++ b/assets/data/stages/mall.xml
@@ -1,21 +1,21 @@
-
+
-
+
-
+
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
\ No newline at end of file
+
diff --git a/source/funkin/backend/system/MainState.hx b/source/funkin/backend/system/MainState.hx
index 32a75569..f3673dd6 100644
--- a/source/funkin/backend/system/MainState.hx
+++ b/source/funkin/backend/system/MainState.hx
@@ -66,9 +66,6 @@ class MainState extends FlxState {
betaWarningShown = true;
}
- #if sys
- sys.FileSystem.createDirectory('./.temp/');
- #if windows new funkin.backend.utils.native.HiddenProcess("attrib +h .temp"); #end
- #end
+ CoolUtil.safeSetAttribute('./.temp/', HIDDEN);
}
}
\ No newline at end of file
diff --git a/source/funkin/backend/utils/CoolUtil.hx b/source/funkin/backend/utils/CoolUtil.hx
index 36f817e8..1fbe4e35 100644
--- a/source/funkin/backend/utils/CoolUtil.hx
+++ b/source/funkin/backend/utils/CoolUtil.hx
@@ -1,5 +1,8 @@
package funkin.backend.utils;
+#if sys
+import sys.FileSystem;
+#end
import flixel.animation.FlxAnimation;
import flixel.input.keyboard.FlxKey;
import flixel.sound.FlxSound;
@@ -62,18 +65,15 @@ class CoolUtil
*/
@:noUsing public static function deleteFolder(delete:String) {
#if sys
- if (!sys.FileSystem.exists(delete)) return;
- var files:Array = sys.FileSystem.readDirectory(delete);
+ if (!FileSystem.exists(delete)) return;
+ var files:Array = FileSystem.readDirectory(delete);
for(file in files) {
- if (sys.FileSystem.isDirectory(delete + "/" + file)) {
+ if (FileSystem.isDirectory(delete + "/" + file)) {
deleteFolder(delete + "/" + file);
- sys.FileSystem.deleteDirectory(delete + "/" + file);
+ FileSystem.deleteDirectory(delete + "/" + file);
} else {
- try {
- sys.FileSystem.deleteFile(delete + "/" + file);
- } catch(e) {
- Logs.trace("Could not delete " + delete + "/" + file, WARNING);
- }
+ try FileSystem.deleteFile(delete + "/" + file)
+ catch(e) Logs.trace("Could not delete " + delete + "/" + file, WARNING);
}
}
#end
@@ -98,6 +98,22 @@ class CoolUtil
#end
}
+ /**
+ * Sets an attribute to a file or a folder adding eventual missing folders in the path
+ * (WARNING: Only works on `windows`. On other platforms the return code it's always going to be `0` but still creates eventual missing folders if the platforms allows it to).
+ * @param path Path to the file or folder
+ * @param attrib The attribute to set (WARNING: There are some non settable attributes, such as the `COMPRESSED` one)
+ * @param useAbsol If it should use the absolute path (By default it's `true` but if it's `false` you can use files outside from this program's directory for example)
+ * @return The result code: 0 means that it failed setting
+ */
+ @:noUsing public static inline function safeSetAttribute(path:String, attrib:NativeAPI.FileAttribute, useAbsol:Bool = true) {
+ addMissingFolders(Path.directory(path));
+
+ var result = NativeAPI.setFileAttribute(path, attrib, useAbsol);
+ if(result == 0) Logs.trace('Failed to set attribute to $path with a code of: $result', WARNING);
+ return result;
+ }
+
/**
* Creates eventual missing folders to the specified `path`
*
@@ -113,9 +129,8 @@ class CoolUtil
for (folder in folders) {
currentPath += folder + "/";
- if (!sys.FileSystem.exists(currentPath)) {
- sys.FileSystem.createDirectory(currentPath);
- }
+ if (!FileSystem.exists(currentPath))
+ FileSystem.createDirectory(currentPath);
}
#end
return path;
diff --git a/source/funkin/backend/utils/NativeAPI.hx b/source/funkin/backend/utils/NativeAPI.hx
index a651645e..495403dc 100644
--- a/source/funkin/backend/utils/NativeAPI.hx
+++ b/source/funkin/backend/utils/NativeAPI.hx
@@ -29,6 +29,30 @@ class NativeAPI {
#end
}
+ /**
+ * Gets the specified file's (or folder) attribute.
+ */
+ public static function getFileAttribute(path:String, useAbsol:Bool = true):FileAttribute {
+ #if windows
+ if(useAbsol) path = sys.FileSystem.absolutePath(path);
+ return Windows.getFileAttribute(path);
+ #else
+ return NORMAL;
+ #end
+ }
+
+ /**
+ * Sets the specified file's (or folder) attribute. If it fails, the return value is `0`.
+ */
+ public static function setFileAttribute(path:String, attrib:FileAttribute, useAbsol:Bool = true):Int {
+ #if windows
+ if(useAbsol) path = sys.FileSystem.absolutePath(path);
+ return Windows.setFileAttribute(path, attrib);
+ #else
+ return 0;
+ #end
+ }
+
public static function setDarkMode(title:String, enable:Bool) {
#if windows
Windows.setDarkMode(title, enable);
@@ -61,15 +85,13 @@ class NativeAPI {
var fg = cast(foregroundColor, Int);
var bg = cast(backgroundColor, Int);
Windows.setConsoleColors((bg * 16) + fg);
- #else
- #if sys
+ #elseif sys
Sys.print("\x1b[0m");
if(foregroundColor != NONE)
Sys.print("\x1b[" + Std.int(consoleColorToANSI(foregroundColor)) + "m");
if(backgroundColor != NONE)
Sys.print("\x1b[" + Std.int(consoleColorToANSI(backgroundColor) + 10) + "m");
#end
- #end
}
public static function consoleColorToANSI(color:ConsoleColor) {
@@ -115,6 +137,26 @@ class NativeAPI {
}
}
+enum abstract FileAttribute(Int) {
+ // Settables
+ var ARCHIVE = 0x20;
+ var HIDDEN = 0x2;
+ var NORMAL = 0x80;
+ var NOT_CONTENT_INDEXED = 0x2000;
+ var OFFLINE = 0x1000;
+ var READONLY = 0x1;
+ var SYSTEM = 0x4;
+ var TEMPORARY = 0x100;
+
+ // Non Settables
+ var COMPRESSED = 0x800;
+ var DEVICE = 0x40;
+ var DIRECTORY = 0x10;
+ var ENCRYPTED = 0x4000;
+ var REPARSE_POINT = 0x400;
+ var SPARSE_FILE = 0x200;
+}
+
enum abstract ConsoleColor(Int) {
var BLACK = 0;
var DARKBLUE = 1;
diff --git a/source/funkin/backend/utils/native/Windows.hx b/source/funkin/backend/utils/native/Windows.hx
index 07312d8d..5b03b904 100644
--- a/source/funkin/backend/utils/native/Windows.hx
+++ b/source/funkin/backend/utils/native/Windows.hx
@@ -1,6 +1,7 @@
package funkin.backend.utils.native;
#if windows
+import funkin.backend.utils.NativeAPI.FileAttribute;
import funkin.backend.utils.NativeAPI.MessageBoxIcon;
@:buildXml('
@@ -153,6 +154,22 @@ class Windows {
public static function allocConsole() {
}
+ @:functionCode('
+ return GetFileAttributes(path);
+ ')
+ public static function getFileAttribute(path:String):FileAttribute
+ {
+ return NORMAL;
+ }
+
+ @:functionCode('
+ return SetFileAttributes(path, attrib);
+ ')
+ public static function setFileAttribute(path:String, attrib:FileAttribute):Int
+ {
+ return 0;
+ }
+
@:functionCode('
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
diff --git a/source/funkin/options/OptionsMenu.hx b/source/funkin/options/OptionsMenu.hx
index dff76067..facfcafc 100644
--- a/source/funkin/options/OptionsMenu.hx
+++ b/source/funkin/options/OptionsMenu.hx
@@ -48,8 +48,6 @@ class OptionsMenu extends TreeMenu {
bg.antialiasing = true;
add(bg);
- Framerate.offset.y = 60;
-
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;
diff --git a/source/funkin/options/TreeMenu.hx b/source/funkin/options/TreeMenu.hx
index 6fb4a8a5..4faa8cd0 100644
--- a/source/funkin/options/TreeMenu.hx
+++ b/source/funkin/options/TreeMenu.hx
@@ -7,6 +7,7 @@ import funkin.backend.FunkinText;
import funkin.editors.ui.UIState;
import funkin.menus.MainMenuState;
import funkin.options.type.OptionType;
+import funkin.backend.system.framerate.Framerate;
class TreeMenu extends UIState {
public var main:OptionsScreen;
@@ -97,6 +98,8 @@ class TreeMenu extends UIState {
var menuChangeTween:FlxTween;
public override function update(elapsed:Float) {
super.update(elapsed);
+
+ Framerate.offset.y = pathBG.height;
// in case path gets so long it goes offscreen
pathLabel.x = lerp(pathLabel.x, Math.max(0, FlxG.width - 4 - pathLabel.width), 0.125);