Scatter improvement

This commit is contained in:
Tanasart 2024-01-17 20:57:32 +07:00
parent 76a05516e5
commit 651facbcb2
11 changed files with 259 additions and 149 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View file

@ -26,7 +26,12 @@ event_inherited();
[ "BBMOD", "BlueBurn" ], [ "BBMOD", "BlueBurn" ],
[ "Additional help", "ChatGPT by OpenAI" ], [ "Additional help", "ChatGPT by OpenAI" ],
] ];
patreons = "";
if(os_is_network_connected())
patron_list_id = http_get("https://gist.githubusercontent.com/Ttanasart-pt/573ab1dea80606616cac5ba497e528fd/raw/6bd76af8751416cd08f9c268cd6b7fb0c06611a1/patreon");
sc_thank = new scrollPane(dialog_w - ui(64), thank_h, function(_y, _m) { sc_thank = new scrollPane(dialog_w - ui(64), thank_h, function(_y, _m) {
var cx = sc_thank.surface_w / 2; var cx = sc_thank.surface_w / 2;
@ -35,27 +40,37 @@ event_inherited();
draw_clear_alpha(COLORS.dialog_about_bg, 0); draw_clear_alpha(COLORS.dialog_about_bg, 0);
BLEND_OVERRIDE BLEND_OVERRIDE
draw_set_font(f_p2); draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text_sub);
draw_set_color(COLORS._main_text_sub);
draw_text(cx, yy, "Special Thanks"); draw_text(cx, yy, "Special Thanks");
for( var i = 0, n = array_length(credits); i < n; i++ ) { for( var i = 0, n = array_length(credits); i < n; i++ ) {
yy += line_get_height(, 8); yy += line_get_height(, 8);
draw_set_font(f_p2); draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text_sub);
draw_set_color(COLORS._main_text_sub);
draw_text(cx, yy, credits[i][0]); draw_text(cx, yy, credits[i][0]);
yy += string_height(credits[i][0]); yy += string_height(credits[i][0]);
draw_set_font(f_p0b); draw_set_text(f_p0b, fa_center, fa_top, COLORS._main_text);
draw_set_color(COLORS._main_text);
draw_text(cx, yy, credits[i][1]); draw_text(cx, yy, credits[i][1]);
yy += ui(8); yy += ui(8);
} }
draw_set_font(f_p0);
draw_set_color(COLORS._main_text_sub);
yy += ui(40); yy += ui(40);
if(patreons != "") {
draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text_sub);
draw_text(cx, yy, "Patreon Suporters");
yy += line_get_height();
draw_set_text(f_p0b, fa_center, fa_top, COLORS._main_text);
draw_text_ext(cx, yy, patreons, -1, sc_thank.surface_w);
yy += string_height_ext(patreons, -1, sc_thank.surface_w);
yy += ui(8);
}
yy += ui(40);
draw_set_text(f_p0b, fa_center, fa_top, COLORS._main_text_sub);
draw_text_line(cx, yy, "Made with GameMaker Studio 2, Adobe Illustrator, Aseprite", -1, sc_thank.w - ui(16)); draw_text_line(cx, yy, "Made with GameMaker Studio 2, Adobe Illustrator, Aseprite", -1, sc_thank.w - ui(16));
yy += ui(32); yy += ui(32);
BLEND_NORMAL BLEND_NORMAL

View file

@ -0,0 +1,5 @@
/// @description Insert description here
if(async_load[? "id"] == patron_list_id) {
var _raw = async_load[? "result"];
patreons = _raw;//string_splice(_raw, ",");
}

View file

@ -5,6 +5,7 @@
"eventList": [ "eventList": [
{"resourceType":"GMEvent","resourceVersion":"1.0","name":"","collisionObjectId":null,"eventNum":0,"eventType":0,"isDnD":false,}, {"resourceType":"GMEvent","resourceVersion":"1.0","name":"","collisionObjectId":null,"eventNum":0,"eventType":0,"isDnD":false,},
{"resourceType":"GMEvent","resourceVersion":"1.0","name":"","collisionObjectId":null,"eventNum":64,"eventType":8,"isDnD":false,}, {"resourceType":"GMEvent","resourceVersion":"1.0","name":"","collisionObjectId":null,"eventNum":64,"eventType":8,"isDnD":false,},
{"resourceType":"GMEvent","resourceVersion":"1.0","name":"","collisionObjectId":null,"eventNum":62,"eventType":7,"isDnD":false,},
], ],
"managed": true, "managed": true,
"overriddenProperties": [], "overriddenProperties": [],

View file

@ -27,6 +27,7 @@ function area_get_random_point(area, distrib = AREA_DISTRIBUTION.area, scatter =
switch(distrib) { switch(distrib) {
case AREA_DISTRIBUTION.area : case AREA_DISTRIBUTION.area :
if(scatter == AREA_SCATTER.uniform) { if(scatter == AREA_SCATTER.uniform) {
if(_area_t == AREA_SHAPE.rectangle) {
var _col = ceil(sqrt(total)); var _col = ceil(sqrt(total));
var _row = ceil(total / _col); var _row = ceil(total / _col);
@ -36,13 +37,37 @@ function area_get_random_point(area, distrib = AREA_DISTRIBUTION.area, scatter =
var _irow = floor(index / _col); var _irow = floor(index / _col);
var _icol = safe_mod(index, _col); var _icol = safe_mod(index, _col);
xx = _area_x - _area_w + _icol * _iwid; xx = _area_x - _area_w + (_icol + 0.5) * _iwid;
yy = _area_y - _area_h + _irow * _ihig; yy = _area_y - _area_h + (_irow + 0.5) * _ihig;
} else {
if(index == 0) {
xx = _area_x;
yy = _area_y;
break;
}
var _r = _area_w;
var _a = _area_w / _area_h;
var _tm = floor(total / (2 * pi));
var _tn = ceil(sqrt(2 * _tm + 1 / 2) - 1 / 2);
var _s = _r / _tn;
var _m = floor(index / (2 * pi));
var _n = floor(sqrt(2 * _m + 1 / 2) - 1 / 2);
var _sr = (_n + 1) * _s;
var _tt = floor((_n * (_n + 1)) / 2 * pi * 2);
var _sa = (index - _tt) / (min(total - _tt, floor((_n + 1) * 2 * pi)) - 1) * 360;
xx = _area_x + lengthdir_x(_sr, _sa);
yy = _area_y + lengthdir_y(_sr, _sa) / _a;
}
} else if(scatter == AREA_SCATTER.random) { } else if(scatter == AREA_SCATTER.random) {
if(_area_t == AREA_SHAPE.rectangle) { if(_area_t == AREA_SHAPE.rectangle) {
xx = _area_x + random_range_seed(-_area_w, _area_w, _sed); _sed++; xx = _area_x + random_range_seed(-_area_w, _area_w, _sed); _sed++;
yy = _area_y + random_range_seed(-_area_h, _area_h, _sed); _sed++; yy = _area_y + random_range_seed(-_area_h, _area_h, _sed); _sed++;
} else { } else if(_area_t == AREA_SHAPE.elipse) {
var rr = random_seed(360, _sed); _sed++; var rr = random_seed(360, _sed); _sed++;
xx = _area_x + lengthdir_x(1, rr) * random_seed(_area_w, _sed); _sed++; xx = _area_x + lengthdir_x(1, rr) * random_seed(_area_w, _sed); _sed++;
yy = _area_y + lengthdir_y(1, rr) * random_seed(_area_h, _sed); _sed++; yy = _area_y + lengthdir_y(1, rr) * random_seed(_area_h, _sed); _sed++;
@ -53,22 +78,35 @@ function area_get_random_point(area, distrib = AREA_DISTRIBUTION.area, scatter =
case AREA_DISTRIBUTION.border : case AREA_DISTRIBUTION.border :
if(scatter == AREA_SCATTER.uniform) { if(scatter == AREA_SCATTER.uniform) {
if(_area_t == AREA_SHAPE.rectangle) { if(_area_t == AREA_SHAPE.rectangle) {
var perimeter = _area_w * 2 + _area_h * 2; var perimeter = _area_w * 4 + _area_h * 4;
var i = perimeter * index / total; var d = perimeter / total;
if(i < _area_w) { var l = perimeter * index / total;
xx = _area_x + random_range_seed(-_area_w, _area_w, _sed); _sed++;
if(l <= _area_w * 2) {
xx = _area_x - _area_w + l;
yy = _area_y - _area_h; yy = _area_y - _area_h;
} else if(i < _area_w + _area_h) { break;
xx = _area_x - _area_w; } l -= _area_w * 2;
yy = _area_y + random_range_seed(-_area_h, _area_h, _sed); _sed++;
} else if(i < _area_w * 2 + _area_h) { if(l <= _area_h * 2) {
xx = _area_x + random_range_seed(-_area_w, _area_w, _sed); _sed++;
yy = _area_y + _area_h;
} else {
xx = _area_x + _area_w; xx = _area_x + _area_w;
yy = _area_y + random_range_seed(-_area_h, _area_h, _sed); _sed++; yy = _area_y - _area_h + l;
} break;
} else { } l -= _area_h * 2;
if(l <= _area_w * 2) {
xx = _area_x + _area_w - l;
yy = _area_y + _area_h;
break;
} l -= _area_w * 2;
if(l <= _area_h * 2) {
xx = _area_x - _area_w;
yy = _area_y + _area_h - l;
break;
} l -= _area_h * 2;
} else if(_area_t == AREA_SHAPE.elipse) {
var rr = 360 * index / total; var rr = 360 * index / total;
xx = _area_x + lengthdir_x(_area_w, rr); xx = _area_x + lengthdir_x(_area_w, rr);
yy = _area_y + lengthdir_y(_area_h, rr); yy = _area_y + lengthdir_y(_area_h, rr);
@ -90,7 +128,7 @@ function area_get_random_point(area, distrib = AREA_DISTRIBUTION.area, scatter =
xx = _area_x + _area_w; xx = _area_x + _area_w;
yy = _area_y + random_range_seed(-_area_h, _area_h, _sed); _sed++; yy = _area_y + random_range_seed(-_area_h, _area_h, _sed); _sed++;
} }
} else { } else if(_area_t == AREA_SHAPE.elipse) {
var rr = random_seed(360, _sed); _sed++; var rr = random_seed(360, _sed); _sed++;
xx = _area_x + lengthdir_x(_area_w, rr); xx = _area_x + lengthdir_x(_area_w, rr);
yy = _area_y + lengthdir_y(_area_h, rr); yy = _area_y + lengthdir_y(_area_h, rr);

View file

@ -54,7 +54,7 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
inputs[| 15] = nodeValue("Array", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0, @"What to do when input array of surface. inputs[| 15] = nodeValue("Array", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0, @"What to do when input array of surface.
- Spread: Create Array of output each scattering single surface. - Spread: Create Array of output each scattering single surface.
- Mixed: Create single output scattering multiple images.") - Mixed: Create single output scattering multiple images.")
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Spread output", "Mixed" ]); .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Spread output", "Index", "Random", "Data", "Texture" ]);
inputs[| 16] = nodeValue("Multiply alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); inputs[| 16] = nodeValue("Multiply alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true);
@ -75,13 +75,18 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
inputs[| 23] = nodeValue("Sort Y", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); inputs[| 23] = nodeValue("Sort Y", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false);
inputs[| 24] = nodeValue("Array indices", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [])
.setArrayDepth(1);
inputs[| 25] = nodeValue("Array texture", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone)
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []) outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, [])
.rejectArrayProcess(); .rejectArrayProcess();
input_display_list = [ input_display_list = [
["Surfaces", true], 0, 1, 15, 10, ["Surfaces", true], 0, 1, 15, 10, 24, 25,
["Scatter", false], 5, 6, 13, 14, 17, 9, 2, ["Scatter", false], 5, 6, 13, 14, 17, 9, 2,
["Path", false], 19, 20, 21, 22, ["Path", false], 19, 20, 21, 22,
["Transform", false], 3, 8, 7, 4, ["Transform", false], 3, 8, 7, 4,
@ -93,8 +98,6 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
scatter_data = []; scatter_data = [];
static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region
if(process_amount > 1) return;
var _distType = current_data[6]; var _distType = current_data[6];
if(_distType < 3) if(_distType < 3)
inputs[| 5].drawOverlay(active, _x, _y, _s, _mx, _my, _snx, _sny); inputs[| 5].drawOverlay(active, _x, _y, _s, _mx, _my, _snx, _sny);
@ -112,7 +115,7 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
static step = function() { #region static step = function() { #region
var _dis = getInputData(6); var _dis = getInputData(6);
var _arr = getInputData(15); var _arr = getInputData(15);
inputs[| 0].array_depth = _arr; inputs[| 0].array_depth = bool(_arr);
inputs[| 13].setVisible(_dis == 2, _dis == 2); inputs[| 13].setVisible(_dis == 2, _dis == 2);
inputs[| 14].setVisible(_dis == 3, _dis == 3); inputs[| 14].setVisible(_dis == 3, _dis == 3);
@ -122,6 +125,8 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
inputs[| 20].setVisible(_dis == 4); inputs[| 20].setVisible(_dis == 4);
inputs[| 21].setVisible(_dis == 4); inputs[| 21].setVisible(_dis == 4);
inputs[| 22].setVisible(_dis == 4); inputs[| 22].setVisible(_dis == 4);
inputs[| 24].setVisible(_arr == 3, _arr == 3);
inputs[| 25].setVisible(_arr == 4, _arr == 4);
} #endregion } #endregion
static processData = function(_outSurf, _data, _output_index, _array_index) { #region static processData = function(_outSurf, _data, _output_index, _array_index) { #region
@ -147,9 +152,9 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
var _unis = _data[8]; var _unis = _data[8];
var seed = _data[10]; var seed = _data[10];
var color = _data[11]; var color = _data[11];
var alpha = _data[12]; var alpha = _data[12];
var _arr = _data[15];
var mulpA = _data[16]; var mulpA = _data[16];
var useV = _data[17]; var useV = _data[17];
var blend = _data[18]; var blend = _data[18];
@ -159,6 +164,8 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
var pathShf = _data[21]; var pathShf = _data[21];
var pathDis = _data[22]; var pathDis = _data[22];
var sortY = _data[23]; var sortY = _data[23];
var arrId = _data[24];
var arrTex = _data[25], useArrTex = is_surface(arrTex);
var _in_w, _in_h; var _in_w, _in_h;
@ -206,6 +213,8 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
var posIndex = 0; var posIndex = 0;
for(var i = 0; i < _amount; i++) { for(var i = 0; i < _amount; i++) {
if(is_array(_inSurf) && array_length(_inSurf) == 0) break;
var sp = noone, _x = 0, _y = 0; var sp = noone, _x = 0, _y = 0;
var _v = noone; var _v = noone;
@ -234,9 +243,23 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
_x = pp.x + random_range_seed(-pathDis, pathDis, _sed); _sed++; _x = pp.x + random_range_seed(-pathDis, pathDis, _sed); _sed++;
_y = pp.y + random_range_seed(-pathDis, pathDis, _sed); _sed++; _y = pp.y + random_range_seed(-pathDis, pathDis, _sed); _sed++;
} else if(_dist == NODE_SCATTER_DIST.tile) { } else if(_dist == NODE_SCATTER_DIST.tile) {
if(_scat == 0) {
var _col = ceil(sqrt(_amount));
var _row = ceil(_amount / _col);
var _iwid = _dim[0] / _col;
var _ihig = _dim[1] / _row;
var _irow = floor(i / _col);
var _icol = safe_mod(i, _col);
_x = _icol * _iwid;
_y = _irow * _ihig;
} else if(_scat == 1) {
_x = random_range_seed(0, _dim[0], _sed); _sed++; _x = random_range_seed(0, _dim[0], _sed); _sed++;
_y = random_range_seed(0, _dim[1], _sed); _sed++; _y = random_range_seed(0, _dim[1], _sed); _sed++;
} }
}
var posS = _dist < 4? seed + _y * _dim[0] + _x : seed + i * 100; var posS = _dist < 4? seed + _y * _dim[0] + _x : seed + i * 100;
var _scx = random_range_seed(_scale[0], _scale[1], posS); posS++; var _scx = random_range_seed(_scale[0], _scale[1], posS); posS++;
@ -263,22 +286,24 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
var surf = _inSurf; var surf = _inSurf;
var ind = 0; var ind = 0;
if(is_array(_inSurf)) {
if(array_length(_inSurf) == 0) break;
ind = irandom_seed(array_length(_inSurf) - 1, posS); if(is_array(_inSurf)) {
surf = _inSurf[ind]; switch(_arr) {
posS++; case 1 : ind = safe_mod(i, array_length(_inSurf)); break;
case 2 : ind = irandom_seed(array_length(_inSurf) - 1, posS); posS++; break;
case 3 : ind = array_safe_get(arrId, i, 0); break;
case 4 : if(useArrTex) ind = color_get_brightness(surface_get_pixel(arrTex, _x, _y)) * (array_length(_inSurf) - 1); break;
}
surf = array_safe_get(_inSurf, ind, 0);
} }
var sw = surface_get_width_safe(surf); var sw = surface_get_width_safe(surf);
var sh = surface_get_height_safe(surf); var sh = surface_get_height_safe(surf);
if(_dist != NODE_SCATTER_DIST.area || _scat != AREA_SCATTER.uniform) { var _p = point_rotate(_x - sw / 2 * _scx, _y - sh * _scy / 2, _x, _y, _r);
var p = point_rotate(-sw / 2 * _scx, -sh * _scy / 2, 0, 0, _r); _x = _p[0];
_x += p[0]; _y = _p[1];
_y += p[1];
}
var grSamp = random_seed(1, posS); posS++; var grSamp = random_seed(1, posS); posS++;
if(vCol && _v != noone) if(vCol && _v != noone)

View file

@ -3,16 +3,19 @@ function Node_Stagger(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
inputs[| 0] = nodeValue("Surface", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); inputs[| 0] = nodeValue("Surface", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone);
inputs[| 1] = nodeValue("Base Delay", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0); inputs[| 1] = nodeValue("Delay Step", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1);
inputs[| 2] = nodeValue("Delay Step", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1); inputs[| 2] = nodeValue("Delay Amount", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1);
inputs[| 3] = nodeValue("Delay Amount", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1); inputs[| 3] = nodeValue("Stagger Curve", self, JUNCTION_CONNECT.input, VALUE_TYPE.curve, CURVE_DEF_01);
inputs[| 4] = nodeValue("Overflow", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
.setDisplay(VALUE_DISPLAY.enum_button, [ "Hide", "Clamp" ]);
outputs[| 0] = nodeValue("Surface", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); outputs[| 0] = nodeValue("Surface", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
input_display_list = [ 0, input_display_list = [ 0,
["Delay", false], 2, 3, ["Stagger", false], 3, 1, 2, 4,
]; ];
surf_indexes = []; surf_indexes = [];
@ -25,14 +28,21 @@ function Node_Stagger(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
static processData = function(_output, _data, _output_index, _array_index = 0) { static processData = function(_output, _data, _output_index, _array_index = 0) {
var _surf = _data[0]; var _surf = _data[0];
var _base = _data[1]; var _step = _data[1];
var _step = _data[2]; var _amnt = _data[2];
var _amnt = _data[3]; var _curv = _data[3];
var _ovfl = _data[4];
var _time = CURRENT_FRAME; var _time = CURRENT_FRAME;
if(_time == -1) return _output; if(_time == -1) return _output;
var _frtm = _time - floor(_array_index / _step) * _amnt; var _aind = _array_index;
var _stps = floor(process_amount / _step);
var _frtm = _time - eval_curve_x(_curv, floor(_aind / _step) / _stps) * _amnt * _stps;
_frtm = round(_frtm);
if(_ovfl == 1)
_frtm = clamp(_frtm, 0, TOTAL_FRAMES - 1);
var _sw = surface_get_width_safe(_surf); var _sw = surface_get_width_safe(_surf);
var _sh = surface_get_height_safe(_surf); var _sh = surface_get_height_safe(_surf);
@ -47,7 +57,7 @@ function Node_Stagger(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
surface_set_target(_output); surface_set_target(_output);
DRAW_CLEAR DRAW_CLEAR
if(_frtm >= 0) { if(0 <= _frtm && _frtm < TOTAL_FRAMES) {
draw_surface_safe(surf_indexes[_array_index][_frtm]); draw_surface_safe(surf_indexes[_array_index][_frtm]);
surface_free(surf_indexes[_array_index][_frtm]); surface_free(surf_indexes[_array_index][_frtm]);

View file

@ -1,5 +1,5 @@
//draw //draw
function draw_surface_safe(surface, _x = 0, _y = 0) { function draw_surface_safe(surface, _x = 0, _y = 0) { #region
INLINE INLINE
if(is_struct(surface)) { if(is_struct(surface)) {
@ -14,9 +14,9 @@ function draw_surface_safe(surface, _x = 0, _y = 0) {
__channel_pre(surface); __channel_pre(surface);
draw_surface(surface, _x, _y); draw_surface(surface, _x, _y);
__channel_pos(surface); __channel_pos(surface);
} } #endregion
function draw_surface_stretched_safe(surface, _x, _y, _w, _h) { function draw_surface_stretched_safe(surface, _x, _y, _w, _h) { #region
INLINE INLINE
if(is_struct(surface)) { if(is_struct(surface)) {
@ -31,9 +31,9 @@ function draw_surface_stretched_safe(surface, _x, _y, _w, _h) {
__channel_pre(surface); __channel_pre(surface);
draw_surface_stretched(surface, _x, _y, _w, _h); draw_surface_stretched(surface, _x, _y, _w, _h);
__channel_pos(surface); __channel_pos(surface);
} } #endregion
function draw_surface_ext_safe(surface, _x, _y, _xs = 1, _ys = 1, _rot = 0, _col = c_white, _alpha = 1) { function draw_surface_ext_safe(surface, _x, _y, _xs = 1, _ys = 1, _rot = 0, _col = c_white, _alpha = 1) { #region
INLINE INLINE
if(is_struct(surface)) { if(is_struct(surface)) {
@ -49,9 +49,9 @@ function draw_surface_ext_safe(surface, _x, _y, _xs = 1, _ys = 1, _rot = 0, _col
__channel_pre(surface); __channel_pre(surface);
draw_surface_ext(surface, _x, _y, _xs, _ys, _rot, _col, _alpha); draw_surface_ext(surface, _x, _y, _xs, _ys, _rot, _col, _alpha);
__channel_pos(surface); __channel_pos(surface);
} } #endregion
function draw_surface_tiled_safe(surface, _x, _y) { function draw_surface_tiled_safe(surface, _x, _y) { #region
INLINE INLINE
if(is_struct(surface)) { if(is_struct(surface)) {
@ -66,9 +66,9 @@ function draw_surface_tiled_safe(surface, _x, _y) {
__channel_pre(surface); __channel_pre(surface);
draw_surface_tiled(surface, _x, _y); draw_surface_tiled(surface, _x, _y);
__channel_pos(surface); __channel_pos(surface);
} } #endregion
function draw_surface_tiled_ext_safe(surface, _x, _y, _xs = 1, _ys = 1, _col = c_white, _alpha = 1) { function draw_surface_tiled_ext_safe(surface, _x, _y, _xs = 1, _ys = 1, _col = c_white, _alpha = 1) { #region
INLINE INLINE
if(is_struct(surface)) { if(is_struct(surface)) {
@ -83,9 +83,9 @@ function draw_surface_tiled_ext_safe(surface, _x, _y, _xs = 1, _ys = 1, _col = c
__channel_pre(surface); __channel_pre(surface);
draw_surface_tiled_ext(surface, _x, _y, _xs, _ys, _col, _alpha); draw_surface_tiled_ext(surface, _x, _y, _xs, _ys, _col, _alpha);
__channel_pos(surface); __channel_pos(surface);
} } #endregion
function draw_surface_part_ext_safe(surface, _l, _t, _w, _h, _x, _y, _xs = 1, _ys = 1, _rot = 0, _col = c_white, _alpha = 1) { function draw_surface_part_ext_safe(surface, _l, _t, _w, _h, _x, _y, _xs = 1, _ys = 1, _rot = 0, _col = c_white, _alpha = 1) { #region
INLINE INLINE
if(is_struct(surface)) { if(is_struct(surface)) {
@ -100,19 +100,19 @@ function draw_surface_part_ext_safe(surface, _l, _t, _w, _h, _x, _y, _xs = 1, _y
__channel_pre(surface); __channel_pre(surface);
draw_surface_part_ext(surface, _l, _t, _w, _h, _x, _y, _xs, _ys, _col, _alpha); draw_surface_part_ext(surface, _l, _t, _w, _h, _x, _y, _xs, _ys, _col, _alpha);
__channel_pos(surface); __channel_pos(surface);
} } #endregion
#macro surface_free surface_free_safe #macro surface_free surface_free_safe
#macro __surface_free surface_free #macro __surface_free surface_free
function surface_free_safe(surface) { function surface_free_safe(surface) { #region
INLINE INLINE
if(!is_surface(surface)) return; if(!is_surface(surface)) return;
__surface_free(surface); __surface_free(surface);
} } #endregion
function surface_save_safe(surface, path) { function surface_save_safe(surface, path) { #region
if(!is_surface(surface)) return; if(!is_surface(surface)) return;
var f = surface_get_format(surface); var f = surface_get_format(surface);
@ -148,7 +148,7 @@ function surface_save_safe(surface, path) {
surface_save(s, path); surface_save(s, path);
surface_free(s); surface_free(s);
return; return;
} } #endregion
function surface_cvt_8unorm(target, surface) { #region function surface_cvt_8unorm(target, surface) { #region
if(!is_surface(surface)) return target; if(!is_surface(surface)) return target;
@ -176,7 +176,7 @@ function surface_cvt_8unorm(target, surface) { #region
return target; return target;
} #endregion } #endregion
function surface_get_width_safe(s, crop = true) { function surface_get_width_safe(s, crop = true) { #region
INLINE INLINE
if(is_struct(s)) { if(is_struct(s)) {
@ -186,9 +186,9 @@ function surface_get_width_safe(s, crop = true) {
} }
return surface_get_width(s); return surface_get_width(s);
} } #endregion
function surface_get_height_safe(s, crop = true) { function surface_get_height_safe(s, crop = true) { #region
INLINE INLINE
if(is_struct(s)) { if(is_struct(s)) {
@ -198,44 +198,60 @@ function surface_get_height_safe(s, crop = true) {
} }
return surface_get_height(s); return surface_get_height(s);
} } #endregion
function surface_get_dimension(s) { function surface_get_dimension(s) { #region
INLINE INLINE
if(!is_surface(s)) return [ 1, 1 ]; if(!is_surface(s)) return [ 1, 1 ];
return [ surface_get_width_safe(s), surface_get_height_safe(s) ]; return [ surface_get_width_safe(s), surface_get_height_safe(s) ];
} } #endregion
//check //check
function is_surface(s) { function is_surface(s) { #region
INLINE INLINE
if(is_instanceof(s, dynaSurf) || is_instanceof(s, SurfaceAtlas)) return true; if(is_instanceof(s, dynaSurf) || is_instanceof(s, SurfaceAtlas)) return true;
if(is_numeric(s) && s > 0 && surface_exists(s)) return true; if(is_numeric(s) && s > 0 && surface_exists(s)) return true;
return false; return false;
} } #endregion
function surface_verify(surf, w, h, format = surface_rgba8unorm) { function surface_verify(surf, w, h, format = surface_rgba8unorm) { #region
INLINE INLINE
if(!is_surface(surf)) return surface_create_valid(w, h, format); if(!is_surface(surf)) return surface_create_valid(w, h, format);
return surface_size_to(surf, w, h, format, true); return surface_size_to(surf, w, h, format, true);
} } #endregion
//get //get
function surface_get_pixel(surface, _x, _y) { function surface_get_pixel(surface, _x, _y) { #region
INLINE INLINE
if(!is_surface(surface)) return; if(!is_surface(surface)) return;
var f = surface_get_format(surface); var f = surface_get_format(surface);
var px = surface_getpixel(surface, _x, _y); var fx = floor(_x);
var fy = floor(_y);
var rx = frac(_x);
var ry = frac(_y);
var px = surface_getpixel(surface, fx, fy);
if(rx == 0 && ry == 0) {
if(is_numeric(px)) return px; if(is_numeric(px)) return px;
return round(px[0] * (255 * power(256, 0))) + round(px[1] * (255 * power(256, 1))) + round(px[2] * (255 * power(256, 2))); return make_color_rgb(px[0] * 256, px[1] * 256, px[2] * 256);
} }
function surface_get_pixel_ext(surface, _x, _y) { var p1 = surface_getpixel(surface, fx + 1, fy + 0);
var p2 = surface_getpixel(surface, fx + 0, fy + 1);
var p3 = surface_getpixel(surface, fx + 1, fy + 1);
return merge_color(
merge_color(px, p1, rx),
merge_color(p2, p3, rx),
ry);
} #endregion
function surface_get_pixel_ext(surface, _x, _y) { #region
INLINE INLINE
if(!is_surface(surface)) return; if(!is_surface(surface)) return;
@ -243,39 +259,39 @@ function surface_get_pixel_ext(surface, _x, _y) {
if(is_numeric(px)) return px; if(is_numeric(px)) return px;
return round(px[0] * (255 * power(256, 0))) + round(px[1] * (255 * power(256, 1))) + round(px[2] * (255 * power(256, 2))) + round(px[3] * (255 * power(256, 3))); return round(px[0] * (255 * power(256, 0))) + round(px[1] * (255 * power(256, 1))) + round(px[2] * (255 * power(256, 2))) + round(px[3] * (255 * power(256, 3)));
} } #endregion
//create //create
function surface_create_empty(w, h, format = surface_rgba8unorm) { function surface_create_empty(w, h, format = surface_rgba8unorm) { #region
INLINE INLINE
var s = surface_create(w, h, format); var s = surface_create(w, h, format);
surface_clear(s); surface_clear(s);
return s; return s;
} } #endregion
function surface_create_size(surface, format = surface_rgba8unorm) { function surface_create_size(surface, format = surface_rgba8unorm) { #region
INLINE INLINE
return surface_create_valid(surface_get_width_safe(surface), surface_get_height_safe(surface), format); return surface_create_valid(surface_get_width_safe(surface), surface_get_height_safe(surface), format);
} } #endregion
function surface_create_valid(w, h, format = surface_rgba8unorm) { function surface_create_valid(w, h, format = surface_rgba8unorm) { #region
INLINE INLINE
return surface_create_empty(surface_valid_size(w), surface_valid_size(h), format); return surface_create_empty(surface_valid_size(w), surface_valid_size(h), format);
} } #endregion
function surface_create_from_buffer(w, h, buff, format = surface_rgba8unorm) { function surface_create_from_buffer(w, h, buff, format = surface_rgba8unorm) { #region
INLINE INLINE
if(buff < 0) return; if(buff < 0) return;
var s = surface_create_valid(surface_valid_size(w), surface_valid_size(h), format); var s = surface_create_valid(surface_valid_size(w), surface_valid_size(h), format);
buffer_set_surface(buff, s, 0); buffer_set_surface(buff, s, 0);
return s; return s;
} } #endregion
function surface_from_buffer(buff) { function surface_from_buffer(buff) { #region
static header_length = 24; static header_length = 24;
if(!buffer_exists(buff)) return noone; if(!buffer_exists(buff)) return noone;
@ -293,9 +309,9 @@ function surface_from_buffer(buff) {
var s = surface_create(w, h, format); var s = surface_create(w, h, format);
buffer_set_surface(buff, s, header_length); buffer_set_surface(buff, s, header_length);
return s; return s;
} } #endregion
function surface_create_from_sprite(spr) { function surface_create_from_sprite(spr) { #region
if(!sprite_exists(spr)) return noone; if(!sprite_exists(spr)) return noone;
if(sprite_get_number(spr) == 1) if(sprite_get_number(spr) == 1)
@ -307,9 +323,9 @@ function surface_create_from_sprite(spr) {
} }
return s; return s;
} } #endregion
function surface_create_from_sprite_ext(spr, ind, format = surface_rgba8unorm) { function surface_create_from_sprite_ext(spr, ind, format = surface_rgba8unorm) { #region
if(!sprite_exists(spr)) return noone; if(!sprite_exists(spr)) return noone;
var sw = sprite_get_width(spr); var sw = sprite_get_width(spr);
var sh = sprite_get_height(spr); var sh = sprite_get_height(spr);
@ -323,9 +339,9 @@ function surface_create_from_sprite_ext(spr, ind, format = surface_rgba8unorm) {
surface_reset_target(); surface_reset_target();
return s; return s;
} } #endregion
function surface_size_lim(surface, width, height) { function surface_size_lim(surface, width, height) { #region
var sw = surface_get_width_safe(surface); var sw = surface_get_width_safe(surface);
var sh = surface_get_height_safe(surface); var sh = surface_get_height_safe(surface);
if(sw <= width && sh <= height) return surface; if(sw <= width && sh <= height) return surface;
@ -337,9 +353,9 @@ function surface_size_lim(surface, width, height) {
draw_surface_ext_safe(surface, 0, 0, ss, ss, 0, c_white, 1); draw_surface_ext_safe(surface, 0, 0, ss, ss, 0, c_white, 1);
surface_reset_target(); surface_reset_target();
return s; return s;
} } #endregion
function surface_size_to(surface, width, height, format = noone, skipCheck = false) { function surface_size_to(surface, width, height, format = noone, skipCheck = false) { #region
if(!skipCheck && !is_surface(surface)) return surface; if(!skipCheck && !is_surface(surface)) return surface;
if(!is_numeric(width) || !is_numeric(height)) return surface; if(!is_numeric(width) || !is_numeric(height)) return surface;
if(width < 1 && height < 1) return surface; if(width < 1 && height < 1) return surface;
@ -361,18 +377,18 @@ function surface_size_to(surface, width, height, format = noone, skipCheck = fal
surface_clear(surface); surface_clear(surface);
return surface; return surface;
} } #endregion
function surface_clear(surface) { function surface_clear(surface) { #region
INLINE INLINE
if(!is_surface(surface)) return; if(!is_surface(surface)) return;
surface_set_target(surface); surface_set_target(surface);
DRAW_CLEAR DRAW_CLEAR
surface_reset_target(); surface_reset_target();
} } #endregion
function surface_copy_from(dst, src, format = noone) { function surface_copy_from(dst, src, format = noone) { #region
INLINE INLINE
surface_set_target(dst); surface_set_target(dst);
@ -381,9 +397,9 @@ function surface_copy_from(dst, src, format = noone) {
draw_surface_safe(src, 0, 0); draw_surface_safe(src, 0, 0);
BLEND_NORMAL BLEND_NORMAL
surface_reset_target(); surface_reset_target();
} } #endregion
function surface_clone(surface, destination = noone, format = noone) { function surface_clone(surface, destination = noone, format = noone) { #region
INLINE INLINE
if(is_struct(surface) && is_instanceof(surface, dynaSurf)) if(is_struct(surface) && is_instanceof(surface, dynaSurf))
@ -400,10 +416,10 @@ function surface_clone(surface, destination = noone, format = noone) {
surface_reset_target(); surface_reset_target();
return destination; return destination;
} } #endregion
//in-place modification //in-place modification
function surface_stretch(surf, _w, _h) { function surface_stretch(surf, _w, _h) { #region
INLINE INLINE
if(!is_surface(surf)) return noone; if(!is_surface(surf)) return noone;
@ -419,9 +435,9 @@ function surface_stretch(surf, _w, _h) {
surface_free(surf); surface_free(surf);
return _surf; return _surf;
} } #endregion
function surface_mirror(surf, _h, _v) { function surface_mirror(surf, _h, _v) { #region
INLINE INLINE
if(!is_surface(surf)) return noone; if(!is_surface(surf)) return noone;
@ -438,10 +454,10 @@ function surface_mirror(surf, _h, _v) {
surface_free(surf); surface_free(surf);
return _surf; return _surf;
} } #endregion
//others //others
function surface_copy_size(dest, source, format = noone) { function surface_copy_size(dest, source, format = noone) { #region
INLINE INLINE
if(!is_surface(dest)) return; if(!is_surface(dest)) return;
@ -453,17 +469,17 @@ function surface_copy_size(dest, source, format = noone) {
surface_reset_target(); surface_reset_target();
surface_copy_from(dest, source); surface_copy_from(dest, source);
} } #endregion
function surface_valid_size(s) { function surface_valid_size(s) { #region
INLINE INLINE
if(!is_numeric(s)) return 1; if(!is_numeric(s)) return 1;
if(is_infinity(s)) return 1; if(is_infinity(s)) return 1;
return clamp(round(s), 1, 8196); return clamp(round(s), 1, 8196);
} } #endregion
function surface_array_free(arr) { function surface_array_free(arr) { #region
INLINE INLINE
if(!is_array(arr)) { if(!is_array(arr)) {
@ -473,9 +489,9 @@ function surface_array_free(arr) {
for( var i = 0, n = array_length(arr); i < n; i++ ) for( var i = 0, n = array_length(arr); i < n; i++ )
surface_array_free(arr[i]); surface_array_free(arr[i]);
} } #endregion
function surface_array_clone(arr) { function surface_array_clone(arr) { #region
if(!is_array(arr)) { if(!is_array(arr)) {
if(is_surface(arr)) if(is_surface(arr))
return surface_clone(arr); return surface_clone(arr);
@ -489,16 +505,16 @@ function surface_array_clone(arr) {
_arr[i] = surface_array_clone(arr[i]); _arr[i] = surface_array_clone(arr[i]);
return _arr; return _arr;
} } #endregion
function surface_array_serialize(arr) { function surface_array_serialize(arr) { #region
INLINE INLINE
var _arr = __surface_array_serialize(arr); var _arr = __surface_array_serialize(arr);
return json_stringify(_arr); return json_stringify(_arr);
} } #endregion
function __surface_array_serialize(arr) { function __surface_array_serialize(arr) { #region
if(!is_array(arr)) { if(!is_array(arr)) {
if(is_surface(arr)) { if(is_surface(arr)) {
var buff = buffer_create(surface_get_width_safe(arr) * surface_get_height_safe(arr) * 4, buffer_fixed, 1); var buff = buffer_create(surface_get_width_safe(arr) * surface_get_height_safe(arr) * 4, buffer_fixed, 1);
@ -517,16 +533,16 @@ function __surface_array_serialize(arr) {
_arr[i] = __surface_array_serialize(arr[i]); _arr[i] = __surface_array_serialize(arr[i]);
return _arr; return _arr;
} } #endregion
function surface_array_deserialize(arr, index = -1) { function surface_array_deserialize(arr, index = -1) { #region
INLINE INLINE
var _arr = json_try_parse(arr); var _arr = json_try_parse(arr);
return index == -1? __surface_array_deserialize(_arr) : __surface_array_deserialize(_arr[index]); return index == -1? __surface_array_deserialize(_arr) : __surface_array_deserialize(_arr[index]);
} } #endregion
function __surface_array_deserialize(arr) { function __surface_array_deserialize(arr) { #region
if(!is_array(arr)) { if(!is_array(arr)) {
if(!is_struct(arr) || !struct_has(arr, "buffer")) if(!is_struct(arr) || !struct_has(arr, "buffer"))
return noone; return noone;
@ -542,9 +558,9 @@ function __surface_array_deserialize(arr) {
_arr[i] = __surface_array_deserialize(arr[i]); _arr[i] = __surface_array_deserialize(arr[i]);
return _arr; return _arr;
} } #endregion
function surface_encode(surface) { function surface_encode(surface) { #region
if(!is_real(surface)) return ""; if(!is_real(surface)) return "";
if(!surface_exists(surface)) return ""; if(!surface_exists(surface)) return "";
@ -555,15 +571,15 @@ function surface_encode(surface) {
buffer_delete(buff); buffer_delete(buff);
var str = { width: surface_get_width_safe(surface), height: surface_get_height_safe(surface), buffer: enc }; var str = { width: surface_get_width_safe(surface), height: surface_get_height_safe(surface), buffer: enc };
return json_stringify(str); return json_stringify(str);
} } #endregion
function surface_decode(struct) { function surface_decode(struct) { #region
var buff = buffer_base64_decode(struct.buffer); var buff = buffer_base64_decode(struct.buffer);
var buff = buffer_decompress(buff); var buff = buffer_decompress(buff);
return surface_create_from_buffer(struct.width, struct.height, buff); return surface_create_from_buffer(struct.width, struct.height, buff);
} } #endregion
function surface_format_get_bytes(format) { function surface_format_get_bytes(format) { #region
switch(format) { switch(format) {
case surface_rgba4unorm : return 4 * 0.5; break; case surface_rgba4unorm : return 4 * 0.5; break;
case surface_rgba8unorm : return 4 * 1; break; case surface_rgba8unorm : return 4 * 1; break;
@ -575,21 +591,21 @@ function surface_format_get_bytes(format) {
case surface_r32float : return 1 * 3; break; case surface_r32float : return 1 * 3; break;
} }
return 1; return 1;
} } #endregion
function surface_get_size(surface) { function surface_get_size(surface) { #region
INLINE INLINE
var sw = surface_get_width_safe(surface); var sw = surface_get_width_safe(surface);
var sh = surface_get_height_safe(surface); var sh = surface_get_height_safe(surface);
var sz = sw * sh * surface_format_get_bytes(surface_get_format(surface)); var sz = sw * sh * surface_format_get_bytes(surface_get_format(surface));
return sz; return sz;
} } #endregion
function surface_texture(surface) { function surface_texture(surface) { #region
INLINE INLINE
if(!is_surface(surface)) return -1; if(!is_surface(surface)) return -1;
return surface_get_texture(surface); return surface_get_texture(surface);
} } #endregion