Skip to content

Instantly share code, notes, and snippets.

@JLChnToZ
Last active September 21, 2018 14:12
Show Gist options
  • Save JLChnToZ/6242630 to your computer and use it in GitHub Desktop.
Save JLChnToZ/6242630 to your computer and use it in GitHub Desktop.
Osu! Storyboard Generation Language (SGL) in pure JavaScript implementation. The code has assumed the interpreter has a print function defined as "print(text)". Reference: http://moonshadow.hostbeef.com/sgl/ and http://osu.ppy.sh/wiki/Storyboard_Scripting
/**
Osu! Storyboard Generation Language (SGL) in pure JavaScript implementaion
Copyright (C) 2013, Jeremy Lam [JLChnToZ]
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
The code has assumed the interpreter has a print function defined as "print(text)".
Reference: http://moonshadow.hostbeef.com/sgl/ and http://osu.ppy.sh/wiki/Storyboard_Scripting
*/
// Layer enums
var Background = "Background", Fail = "Fail"
Pass = "Pass", Foreground = "Foreground";
// Origin enums
var TopLeft = "TopLeft", TopCentre = "TopCentre", TopRight = "TopRight",
CentreLeft = "CentreLeft", Centre = "Centre", CentreRight = "CentreRight",
BottomLeft = "BottomLeft", BottomCentre = "BottomCentre", BottomRight = "BottomRight";
// Loop enums
var LoopForever = "LoopForever", LoopOnce = "LoopOnce";
var output = new Array();
// SGL Only Functions
function println(text) {
return print(text+"\n");
}
function rand(min, max) {
return Math.round(Math.random()*(max-min)+min);
}
function sin(number) {
return Math.sin(number);
}
// Sprite Constructor
function Sprite() {
this.sequence = new Array();
var _args = new Array();
var _type = "Sprite", _layer = Foreground, _origin = Centre, _x = 320, _y = 240,
_filepath = arguments[0], _framecount = 0, _framedelay = 0, _looptype = LoopForever;
switch(arguments.length) {
case 1:
break;
case 2:
_layer = arguments[1];
break;
case 3:
if(typeof arguments[1] == "string") {
_layer = arguments[1];
_origin = arguments[2];
} else {
_type = "Animation";
_framecount = arguments[1];
_framedelay = arguments[2];
}
break;
case 4:
_type = "Animation";
_layer = arguments[1];
_framecount = arguments[2];
_framedelay = arguments[3];
break;
case 5:
_type = "Animation";
_layer = arguments[1];
_origin = arguments[2];
_framecount = arguments[3];
_framedelay = arguments[4];
break;
case 6:
_type = "Animation";
_layer = arguments[1];
_origin = arguments[2];
_framecount = arguments[3];
_framedelay = arguments[4];
_looptype = arguments[5];
break;
}
_args.push(_type, _layer, _origin, '"'+_filepath+'"', _x, _y);
if(_type == "Animation")
_args.push(_framecount, _framedelay, _looptype);
this.sequence.push(_args);
this.move = function() {
_pushevent.call(this, "_M", 2, arguments);
};
this.moveX = function() {
_pushevent.call(this, "_MX", 1, arguments);
};
this.moveY = function() {
_pushevent.call(this, "_MY", 1, arguments);
};
this.scale = function() {
_pushevent.call(this, "_S", 1, arguments);
};
this.scaleVec = function() {
_pushevent.call(this, "_V", 2, arguments);
};
this.rotate = function() {
_pushevent.call(this, "_R", 1, arguments);
};
this.fade = function() {
_pushevent.call(this, "_F", 1, arguments);
};
this.color = function() {
_pushevent.call(this, "_C", 3, arguments);
};
function _pushevent(type, pcount, args) {
var i = 0, _easing = 0, _stime = 0, _etime = 0,
_p1 = new Array(), _p2 = new Array(), _ev = new Array(type);
switch(args.length) {
case pcount:
for(i = 0; i < pcount; i++) {
_p1.push(args[i]);
_p2.push(args[i]);
}
break;
case pcount+1:
_stime = _etime = args[0];
for(i = 1; i < pcount+1; i++) {
_p1.push(args[i]);
_p2.push(args[i]);
}
break;
case pcount*2+2:
_stime = args[0];
_etime = args[1];
for(i = 2; i < pcount+2; i++)
_p1.push(args[i]);
for( ; i < pcount*2+2; i++)
_p2.push(args[i]);
break;
case pcount*2+3:
_easing = args[0];
_stime = args[1];
_etime = args[2];
for(i = 3; i < pcount+3; i++)
_p1.push(args[i]);
for( ; i < pcount*2+3; i++)
_p2.push(args[i]);
break;
}
_ev.push(_easing, _stime, _etime);
for(i = 0; i < _p1.length; i++)
_ev.push(_p1[i]);
for(i = 0; i < _p2.length; i++)
_ev.push(_p2[i]);
this.sequence.push(_ev);
}
if(arguments.length > 0)
output.push(this);
}
// Animation Constructor
function Animation() {}
Animation = Sprite;
// Function for outputting the result
function generate() {
return "[Events]\n\n"+
"//Background and Video events\n"+
"//Storyboard Layer 0 (Background)\n"+
generatePart(Background)+
"//Storyboard Layer 1 (Fail)\n"+
generatePart(Fail)+
"//Storyboard Layer 2 (Pass)\n"+
generatePart(Pass)+
"//Storyboard Layer 3 (Foreground)\n"+
generatePart(Foreground)+
"//Storyboard Sound Samples\n";
// TODO: Implement SE generation script and finish this part.
}
function generatePart(LayerType) {
var s = "";
for(var i = 0; i < output.length; i++) {
if(LayerType != "" && output[i].sequence[0][1] != LayerType)
continue;
for(var j = 0; j < output[i].sequence.length; j++) {
for(var k = 0; k < output[i].sequence[j].length; k++) {
if(k != 0)
s += ",";
s += output[i].sequence[j][k];
}
s += "\n";
}
}
return s;
}
//
// Put Your Storyboard Generation Language Code Here:
//
// Please do not remove the lines below!
print("\n\n----------------------------------------\n\n");
print(generate());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment