diff --git a/buildnumber.txt b/buildnumber.txt
index faf0797b..60177172 100644
--- a/buildnumber.txt
+++ b/buildnumber.txt
@@ -1 +1 @@
-1448
\ No newline at end of file
+1451
\ No newline at end of file
diff --git a/docs/doc.xml b/docs/doc.xml
index c7f9c553..6b4b4e92 100644
--- a/docs/doc.xml
+++ b/docs/doc.xml
@@ -12482,15 +12482,15 @@
-
+
-
+
-
+
@@ -66130,9 +66130,9 @@
- <__touch get="inline" set="null" expr=""1.670677951e+012"" line="22" static="1">
+ <__touch get="inline" set="null" expr=""1.670707736e+012"" line="22" static="1">
- "1.670677951e+012"
+ "1.670707736e+012"
@@ -129782,6 +129782,10 @@
+
+
+
+
diff --git a/source/funkin/system/CoolUtil.hx b/source/funkin/system/CoolUtil.hx
index f24d24c3..0bb00c47 100644
--- a/source/funkin/system/CoolUtil.hx
+++ b/source/funkin/system/CoolUtil.hx
@@ -49,6 +49,10 @@ class CoolUtil
return false;
}
+ public static function last(array:Array):T {
+ return array[array.length - 1];
+ }
+
public static function setFieldDefault(v:Dynamic, name:String, defaultValue:T):T {
if (Reflect.hasField(v, name)) {
var f:Null = Reflect.field(v, name);
@@ -274,13 +278,6 @@ class CoolUtil
return xml.att.resolve(name);
}
- /**
- * Returns last member of array
- */
- public static function last(array:Array):T {
- return array[array.length-1];
- }
-
public static function loadFrames(path:String, Unique:Bool = false, Key:String = null):FlxFramesCollection {
var noExt = Path.withoutExtension(path);
diff --git a/source/funkin/system/CrashHandler.hx b/source/funkin/system/CrashHandler.hx
new file mode 100644
index 00000000..7c8c2fb0
--- /dev/null
+++ b/source/funkin/system/CrashHandler.hx
@@ -0,0 +1,56 @@
+package funkin.system;
+
+import lime.system.System;
+import funkin.windows.WindowsAPI;
+import openfl.Lib;
+import openfl.events.UncaughtErrorEvent;
+import openfl.events.ErrorEvent;
+import openfl.errors.Error;
+import openfl.events.UncaughtErrorEvent;
+import haxe.CallStack;
+
+class CrashHandler {
+ public static function init() {
+ Lib.current.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onError);
+ }
+
+ public static function onError(e:UncaughtErrorEvent) {
+ var m:String = e.error;
+ if (Std.isOfType(e.error, Error)) {
+ var err = cast(e.error, Error);
+ m = '${err.message}';
+ } else if (Std.isOfType(e.error, ErrorEvent)) {
+ var err = cast(e.error, ErrorEvent);
+ m = '${err.text}';
+ }
+ var stack = CallStack.exceptionStack();
+ var stackLabel:String = "";
+ for(e in stack) {
+ switch(e) {
+ case CFunction: stackLabel += "- Non-Haxe (C) Function";
+ case Module(c): stackLabel += '- Module ${c}';
+ case FilePos(parent, file, line, col):
+ switch(parent) {
+ case Method(cla, func):
+ stackLabel += '- (${file}) ${cla.split(".").last()}.$func() - line $line';
+ case _:
+ stackLabel += '- (${file}) - line $line';
+ }
+ case LocalFunction(v):
+ stackLabel += '- Local Function ${v}';
+ case Method(cl, m):
+ stackLabel += '- ${cl} - ${m}';
+ }
+ stackLabel += "\r\n";
+ }
+
+ e.preventDefault();
+ e.stopPropagation();
+ e.stopImmediatePropagation();
+
+ WindowsAPI.showMessageBox("Codename Engine Crash Handler", 'Uncaught Error:$m\n\n$stackLabel');
+ #if sys
+ Sys.exit(1);
+ #end
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/system/Main.hx b/source/funkin/system/Main.hx
index 7cfa3a3d..28ef0063 100644
--- a/source/funkin/system/Main.hx
+++ b/source/funkin/system/Main.hx
@@ -133,6 +133,7 @@ class Main extends Sprite
#end
Paths.assetsTree = new AssetsLibraryList();
+ CrashHandler.init();
Logs.init();
Paths.init();
ModsFolder.init();
@@ -231,6 +232,6 @@ class Main extends Sprite
Paths.assetsTree.clearCache();
-
+
}
}
diff --git a/source/funkin/windows/WindowsAPI.hx b/source/funkin/windows/WindowsAPI.hx
index fcaa58f9..c8b31e97 100644
--- a/source/funkin/windows/WindowsAPI.hx
+++ b/source/funkin/windows/WindowsAPI.hx
@@ -32,6 +32,17 @@ class WindowsAPI {
#end
}
+ /**
+ * Shows a message box
+ */
+ public static function showMessageBox(caption:String, message:String, icon:MessageBoxIcon = MSG_WARNING) {
+ #if windows
+ native.WinAPI.showMessageBox(caption, message, icon);
+ #else
+ lime.app.Application.current.window.alert(title, text);
+ #end
+ }
+
/**
* Sets the console colors
*/
@@ -82,4 +93,11 @@ class WindowsAPI {
var MAGENTA:ConsoleColor = 13;
var YELLOW:ConsoleColor = 14;
var WHITE:ConsoleColor = 15;
+}
+
+@:enum abstract MessageBoxIcon(Int) {
+ var MSG_ERROR:MessageBoxIcon = 0x00000010;
+ var MSG_QUESTION:MessageBoxIcon = 0x00000020;
+ var MSG_WARNING:MessageBoxIcon = 0x00000030;
+ var MSG_INFORMATION:MessageBoxIcon = 0x00000040;
}
\ No newline at end of file
diff --git a/source/native/WinAPI.hx b/source/native/WinAPI.hx
index df3d151d..51dc314e 100644
--- a/source/native/WinAPI.hx
+++ b/source/native/WinAPI.hx
@@ -1,5 +1,6 @@
package native;
+import funkin.windows.WindowsAPI.MessageBoxIcon;
#if windows
@:buildXml('
@@ -168,5 +169,15 @@ class WinAPI {
public static function clearScreen() {
}
+
+
+ #if windows
+ @:functionCode('
+ MessageBox(GetActiveWindow(), message, caption, icon | MB_SETFOREGROUND);
+ ')
+ #end
+ public static function showMessageBox(caption:String, message:String, icon:MessageBoxIcon = MSG_WARNING) {
+
+ }
}
#end
\ No newline at end of file