Compare commits
2 Commits
0262ed7388
...
ce6b0ddb3a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce6b0ddb3a | ||
|
|
ef7e3e6449 |
@@ -234,7 +234,7 @@ action.on_input = function(action_id, evt)
|
||||
var matched_actions = []
|
||||
arrfor(array(this.action_map), mapped_action => {
|
||||
if (find(this.action_map[mapped_action], action_id) != null) {
|
||||
push(matched_actions, mapped_action)
|
||||
matched_actions[] = mapped_action
|
||||
|
||||
if (evt.pressed)
|
||||
this.down[mapped_action] = true
|
||||
|
||||
185
clay.cm
185
clay.cm
@@ -1,17 +1,21 @@
|
||||
// clay2.cm - Revised UI layout engine emitting flat drawables
|
||||
// clay.cm - UI layout engine emitting flat drawables with annotated tree
|
||||
//
|
||||
// Changes from clay.cm:
|
||||
// - No __proto__, uses meme/merge
|
||||
// - Uses meme/merge for config chains
|
||||
// - Emits flat list of drawables for film2d
|
||||
// - Supports scissor clipping
|
||||
//
|
||||
// Now returns [drawable, drawable, ...] instead of {type:'group', ...}
|
||||
// - Returns annotated tree root with .drawables for clay_input compatibility
|
||||
|
||||
var layout = use('layout')
|
||||
var graphics = use('graphics')
|
||||
|
||||
var clay = {}
|
||||
|
||||
// Unique key objects for tree traversal (used by clay_input)
|
||||
var CHILDREN = {}
|
||||
var PARENT = {}
|
||||
clay.CHILDREN = CHILDREN
|
||||
clay.PARENT = PARENT
|
||||
|
||||
// Layout context
|
||||
var lay_ctx = layout.make_context()
|
||||
|
||||
@@ -65,28 +69,49 @@ var config_stack = []
|
||||
|
||||
// Rewriting state management for cleaner recursion
|
||||
var tree_stack = []
|
||||
var _next_id = 0
|
||||
|
||||
function annotate_tree(node, root_height, parent_node) {
|
||||
var rect = lay_ctx.get_rect(node.id)
|
||||
node.boundingbox = {
|
||||
x: rect.x,
|
||||
y: root_height - (rect.y + rect.height),
|
||||
width: rect.width,
|
||||
height: rect.height
|
||||
}
|
||||
node[CHILDREN] = node.children
|
||||
node[PARENT] = parent_node
|
||||
arrfor(node.children, function(child) {
|
||||
annotate_tree(child, root_height, node)
|
||||
})
|
||||
}
|
||||
|
||||
clay.layout = function(fn, size) {
|
||||
lay_ctx.reset()
|
||||
_next_id = 0
|
||||
var root_id = lay_ctx.item()
|
||||
|
||||
|
||||
lay_ctx.set_size(root_id, size)
|
||||
lay_ctx.set_contain(root_id, layout.contain.row)
|
||||
|
||||
|
||||
var root_node = {
|
||||
id: root_id,
|
||||
config: meme(base_config, {size: size}),
|
||||
children: []
|
||||
}
|
||||
|
||||
|
||||
tree_stack = [root_node]
|
||||
|
||||
|
||||
fn() // User builds tree
|
||||
|
||||
|
||||
lay_ctx.run()
|
||||
|
||||
// Post-layout: build flat drawable list
|
||||
return build_drawables(root_node, size.height)
|
||||
|
||||
// Annotate tree for clay_input (boundingbox, CHILDREN, PARENT)
|
||||
annotate_tree(root_node, size.height, null)
|
||||
|
||||
// Build flat drawable list and attach to tree root
|
||||
root_node.drawables = build_drawables(root_node, size.height)
|
||||
return root_node
|
||||
}
|
||||
|
||||
function build_drawables(node, root_height, parent, parent_scissor) {
|
||||
@@ -130,8 +155,10 @@ function build_drawables(node, root_height, parent, parent_scissor) {
|
||||
|
||||
// Background
|
||||
if (node.config.background_image) {
|
||||
_next_id = _next_id + 1
|
||||
if (node.config.slice) {
|
||||
push(drawables, {
|
||||
drawables[] = {
|
||||
_id: _next_id,
|
||||
type: 'sprite',
|
||||
image: node.config.background_image,
|
||||
pos: {x: vis_x, y: vis_y},
|
||||
@@ -139,11 +166,12 @@ function build_drawables(node, root_height, parent, parent_scissor) {
|
||||
height: rect.height,
|
||||
slice: node.config.slice,
|
||||
color: node.config.background_color || {r:1, g:1, b:1, a:1},
|
||||
layer: p_layer - 0.1, // slightly behind content
|
||||
layer: p_layer - 0.1,
|
||||
scissor: current_scissor
|
||||
})
|
||||
}
|
||||
} else {
|
||||
push(drawables, {
|
||||
drawables[] = {
|
||||
_id: _next_id,
|
||||
type: 'sprite',
|
||||
image: node.config.background_image,
|
||||
pos: {x: vis_x, y: vis_y},
|
||||
@@ -152,10 +180,12 @@ function build_drawables(node, root_height, parent, parent_scissor) {
|
||||
color: node.config.background_color || {r:1, g:1, b:1, a:1},
|
||||
layer: p_layer - 0.1,
|
||||
scissor: current_scissor
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if (node.config.background_color) {
|
||||
push(drawables, {
|
||||
_next_id = _next_id + 1
|
||||
drawables[] = {
|
||||
_id: _next_id,
|
||||
type: 'rect',
|
||||
pos: {x: vis_x, y: vis_y},
|
||||
width: rect.width,
|
||||
@@ -163,43 +193,39 @@ function build_drawables(node, root_height, parent, parent_scissor) {
|
||||
color: node.config.background_color,
|
||||
layer: p_layer - 0.1,
|
||||
scissor: current_scissor
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Content (Image/Text)
|
||||
if (node.config.image) {
|
||||
push(drawables, {
|
||||
_next_id = _next_id + 1
|
||||
drawables[] = {
|
||||
_id: _next_id,
|
||||
type: 'sprite',
|
||||
image: node.config.image,
|
||||
pos: {x: vis_x, y: vis_y},
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
height: rect.height,
|
||||
color: node.config.color,
|
||||
layer: p_layer,
|
||||
scissor: current_scissor
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (node.config.text) {
|
||||
push(drawables, {
|
||||
_next_id = _next_id + 1
|
||||
drawables[] = {
|
||||
_id: _next_id,
|
||||
type: 'text',
|
||||
text: node.config.text,
|
||||
font: node.config.font_path,
|
||||
size: node.config.font_size,
|
||||
size: node.config.font_size,
|
||||
color: node.config.color,
|
||||
pos: {x: vis_x, y: vis_y + rect.height}, // Baseline adjustment
|
||||
anchor_y: 1.0, // Text usually draws from baseline up or top down?
|
||||
// film2d text uses top-left by default unless anchor set.
|
||||
// Original clay put it at `y + rect.height`.
|
||||
// Let's assume origin top-left, so we might need anchor adjustment or just position.
|
||||
// If frame is top-down (0 at top), `abs_y` is top.
|
||||
// `rect.y` in layout is bottom-up? "rect.y is from bottom" says original comment.
|
||||
// `abs_y = root_height - (rect.y + rect.height)` -> Top edge of element.
|
||||
// Text usually wants baseline.
|
||||
// If we put it at `vis_y + rect.height`, that's bottom of element.
|
||||
pos: {x: vis_x, y: vis_y + rect.height},
|
||||
anchor_y: 1.0,
|
||||
layer: p_layer,
|
||||
scissor: current_scissor
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Children
|
||||
@@ -216,6 +242,20 @@ function build_drawables(node, root_height, parent, parent_scissor) {
|
||||
function process_configs(configs) {
|
||||
var cfg = meme(base_config, configs)
|
||||
|
||||
// Parse shorthand font string (e.g. 'blackcastle.64') into font_path and font_size
|
||||
var font_parts = null
|
||||
var parsed_size = null
|
||||
if (cfg.font && is_text(cfg.font)) {
|
||||
font_parts = array(cfg.font, '.')
|
||||
if (length(font_parts) >= 2) {
|
||||
parsed_size = number(font_parts[length(font_parts) - 1])
|
||||
if (parsed_size) {
|
||||
cfg.font_size = parsed_size
|
||||
cfg.font_path = font_parts[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cfg.color = normalize_color(cfg.color, base_config.color)
|
||||
if (cfg.background_color) cfg.background_color = normalize_color(cfg.background_color, {r:1,g:1,b:1,a:1})
|
||||
|
||||
@@ -250,15 +290,15 @@ function push_node(configs, contain_mode) {
|
||||
|
||||
// Add to parent
|
||||
var parent = tree_stack[length(tree_stack)-1]
|
||||
push(parent.children, node)
|
||||
parent.children[] = node
|
||||
lay_ctx.insert(parent.id, item)
|
||||
|
||||
push(tree_stack, node)
|
||||
tree_stack[] = node
|
||||
return node
|
||||
}
|
||||
|
||||
function pop_node() {
|
||||
pop(tree_stack)
|
||||
tree_stack[]
|
||||
}
|
||||
|
||||
// Generic container
|
||||
@@ -305,34 +345,34 @@ clay.zstack = function(configs, fn) {
|
||||
}
|
||||
|
||||
// Leaf nodes
|
||||
clay.image = function(path, configs) {
|
||||
clay.image = function(path, configs, extra) {
|
||||
var img = graphics.texture(path)
|
||||
var c = [{image: path}]
|
||||
var final_config = process_configs(configs)
|
||||
var _configs = configs ? (is_array(configs) ? configs : [configs]) : []
|
||||
if (extra) _configs = array(_configs, is_array(extra) ? extra : [extra])
|
||||
var final_config = process_configs(_configs)
|
||||
if (!final_config.size && !final_config.behave)
|
||||
c.size = {width: img.width, height: img.height}
|
||||
|
||||
var _configs = is_array(configs) ? configs : [configs]
|
||||
c[] = {size: {width: img.width, height: img.height}}
|
||||
|
||||
push_node(array(c, _configs), null)
|
||||
pop_node()
|
||||
}
|
||||
|
||||
clay.text = function(str, configs) {
|
||||
clay.text = function(str, configs, extra) {
|
||||
var c = [{text: str}]
|
||||
var final_config = process_configs(configs)
|
||||
var _configs = configs ? (is_array(configs) ? configs : [configs]) : []
|
||||
if (extra) _configs = array(_configs, is_array(extra) ? extra : [extra])
|
||||
var final_config = process_configs(_configs)
|
||||
if (!final_config.size && !final_config.behave) {
|
||||
c.size = {width: 100, height: 20}
|
||||
c[] = {size: {width: 100, height: 20}}
|
||||
}
|
||||
|
||||
var _configs = is_array(configs) ? configs : [configs]
|
||||
|
||||
push_node(array(c, _configs), null)
|
||||
pop_node()
|
||||
}
|
||||
|
||||
clay.rectangle = function(configs) {
|
||||
var _configs = is_array(configs) ? configs : [configs]
|
||||
var _configs = configs ? (is_array(configs) ? configs : [configs]) : [{}]
|
||||
push_node(_configs, null)
|
||||
pop_node()
|
||||
}
|
||||
@@ -350,6 +390,47 @@ clay.button = function(str, action, configs) {
|
||||
})
|
||||
}
|
||||
|
||||
// Spacer — fills available space
|
||||
clay.spacer = function(config) {
|
||||
var cfg = config || {}
|
||||
if (!cfg.behave) cfg.behave = layout.behave.hfill | layout.behave.vfill
|
||||
push_node([cfg], null)
|
||||
pop_node()
|
||||
}
|
||||
|
||||
// Convenience draw wrapper — auto-detects call patterns:
|
||||
// clay.draw(fn) — default 640x360
|
||||
// clay.draw(fn, size_obj) — fn first, size object second
|
||||
// clay.draw(size_array, fn) — size array first, fn second
|
||||
clay.draw = function(arg1, arg2) {
|
||||
var fn = null
|
||||
var size = {width: 640, height: 360}
|
||||
if (is_function(arg1)) {
|
||||
fn = arg1
|
||||
if (arg2) {
|
||||
if (is_array(arg2)) size = {width: arg2[0], height: arg2[1]}
|
||||
else if (is_object(arg2)) size = arg2
|
||||
}
|
||||
} else if (is_array(arg1)) {
|
||||
size = {width: arg1[0], height: arg1[1]}
|
||||
fn = arg2
|
||||
}
|
||||
return clay.layout(fn, size)
|
||||
}
|
||||
|
||||
// Offset all drawables in an array by a position
|
||||
clay.offset_drawables = function(drawables, offset) {
|
||||
var result = []
|
||||
var i = 0
|
||||
var d = null
|
||||
for (i = 0; i < length(drawables); i = i + 1) {
|
||||
d = meme(drawables[i])
|
||||
d.pos = {x: d.pos.x + offset.x, y: d.pos.y + offset.y}
|
||||
result[] = d
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Constants
|
||||
clay.behave = layout.behave
|
||||
clay.contain = layout.contain
|
||||
|
||||
@@ -34,7 +34,8 @@ function find_path(node, path, pos) {
|
||||
if (!pointer_enabled(node)) return null
|
||||
if (!rect_contains(node, pos)) return null
|
||||
|
||||
var next_path = array(path, node)
|
||||
var next_path = array(path)
|
||||
next_path[] = node
|
||||
var i = 0
|
||||
var child = null
|
||||
var child_path = null
|
||||
@@ -79,7 +80,7 @@ clay_input.click = function click(tree_root, mousepos, button) {
|
||||
clay_input.get_actionable = function get_actionable(tree_root) {
|
||||
var actionable = []
|
||||
function walk(node) {
|
||||
if (node.config.action) push(actionable, node)
|
||||
if (node.config.action) actionable[] = node
|
||||
if (node[clay.CHILDREN])
|
||||
arrfor(node[clay.CHILDREN], walk)
|
||||
}
|
||||
@@ -90,7 +91,7 @@ clay_input.get_actionable = function get_actionable(tree_root) {
|
||||
clay_input.filter = function filter(tree_root, predicate) {
|
||||
var results = []
|
||||
function rec(node) {
|
||||
if (predicate(node)) push(results, node)
|
||||
if (predicate(node)) results[] = node
|
||||
if (node[clay.CHILDREN])
|
||||
arrfor(node[clay.CHILDREN], rec)
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ collision2d.overlap = function(body, pos, others) {
|
||||
for (i = 0; i < length(others); i++) {
|
||||
other = others[i]
|
||||
if (collision2d.test(body, pos, other.body, other.pos))
|
||||
push(results, other)
|
||||
results[] = other
|
||||
}
|
||||
return results
|
||||
}
|
||||
@@ -94,12 +94,12 @@ collision2d.overlap_point = function(point, bodies) {
|
||||
hw = b.body.width * 0.5
|
||||
hh = b.body.height * 0.5
|
||||
if (abs(point.x - c.x) < hw && abs(point.y - c.y) < hh)
|
||||
push(results, b)
|
||||
results[] = b
|
||||
} else if (b.body.type == 'circle') {
|
||||
dx = point.x - c.x
|
||||
dy = point.y - c.y
|
||||
if (dx * dx + dy * dy < b.body.radius * b.body.radius)
|
||||
push(results, b)
|
||||
results[] = b
|
||||
}
|
||||
}
|
||||
return results
|
||||
|
||||
@@ -23,7 +23,7 @@ compositor.compile = function(config) {
|
||||
|
||||
// Clear screen
|
||||
if (config.clear)
|
||||
push(ctx.passes, {type: 'clear', target: 'screen', color: config.clear})
|
||||
ctx.passes[] = {type: 'clear', target: 'screen', color: config.clear}
|
||||
|
||||
// Process each plane (supports both 'planes' and legacy 'layers' key)
|
||||
var planes = config.planes || config.layers || []
|
||||
@@ -44,11 +44,11 @@ compositor.compile = function(config) {
|
||||
}
|
||||
|
||||
function compile_imgui_layer(layer, ctx) {
|
||||
push(ctx.passes, {
|
||||
ctx.passes[] = {
|
||||
type: 'imgui',
|
||||
target: 'screen',
|
||||
draw: layer.draw
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function compile_plane(plane_config, ctx, group_effects) {
|
||||
@@ -75,7 +75,7 @@ function compile_plane(plane_config, ctx, group_effects) {
|
||||
var di = 0
|
||||
if (plane_config.drawables) {
|
||||
for (di = 0; di < length(plane_config.drawables); di++)
|
||||
push(all_sprites, plane_config.drawables[di])
|
||||
all_sprites[] = plane_config.drawables[di]
|
||||
}
|
||||
|
||||
// Find which sprites belong to groups with effects
|
||||
@@ -110,21 +110,21 @@ function compile_plane(plane_config, ctx, group_effects) {
|
||||
if (group_effects[gname]) {
|
||||
if (!effect_groups[gname])
|
||||
effect_groups[gname] = {sprites: [], effects: group_effects[gname].effects}
|
||||
push(effect_groups[gname].sprites, s)
|
||||
effect_groups[gname].sprites[] = s
|
||||
assigned = true
|
||||
break // Only assign to first matching effect group
|
||||
}
|
||||
}
|
||||
|
||||
// Add to base sprites if not assigned to effect group and not mask-only
|
||||
if (!assigned && !is_mask_only) push(base_sprites, s)
|
||||
if (!assigned && !is_mask_only) base_sprites[] = s
|
||||
}
|
||||
|
||||
// Allocate plane target
|
||||
var plane_target = ctx.alloc(res.width, res.height, plane_config.name)
|
||||
|
||||
// Always clear plane target to prevent stale data between frames
|
||||
push(ctx.passes, {type: 'clear', target: plane_target, color: plane_config.clear || {r: 0, g: 0, b: 0, a: 0}})
|
||||
ctx.passes[] = {type: 'clear', target: plane_target, color: plane_config.clear || {r: 0, g: 0, b: 0, a: 0}}
|
||||
|
||||
// Render each effect group to temp target, apply effects, composite back
|
||||
arrfor(array(effect_groups), gname => {
|
||||
@@ -134,7 +134,7 @@ function compile_plane(plane_config, ctx, group_effects) {
|
||||
var group_target = ctx.alloc(res.width, res.height, gname + '_content')
|
||||
|
||||
// Render group content
|
||||
push(ctx.passes, {
|
||||
ctx.passes[] = {
|
||||
type: 'render',
|
||||
renderer: 'film2d',
|
||||
drawables: eg.sprites,
|
||||
@@ -143,7 +143,7 @@ function compile_plane(plane_config, ctx, group_effects) {
|
||||
target_size: res,
|
||||
layer_sort: layer_sort,
|
||||
clear: {r: 0, g: 0, b: 0, a: 0}
|
||||
})
|
||||
}
|
||||
|
||||
// Apply effects
|
||||
var current = group_target
|
||||
@@ -155,19 +155,19 @@ function compile_plane(plane_config, ctx, group_effects) {
|
||||
}
|
||||
|
||||
// Composite result to plane
|
||||
push(ctx.passes, {
|
||||
ctx.passes[] = {
|
||||
type: 'composite',
|
||||
source: current,
|
||||
dest: plane_target,
|
||||
source_size: res,
|
||||
dest_size: res,
|
||||
blend: 'over'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Render base sprites (no effects)
|
||||
if (length(base_sprites) > 0) {
|
||||
push(ctx.passes, {
|
||||
ctx.passes[] = {
|
||||
type: 'render',
|
||||
renderer: 'film2d',
|
||||
drawables: base_sprites,
|
||||
@@ -176,17 +176,17 @@ function compile_plane(plane_config, ctx, group_effects) {
|
||||
target_size: res,
|
||||
layer_sort: layer_sort,
|
||||
clear: null // Don't clear, blend on top
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Composite plane to screen
|
||||
push(ctx.passes, {
|
||||
ctx.passes[] = {
|
||||
type: 'blit_to_screen',
|
||||
source: plane_target,
|
||||
source_size: res,
|
||||
dest_size: ctx.screen_size,
|
||||
presentation: plane_config.presentation || 'stretch'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function apply_effect(ctx, effect, input, params) {
|
||||
@@ -212,25 +212,25 @@ function apply_effect(ctx, effect, input, params) {
|
||||
blur2 = ctx.alloc(size.width, size.height, hint + '_blur2')
|
||||
|
||||
// Threshold
|
||||
push(ctx.passes, {
|
||||
ctx.passes[] = {
|
||||
type: 'shader_pass',
|
||||
shader: 'threshold',
|
||||
input: input,
|
||||
output: bright,
|
||||
uniforms: {threshold: effect.threshold || 0.8, intensity: effect.intensity || 1}
|
||||
})
|
||||
}
|
||||
|
||||
// Blur passes
|
||||
blur_passes = effect.blur_passes || 2
|
||||
blur_in = bright
|
||||
for (p = 0; p < blur_passes; p++) {
|
||||
push(ctx.passes, {type: 'shader_pass', shader: 'blur', input: blur_in, output: blur1, uniforms: {direction: {x: 1, y: 0}, texel_size: {x: 1/size.width, y: 1/size.height}}})
|
||||
push(ctx.passes, {type: 'shader_pass', shader: 'blur', input: blur1, output: blur2, uniforms: {direction: {x: 0, y: 1}, texel_size: {x: 1/size.width, y: 1/size.height}}})
|
||||
ctx.passes[] = {type: 'shader_pass', shader: 'blur', input: blur_in, output: blur1, uniforms: {direction: {x: 1, y: 0}, texel_size: {x: 1/size.width, y: 1/size.height}}}
|
||||
ctx.passes[] = {type: 'shader_pass', shader: 'blur', input: blur1, output: blur2, uniforms: {direction: {x: 0, y: 1}, texel_size: {x: 1/size.width, y: 1/size.height}}}
|
||||
blur_in = blur2
|
||||
}
|
||||
|
||||
// Composite bloom
|
||||
push(ctx.passes, {type: 'composite_textures', base: input, overlay: blur2, output: output, mode: 'add'})
|
||||
ctx.passes[] = {type: 'composite_textures', base: input, overlay: blur2, output: output, mode: 'add'}
|
||||
|
||||
} else if (effect.type == 'mask') {
|
||||
mask_group = effect.mask_group
|
||||
@@ -241,7 +241,7 @@ function apply_effect(ctx, effect, input, params) {
|
||||
mask_target = ctx.alloc(size.width, size.height, hint + '_mask')
|
||||
|
||||
// Render mask
|
||||
push(ctx.passes, {
|
||||
ctx.passes[] = {
|
||||
type: 'render',
|
||||
renderer: 'film2d',
|
||||
drawables: mask_sprites,
|
||||
@@ -249,24 +249,24 @@ function apply_effect(ctx, effect, input, params) {
|
||||
target: mask_target,
|
||||
target_size: size,
|
||||
clear: {r: 0, g: 0, b: 0, a: 0}
|
||||
})
|
||||
}
|
||||
|
||||
// Apply mask
|
||||
push(ctx.passes, {
|
||||
ctx.passes[] = {
|
||||
type: 'apply_mask',
|
||||
content: input,
|
||||
mask: mask_target,
|
||||
output: output,
|
||||
mode: effect.channel || 'alpha',
|
||||
invert: effect.invert || false
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// No mask sprites, pass through
|
||||
push(ctx.passes, {type: 'blit', source: input, dest: output})
|
||||
ctx.passes[] = {type: 'blit', source: input, dest: output}
|
||||
}
|
||||
} else {
|
||||
// Unknown effect, pass through
|
||||
push(ctx.passes, {type: 'blit', source: input, dest: output})
|
||||
ctx.passes[] = {type: 'blit', source: input, dest: output}
|
||||
}
|
||||
|
||||
return output
|
||||
@@ -302,8 +302,8 @@ compositor.execute = function(plan) {
|
||||
|
||||
if (pass.type == 'clear') {
|
||||
target = resolve(pass.target)
|
||||
push(commands, {cmd: 'begin_render', target: target, clear: pass.color})
|
||||
push(commands, {cmd: 'end_render'})
|
||||
commands[] = {cmd: 'begin_render', target: target, clear: pass.color}
|
||||
commands[] = {cmd: 'end_render'}
|
||||
|
||||
} else if (pass.type == 'render') {
|
||||
result = film2d.render({
|
||||
@@ -315,68 +315,68 @@ compositor.execute = function(plan) {
|
||||
clear: pass.clear
|
||||
}, backend)
|
||||
for (c = 0; c < length(result.commands); c++)
|
||||
push(commands, result.commands[c])
|
||||
commands[] = result.commands[c]
|
||||
|
||||
} else if (pass.type == 'shader_pass') {
|
||||
push(commands, {
|
||||
commands[] = {
|
||||
cmd: 'shader_pass',
|
||||
shader: pass.shader,
|
||||
input: resolve(pass.input),
|
||||
output: resolve(pass.output),
|
||||
uniforms: pass.uniforms
|
||||
})
|
||||
}
|
||||
|
||||
} else if (pass.type == 'composite_textures') {
|
||||
push(commands, {
|
||||
commands[] = {
|
||||
cmd: 'composite_textures',
|
||||
base: resolve(pass.base),
|
||||
overlay: resolve(pass.overlay),
|
||||
output: resolve(pass.output),
|
||||
mode: pass.mode
|
||||
})
|
||||
}
|
||||
|
||||
} else if (pass.type == 'apply_mask') {
|
||||
push(commands, {
|
||||
commands[] = {
|
||||
cmd: 'apply_mask',
|
||||
content_texture: resolve(pass.content),
|
||||
mask_texture: resolve(pass.mask),
|
||||
output: resolve(pass.output),
|
||||
mode: pass.mode,
|
||||
invert: pass.invert
|
||||
})
|
||||
}
|
||||
|
||||
} else if (pass.type == 'composite') {
|
||||
push(commands, {
|
||||
commands[] = {
|
||||
cmd: 'blit',
|
||||
texture: resolve(pass.source),
|
||||
target: resolve(pass.dest),
|
||||
dst_rect: {x: 0, y: 0, width: pass.dest_size.width, height: pass.dest_size.height}
|
||||
})
|
||||
}
|
||||
|
||||
} else if (pass.type == 'blit_to_screen') {
|
||||
rect = _calc_presentation(pass.source_size, pass.dest_size, pass.presentation)
|
||||
push(commands, {
|
||||
commands[] = {
|
||||
cmd: 'blit',
|
||||
texture: resolve(pass.source),
|
||||
target: 'screen',
|
||||
dst_rect: rect,
|
||||
filter: pass.presentation == 'integer_scale' ? 'nearest' : 'linear'
|
||||
})
|
||||
}
|
||||
} else if (pass.type == 'blit') {
|
||||
src = resolve(pass.source)
|
||||
dst = resolve(pass.dest)
|
||||
push(commands, {
|
||||
commands[] = {
|
||||
cmd: 'blit',
|
||||
texture: src,
|
||||
target: dst,
|
||||
dst_rect: {x: 0, y: 0, width: dst.width, height: dst.height}
|
||||
})
|
||||
}
|
||||
} else if (pass.type == 'imgui') {
|
||||
push(commands, {
|
||||
commands[] = {
|
||||
cmd: 'imgui',
|
||||
target: resolve(pass.target),
|
||||
draw: pass.draw
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ compositor.snapshot = function() {
|
||||
for (i = 0; i < length(_last_plan.passes); i++) {
|
||||
pass = _last_plan.passes[i]
|
||||
if (pass.type == 'render') {
|
||||
push(planes, {
|
||||
planes[] = {
|
||||
drawable_count: length(pass.drawables),
|
||||
camera: pass.camera ? {
|
||||
pos: pass.camera.pos,
|
||||
@@ -433,7 +433,7 @@ compositor.snapshot = function() {
|
||||
height: pass.camera.height
|
||||
} : null,
|
||||
target_size: pass.target_size
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
|
||||
9
core.cm
9
core.cm
@@ -78,6 +78,9 @@ core.start = function(config) {
|
||||
// Start main loop
|
||||
_main_loop()
|
||||
|
||||
// Call start callback after the first frame and main loop are established
|
||||
if (config.start) config.start()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -105,7 +108,7 @@ function fps_add_sample(sample) {
|
||||
var n = length(_fps_samples)
|
||||
var old = null
|
||||
if (n < _fps_sample_count) {
|
||||
push(_fps_samples, sample)
|
||||
_fps_samples[] = sample
|
||||
_fps_sample_sum += sample
|
||||
} else {
|
||||
old = _fps_samples[_fps_sample_pos]
|
||||
@@ -225,7 +228,7 @@ function _main_loop() {
|
||||
// Handle both compositor result ({commands: [...]}) and fx_graph (graph object)
|
||||
if (render_result.commands) {
|
||||
if (_config.imgui || _config.editor) {
|
||||
push(render_result.commands, {
|
||||
render_result.commands[] = {
|
||||
cmd: 'imgui',
|
||||
draw: function(ui) {
|
||||
if (_config.imgui) _config.imgui(ui)
|
||||
@@ -235,7 +238,7 @@ function _main_loop() {
|
||||
}
|
||||
},
|
||||
target: 'screen'
|
||||
})
|
||||
}
|
||||
}
|
||||
// Compositor result - execute commands directly
|
||||
_backend.execute_commands(render_result.commands, win_size, dbg)
|
||||
|
||||
@@ -144,31 +144,31 @@ function _render_node_summary(imgui, node) {
|
||||
var info = []
|
||||
|
||||
if (node.pos) {
|
||||
push(info, "pos:(" + text(round(node.pos.x)) + "," + text(round(node.pos.y)) + ")")
|
||||
info[] = "pos:(" + text(round(node.pos.x)) + "," + text(round(node.pos.y)) + ")"
|
||||
}
|
||||
|
||||
if (node.width && node.height) {
|
||||
push(info, "size:" + text(node.width) + "x" + text(node.height))
|
||||
info[] = "size:" + text(node.width) + "x" + text(node.height)
|
||||
}
|
||||
|
||||
if (node.image) {
|
||||
push(info, "img:" + node.image)
|
||||
info[] = "img:" + node.image
|
||||
}
|
||||
|
||||
var t = null
|
||||
if (node.text) {
|
||||
t = node.text
|
||||
if (length(t) > 20) t = text(t, 0, 17) + "..."
|
||||
push(info, "\"" + t + "\"")
|
||||
info[] = "\"" + t + "\""
|
||||
}
|
||||
|
||||
var fx = []
|
||||
var j = 0
|
||||
if (node.effects && length(node.effects) > 0) {
|
||||
for (j = 0; j < length(node.effects); j++) {
|
||||
push(fx, node.effects[j].type)
|
||||
fx[] = node.effects[j].type
|
||||
}
|
||||
push(info, "fx:[" + text(fx, ",") + "]")
|
||||
info[] = "fx:[" + text(fx, ",") + "]"
|
||||
}
|
||||
|
||||
if (length(info) > 0) {
|
||||
|
||||
34
effects.cm
34
effects.cm
@@ -36,7 +36,7 @@ effects.register('bloom', {
|
||||
|
||||
// Threshold extraction
|
||||
var thresh_target = ctx.alloc_target(size.width, size.height, 'bloom_thresh')
|
||||
push(passes, {
|
||||
passes[] = {
|
||||
type: 'shader',
|
||||
shader: 'threshold',
|
||||
input: input,
|
||||
@@ -45,7 +45,7 @@ effects.register('bloom', {
|
||||
threshold: params.threshold != null ? params.threshold : 0.8,
|
||||
intensity: params.intensity != null ? params.intensity : 1.0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Blur ping-pong
|
||||
var blur_a = ctx.alloc_target(size.width, size.height, 'bloom_blur_a')
|
||||
@@ -56,31 +56,31 @@ effects.register('bloom', {
|
||||
var i = 0
|
||||
|
||||
for (i = 0; i < blur_count; i++) {
|
||||
push(passes, {
|
||||
passes[] = {
|
||||
type: 'shader',
|
||||
shader: 'blur',
|
||||
input: blur_src,
|
||||
output: blur_a,
|
||||
uniforms: {direction: {x: 2, y: 0}, texel_size: texel}
|
||||
})
|
||||
push(passes, {
|
||||
}
|
||||
passes[] = {
|
||||
type: 'shader',
|
||||
shader: 'blur',
|
||||
input: blur_a,
|
||||
output: blur_b,
|
||||
uniforms: {direction: {x: 0, y: 2}, texel_size: texel}
|
||||
})
|
||||
}
|
||||
blur_src = blur_b
|
||||
}
|
||||
|
||||
// Additive composite
|
||||
push(passes, {
|
||||
passes[] = {
|
||||
type: 'composite',
|
||||
base: input,
|
||||
overlay: blur_src,
|
||||
output: output,
|
||||
blend: 'add'
|
||||
})
|
||||
}
|
||||
|
||||
return passes
|
||||
}
|
||||
@@ -125,16 +125,16 @@ effects.register('mask', {
|
||||
|
||||
// Render mask source to target
|
||||
var mask_target = ctx.alloc_target(size.width, size.height, 'mask_src')
|
||||
push(passes, {
|
||||
passes[] = {
|
||||
type: 'render_subtree',
|
||||
root: mask_source,
|
||||
output: mask_target,
|
||||
clear: {r: 0, g: 0, b: 0, a: 0},
|
||||
space: params.space || 'local'
|
||||
})
|
||||
}
|
||||
|
||||
// Apply mask shader
|
||||
push(passes, {
|
||||
passes[] = {
|
||||
type: 'shader',
|
||||
shader: 'mask',
|
||||
inputs: [input, mask_target],
|
||||
@@ -143,7 +143,7 @@ effects.register('mask', {
|
||||
channel: params.channel == 'alpha' ? 0 : 1,
|
||||
invert: params.invert ? 1 : 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return passes
|
||||
}
|
||||
@@ -192,25 +192,25 @@ effects.register('blur', {
|
||||
var i = 0
|
||||
|
||||
for (i = 0; i < blur_count; i++) {
|
||||
push(passes, {
|
||||
passes[] = {
|
||||
type: 'shader',
|
||||
shader: 'blur',
|
||||
input: src,
|
||||
output: blur_a,
|
||||
uniforms: {direction: {x: 2, y: 0}, texel_size: texel}
|
||||
})
|
||||
push(passes, {
|
||||
}
|
||||
passes[] = {
|
||||
type: 'shader',
|
||||
shader: 'blur',
|
||||
input: blur_a,
|
||||
output: blur_b,
|
||||
uniforms: {direction: {x: 0, y: 2}, texel_size: texel}
|
||||
})
|
||||
}
|
||||
src = blur_b
|
||||
}
|
||||
|
||||
// Final blit to output
|
||||
push(passes, {type: 'blit', source: src, dest: output})
|
||||
passes[] = {type: 'blit', source: src, dest: output}
|
||||
return passes
|
||||
}
|
||||
})
|
||||
|
||||
@@ -47,8 +47,8 @@ function add_bunny(x, y) {
|
||||
anchor_x: 0.5, anchor_y: 0.5,
|
||||
plane: 'game'
|
||||
})
|
||||
push(bunnies, bunny)
|
||||
push(bunny_sprites, s)
|
||||
bunnies[] = bunny
|
||||
bunny_sprites[] = s
|
||||
}
|
||||
|
||||
// Initial bunnies
|
||||
|
||||
@@ -29,14 +29,14 @@ function init(grid) {
|
||||
row = []
|
||||
for (bx = 0; bx < 8; bx++) {
|
||||
col = ((bx + by) & 1) ? dark_color : light_color
|
||||
push(row, shape.rect({
|
||||
row[] = shape.rect({
|
||||
pos: {x: bx * S + S / 2, y: by * S + S / 2},
|
||||
width: S, height: S,
|
||||
fill: {r: col.r, g: col.g, b: col.b, a: col.a},
|
||||
plane: 'game', layer: 0
|
||||
}))
|
||||
})
|
||||
}
|
||||
push(board_shapes, row)
|
||||
board_shapes[] = row
|
||||
}
|
||||
|
||||
next_id = 0
|
||||
|
||||
@@ -49,7 +49,7 @@ function compute_valid_moves(from) {
|
||||
dest = grid.at(to)
|
||||
if (length(dest) && dest[0].colour == piece.colour) continue
|
||||
if (rules.canMove(piece, from, to, grid))
|
||||
push(validMoves, to)
|
||||
validMoves[] = to
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ function compute_valid_moves(from) {
|
||||
dest = grid.at(to)
|
||||
if (length(dest) && dest[0].colour == piece.colour) continue
|
||||
if (rules.canMove(piece, from, to, grid))
|
||||
push(validMoves, to)
|
||||
validMoves[] = to
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ var grid_prototype = {
|
||||
// add an entity into a cell
|
||||
add(entity, pos) {
|
||||
var cx = px(pos), cy = py(pos);
|
||||
push(this.cell(cx, cy), entity);
|
||||
this.cell(cx, cy)[] = entity;
|
||||
entity.coord = [cx, cy];
|
||||
},
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ function compute_valid_moves(from) {
|
||||
dest = grid.at(to)
|
||||
if (length(dest) && dest[0].colour == piece.colour) continue
|
||||
if (rules.canMove(piece, from, to, grid))
|
||||
push(validMoves, to)
|
||||
validMoves[] = to
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,12 +91,12 @@ function reset_game() {
|
||||
var cy = floor(gridH / 2)
|
||||
var wp = null
|
||||
for (i = 0; i < 3; i++) {
|
||||
push(snake_pos, {x: cx - i, y: cy})
|
||||
snake_pos[] = {x: cx - i, y: cy}
|
||||
wp = grid_to_world(cx - i, cy)
|
||||
push(snake_shapes, shape.rect({
|
||||
snake_shapes[] = shape.rect({
|
||||
pos: {x: wp.x, y: wp.y}, width: cellSize - 2, height: cellSize - 2,
|
||||
fill: {r: 0, g: 1, b: 0.3, a: 1}, plane: 'game'
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
dir = {x: 1, y: 0}
|
||||
@@ -166,7 +166,7 @@ core.start({
|
||||
var old_wp = grid_to_world(snake_pos[0].x, snake_pos[0].y)
|
||||
var new_wp = grid_to_world(hx, hy)
|
||||
var new_pos = [{x: hx, y: hy}]
|
||||
for (i = 0; i < length(snake_pos); i++) push(new_pos, snake_pos[i])
|
||||
for (i = 0; i < length(snake_pos); i++) new_pos[] = snake_pos[i]
|
||||
snake_pos = new_pos
|
||||
var head = shape.rect({
|
||||
pos: {x: old_wp.x, y: old_wp.y}, width: cellSize - 2, height: cellSize - 2,
|
||||
@@ -175,7 +175,7 @@ core.start({
|
||||
// Smooth tween from old position to new position
|
||||
tw.tween(head.pos).to({x: new_wp.x, y: new_wp.y}, move_interval).ease(ease.linear)
|
||||
var new_shapes = [head]
|
||||
for (i = 0; i < length(snake_shapes); i++) push(new_shapes, snake_shapes[i])
|
||||
for (i = 0; i < length(snake_shapes); i++) new_shapes[] = snake_shapes[i]
|
||||
snake_shapes = new_shapes
|
||||
|
||||
// Eat apple?
|
||||
@@ -185,9 +185,9 @@ core.start({
|
||||
spawn_apple()
|
||||
} else {
|
||||
// Remove tail
|
||||
tail = pop(snake_shapes)
|
||||
tail = snake_shapes[]
|
||||
tail.destroy()
|
||||
pop(snake_pos)
|
||||
snake_pos[]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -50,16 +50,16 @@ function init_board() {
|
||||
row = []
|
||||
srow = []
|
||||
for (c = 0; c < COLS; c++) {
|
||||
push(row, null)
|
||||
push(srow, shape.rect({
|
||||
row[] = null
|
||||
srow[] = shape.rect({
|
||||
pos: {x: c * TILE + TILE / 2, y: r * TILE + TILE / 2},
|
||||
width: TILE - 1, height: TILE - 1,
|
||||
fill: {r: 0.5, g: 0.5, b: 0.5, a: 1},
|
||||
plane: 'game', layer: 0, visible: false
|
||||
}))
|
||||
})
|
||||
}
|
||||
push(board, row)
|
||||
push(board_shapes, srow)
|
||||
board[] = row
|
||||
board_shapes[] = srow
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,10 +104,10 @@ var next_label = text2d({
|
||||
var next_shapes = []
|
||||
var ns = 0
|
||||
for (ns = 0; ns < 4; ns++) {
|
||||
push(next_shapes, shape.rect({
|
||||
next_shapes[] = shape.rect({
|
||||
pos: {x: 0, y: 0}, width: TILE - 1, height: TILE - 1,
|
||||
fill: {r: 1, g: 1, b: 1, a: 1}, plane: 'game', layer: 2, visible: false
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
function random_shape() {
|
||||
@@ -244,10 +244,10 @@ function place_piece() {
|
||||
// Create 4 shapes for active piece (layer 1 = on top of board)
|
||||
var pi = 0
|
||||
for (pi = 0; pi < 4; pi++) {
|
||||
push(piece_shapes, shape.rect({
|
||||
piece_shapes[] = shape.rect({
|
||||
pos: {x: 0, y: 0}, width: TILE - 1, height: TILE - 1,
|
||||
fill: {r: 1, g: 1, b: 1, a: 1}, plane: 'game', layer: 1, visible: false
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
init_board()
|
||||
|
||||
66
film2d.cm
66
film2d.cm
@@ -129,7 +129,7 @@ film2d.register = function(drawable) {
|
||||
// Index by plane
|
||||
var plane = drawable.plane || 'default'
|
||||
if (!plane_index[plane]) plane_index[plane] = []
|
||||
push(plane_index[plane], id)
|
||||
plane_index[plane][] = id
|
||||
|
||||
// Index by groups (effect routing only)
|
||||
var groups = drawable.groups || []
|
||||
@@ -138,7 +138,7 @@ film2d.register = function(drawable) {
|
||||
for (i = 0; i < length(groups); i++) {
|
||||
g = groups[i]
|
||||
if (!group_index[g]) group_index[g] = []
|
||||
push(group_index[g], id)
|
||||
group_index[g][] = id
|
||||
}
|
||||
|
||||
return id
|
||||
@@ -177,7 +177,7 @@ film2d.unregister = function(id) {
|
||||
film2d.index_group = function(id, group) {
|
||||
if (!group_index[group]) group_index[group] = []
|
||||
if (search(group_index[group], text(id)) == null)
|
||||
push(group_index[group], text(id))
|
||||
group_index[group][] = text(id)
|
||||
}
|
||||
|
||||
film2d.unindex_group = function(id, group) {
|
||||
@@ -218,9 +218,9 @@ film2d.query = function(selector) {
|
||||
// If also filtering by group, check membership
|
||||
if (selector.group) {
|
||||
groups = d.groups || []
|
||||
if (search(groups, selector.group) != null) push(result, d)
|
||||
if (search(groups, selector.group) != null) result[] = d
|
||||
} else {
|
||||
push(result, d)
|
||||
result[] = d
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,7 +232,7 @@ film2d.query = function(selector) {
|
||||
ids = group_index[selector.group] || []
|
||||
for (i = 0; i < length(ids); i++) {
|
||||
d = registry[ids[i]]
|
||||
if (d && d.visible != false) push(result, d)
|
||||
if (d && d.visible != false) result[] = d
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -245,7 +245,7 @@ film2d.query = function(selector) {
|
||||
if (!seen[ids[i]]) {
|
||||
seen[ids[i]] = true
|
||||
d = registry[ids[i]]
|
||||
if (d && d.visible != false) push(result, d)
|
||||
if (d && d.visible != false) result[] = d
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,7 +268,7 @@ film2d.get_groups = function(id) {
|
||||
film2d.all_groups = function() {
|
||||
var groups = []
|
||||
arrfor(array(group_index), g => {
|
||||
if (length(group_index[g]) > 0) push(groups, g)
|
||||
if (length(group_index[g]) > 0) groups[] = g
|
||||
})
|
||||
return groups
|
||||
}
|
||||
@@ -312,7 +312,7 @@ film2d.render = function(params, render_backend) {
|
||||
b = []
|
||||
buckets[layer_key] = b
|
||||
}
|
||||
push(b, d)
|
||||
b[] = d
|
||||
}
|
||||
|
||||
// Sort layers numerically (keys are text)
|
||||
@@ -339,14 +339,14 @@ film2d.render = function(params, render_backend) {
|
||||
if (!y_down) b = reverse(b) // y_up => smaller y draws later => reverse
|
||||
}
|
||||
|
||||
for (j = 0; j < length(b); j++) push(sorted_drawables, b[j])
|
||||
for (j = 0; j < length(b); j++) sorted_drawables[] = b[j]
|
||||
}
|
||||
|
||||
drawables = sorted_drawables
|
||||
|
||||
var commands = []
|
||||
push(commands, { cmd: "begin_render", target: target, clear: clear_color, target_size: target_size })
|
||||
push(commands, { cmd: "set_camera", camera: camera })
|
||||
commands[] = { cmd: "begin_render", target: target, clear: clear_color, target_size: target_size }
|
||||
commands[] = { cmd: "set_camera", camera: camera }
|
||||
|
||||
var batches = _batch_drawables(drawables)
|
||||
var batch = null
|
||||
@@ -354,18 +354,18 @@ film2d.render = function(params, render_backend) {
|
||||
for (i = 0; i < length(batches); i++) {
|
||||
batch = batches[i]
|
||||
if (batch.type == "sprite_batch")
|
||||
push(commands, { cmd: "draw_batch", batch_type: "sprites", geometry: { sprites: batch.sprites }, texture: batch.texture, material: batch.material })
|
||||
commands[] = { cmd: "draw_batch", batch_type: "sprites", geometry: { sprites: batch.sprites }, texture: batch.texture, material: batch.material }
|
||||
else if (batch.type == "mesh2d_batch")
|
||||
push(commands, { cmd: "draw_mesh2d", meshes: batch.meshes, texture: batch.texture, material: batch.material })
|
||||
commands[] = { cmd: "draw_mesh2d", meshes: batch.meshes, texture: batch.texture, material: batch.material }
|
||||
else if (batch.type == "text")
|
||||
push(commands, { cmd: "draw_text", drawable: batch.drawable })
|
||||
commands[] = { cmd: "draw_text", drawable: batch.drawable }
|
||||
else if (batch.type == "texture_ref")
|
||||
push(commands, { cmd: "draw_texture_ref", drawable: batch.drawable })
|
||||
commands[] = { cmd: "draw_texture_ref", drawable: batch.drawable }
|
||||
else if (batch.type == "shape")
|
||||
push(commands, { cmd: "draw_shape", drawable: batch.drawable })
|
||||
commands[] = { cmd: "draw_shape", drawable: batch.drawable }
|
||||
}
|
||||
|
||||
push(commands, { cmd: "end_render" })
|
||||
commands[] = { cmd: "end_render" }
|
||||
return { commands: commands }
|
||||
}
|
||||
|
||||
@@ -408,9 +408,9 @@ function _batch_drawables(drawables) {
|
||||
mat = d.material || {blend: 'alpha', sampler: d.filter || 'nearest'}
|
||||
|
||||
if (current && current.type == 'sprite_batch' && current.texture == tex && _mat_eq(current.material, mat)) {
|
||||
push(current.sprites, d)
|
||||
current.sprites[] = d
|
||||
} else {
|
||||
if (current) push(batches, current)
|
||||
if (current) batches[] = current
|
||||
current = {type: 'sprite_batch', texture: tex, material: mat, sprites: [d]}
|
||||
}
|
||||
} else if (d.type == 'particles') {
|
||||
@@ -437,9 +437,9 @@ function _batch_drawables(drawables) {
|
||||
}
|
||||
|
||||
if (current && current.type == 'sprite_batch' && current.texture == tex && _mat_eq(current.material, mat)) {
|
||||
push(current.sprites, sprite)
|
||||
current.sprites[] = sprite
|
||||
} else {
|
||||
if (current) push(batches, current)
|
||||
if (current) batches[] = current
|
||||
current = {type: 'sprite_batch', texture: tex, material: mat, sprites: [sprite]}
|
||||
}
|
||||
}
|
||||
@@ -480,9 +480,9 @@ function _batch_drawables(drawables) {
|
||||
tex = img
|
||||
mat = default_mat
|
||||
if (current && current.type == 'sprite_batch' && current.texture == tex && _mat_eq(current.material, mat)) {
|
||||
push(current.sprites, sprite)
|
||||
current.sprites[] = sprite
|
||||
} else {
|
||||
if (current) push(batches, current)
|
||||
if (current) batches[] = current
|
||||
current = {type: 'sprite_batch', texture: tex, material: mat, sprites: [sprite]}
|
||||
}
|
||||
}
|
||||
@@ -493,28 +493,28 @@ function _batch_drawables(drawables) {
|
||||
mat = d.material || {blend: d.blend || 'alpha', sampler: d.filter || 'linear'}
|
||||
|
||||
if (current && current.type == 'mesh2d_batch' && current.texture == tex && _mat_eq(current.material, mat)) {
|
||||
push(current.meshes, d)
|
||||
current.meshes[] = d
|
||||
} else {
|
||||
if (current) push(batches, current)
|
||||
if (current) batches[] = current
|
||||
current = {type: 'mesh2d_batch', texture: tex, material: mat, meshes: [d]}
|
||||
}
|
||||
} else if (d.type == 'shape') {
|
||||
// Shapes are rendered individually (each has unique SDF params)
|
||||
if (current) {
|
||||
push(batches, current)
|
||||
batches[] = current
|
||||
current = null
|
||||
}
|
||||
push(batches, {type: 'shape', drawable: d})
|
||||
batches[] = {type: 'shape', drawable: d}
|
||||
} else {
|
||||
if (current) {
|
||||
push(batches, current)
|
||||
batches[] = current
|
||||
current = null
|
||||
}
|
||||
push(batches, {type: d.type, drawable: d})
|
||||
batches[] = {type: d.type, drawable: d}
|
||||
}
|
||||
}
|
||||
|
||||
if (current) push(batches, current)
|
||||
if (current) batches[] = current
|
||||
return batches
|
||||
}
|
||||
|
||||
@@ -531,7 +531,7 @@ film2d.snapshot = function() {
|
||||
for (i = 0; i < length(ids); i++) {
|
||||
d = registry[ids[i]]
|
||||
if (!d) continue
|
||||
push(result, {
|
||||
result[] = {
|
||||
id: ids[i],
|
||||
type: d.type,
|
||||
pos: d.pos ? {x: d.pos.x, y: d.pos.y} : null,
|
||||
@@ -546,7 +546,7 @@ film2d.snapshot = function() {
|
||||
opacity: d.opacity,
|
||||
image: d.image ? (is_text(d.image) ? d.image : '(texture)') : null,
|
||||
text: d.text
|
||||
})
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
20
fx_graph.cm
20
fx_graph.cm
@@ -67,7 +67,7 @@ fx_graph.add_node = function(type, params) {
|
||||
params: local_params,
|
||||
output: {node_id: this.next_id - 1, slot: 'output'}
|
||||
}
|
||||
push(this.nodes, node)
|
||||
this.nodes[] = node
|
||||
return node
|
||||
}
|
||||
|
||||
@@ -203,14 +203,14 @@ NODE_EXECUTORS.composite = function(params, backend) {
|
||||
|
||||
// Emit composite_textures command (handled outside render pass)
|
||||
var commands = []
|
||||
push(commands, {
|
||||
commands[] = {
|
||||
cmd: 'composite_textures',
|
||||
base: base.target,
|
||||
overlay: overlay.target,
|
||||
output: target,
|
||||
mode: mode,
|
||||
opacity: opacity
|
||||
})
|
||||
}
|
||||
|
||||
return {target: target, commands: commands}
|
||||
}
|
||||
@@ -233,14 +233,14 @@ NODE_EXECUTORS.mask = function(params, backend) {
|
||||
|
||||
// Emit apply_mask command (handled via shader pass outside render pass)
|
||||
var commands = []
|
||||
push(commands, {
|
||||
commands[] = {
|
||||
cmd: 'apply_mask',
|
||||
content_texture: content.target,
|
||||
mask_texture: mask.target,
|
||||
output: target,
|
||||
mode: mode,
|
||||
invert: invert
|
||||
})
|
||||
}
|
||||
|
||||
return {target: target, commands: commands}
|
||||
}
|
||||
@@ -307,13 +307,13 @@ NODE_EXECUTORS.blit = function(params, backend) {
|
||||
}
|
||||
|
||||
var commands = []
|
||||
push(commands, {
|
||||
commands[] = {
|
||||
cmd: 'blit',
|
||||
texture: src_target,
|
||||
target: target,
|
||||
dst_rect: dst_rect,
|
||||
filter: filter
|
||||
})
|
||||
}
|
||||
|
||||
return {target: target, commands: commands}
|
||||
}
|
||||
@@ -323,7 +323,7 @@ NODE_EXECUTORS.present = function(params, backend) {
|
||||
var input = params.input
|
||||
|
||||
var commands = []
|
||||
push(commands, {cmd: 'present'})
|
||||
commands[] = {cmd: 'present'}
|
||||
|
||||
return {commands: commands}
|
||||
}
|
||||
@@ -354,13 +354,13 @@ NODE_EXECUTORS.shader_pass = function(params, backend) {
|
||||
}
|
||||
|
||||
var commands = []
|
||||
push(commands, {
|
||||
commands[] = {
|
||||
cmd: 'shader_pass',
|
||||
shader: shader,
|
||||
input: src,
|
||||
output: target,
|
||||
uniforms: uniforms
|
||||
})
|
||||
}
|
||||
|
||||
return {target: target, commands: commands}
|
||||
}
|
||||
|
||||
12
graphics.cm
12
graphics.cm
@@ -21,8 +21,8 @@ graphics.Image = function(surfaceData) {
|
||||
img.cpu = surfaceData || null;
|
||||
img.texture = 0;
|
||||
img.surface = img.cpu;
|
||||
img.width = surfaceData?.width || 0;
|
||||
img.height = surfaceData?.height || 0;
|
||||
img.width = surfaceData.width || 0;
|
||||
img.height = surfaceData.height || 0;
|
||||
img.rect = {x:0, y:0, width:img.width, height:img.height};
|
||||
img[LOADING] = false;
|
||||
img[LASTUSE] = time.number();
|
||||
@@ -157,7 +157,7 @@ function decode_aseprite(decoded) {
|
||||
function create_image(path){
|
||||
def bytes = io.slurp(path);
|
||||
|
||||
var ext = pop(array(path, '.'))
|
||||
var ext = array(path, '.')[]
|
||||
var raw = decode_image(bytes, ext);
|
||||
var anims = null
|
||||
var keys = null
|
||||
@@ -367,7 +367,7 @@ graphics.texture = function texture(path) {
|
||||
}
|
||||
|
||||
graphics.tex_hotreload = function tex_hotreload(file) {
|
||||
var basename = array(pop(array(file, '/')), '.')[0]
|
||||
var basename = array(array(file, '/')[], '.')[0]
|
||||
|
||||
// Check if this basename exists in our cache
|
||||
if (!(basename in cache)) return
|
||||
@@ -479,10 +479,10 @@ graphics.snapshot = function() {
|
||||
info.frame_count = length(entry.frames)
|
||||
info.type = 'animation'
|
||||
}
|
||||
push(images, info)
|
||||
images[] = info
|
||||
})
|
||||
arrfor(array(fontcache), function(k) {
|
||||
push(fonts, k)
|
||||
fonts[] = k
|
||||
})
|
||||
return {images: images, fonts: fonts}
|
||||
}
|
||||
|
||||
12
input.cm
12
input.cm
@@ -93,13 +93,13 @@ function create_user(index, config) {
|
||||
|
||||
// Push entity onto control stack
|
||||
push: function(entity) {
|
||||
push(this.control_stack, entity)
|
||||
this.control_stack[] = entity
|
||||
},
|
||||
|
||||
// Pop from control stack
|
||||
pop: function() {
|
||||
if (length(this.control_stack) > 1) {
|
||||
return pop(this.control_stack)
|
||||
return this.control_stack[]
|
||||
}
|
||||
return null
|
||||
},
|
||||
@@ -169,7 +169,7 @@ function pick_user(canon) {
|
||||
|
||||
picked.active_device = canon.device_id
|
||||
if (find(picked.paired_devices, canon.device_id) == null) {
|
||||
push(picked.paired_devices, canon.device_id)
|
||||
picked.paired_devices[] = canon.device_id
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,7 +211,7 @@ function configure(o) {
|
||||
// Create users
|
||||
_users = []
|
||||
for (i = 0; i < _config.max_users; i++) {
|
||||
push(_users, create_user(i, _config))
|
||||
_users[] = create_user(i, _config)
|
||||
}
|
||||
|
||||
_initialized = true
|
||||
@@ -268,7 +268,7 @@ function snapshot() {
|
||||
for (i = 0; i < length(_users); i++) {
|
||||
u = _users[i]
|
||||
target = u.target()
|
||||
push(users, {
|
||||
users[] = {
|
||||
index: u.index,
|
||||
device_kind: u.device_kind(),
|
||||
active_device: u.active_device,
|
||||
@@ -276,7 +276,7 @@ function snapshot() {
|
||||
down: u.down(),
|
||||
control_stack_depth: length(u.control_stack),
|
||||
target: target ? (target.name || '(entity)') : null
|
||||
})
|
||||
}
|
||||
}
|
||||
return {
|
||||
max_users: _config.max_users,
|
||||
|
||||
@@ -54,7 +54,7 @@ function gesture_stage(cfg) {
|
||||
|
||||
// Only process gamepad touchpad events
|
||||
if (ev.control != 'gamepad_touchpad') {
|
||||
push(output, ev)
|
||||
output[] = ev
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ function gesture_stage(cfg) {
|
||||
d = currentDist - start_dist
|
||||
|
||||
if (Math.abs(d) >= pinch_th / 100) {
|
||||
push(output, {
|
||||
output[] = {
|
||||
kind: 'gesture',
|
||||
device_id: ev.device_id,
|
||||
control: d > 0 ? 'pinch_out' : 'pinch_in',
|
||||
@@ -94,7 +94,7 @@ function gesture_stage(cfg) {
|
||||
released: false,
|
||||
delta: d,
|
||||
time: ev.time
|
||||
})
|
||||
}
|
||||
start_dist = currentDist
|
||||
}
|
||||
}
|
||||
@@ -118,14 +118,14 @@ function gesture_stage(cfg) {
|
||||
? (dx > 0 ? 'swipe_right' : 'swipe_left')
|
||||
: (dy > 0 ? 'swipe_down' : 'swipe_up')
|
||||
|
||||
push(output, {
|
||||
output[] = {
|
||||
kind: 'gesture',
|
||||
device_id: ev.device_id,
|
||||
control: dir,
|
||||
pressed: true,
|
||||
released: false,
|
||||
time: ev.time
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,18 +158,18 @@ function emacs_stage() {
|
||||
|
||||
// Only process keyboard button events
|
||||
if (ev.device_id != 'kbm' || ev.kind != 'button' || !ev.pressed) {
|
||||
push(output, ev)
|
||||
output[] = ev
|
||||
continue
|
||||
}
|
||||
|
||||
/* if (find(valid_emacs_keys, ev.control) == null) {
|
||||
push(output, ev)
|
||||
output[] = ev
|
||||
continue
|
||||
}
|
||||
*/
|
||||
// Only process if we have modifiers OR waiting for chord
|
||||
if (!ev.mods?.ctrl && !ev.mods?.alt && !prefix) {
|
||||
push(output, ev)
|
||||
output[] = ev
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -193,23 +193,23 @@ function emacs_stage() {
|
||||
if (prefix) {
|
||||
chord = prefix + " " + notation
|
||||
prefix = null
|
||||
push(output, {
|
||||
output[] = {
|
||||
kind: 'chord',
|
||||
device_id: ev.device_id,
|
||||
control: chord,
|
||||
pressed: true,
|
||||
released: false,
|
||||
time: ev.time
|
||||
})
|
||||
}
|
||||
} else {
|
||||
push(output, {
|
||||
output[] = {
|
||||
kind: 'chord',
|
||||
device_id: ev.device_id,
|
||||
control: notation,
|
||||
pressed: true,
|
||||
released: false,
|
||||
time: ev.time
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,14 +237,14 @@ function action_stage(bindings) {
|
||||
|
||||
// Pass through non-button events
|
||||
if (ev.kind != 'button' && ev.kind != 'chord' && ev.kind != 'gesture') {
|
||||
push(output, ev)
|
||||
output[] = ev
|
||||
continue
|
||||
}
|
||||
|
||||
actions = bindings.get_actions(ev.control)
|
||||
|
||||
if (length(actions) == 0) {
|
||||
push(output, ev)
|
||||
output[] = ev
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ function action_stage(bindings) {
|
||||
if (ev.pressed) down[action] = true
|
||||
else if (ev.released) down[action] = false
|
||||
|
||||
push(output, {
|
||||
output[] = {
|
||||
kind: 'action',
|
||||
device_id: ev.device_id,
|
||||
control: action,
|
||||
@@ -262,7 +262,7 @@ function action_stage(bindings) {
|
||||
released: ev.released,
|
||||
time: ev.time,
|
||||
original: ev
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,16 +304,16 @@ function make(user, cfg) {
|
||||
var action = null
|
||||
|
||||
if (o.gestures != false) {
|
||||
push(stages, gesture_stage(o))
|
||||
stages[] = gesture_stage(o)
|
||||
}
|
||||
|
||||
if (o.emacs != false) {
|
||||
push(stages, emacs_stage())
|
||||
stages[] = emacs_stage()
|
||||
}
|
||||
|
||||
action = action_stage(user.bindings)
|
||||
push(stages, action)
|
||||
push(stages, delivery_stage(user))
|
||||
stages[] = action
|
||||
stages[] = delivery_stage(user)
|
||||
|
||||
return {
|
||||
stages: stages,
|
||||
|
||||
74
line2d.cm
74
line2d.cm
@@ -86,9 +86,9 @@ function build_polyline_mesh(line) {
|
||||
for (i = 0; i < length(points); i++) {
|
||||
p = points[i]
|
||||
if (points_space == 'local') {
|
||||
push(pts, {x: p.x + pos.x, y: p.y + pos.y})
|
||||
pts[] = {x: p.x + pos.x, y: p.y + pos.y}
|
||||
} else {
|
||||
push(pts, {x: p.x, y: p.y})
|
||||
pts[] = {x: p.x, y: p.y}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ function build_polyline_mesh(line) {
|
||||
for (i = 1; i < length(pts); i++) {
|
||||
dx = pts[i].x - pts[i-1].x
|
||||
dy = pts[i].y - pts[i-1].y
|
||||
push(cumulative, cumulative[i-1] + math.sqrt(dx*dx + dy*dy))
|
||||
cumulative[] = cumulative[i-1] + math.sqrt(dx*dx + dy*dy)
|
||||
}
|
||||
var total_length = cumulative[length(cumulative) - 1]
|
||||
|
||||
@@ -207,7 +207,7 @@ function build_polyline_mesh(line) {
|
||||
n.y = dx
|
||||
}
|
||||
|
||||
push(normals, n)
|
||||
normals[] = n
|
||||
}
|
||||
|
||||
// Generate vertices (2 per point - left and right of line)
|
||||
@@ -220,22 +220,22 @@ function build_polyline_mesh(line) {
|
||||
u = get_u(i)
|
||||
|
||||
// Left vertex (v=0)
|
||||
push(verts, {
|
||||
verts[] = {
|
||||
x: p.x + n.x * w,
|
||||
y: p.y + n.y * w,
|
||||
u: u,
|
||||
v: v_offset,
|
||||
r: 1, g: 1, b: 1, a: 1
|
||||
})
|
||||
}
|
||||
|
||||
// Right vertex (v=1)
|
||||
push(verts, {
|
||||
verts[] = {
|
||||
x: p.x - n.x * w,
|
||||
y: p.y - n.y * w,
|
||||
u: u,
|
||||
v: v_scale + v_offset,
|
||||
r: 1, g: 1, b: 1, a: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Generate indices (triangle strip as triangles)
|
||||
@@ -243,25 +243,25 @@ function build_polyline_mesh(line) {
|
||||
for (i = 0; i < length(pts) - 1; i++) {
|
||||
base = i * 2
|
||||
// First triangle
|
||||
push(indices, base + 0)
|
||||
push(indices, base + 1)
|
||||
push(indices, base + 2)
|
||||
indices[] = base + 0
|
||||
indices[] = base + 1
|
||||
indices[] = base + 2
|
||||
// Second triangle
|
||||
push(indices, base + 1)
|
||||
push(indices, base + 3)
|
||||
push(indices, base + 2)
|
||||
indices[] = base + 1
|
||||
indices[] = base + 3
|
||||
indices[] = base + 2
|
||||
}
|
||||
|
||||
// Handle closed path
|
||||
var last = 0
|
||||
if (closed && length(pts) > 2) {
|
||||
last = (length(pts) - 1) * 2
|
||||
push(indices, last + 0)
|
||||
push(indices, last + 1)
|
||||
push(indices, 0)
|
||||
push(indices, last + 1)
|
||||
push(indices, 1)
|
||||
push(indices, 0)
|
||||
indices[] = last + 0
|
||||
indices[] = last + 1
|
||||
indices[] = 0
|
||||
indices[] = last + 1
|
||||
indices[] = 1
|
||||
indices[] = 0
|
||||
}
|
||||
|
||||
// Add round caps if requested
|
||||
@@ -301,13 +301,13 @@ function add_round_cap(opts) {
|
||||
var dy = is_start ? n.x : -n.x
|
||||
|
||||
// Center vertex
|
||||
push(verts, {
|
||||
verts[] = {
|
||||
x: p.x,
|
||||
y: p.y,
|
||||
u: u,
|
||||
v: 0.5 * v_scale + v_offset,
|
||||
r: 1, g: 1, b: 1, a: 1
|
||||
})
|
||||
}
|
||||
|
||||
// Arc vertices
|
||||
var start_angle = is_start ? math.arc_tangent(n.y, n.x) : math.arc_tangent(-n.y, -n.x)
|
||||
@@ -320,20 +320,20 @@ function add_round_cap(opts) {
|
||||
cx = math.cosine(angle)
|
||||
cy = math.sine(angle)
|
||||
|
||||
push(verts, {
|
||||
verts[] = {
|
||||
x: p.x + cx * w,
|
||||
y: p.y + cy * w,
|
||||
u: u,
|
||||
v: (0.5 + cy * 0.5) * v_scale + v_offset,
|
||||
r: 1, g: 1, b: 1, a: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Fan triangles
|
||||
for (i = 0; i < segments; i++) {
|
||||
push(indices, base_idx)
|
||||
push(indices, base_idx + 1 + i)
|
||||
push(indices, base_idx + 2 + i)
|
||||
indices[] = base_idx
|
||||
indices[] = base_idx + 1 + i
|
||||
indices[] = base_idx + 2 + i
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,17 +364,17 @@ function add_square_cap(opts) {
|
||||
var ey = p.y + dy * ext
|
||||
|
||||
// Four corners of the cap
|
||||
push(verts, {x: p.x + n.x * w, y: p.y + n.y * w, u: u, v: v_offset, r: 1, g: 1, b: 1, a: 1})
|
||||
push(verts, {x: p.x - n.x * w, y: p.y - n.y * w, u: u, v: v_scale + v_offset, r: 1, g: 1, b: 1, a: 1})
|
||||
push(verts, {x: ex + n.x * w, y: ey + n.y * w, u: u, v: v_offset, r: 1, g: 1, b: 1, a: 1})
|
||||
push(verts, {x: ex - n.x * w, y: ey - n.y * w, u: u, v: v_scale + v_offset, r: 1, g: 1, b: 1, a: 1})
|
||||
verts[] = {x: p.x + n.x * w, y: p.y + n.y * w, u: u, v: v_offset, r: 1, g: 1, b: 1, a: 1}
|
||||
verts[] = {x: p.x - n.x * w, y: p.y - n.y * w, u: u, v: v_scale + v_offset, r: 1, g: 1, b: 1, a: 1}
|
||||
verts[] = {x: ex + n.x * w, y: ey + n.y * w, u: u, v: v_offset, r: 1, g: 1, b: 1, a: 1}
|
||||
verts[] = {x: ex - n.x * w, y: ey - n.y * w, u: u, v: v_scale + v_offset, r: 1, g: 1, b: 1, a: 1}
|
||||
|
||||
push(indices, base_idx + 0)
|
||||
push(indices, base_idx + 1)
|
||||
push(indices, base_idx + 2)
|
||||
push(indices, base_idx + 1)
|
||||
push(indices, base_idx + 3)
|
||||
push(indices, base_idx + 2)
|
||||
indices[] = base_idx + 0
|
||||
indices[] = base_idx + 1
|
||||
indices[] = base_idx + 2
|
||||
indices[] = base_idx + 1
|
||||
indices[] = base_idx + 3
|
||||
indices[] = base_idx + 2
|
||||
}
|
||||
|
||||
var defaults = {
|
||||
|
||||
@@ -18,7 +18,7 @@ var particles2d_proto = {
|
||||
var emitters = {
|
||||
// Spawn a particle for an emitter
|
||||
spawn: function(emitter) {
|
||||
push(emitter.particles, {
|
||||
emitter.particles[] = {
|
||||
pos: {
|
||||
x: emitter.pos.x + (random() - 0.5) * emitter.spawn_area.width,
|
||||
y: emitter.pos.y + (random() - 0.5) * emitter.spawn_area.height
|
||||
@@ -37,7 +37,7 @@ var emitters = {
|
||||
b: emitter.color.b,
|
||||
a: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// Update an emitter and its particles
|
||||
|
||||
@@ -56,7 +56,7 @@ PlaydateBackend.prototype.get_or_create_target = function(width, height, key) {
|
||||
key: key
|
||||
}
|
||||
|
||||
push(this.target_pool[pool_key], target)
|
||||
this.target_pool[pool_key][] = target
|
||||
return target
|
||||
}
|
||||
|
||||
|
||||
12
rasterize.cm
12
rasterize.cm
@@ -109,12 +109,12 @@ rasterize.ellipse = function ellipse(pos, radii, opt) {
|
||||
within_wedge(dx+1, dy, wedge_info)
|
||||
|
||||
if (last || !next_in_ring) {
|
||||
push(strips, {
|
||||
strips[] = {
|
||||
x: run_start,
|
||||
y: y_screen,
|
||||
width: (cx + dx) - run_start + 1,
|
||||
height: 1
|
||||
})
|
||||
}
|
||||
run_start = null
|
||||
}
|
||||
}
|
||||
@@ -199,12 +199,10 @@ rasterize.round_rect = function round_rect(rect, radius, thickness) {
|
||||
w = dx_out - dx_in
|
||||
if (w <= 0) continue
|
||||
|
||||
push(strips,
|
||||
{ x:cx_l - dx_out, y:cy_t - dy, width:w, height:1 },
|
||||
strips[] = { x:cx_l - dx_out, y:cy_t - dy, width:w, height:1 },
|
||||
{ x:cx_r + dx_in + 1, y:cy_t - dy, width:w, height:1 },
|
||||
{ x:cx_l - dx_out, y:cy_b + dy, width:w, height:1 },
|
||||
{ x:cx_r + dx_in + 1, y:cy_b + dy, width:w, height:1 }
|
||||
)
|
||||
}
|
||||
|
||||
return {type: 'rects', data: array(rects, strips)}
|
||||
@@ -235,12 +233,10 @@ rasterize.fill_round_rect = function fill_round_rect(rect, radius) {
|
||||
dx = floor(math.sqrt(_radius * _radius - dy * dy))
|
||||
w = (dx << 1) + 1
|
||||
|
||||
push(caps,
|
||||
{ x:cx_l - dx, y:cy_t - dy, width:w, height:1 },
|
||||
caps[] = { x:cx_l - dx, y:cy_t - dy, width:w, height:1 },
|
||||
{ x:cx_r - dx, y:cy_t - dy, width:w, height:1 },
|
||||
{ x:cx_l - dx, y:cy_b + dy, width:w, height:1 },
|
||||
{ x:cx_r - dx, y:cy_b + dy, width:w, height:1 }
|
||||
)
|
||||
}
|
||||
|
||||
return {type: 'rects', data: array(rects, caps)}
|
||||
|
||||
@@ -94,7 +94,7 @@ function read_ignore(dir) {
|
||||
arrfor(lines, function(line) {
|
||||
var trimmed = trim(line)
|
||||
if (!trimmed || starts_with(trimmed, '#')) return
|
||||
push(patterns, trimmed)
|
||||
patterns[] = trimmed
|
||||
})
|
||||
}
|
||||
return patterns
|
||||
@@ -115,7 +115,7 @@ Resources.getAllFiles = function(dir) {
|
||||
if (!st.filesize) return
|
||||
var ext = getExtension(f)
|
||||
if (!isRecognizedExtension(ext)) return
|
||||
push(results, fullPath)
|
||||
results[] = fullPath
|
||||
} disruption {
|
||||
// skip files that can't be stat'd
|
||||
}
|
||||
|
||||
12
sdl_gpu.cm
12
sdl_gpu.cm
@@ -700,7 +700,7 @@ function _load_image_file(path) {
|
||||
var decoded = null
|
||||
if (!bytes) return null
|
||||
|
||||
var ext = lower(pop(array(path, '.')))
|
||||
var ext = lower(array(path, '.')[])
|
||||
var surface = null
|
||||
|
||||
if (ext == 'png' || ext == 'jpg' || ext == 'jpeg' || ext == 'bmp') {
|
||||
@@ -814,7 +814,7 @@ sdl_gpu.get_or_create_target = function(width, height, key) {
|
||||
key: key
|
||||
}
|
||||
|
||||
push(_target_pool[pool_key], target)
|
||||
_target_pool[pool_key][] = target
|
||||
return target
|
||||
}
|
||||
|
||||
@@ -1225,7 +1225,7 @@ function _execute_commands(commands, window_size) {
|
||||
current_camera = cmd.camera
|
||||
|
||||
} else if (cmd.cmd == 'draw_batch' || cmd.cmd == 'draw_text' || cmd.cmd == 'draw_texture_ref' || cmd.cmd == 'draw_shape' || cmd.cmd == 'draw_mesh2d') {
|
||||
push(pending_draws, cmd)
|
||||
pending_draws[] = cmd
|
||||
|
||||
} else if (cmd.cmd == 'blit') {
|
||||
// Flush pending draws first
|
||||
@@ -1824,8 +1824,8 @@ function _render_text(ctx, drawable) {
|
||||
if (ax != 0 || ay != 0) {
|
||||
dim = font.text_size(drawable.text)
|
||||
if (dim) {
|
||||
text_pos.x -= dim.x * ax
|
||||
text_pos.y -= dim.y * ay
|
||||
text_pos.x -= dim[0] * ax
|
||||
text_pos.y -= dim[1] * ay
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2248,7 +2248,7 @@ function _do_shader_pass(cmd_buffer, cmd, get_swapchain_tex) {
|
||||
var samplers = [{texture: input.texture, sampler: _sampler_linear}]
|
||||
if (cmd.extra_inputs) {
|
||||
arrfor(cmd.extra_inputs, function(extra) {
|
||||
push(samplers, {texture: extra.texture, sampler: _sampler_linear})
|
||||
samplers[] = {texture: extra.texture, sampler: _sampler_linear}
|
||||
})
|
||||
}
|
||||
pass.bind_fragment_samplers(0, samplers)
|
||||
|
||||
@@ -25,7 +25,7 @@ for (i = 0; i < length(formats); i++) {
|
||||
if (!colorspaces[fmt.colorspace]) {
|
||||
colorspaces[fmt.colorspace] = [];
|
||||
}
|
||||
push(colorspaces[fmt.colorspace], fmt);
|
||||
colorspaces[fmt.colorspace][] = fmt;
|
||||
}
|
||||
|
||||
log.console("\nFound colorspaces:");
|
||||
|
||||
@@ -19,10 +19,10 @@ var tilemap = {
|
||||
var y = pos.y - this.offset_y
|
||||
|
||||
while (length(this.tiles) <= x)
|
||||
push(this.tiles, [])
|
||||
this.tiles[] = []
|
||||
|
||||
while (length(this.tiles[x]) <= y)
|
||||
push(this.tiles[x], null)
|
||||
this.tiles[x][] = null
|
||||
|
||||
this.tiles[x][y] = image
|
||||
},
|
||||
|
||||
8
tween.cm
8
tween.cm
@@ -8,7 +8,7 @@ function make_engine(default_clock) {
|
||||
tweens: [],
|
||||
default_clock: default_clock || null,
|
||||
add(tween) {
|
||||
push(this.tweens, tween)
|
||||
this.tweens[] = tween
|
||||
},
|
||||
remove(tween) {
|
||||
this.tweens = filter(this.tweens, t => t != tween)
|
||||
@@ -164,7 +164,7 @@ var TimelineProto = {
|
||||
engine: null,
|
||||
|
||||
add_event: function(time_value, fn) {
|
||||
push(this.events, { time: time_value, fn, fired: false })
|
||||
this.events[] = { time: time_value, fn, fired: false }
|
||||
},
|
||||
|
||||
add_tween: function(obj, props, duration, start_time) {
|
||||
@@ -257,13 +257,13 @@ $delay(() => {
|
||||
function snapshot() {
|
||||
var result = []
|
||||
arrfor(TweenEngine.tweens, function(tw) {
|
||||
push(result, {
|
||||
result[] = {
|
||||
startVals: tw.startVals,
|
||||
endVals: tw.endVals,
|
||||
duration: tw.duration,
|
||||
startTime: tw.startTime,
|
||||
easing: tw.easing ? (tw.easing.name || 'unknown') : 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
return {active_count: length(TweenEngine.tweens), tweens: result}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user