whoa. just being able to actually edit something without any instructions is impressive :-)
ok, well, this it my (probably) fifth attempt at writing something about it, i know it's necessary, but words doesn't come out as i think them inside my head, especially not in a foreign language, and things are still a bit abstract.. so... it became a lot of babbling, confusing more than explaining.. being ashamed about it, i wanted to delete this completely, but decided to "ow, fuck it", and post it anyway.. better than nothing, eh? as mentined everywhere else, ask about anything if you want to know more..
<
waffle[varies] this, and calls the son/bro either conditionally, a number of times, or other things...more on that later..
in the editor (the large grid), nodes are the colored blocks, son-nodes are below, and brothers to the right of each node.. a black line either at the bottom or the right inside the node indicates that this assumption is not valid for that node.
so, that was the traversal. but just parsing through the graph's nodes doesn't do much, that's what the node type/arg is about.. there are a bunch of node types for influencing the parsing:
- empty
return to the caller, exit/quit the graph parsing, finito
- noop
nothing, just call son/bro
- proc
callback function
arg : proc-index (array of pointers to callbacks)
- expr
script/expression
arg : list-index (array of pointers to lists of bytes)
- cond
conditional, just like scripts, but after its execution, if the top of the stack is positive, the son is called, else the brother
arg: list
- repeat
call son a specified number of times, before calling brother
arg: number of times
- loc
set location (like a bookmark)
arg: loc-index
- call
jump to location (bookmark)
arg: loc-index
- [cycle]
deprecated, because of some changes in graph parsing
arg: number
- [pattern]
deprecated, because of some changes in graph parsing
new ideas are bubbling, so it will be re-introduced, but slightly different
arg: list
- wait
calls son only every x time
arg: num
- poly
'polyphonic registers'
mainly for
call son for every polyphonic voice (or layer, can be used for other things than audio), but switches 'polyphonic register bank' before calling..
more info later, as this is still in the baby-stages..
arg: num
- voice
same as poly, but one specific voice/layer
arg: num/voice
the rest are (mostly?) open-gl specific nodes... i wanted these to be 'callbacks' originally, so that nodes were only for traversing the graph and handling array indexes, procs for calling functions/code, and expression for doing math with floats..
but, they need a parameter (shader number, etc), and callbacks have none (the byte arg in proc nodes are used for selecting which procedure).
but, there are some ideas bubling around, so these may change...
- vertex shader: define vertexshader
- fragment shader: --"-- fragment shader
- compile compile: compile currently selected vertex/fragment shader
- select shader: select/use shader
- init texture: init texture with last selected bitmap
- select texture: use texture
- render target: not finished...
- begin mesh: start mesh definition..
- end mesh: finalize mesh
- render mesh: and render it
- init bitmap: procedural generation, two for loops /x/y) is being run, and the son node is called for each pixel. scripts have access to the X/Y for the current pixel (0..1), eventually the result for a previous script, and save the result to R,G,B,A registers..
- select bitmap: not much use yet...
as you can see, there's a lot of "work in progress", half finished stuff, etc...
the final thing that need explanation, the expressions/scripts:
this is like a tiny, simplified virtual machine, parsing bytecode, the vm has 256 virtual registers (an array of floats), and a data-stack.. and that's it, really
the various opcodes available in expressions (and conditionals):
push/pop: for moving floats between the stack and the registers
add,sub,mul,div,sin,cos,rand etc: do some math on the top-of-stack values
dup, drop, rot, etc: manipulate the stack
---
so, that was a little introduction (probably completely confusing and non-understandable) to the s4k system..
the editor tries to edit the various arrays directly, and show as much detail of selected node and stuff as possible, and you can edit names for the array elements, to make it easier to remember which array element does what..
you edit the nodes and other arrays, compile to convert everything to bytes, and then play to get it started.. play searches for a location node called 'intro_init' and calls this before starting its main loop.. then looks for 'intro_frame', which is called for every frame..
especially the list editor is a little shaky at the moment.. it can edit text by having a " character as the first one (which will be skipped, no ending ") to directly copy/paste the text (for shaders, etc). if no " is found first, it parses each word and convert them individually to bytes.. script opcodes are translated to their corresponding value (for bytecode interpreter), and register names to their indexes.
---
the editor will eventually/later also export a .h file, "used_elements.h", or "optimize.h" or whatever, with a bunch of "define USED_OPCODE_PUSH, #define USES_NODE_CALL, etc, and the intro source code is filled with relevant #ifdef/#endif's.. so things you don't use in the editor, will not be compiled into a final 4k intro...
and, added music and audio yesterday, using nodes and expressions for both the sequencing and audio generation... seems to work really great! when this is a bit more stable, i'll start formalizing the nodes and opcodes and stuff..
and also, as mentioned, a few project files for testing and showing off things, would be really great, but, if the nodes and/or opcodes change, that would make the files useless... need to formalize, make a final decision about the nodes/opcodes, and perhaps have some version info in the project file first...
<
waffle OFF >