diff --git a/assets/data/characters/bf-car.xml b/assets/data/characters/bf-car.xml
index bd276ca8..b73d5a12 100644
--- a/assets/data/characters/bf-car.xml
+++ b/assets/data/characters/bf-car.xml
@@ -10,9 +10,9 @@
-
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/data/characters/bf-christmas.xml b/assets/data/characters/bf-christmas.xml
index 88feb049..1289abdc 100644
--- a/assets/data/characters/bf-christmas.xml
+++ b/assets/data/characters/bf-christmas.xml
@@ -1,13 +1,13 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/data/characters/bf-holding-gf.xml b/assets/data/characters/bf-holding-gf.xml
index 390504bc..9053ec5c 100644
--- a/assets/data/characters/bf-holding-gf.xml
+++ b/assets/data/characters/bf-holding-gf.xml
@@ -1,13 +1,13 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/data/characters/bf-pixel.xml b/assets/data/characters/bf-pixel.xml
index b1c668a3..621ec9e0 100644
--- a/assets/data/characters/bf-pixel.xml
+++ b/assets/data/characters/bf-pixel.xml
@@ -1,15 +1,12 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/data/characters/bf.xml b/assets/data/characters/bf.xml
index 245fbffd..96f90b81 100644
--- a/assets/data/characters/bf.xml
+++ b/assets/data/characters/bf.xml
@@ -1,18 +1,18 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/data/characters/dad.xml b/assets/data/characters/dad.xml
index 39319727..3c8da4c2 100644
--- a/assets/data/characters/dad.xml
+++ b/assets/data/characters/dad.xml
@@ -1,13 +1,12 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/data/characters/gf-car.xml b/assets/data/characters/gf-car.xml
index 72ca5814..02fe7e1b 100644
--- a/assets/data/characters/gf-car.xml
+++ b/assets/data/characters/gf-car.xml
@@ -1,5 +1,5 @@
-
-
+
+
\ No newline at end of file
diff --git a/assets/data/characters/gf-christmas.xml b/assets/data/characters/gf-christmas.xml
index 1a995a2a..d9a05715 100644
--- a/assets/data/characters/gf-christmas.xml
+++ b/assets/data/characters/gf-christmas.xml
@@ -1,14 +1,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/data/characters/gf-pixel.xml b/assets/data/characters/gf-pixel.xml
index 73aa39e9..eefc4cba 100644
--- a/assets/data/characters/gf-pixel.xml
+++ b/assets/data/characters/gf-pixel.xml
@@ -1,5 +1,5 @@
-
-
-
-
\ No newline at end of file
+
+
+
+
diff --git a/assets/data/characters/gf-tankmen.xml b/assets/data/characters/gf-tankmen.xml
index 7ba7df0a..a332b124 100644
--- a/assets/data/characters/gf-tankmen.xml
+++ b/assets/data/characters/gf-tankmen.xml
@@ -1,7 +1,7 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/assets/data/characters/gf.xml b/assets/data/characters/gf.xml
index 911d2073..54a8ad59 100644
--- a/assets/data/characters/gf.xml
+++ b/assets/data/characters/gf.xml
@@ -1,14 +1,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/data/characters/mom-car.xml b/assets/data/characters/mom-car.xml
index e511498f..ff23aa88 100644
--- a/assets/data/characters/mom-car.xml
+++ b/assets/data/characters/mom-car.xml
@@ -1,16 +1,13 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/data/characters/mom.xml b/assets/data/characters/mom.xml
index 43d52076..88cbc3c9 100644
--- a/assets/data/characters/mom.xml
+++ b/assets/data/characters/mom.xml
@@ -1,16 +1,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/data/characters/monster-christmas.xml b/assets/data/characters/monster-christmas.xml
index 61bae9ee..73eeed57 100644
--- a/assets/data/characters/monster-christmas.xml
+++ b/assets/data/characters/monster-christmas.xml
@@ -1,8 +1,8 @@
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
diff --git a/assets/data/characters/monster.xml b/assets/data/characters/monster.xml
index df8d70bd..0da80ca9 100644
--- a/assets/data/characters/monster.xml
+++ b/assets/data/characters/monster.xml
@@ -1,8 +1,8 @@
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
diff --git a/assets/data/characters/parents-christmas.xml b/assets/data/characters/parents-christmas.xml
index 991fff09..4371389f 100644
--- a/assets/data/characters/parents-christmas.xml
+++ b/assets/data/characters/parents-christmas.xml
@@ -1,12 +1,25 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/data/characters/pico-speakers.xml b/assets/data/characters/pico-speakers.xml
index ffb35177..36ec2528 100644
--- a/assets/data/characters/pico-speakers.xml
+++ b/assets/data/characters/pico-speakers.xml
@@ -1,16 +1,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/data/characters/pico.xml b/assets/data/characters/pico.xml
index 74e9baed..e5685dd8 100644
--- a/assets/data/characters/pico.xml
+++ b/assets/data/characters/pico.xml
@@ -1,16 +1,12 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/data/characters/senpai-angry.xml b/assets/data/characters/senpai-angry.xml
index c1203449..b9450a24 100644
--- a/assets/data/characters/senpai-angry.xml
+++ b/assets/data/characters/senpai-angry.xml
@@ -1,8 +1,8 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/assets/data/characters/senpai.xml b/assets/data/characters/senpai.xml
index f243b2e5..762afb67 100644
--- a/assets/data/characters/senpai.xml
+++ b/assets/data/characters/senpai.xml
@@ -1,10 +1,9 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
diff --git a/assets/data/characters/spirit.xml b/assets/data/characters/spirit.xml
index d1ee5dc9..9885a662 100644
--- a/assets/data/characters/spirit.xml
+++ b/assets/data/characters/spirit.xml
@@ -1,10 +1,8 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
diff --git a/assets/data/characters/spooky.xml b/assets/data/characters/spooky.xml
index 2a434f21..f60758e4 100644
--- a/assets/data/characters/spooky.xml
+++ b/assets/data/characters/spooky.xml
@@ -1,9 +1,9 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
diff --git a/assets/data/characters/tankman.xml b/assets/data/characters/tankman.xml
index 092e0368..c06aa6c4 100644
--- a/assets/data/characters/tankman.xml
+++ b/assets/data/characters/tankman.xml
@@ -1,10 +1,10 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/assets/images/characters/senpai.png b/assets/images/characters/senpai.png
index fa5a3293..1c7f8f52 100644
Binary files a/assets/images/characters/senpai.png and b/assets/images/characters/senpai.png differ
diff --git a/assets/images/characters/senpai.xml b/assets/images/characters/senpai.xml
index d8e532e4..fb01b854 100644
--- a/assets/images/characters/senpai.xml
+++ b/assets/images/characters/senpai.xml
@@ -1,159 +1,164 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/songs/test/dialogue.hx b/assets/songs/test/dialogue.hx
new file mode 100644
index 00000000..5d3e7fa0
--- /dev/null
+++ b/assets/songs/test/dialogue.hx
@@ -0,0 +1,5 @@
+function next(event)
+ if (!event.playFirst) trace("-");
+
+function postNext(event)
+ trace(curLine.char + " says: " + curLine.text);
\ No newline at end of file
diff --git a/source/funkin/backend/assets/Paths.hx b/source/funkin/backend/assets/Paths.hx
index db6d8131..74d6947b 100644
--- a/source/funkin/backend/assets/Paths.hx
+++ b/source/funkin/backend/assets/Paths.hx
@@ -180,7 +180,7 @@ class Paths
return FlxAtlasFrames.fromAseprite('$key.png', '$key.json');
inline static public function getAssetsRoot():String
- return ModsFolder.currentModFolder != null ? '${ModsFolder.modsPath}${ModsFolder.currentModFolder}' : './assets';
+ return ModsFolder.currentModFolder != null ? '${ModsFolder.modsPath}${ModsFolder.currentModFolder}' : #if (sys && TEST_BUILD) './${Main.pathBack}assets/' #else './assets' #end;
/**
* Gets frames at specified path.
diff --git a/source/funkin/backend/scripting/events/NoteHitEvent.hx b/source/funkin/backend/scripting/events/NoteHitEvent.hx
index 6b761aed..d0b58f5a 100644
--- a/source/funkin/backend/scripting/events/NoteHitEvent.hx
+++ b/source/funkin/backend/scripting/events/NoteHitEvent.hx
@@ -24,9 +24,19 @@ final class NoteHitEvent extends CancellableEvent {
*/
public var countScore:Bool = true;
/**
- * Whenever ratings should be shown or not.
+ * Whenever ratings (Rating sprite, Digits sprites and Combo sprite) should be shown or not.
+ *
+ * NOTE: Whether it's `true` use `displayRating` and `displayCombo` (plus `minDigitDisplay` in the PlayState class) to change what's going to pop up!
*/
public var showRating:Null = null;
+ /**
+ * Whenever the Rating sprites should be shown or not.
+ */
+ public var displayRating:Bool;
+ /**
+ * Whenever the Combo sprite should be shown or not (like old Week 7 patches).
+ */
+ public var displayCombo:Bool;
/**
* Note that has been pressed
*/
diff --git a/source/funkin/backend/scripting/events/dialogue/DialogueNextLineEvent.hx b/source/funkin/backend/scripting/events/dialogue/DialogueNextLineEvent.hx
new file mode 100644
index 00000000..7a5e3eac
--- /dev/null
+++ b/source/funkin/backend/scripting/events/dialogue/DialogueNextLineEvent.hx
@@ -0,0 +1,14 @@
+package funkin.backend.scripting.events.dialogue;
+
+/**
+ * CANCEL this event to prevent continuing with the next dialogue.
+ *
+ * **NOTE**: To access the current, past or next lines, use `curLine`, `lastLine` or also `dialogueLines` in the `DialogueCutscene` class (they're globals and can be accessed at any time as long as the Dialogue Cutscene is active)!
+ */
+final class DialogueNextLineEvent extends CancellableEvent
+{
+ /**
+ * If the dialogue has just been opened.
+ */
+ public var playFirst:Bool = false;
+}
\ No newline at end of file
diff --git a/source/funkin/backend/shaders/CustomShader.hx b/source/funkin/backend/shaders/CustomShader.hx
index 93d480c6..a4d69f2a 100644
--- a/source/funkin/backend/shaders/CustomShader.hx
+++ b/source/funkin/backend/shaders/CustomShader.hx
@@ -25,6 +25,9 @@ class CustomShader extends FunkinShader {
var fragCode = Assets.exists(fragShaderPath) ? Assets.getText(fragShaderPath) : null;
var vertCode = Assets.exists(vertShaderPath) ? Assets.getText(vertShaderPath) : null;
+ fragFileName = fragShaderPath;
+ vertFileName = vertShaderPath;
+
path = fragShaderPath+vertShaderPath;
if (fragCode == null && vertCode == null)
diff --git a/source/funkin/backend/shaders/FunkinShader.hx b/source/funkin/backend/shaders/FunkinShader.hx
index 0b282ffb..3c685f3d 100644
--- a/source/funkin/backend/shaders/FunkinShader.hx
+++ b/source/funkin/backend/shaders/FunkinShader.hx
@@ -1,15 +1,16 @@
package funkin.backend.shaders;
+import flixel.system.FlxAssets.FlxShader;
import haxe.Exception;
import hscript.IHScriptCustomBehaviour;
-import flixel.system.FlxAssets.FlxShader;
-
import lime.utils.Float32Array;
-
-import openfl.display.ShaderParameterType;
-import openfl.display.ShaderParameter;
import openfl.display.BitmapData;
import openfl.display.ShaderInput;
+import openfl.display.ShaderParameter;
+import openfl.display.ShaderParameterType;
+import openfl.display3D._internal.GLProgram;
+import openfl.display3D._internal.GLShader;
+import openfl.utils._internal.Log;
using StringTools;
@:access(openfl.display3D.Context3D)
@@ -20,6 +21,8 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
private static var __instanceFields = Type.getInstanceFields(FunkinShader);
public var glslVer:String = "120";
+ public var fragFileName:String;
+ public var vertFileName:String;
/**
* Creates a new shader from the specified fragment and vertex source.
@@ -38,10 +41,135 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
super();
}
+ var ERROR_POS_REGEX = ~/(\d+):(\d+): (.*)/g;
+ var ERROR_REGEX = ~/ERROR: (\d+):(\d+): (.*)/g;
+ var ERROR_REGEX_2 = ~/(\d+)\((\d+)\) : error ([^:]+): (.*)/g;
+ @:noCompletion private override function __createGLShader(source:String, type:Int):GLShader
+ {
+ var gl = __context.gl;
+
+ var shader = gl.createShader(type);
+ gl.shaderSource(shader, source);
+ gl.compileShader(shader);
+ var shaderInfoLog = gl.getShaderInfoLog(shader);
+ var hasInfoLog = shaderInfoLog != null && StringTools.trim(shaderInfoLog) != "";
+ var compileStatus = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
+
+ if (hasInfoLog || compileStatus == 0)
+ {
+ var isVertexShader = type == gl.VERTEX_SHADER;
+ var messageBuf = new StringBuf();
+ messageBuf.add((compileStatus == 0) ? "Error" : "Info");
+ if(isVertexShader) {
+ messageBuf.add(" compiling vertex shader");
+ if(vertFileName != null && vertFileName.length > 0) {
+ messageBuf.add(" (" + vertFileName + ")");
+ }
+ } else {
+ messageBuf.add(" compiling fragment shader");
+ if(fragFileName != null && fragFileName.length > 0) {
+ messageBuf.add(" (" + fragFileName + ")");
+ }
+ }
+ messageBuf.add("\n");
+ var errorPositions = [];
+ var regex = null;
+ var tmp = shaderInfoLog;
+ if(shaderInfoLog.contains(" : error ")) {
+ regex = ERROR_REGEX_2;
+
+ while(regex.match(tmp)) {
+ errorPositions.push(new ShaderErrorPosition(regex.matched(2), regex.matched(1), regex.matched(4)));
+ tmp = regex.matchedRight();
+ }
+ } else if(shaderInfoLog.contains("ERROR: ")) {
+ regex = ERROR_REGEX;
+
+ while(regex.match(tmp)) {
+ errorPositions.push(new ShaderErrorPosition(regex.matched(2), regex.matched(1), regex.matched(3)));
+ tmp = regex.matchedRight();
+ }
+ } else {
+ regex = ERROR_POS_REGEX;
+
+ while(regex.match(tmp)) {
+ errorPositions.push(new ShaderErrorPosition(regex.matched(2), regex.matched(1), regex.matched(3)));
+ tmp = regex.matchedRight();
+ }
+ }
+ var splitSource = source.split("\n");
+ for(error in errorPositions) {
+ messageBuf.add("ERROR: Line: " + error.line);
+ if(error.column > 0) {
+ messageBuf.add(", Column: " + error.column);
+ }
+ messageBuf.add(", " + error.message);
+ if(error.line < splitSource.length) {
+ messageBuf.add("\nLine: ");
+ messageBuf.add(splitSource[error.line-1].trim());
+ }
+ messageBuf.add("\n\n");
+ }
+ var hasErrorPosition = errorPositions.length > 0;
+ if(hasErrorPosition) {
+ messageBuf.add("Raw shader info log:\n");
+ }
+ messageBuf.add(shaderInfoLog);
+ messageBuf.add("\n");
+ messageBuf.add(source);
+
+ var message = messageBuf.toString();
+ if (compileStatus == 0) Log.error(message);
+ else if (hasInfoLog) Log.debug(message);
+ }
+
+ return shader;
+ }
+
+ @:noCompletion private override function __createGLProgram(vertexSource:String, fragmentSource:String):GLProgram
+ {
+ var gl = __context.gl;
+
+ var vertexShader = __createGLShader(vertexSource, gl.VERTEX_SHADER);
+ var fragmentShader = __createGLShader(fragmentSource, gl.FRAGMENT_SHADER);
+
+ var program = gl.createProgram();
+
+ // Fix support for drivers that don't draw if attribute 0 is disabled
+ for (param in __paramFloat)
+ {
+ if (param.name.indexOf("Position") > -1 && StringTools.startsWith(param.name, "openfl_"))
+ {
+ gl.bindAttribLocation(program, 0, param.name);
+ break;
+ }
+ }
+
+ gl.attachShader(program, vertexShader);
+ gl.attachShader(program, fragmentShader);
+ gl.linkProgram(program);
+
+ if (gl.getProgramParameter(program, gl.LINK_STATUS) == 0)
+ {
+ var messageBuf = new StringBuf();
+ messageBuf.add("Unable to initialize the shader program");
+ messageBuf.add("\n");
+ messageBuf.add(gl.getProgramInfoLog(program));
+ var message = messageBuf.toString();
+ Log.error(message);
+ }
+
+ return program;
+ }
+
+ var glRawFragmentSource:String;
+ var glRawVertexSource:String;
+
@:noCompletion override private function set_glFragmentSource(value:String):String
{
if(value == null)
value = ShaderTemplates.defaultFragmentSource;
+ glRawFragmentSource = value;
value = value.replace("#pragma header", ShaderTemplates.fragHeader).replace("#pragma body", ShaderTemplates.fragBody);
if (value != __glFragmentSource)
{
@@ -55,6 +183,7 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
{
if(value == null)
value = ShaderTemplates.defaultVertexSource;
+ glRawVertexSource = value;
value = value.replace("#pragma header", ShaderTemplates.vertHeader).replace("#pragma body", ShaderTemplates.vertBody);
if (value != __glVertexSource)
{
@@ -83,20 +212,24 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
if (__context != null && program == null)
{
- var prefix = '#version ${glslVer}\n';
+ var prefixBuf = new StringBuf();
+ prefixBuf.add('#version ${glslVer}\n');
var gl = __context.gl;
- prefix += "#ifdef GL_ES
- "
- + (precisionHint == FULL ? "#ifdef GL_FRAGMENT_PRECISION_HIGH
- precision highp float;
- #else
- precision mediump float;
- #endif" : "precision lowp float;")
- + "
- #endif
- ";
+ prefixBuf.add("#ifdef GL_ES\n");
+ if (precisionHint == FULL) {
+ prefixBuf.add("#ifdef GL_FRAGMENT_PRECISION_HIGH\n");
+ prefixBuf.add("precision highp float;\n");
+ prefixBuf.add("#else\n");
+ prefixBuf.add("precision mediump float;\n");
+ prefixBuf.add("#endif\n");
+ } else {
+ prefixBuf.add("precision lowp float;\n");
+ }
+ prefixBuf.add("#endif\n");
+
+ var prefix = prefixBuf.toString();
var vertex = prefix + glVertexSource;
var fragment = prefix + glFragmentSource;
@@ -110,9 +243,7 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
else
{
program = __context.createProgram(GLSL);
-
program.__glProgram = __createGLProgram(vertex, fragment);
-
__context.__programs.set(id, program);
}
@@ -120,56 +251,35 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
{
glProgram = program.__glProgram;
- for (input in __inputBitmapData)
- {
+ for (input in __inputBitmapData) {
- if (input.__isUniform)
- {
+ if (input.__isUniform) {
input.index = gl.getUniformLocation(glProgram, input.name);
- }
- else
- {
+ } else {
input.index = gl.getAttribLocation(glProgram, input.name);
}
}
- for (parameter in __paramBool)
- {
-
- if (parameter.__isUniform)
- {
+ for (parameter in __paramBool) {
+ if (parameter.__isUniform) {
parameter.index = gl.getUniformLocation(glProgram, parameter.name);
- }
- else
- {
+ } else {
parameter.index = gl.getAttribLocation(glProgram, parameter.name);
}
}
- for (parameter in __paramFloat)
- {
-
- if (parameter.__isUniform)
- {
+ for (parameter in __paramFloat) {
+ if (parameter.__isUniform) {
parameter.index = gl.getUniformLocation(glProgram, parameter.name);
- }
- else
- {
+ } else {
parameter.index = gl.getAttribLocation(glProgram, parameter.name);
}
}
- for (parameter in __paramInt)
- {
-
- if (parameter.__isUniform)
- {
-
+ for (parameter in __paramInt) {
+ if (parameter.__isUniform) {
parameter.index = gl.getUniformLocation(glProgram, parameter.name);
- }
- else
- {
-
+ } else {
parameter.index = gl.getAttribLocation(glProgram, parameter.name);
}
}
@@ -207,7 +317,6 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
{
var input = new ShaderInput();
input.name = name;
- @:privateAccess
input.__isUniform = isUniform;
__inputBitmapData.push(input);
@@ -274,15 +383,10 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
case BOOL, BOOL2, BOOL3, BOOL4:
var parameter = new ShaderParameter();
parameter.name = name;
- @:privateAccess
parameter.type = parameterType;
- @:privateAccess
parameter.__arrayLength = arrayLength;
- @:privateAccess
parameter.__isBool = true;
- @:privateAccess
parameter.__isUniform = isUniform;
- @:privateAccess
parameter.__length = length;
__paramBool.push(parameter);
@@ -297,17 +401,11 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
case INT, INT2, INT3, INT4:
var parameter = new ShaderParameter();
parameter.name = name;
- @:privateAccess
parameter.type = parameterType;
- @:privateAccess
parameter.__arrayLength = arrayLength;
- @:privateAccess
parameter.__isInt = true;
- @:privateAccess
parameter.__isUniform = isUniform;
- @:privateAccess
parameter.__length = length;
- @:privateAccess
__paramInt.push(parameter);
Reflect.setField(__data, name, parameter);
try{Reflect.setField(this, name, parameter);} catch(e) {}
@@ -315,19 +413,13 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
default:
var parameter = new ShaderParameter();
parameter.name = name;
- @:privateAccess
parameter.type = parameterType;
- @:privateAccess
parameter.__arrayLength = arrayLength;
#if lime
- @:privateAccess
if (arrayLength > 0) parameter.__uniformMatrix = new Float32Array(arrayLength * arrayLength);
#end
- @:privateAccess
parameter.__isFloat = true;
- @:privateAccess
parameter.__isUniform = isUniform;
- @:privateAccess
parameter.__length = length;
__paramFloat.push(parameter);
@@ -394,7 +486,6 @@ class FunkinShader extends FlxShader implements IHScriptCustomBehaviour {
var cl:String = Type.getClassName(Type.getClass(field));
// cant do "field is ShaderInput" for some reason
if (cl.startsWith("openfl.display.ShaderParameter")) {
- @:privateAccess
if (field.__length <= 1) {
if ((val is Array))
return field.value = val;
@@ -546,4 +637,16 @@ class ShaderTypeException extends Exception {
this.name = name;
super('ShaderTypeException - Tried to set the shader uniform "${name}" as a ${Type.getClassName(has)}, but the shader uniform is a ${Std.string(want)}.');
}
+}
+
+class ShaderErrorPosition {
+ public var column:Int;
+ public var line:Int;
+ public var message:String;
+
+ public function new(line:String, column:String, message:String) {
+ this.line = Std.parseInt(line);
+ this.column = Std.parseInt(column);
+ this.message = message;
+ }
}
\ No newline at end of file
diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx
index d020b4eb..53c1591a 100644
--- a/source/funkin/game/PlayState.hx
+++ b/source/funkin/game/PlayState.hx
@@ -459,6 +459,22 @@ class PlayState extends MusicBeatState
* Group containing all of the combo sprites.
*/
public var comboGroup:RotatingSpriteGroup;
+ /**
+ * Whenever the Rating sprites should be shown or not.
+ *
+ * NOTE: This is just a default value for the final value, the final value can be changed through notes hit events.
+ */
+ public var defaultDisplayRating:Bool = true;
+ /**
+ * Whenever the Combo sprite should be shown or not (like old Week 7 patches).
+ *
+ * NOTE: This is just a default value for the final value, the final value can be changed through notes hit events.
+ */
+ public var defaultDisplayCombo:Bool = false;
+ /**
+ * Minimum Combo Count to display the combo digits. Anything less than 0 means it won't be shown.
+ */
+ public var minDigitDisplay:Int = 10;
/**
* Array containing all of the note types names.
*/
@@ -1655,9 +1671,9 @@ class PlayState extends MusicBeatState
var event:NoteHitEvent;
if (strumLine != null && !strumLine.cpu)
- event = EventManager.get(NoteHitEvent).recycle(false, !note.isSustainNote, !note.isSustainNote, note, strumLine.characters, true, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, score, note.isSustainNote ? null : accuracy, 0.023, daRating, Options.splashesEnabled && !note.isSustainNote && daRating == "sick");
+ event = EventManager.get(NoteHitEvent).recycle(false, !note.isSustainNote, !note.isSustainNote, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, true, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, score, note.isSustainNote ? null : accuracy, 0.023, daRating, Options.splashesEnabled && !note.isSustainNote && daRating == "sick");
else
- event = EventManager.get(NoteHitEvent).recycle(false, false, false, note, strumLine.characters, false, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, 0, null, 0, daRating, false);
+ event = EventManager.get(NoteHitEvent).recycle(false, false, false, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, false, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, 0, null, 0, daRating, false);
event.deleteNote = !note.isSustainNote; // work around, to allow sustain notes to be deleted
event = scripts.event(strumLine != null && !strumLine.cpu ? "onPlayerHit" : "onDadHit", event);
strumLine.onHit.dispatch(event);
@@ -1676,7 +1692,8 @@ class PlayState extends MusicBeatState
if (event.showRating || (event.showRating == null && event.player))
{
displayCombo(event);
- displayRating(event.rating, event);
+ if (event.displayRating)
+ displayRating(event.rating, event);
ratingNum += 1;
}
}
@@ -1735,14 +1752,12 @@ class PlayState extends MusicBeatState
}
public function displayCombo(?evt:NoteHitEvent = null):Void {
- var hasEvent = evt != null;
- var pre:String = hasEvent ? evt.ratingPrefix : "";
- var suf:String = hasEvent ? evt.ratingSuffix : "";
+ if (minDigitDisplay >= 0 && (combo == 0 || combo >= minDigitDisplay)) {
+ var hasEvent = evt != null;
+ var pre:String = hasEvent ? evt.ratingPrefix : "";
+ var suf:String = hasEvent ? evt.ratingSuffix : "";
- var separatedScore:String = Std.string(combo).addZeros(3);
-
- if (combo == 0 || combo >= 10) {
- if (combo >= 10) {
+ if (evt.displayCombo) {
var comboSpr:FlxSprite = comboGroup.recycleLoop(FlxSprite).loadAnimatedGraphic(Paths.image('${pre}combo${suf}'));
comboSpr.resetSprite(comboGroup.x, comboGroup.y);
comboSpr.acceleration.y = 600;
@@ -1764,6 +1779,7 @@ class PlayState extends MusicBeatState
});
}
+ var separatedScore:String = Std.string(combo).addZeros(3);
for (i in 0...separatedScore.length)
{
var numScore:FlxSprite = comboGroup.recycleLoop(FlxSprite).loadAnimatedGraphic(Paths.image('${pre}num${separatedScore.charAt(i)}${suf}'));
diff --git a/source/funkin/game/cutscenes/DialogueCutscene.hx b/source/funkin/game/cutscenes/DialogueCutscene.hx
index b24e2396..3c83d563 100644
--- a/source/funkin/game/cutscenes/DialogueCutscene.hx
+++ b/source/funkin/game/cutscenes/DialogueCutscene.hx
@@ -138,8 +138,8 @@ class DialogueCutscene extends Cutscene {
public var canProceed:Bool = true;
public function next(playFirst:Bool = false) {
- var event = EventManager.get(DynamicEvent).recycle(playFirst);
- dialogueScript.call("next", [playFirst]);
+ var event = EventManager.get(DialogueNextLineEvent).recycle(playFirst);
+ dialogueScript.call("next", [event]);
if(event.cancelled || !canProceed) return;
if ((curLine = dialogueLines.shift()) == null) {
@@ -154,7 +154,7 @@ class DialogueCutscene extends Cutscene {
}
if (curLine.callback != null)
- dialogueScript.call(curLine.callback, [playFirst]);
+ dialogueScript.call(curLine.callback, [event.playFirst]);
for (k=>c in charMap)
if (k != curLine.char)
@@ -167,8 +167,8 @@ class DialogueCutscene extends Cutscene {
dialogueBox.popupChar(char, force);
}
- var finalSuffix:String = playFirst && dialogueBox.hasAnimation(curLine.bubble + "-firstOpen") ? "-firstOpen" : dialogueBox.hasAnimation(curLine.bubble + "-open") ? "-open" : "";
- dialogueBox.playBubbleAnim(curLine.bubble, finalSuffix, curLine.text, curLine.format, curLine.speed, curLine.nextSound, curLine.textSound != null ? [curLine.textSound] : null, finalSuffix == "-firstOpen" || finalSuffix == "-open", !playFirst);
+ var finalSuffix:String = event.playFirst && dialogueBox.hasAnimation(curLine.bubble + "-firstOpen") ? "-firstOpen" : dialogueBox.hasAnimation(curLine.bubble + "-open") ? "-open" : "";
+ dialogueBox.playBubbleAnim(curLine.bubble, finalSuffix, curLine.text, curLine.format, curLine.speed, curLine.nextSound, curLine.textSound != null ? [curLine.textSound] : null, finalSuffix == "-firstOpen" || finalSuffix == "-open", !event.playFirst);
if(curLine.playSound != null) curLine.playSound.play();
if(curLine.changeMusic != null) {
@@ -178,7 +178,7 @@ class DialogueCutscene extends Cutscene {
curMusic.fadeIn(1, 0, curMusic.volume);
} else if(curLine.musicVolume != null && curMusic != null) curMusic.volume = curLine.musicVolume;
- dialogueScript.call("postNext", [playFirst]);
+ dialogueScript.call("postNext", [event]);
}
public override function close() {
diff --git a/source/openfl/display/GraphicsShader.hx b/source/openfl/display/GraphicsShader.hx
new file mode 100644
index 00000000..72c0ed97
--- /dev/null
+++ b/source/openfl/display/GraphicsShader.hx
@@ -0,0 +1,89 @@
+package openfl.display;
+
+import openfl.utils.ByteArray;
+
+#if !openfl_debug
+@:fileXml('tags="haxe,release"')
+@:noDebug
+#end
+class GraphicsShader extends Shader
+{
+ @:glVertexHeader("attribute float openfl_Alpha;
+attribute vec4 openfl_ColorMultiplier;
+attribute vec4 openfl_ColorOffset;
+attribute vec4 openfl_Position;
+attribute vec2 openfl_TextureCoord;
+
+varying float openfl_Alphav;
+varying vec4 openfl_ColorMultiplierv;
+varying vec4 openfl_ColorOffsetv;
+varying vec2 openfl_TextureCoordv;
+
+uniform mat4 openfl_Matrix;
+uniform bool openfl_HasColorTransform;
+uniform vec2 openfl_TextureSize;")
+ @:glVertexBody("openfl_Alphav = openfl_Alpha;
+openfl_TextureCoordv = openfl_TextureCoord;
+
+if (openfl_HasColorTransform) {
+ openfl_ColorMultiplierv = openfl_ColorMultiplier;
+ openfl_ColorOffsetv = openfl_ColorOffset / 255.0;
+}
+
+gl_Position = openfl_Matrix * openfl_Position;")
+ @:glVertexSource("#pragma header
+
+void main(void) {
+ #pragma body
+}")
+ @:glFragmentHeader("varying float openfl_Alphav;
+varying vec4 openfl_ColorMultiplierv;
+varying vec4 openfl_ColorOffsetv;
+varying vec2 openfl_TextureCoordv;
+
+uniform bool openfl_HasColorTransform;
+uniform vec2 openfl_TextureSize;
+uniform sampler2D bitmap;")
+ @:glFragmentBody("vec4 color = texture2D (bitmap, openfl_TextureCoordv);
+
+if (color.a == 0.0) {
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+} else if (openfl_HasColorTransform) {
+ color = vec4(color.rgb / color.a, color.a);
+
+ mat4 colorMultiplier = mat4(0);
+ colorMultiplier[0][0] = openfl_ColorMultiplierv.x;
+ colorMultiplier[1][1] = openfl_ColorMultiplierv.y;
+ colorMultiplier[2][2] = openfl_ColorMultiplierv.z;
+ colorMultiplier[3][3] = 1.0; // openfl_ColorMultiplierv.w;
+
+ color = clamp(openfl_ColorOffsetv + (color * colorMultiplier), 0.0, 1.0);
+
+ if (color.a > 0.0) {
+ gl_FragColor = vec4(color.rgb * color.a * openfl_Alphav, color.a * openfl_Alphav);
+ } else {
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+ }
+} else {
+ gl_FragColor = color * openfl_Alphav;
+}")
+ #if emscripten
+ @:glFragmentSource("#pragma header
+
+void main(void) {
+ #pragma body
+
+ gl_FragColor = gl_FragColor.bgra;
+}")
+ #else
+ @:glFragmentSource("#pragma header
+
+void main(void) {
+ #pragma body
+}")
+ #end
+ public function new(code:ByteArray = null)
+ {
+ super(code);
+ }
+}