pax_global_header00006660000000000000000000000064135347730770014532gustar00rootroot0000000000000052 comment=aa6da16fa58bffea6602a2cf6dd5237c88d28452 jsusfx-0.4.0/000077500000000000000000000000001353477307700130555ustar00rootroot00000000000000jsusfx-0.4.0/.gitignore000066400000000000000000000002611353477307700150440ustar00rootroot00000000000000# Compiled Object files *.slo *.lo *.o *.obj # Compiled Dynamic libraries *.so *.dylib *.dll # Compiled Static libraries *.lai *.la *.a *.lib # Executables *.exe *.out *.app jsusfx-0.4.0/.gitmodules000066400000000000000000000001371353477307700152330ustar00rootroot00000000000000[submodule "pd/pd.build"] path = pd/pd.build url = https://github.com/pierreguillot/pd.build jsusfx-0.4.0/LICENSE000066400000000000000000000010611353477307700140600ustar00rootroot00000000000000Copyright 2014-2015 Pascal Gauthier Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. jsusfx-0.4.0/README.md000066400000000000000000000035021353477307700143340ustar00rootroot00000000000000jsusfx - Opensource Jesusonic FX implementation ================================================ jsusfx is an opensource implementation of the [JSFX](http://www.reaper.fm/sdk/js/js.php) scripting language that was created by [Cockos](http://www.cockos.com/jesusonic/) and is made available with [Reaper](http://www.reaper.fm). While the original JSFX scripting language can do a lot of things in Reaper, this implementation is focusing on providing dsp scripting processing for other hosts (like pure-data and Max/MSP) and platforms. This project comes with a subset of the original eel2 code from Cockos [WDL](http://www.cockos.com/wdl). While this project could support plugin formats like LV2 or VST, this implementation focuses on Pure Data support. Support for version 0.4 is in progress for Pure Data. See subdirectory [pd](pd). Marcel Smit, who is also working on [Framework](https://github.com/marcel303/framework) that uses JsusFx, greatly contributed on version 0.4, see below video. [![Framework](https://img.youtube.com/vi/7f9fOeBecaY/0.jpg)](https://www.youtube.com/watch?v=7f9fOeBecaY) Version 0.4 ----------- * Multi-channel support * File API support * @import and @gfx section support * Midi support * More support of extended sliders * Various bug fixes * Native ARM support * CMake now global build system Version 0.3 ----------- * Native x86 x86_64 for OS X and Linux (10 times faster than portable) * gcc generated code now works at runtime Limitations ----------- * @serialize section is ignored Building -------- * cmake is the build system and PHP and nasm are required to build native x86_64 support code Credits ------- * @marcel303 (Marcel Smit) did a lot of work (Version 0.4) in implementing the missing features from the previous versions * The core of the language is from WDL (the authors of JSFX and Reaper) jsusfx-0.4.0/max/000077500000000000000000000000001353477307700136425ustar00rootroot00000000000000jsusfx-0.4.0/max/Info.plist000066400000000000000000000017031353477307700156130ustar00rootroot00000000000000 CFBundleDevelopmentRegion English CFBundleExecutable ${PRODUCT_NAME} CFBundleIconFile CFBundleIdentifier com.digitalsuburban.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion ${PRODUCT_VERSION} CFBundlePackageType iLaX CFBundleSignature max2 CFBundleVersion ${PRODUCT_VERSION} CFBundleShortVersionString ${PRODUCT_VERSION} CFBundleLongVersionString ${PRODUCT_NAME} ${PRODUCT_VERSION}, Copyright 2014 Digital Suburban CSResourcesFileMapped jsusfx-0.4.0/max/README.md000066400000000000000000000001701353477307700151170ustar00rootroot00000000000000jsusfx_max - Jesusonic FX for Max ================================= For now this is on hold and focusing on Pure Data. jsusfx-0.4.0/max/gain.jsfx000066400000000000000000000002071353477307700154530ustar00rootroot00000000000000desc:gain balblabla ok slider1:1<0,5,0.01>GAINLC slider2:1<0,5,0.01>GAINRR @init gg=0; @sample spl0=spl0*slider1; spl1=spl1*slider2; jsusfx-0.4.0/max/jsusfx_max.cpp000066400000000000000000000235301353477307700165400ustar00rootroot00000000000000/* * Copyright 2014-2015 Pascal Gauthier * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * *distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "ext.h" #include "ext_obex.h" #include "ext_common.h" #include "z_dsp.h" #include "ext_buffer.h" #include "ext_critical.h" #include "ext_path.h" #include "ext_sysfile.h" #include "../jsusfx.h" class JsusFxMax : public JsusFx { public: void displayMsg(const char *fmt, ...) { char output[4096]; va_list argptr; va_start(argptr, fmt); vsnprintf(output, 4095, fmt, argptr); va_end(argptr); post("%s\n", output); } void displayError(const char *fmt, ...) { char output[4096]; va_list argptr; va_start(argptr, fmt); vsnprintf(output, 4095, fmt, argptr); va_end(argptr); error("%s\n", output); } }; typedef struct _jsusfx { t_pxobject l_obj; bool bypass; JsusFxMax *fx; t_critical critical; t_object *m_editor; void *outlet1; char scriptname[MAX_PATH_CHARS]; short path; } t_jsusfx; static t_class *jsusfx_class; void jsusfx_describe(t_jsusfx *x) { post("jsusfx~ script %s : %s", x->scriptname, x->fx->desc); for(int i=0;i<64;i++) { if ( x->fx->sliders[i].exists ) { JsusFx_Slider *s = &(x->fx->sliders[i]); post(" slider%d: %g %g %s", i, s->min, s->max, s->desc); t_atom argv[5]; atom_setlong(argv, i); atom_setfloat(argv+1, s->def); atom_setfloat(argv+2, s->min); atom_setfloat(argv+3, s->max); atom_setsym(argv+4, gensym(s->desc)); outlet_anything(x->outlet1, gensym("slider"), 4, argv); } } } void jsusfx_showvars(t_jsusfx *x) { x->fx->dumpvars(); } void jsusfx_dblclick(t_jsusfx *x) { if (!x->m_editor) { t_filehandle fh_read; if ( path_opensysfile(x->scriptname, x->path, &fh_read, READ_PERM) ) { error("jsusfx~: unable to script file"); return; } t_handle texthandle; texthandle = sysmem_newhandle(0); sysfile_readtextfile(fh_read, texthandle, 0, TEXT_NULL_TERMINATE); x->m_editor = reinterpret_cast(object_new(CLASS_NOBOX, gensym("jed"), (t_object *)x, 0)); object_attr_setchar(x->m_editor, gensym("scratch"), 1); object_method(x->m_editor, gensym("settext"), *texthandle, gensym("utf-8")); object_method(x->m_editor, gensym("filename"), x->scriptname, x->path); sysmem_freehandle(texthandle); sysfile_close(fh_read); } else { object_attr_setchar(x->m_editor, gensym("visible"), 1); } } void jsusfx_compile(t_jsusfx *x, t_symbol *notused, long argc, t_atom *argv) { // new file if ( argc >= 1 && atom_gettype(argv) == A_SYM ) { t_fourcc filetype = 'TEXT', outtype; short path; char filename[MAX_PATH_CHARS]; strcpy(filename, atom_getsym(argv)->s_name); if (locatefile_extended(filename, &path, &outtype, &filetype, 1)) { error("jsusfx~: script %s not found", filename); return; } if ( x->m_editor ) { object_method(x->m_editor, gensym("w_close")); x->m_editor = NULL; } strncpy(x->scriptname, filename, MAX_PATH_CHARS); x->path = path; } char fullpath[1024]; path_toabsolutesystempath(x->path, x->scriptname, fullpath); std::ifstream is(fullpath); if ( ! is.is_open() ) { error("jsusfx~: error opening file %s", fullpath); return; } critical_enter(x->critical); if ( x->fx->compile(is) == true ) { x->fx->prepare(sys_getsr(), sys_getmaxblksize()); } critical_exit(x->critical); } long jsusfx_edsave(t_jsusfx *x, char **ht, long size) { t_filehandle fh_write; if ( path_opensysfile(x->scriptname, x->path, &fh_write, WRITE_PERM) ) { error("jsusfx~: unable to save script file"); return 1; } sysfile_writetextfile(fh_write, ht, TEXT_LB_NATIVE); sysfile_close(fh_write); jsusfx_compile(x, NULL, 0, NULL); return 0; } void jsusfx_edclose(t_jsusfx *x, char **ht, long size) { x->m_editor = NULL; } void *jsusfx_new(t_symbol *notused, long argc, t_atom *argv) { if ( argc < 1 || atom_gettype(argv) != A_SYM ) { error("jsusfx~: missing script name"); return NULL; } t_jsusfx *x = reinterpret_cast(object_alloc(jsusfx_class)); t_symbol *s = atom_getsym(argv); t_fourcc filetype = 'TEXT', outtype; short path; char filename[MAX_PATH_CHARS]; strcpy(filename, s->s_name); if (locatefile_extended(filename, &path, &outtype, &filetype, 1)) { t_object *mypatcher; object_obex_lookup(x, gensym("#P"), &mypatcher); t_symbol *checkExists = object_attr_getsym(mypatcher, gensym("filepath")); if ( checkExists->s_name[0] == 0 ) { error("jsusfx~: patch needs to be saved in order to create new jsusfx script file"); return NULL; } path = path_getdefault(); t_fourcc type = 'TEXT'; t_filehandle ref; if ( path_createsysfile(filename, path, type, &ref) ) { error("jsusfx~: unable to create file"); return NULL; } char initText[] = "@sample\nspl0=1\nspl1=-1\n"; t_handle h = sysmem_newhandle(0); sysmem_ptrandhand(initText,h,strlen(initText)); if ( sysfile_writetextfile(ref, h, TEXT_LB_NATIVE) ) { error("jsusfx~: unable to write file"); return NULL; } sysfile_close(ref); sysmem_freehandle(h); } strcpy(x->scriptname, filename); x->path = path; char fullpath[MAX_PATH_CHARS]; path_toabsolutesystempath(path, filename, fullpath); std::ifstream is(fullpath); if ( ! is.is_open() ) { error("jsusfx~: error opening file %s", fullpath); return NULL; } x->bypass = false; dsp_setup((t_pxobject *)x, 2); x->outlet1 = outlet_new((t_object *)x, NULL); outlet_new((t_object *)x, "signal"); outlet_new((t_object *)x, "signal"); critical_new(&(x->critical)); x->m_editor = NULL; JsusFxMax *fx = new JsusFxMax(); fx->compile(is); x->fx = fx; /*if ( argc >= 2 && atom_gettype(argv+1) == A_LONG ) { x->fx->normalizeSliders = atom_getlong(argv+1); } else { x->fx->normalizeSliders = 1; } post("normalizer sl %x", x->fx->normalizeSliders);*/ return (x); } void jsusfx_free(t_jsusfx *x) { if ( x->m_editor ) object_method(x->m_editor, gensym("w_close")); dsp_free((t_pxobject*)x); critical_free(x->critical); delete x->fx; } void jsusfx_slider(t_jsusfx *x, t_int id, double value) { if ( id >= 64 || id < 0 ) return; if ( ! x->fx->sliders[id].exists ) { error("jsusfx~: slider number %d is not assigned for this effect", id); return; } x->fx->moveSlider(id, value); } void jsusfx_bypass(t_jsusfx *x, t_int id) { x->bypass = (bool) id; } void jsusfx_perform64(t_jsusfx *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam) { const double *inv[2]; inv[0] = ins[1]; inv[1] = ins[0]; if ( x->bypass ) goto bypass; if ( critical_tryenter(x->critical) ) goto bypass; x->fx->process64(inv, outs, sampleframes, 2, 2); critical_exit(x->critical); return; bypass: for(int i=0;ifx->prepare(samplerate, maxvectorsize); object_method(dsp64, gensym("dsp_add64"), x, jsusfx_perform64, 0, NULL); } void jsusfx_assist(t_jsusfx *x, void *b, long m, long a, char *s) { if (m == ASSIST_INLET) { switch(a) { case 0: sprintf(s,"(signal) Left Input"); break; case 1: sprintf(s,"(signal) Right Input"); break; } } else { switch (a) { case 0: sprintf(s,"(signal) Left Output"); break; case 1: sprintf(s,"(signal) Right Output"); break; case 2: sprintf(s,"jsfx info"); break; } } } int C74_EXPORT main(void) { t_class *c = class_new("jsusfx~", (method)jsusfx_new, (method)jsusfx_free, sizeof(t_jsusfx), 0L, A_GIMME, 0); class_addmethod(c, (method)jsusfx_dsp64, "dsp64", A_CANT, 0); class_addmethod(c, (method)jsusfx_slider, "slider", A_LONG, A_FLOAT, 0); class_addmethod(c, (method)jsusfx_assist, "assist", A_CANT, 0); class_addmethod(c, (method)jsusfx_compile, "compile", A_GIMME, 0); class_addmethod(c, (method)jsusfx_dblclick, "dblclick", A_CANT, 0); class_addmethod(c, (method)jsusfx_edsave, "edsave", A_CANT, 0); class_addmethod(c, (method)jsusfx_edclose, "edclose", A_CANT, 0); class_addmethod(c, (method)jsusfx_bypass, "bypass", A_LONG, 0); class_addmethod(c, (method)jsusfx_describe, "describe", 0); class_addmethod(c, (method)jsusfx_showvars, "showvars", 0); class_dspinit(c); class_register(CLASS_BOX, c); jsusfx_class = c; JsusFx::init(); return 0; } jsusfx-0.4.0/max/jsusfx_test.maxpat000066400000000000000000000451231353477307700174440ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 7, "minor" : 0, "revision" : 4, "architecture" : "x86", "modernui" : 1 } , "rect" : [ 221.0, 262.0, 1067.0, 678.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "boxes" : [ { "box" : { "bgcolor" : [ 0.862, 0.862, 0.862, 1.0 ], "floatoutput" : 1, "id" : "obj-25", "maxclass" : "dial", "needlecolor" : [ 0.784314, 0.368627, 0.368627, 1.0 ], "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "outlinecolor" : [ 0.67451, 0.690196, 0.345098, 1.0 ], "parameter_enable" : 0, "patching_rect" : [ 1013.0, 153.5, 40.0, 40.0 ], "size" : 1.0, "style" : "" } } , { "box" : { "bgcolor" : [ 0.862, 0.862, 0.862, 1.0 ], "floatoutput" : 1, "id" : "obj-26", "maxclass" : "dial", "needlecolor" : [ 0.784314, 0.368627, 0.368627, 1.0 ], "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "outlinecolor" : [ 0.67451, 0.690196, 0.345098, 1.0 ], "parameter_enable" : 0, "patching_rect" : [ 962.0, 153.5, 40.0, 40.0 ], "size" : 1.0, "style" : "" } } , { "box" : { "bgcolor" : [ 0.862, 0.862, 0.862, 1.0 ], "floatoutput" : 1, "id" : "obj-27", "maxclass" : "dial", "needlecolor" : [ 0.784314, 0.368627, 0.368627, 1.0 ], "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "outlinecolor" : [ 0.67451, 0.690196, 0.345098, 1.0 ], "parameter_enable" : 0, "patching_rect" : [ 911.0, 153.5, 40.0, 40.0 ], "size" : 1.0, "style" : "" } } , { "box" : { "bgcolor" : [ 0.862, 0.862, 0.862, 1.0 ], "floatoutput" : 1, "id" : "obj-28", "maxclass" : "dial", "needlecolor" : [ 0.784314, 0.368627, 0.368627, 1.0 ], "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "outlinecolor" : [ 0.67451, 0.690196, 0.345098, 1.0 ], "parameter_enable" : 0, "patching_rect" : [ 860.0, 153.5, 40.0, 40.0 ], "size" : 1.0, "style" : "" } } , { "box" : { "id" : "obj-19", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 22.0, 44.5, 294.0, 20.0 ], "style" : "", "text" : "Reaper JesuSonic support for Max" } } , { "box" : { "bgcolor" : [ 0.862, 0.862, 0.862, 1.0 ], "floatoutput" : 1, "id" : "obj-22", "maxclass" : "dial", "needlecolor" : [ 0.784314, 0.368627, 0.368627, 1.0 ], "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "outlinecolor" : [ 0.67451, 0.690196, 0.345098, 1.0 ], "parameter_enable" : 0, "patching_rect" : [ 809.0, 153.5, 40.0, 40.0 ], "size" : 1.0, "style" : "" } } , { "box" : { "bgcolor" : [ 0.862, 0.862, 0.862, 1.0 ], "floatoutput" : 1, "id" : "obj-23", "maxclass" : "dial", "needlecolor" : [ 0.784314, 0.368627, 0.368627, 1.0 ], "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "outlinecolor" : [ 0.67451, 0.690196, 0.345098, 1.0 ], "parameter_enable" : 0, "patching_rect" : [ 758.0, 153.5, 40.0, 40.0 ], "size" : 1.0, "style" : "" } } , { "box" : { "fontsize" : 20.0, "id" : "obj-21", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 22.0, 12.0, 232.0, 29.0 ], "style" : "", "text" : "jsusfx~" } } , { "box" : { "id" : "obj-16", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 482.0, 340.5, 65.0, 22.0 ], "style" : "", "text" : "bypass $1" } } , { "box" : { "id" : "obj-15", "maxclass" : "toggle", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "int" ], "parameter_enable" : 0, "patching_rect" : [ 482.0, 304.0, 24.0, 24.0 ], "style" : "" } } , { "box" : { "id" : "obj-5", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 676.0, 340.5, 61.0, 22.0 ], "style" : "", "text" : "showvars" } } , { "box" : { "id" : "obj-3", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 579.0, 340.5, 56.0, 22.0 ], "style" : "", "text" : "describe" } } , { "box" : { "autopopulate" : 1, "depth" : 1, "id" : "obj-14", "items" : [ "liteon/3bandpeakfilter", ",", "liteon/applefilter12db", ",", "liteon/applefilter72db", ",", "liteon/bassmanager", ",", "liteon/butterworth24db", ",", "liteon/cheby24db", ",", "liteon/deesser", ",", "liteon/farmodulator", ",", "liteon/LICENSE", ",", "liteon/lo-fi", ",", "liteon/lorenzattractor", ",", "liteon/moog24db", ",", "liteon/nonlinear", ",", "liteon/np1136peaklimiter", ",", "liteon/phasemetergfx", ",", "liteon/pinknoisegen", ",", "liteon/presenceeq", ",", "liteon/prngplot", ",", "liteon/pseudostereo", ",", "liteon/rbjstereofilter12db", ",", "liteon/README.md", ",", "liteon/ringmodulator", ",", "liteon/shelvingfilter", ",", "liteon/simplelp6db", ",", "liteon/sonic_enhancer", ",", "liteon/statevariable", ",", "liteon/stereotilt", ",", "liteon/tilteq", ",", "liteon/tubeharmonics", ",", "liteon/tubeharmonics_amp", ",", "liteon/vumetergfx", ",", "liteon/vumetergfxsum", ",", "liteon/waveshapermulti" ], "maxclass" : "umenu", "numinlets" : 1, "numoutlets" : 3, "outlettype" : [ "int", "", "" ], "parameter_enable" : 0, "patching_rect" : [ 15.0, 291.5, 289.0, 22.0 ], "prefix" : "Macintosh HD:/Users/asb2m10/Documents/src/jsusfx/scripts/", "style" : "", "types" : "TEXT" } } , { "box" : { "id" : "obj-9", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 150.0, 350.5, 99.0, 22.0 ], "style" : "", "text" : "prepend compile" } } , { "box" : { "clipheight" : 52.0, "data" : { "clips" : [ { "filename" : "brushes.aif", "filekind" : "audiofile", "selection" : [ 0.0, 0.967742 ], "loop" : 1, "content_state" : { "slurtime" : [ 0.0 ], "play" : [ 0 ], "quality" : [ "basic" ], "pitchcorrection" : [ 0 ], "pitchshift" : [ 1.0 ], "speed" : [ 1.0 ], "originallength" : [ 0.0, "ticks" ], "formantcorrection" : [ 0 ], "originaltempo" : [ 120.0 ], "formant" : [ 1.0 ], "followglobaltempo" : [ 0 ], "originallengthms" : [ 0.0 ], "mode" : [ "basic" ], "timestretch" : [ 0 ], "basictuning" : [ 440 ] } } ] } , "id" : "obj-6", "maxclass" : "playlist~", "numinlets" : 1, "numoutlets" : 5, "outlettype" : [ "signal", "signal", "signal", "", "dictionary" ], "patching_rect" : [ 343.0, 71.0, 263.0, 53.0 ], "style" : "" } } , { "box" : { "clipheight" : 53.0, "data" : { "clips" : [ { "filename" : "RUWA - Scared to Be Alone.mp3", "filekind" : "audiofile", "selection" : [ 0.15544, 0.626943 ], "loop" : 1, "content_state" : { "slurtime" : [ 0.0 ], "play" : [ 0 ], "quality" : [ "basic" ], "pitchcorrection" : [ 0 ], "pitchshift" : [ 1.0 ], "speed" : [ 1.0 ], "originallength" : [ 0.0, "ticks" ], "formantcorrection" : [ 0 ], "originaltempo" : [ 120.0 ], "formant" : [ 1.0 ], "followglobaltempo" : [ 0 ], "originallengthms" : [ 0.0 ], "mode" : [ "basic" ], "timestretch" : [ 0 ], "basictuning" : [ 440 ] } } ] } , "id" : "obj-4", "maxclass" : "playlist~", "numinlets" : 1, "numoutlets" : 5, "outlettype" : [ "signal", "signal", "signal", "", "dictionary" ], "patching_rect" : [ 343.0, 16.0, 263.0, 53.0 ], "style" : "" } } , { "box" : { "bgcolor" : [ 0.862, 0.862, 0.862, 1.0 ], "floatoutput" : 1, "id" : "obj-18", "maxclass" : "dial", "needlecolor" : [ 0.784314, 0.368627, 0.368627, 1.0 ], "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "outlinecolor" : [ 0.67451, 0.690196, 0.345098, 1.0 ], "parameter_enable" : 0, "patching_rect" : [ 707.0, 153.5, 40.0, 40.0 ], "size" : 1.0, "style" : "" } } , { "box" : { "fontsize" : 13.0, "id" : "obj-13", "maxclass" : "live.gain~", "numinlets" : 2, "numoutlets" : 5, "orientation" : 1, "outlettype" : [ "signal", "signal", "", "float", "list" ], "parameter_enable" : 1, "patching_rect" : [ 343.0, 479.0, 136.0, 42.0 ], "presentation_rect" : [ 381.0, 481.0, 50.0, 42.0 ], "saved_attribute_attributes" : { "valueof" : { "parameter_longname" : "live.gain~[1]", "parameter_shortname" : "live.gain~", "parameter_type" : 0, "parameter_mmin" : -70.0, "parameter_mmax" : 6.0, "parameter_initial_enable" : 1, "parameter_initial" : [ -2.314049 ], "parameter_unitstyle" : 4 } } , "showname" : 0, "varname" : "live.gain~[1]" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-11", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 452.0, 247.5, 87.0, 22.0 ], "style" : "", "text" : "prepend slider" } } , { "box" : { "fontface" : 0, "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-8", "maxclass" : "newobj", "numinlets" : 12, "numoutlets" : 1, "outlettype" : [ "list" ], "patching_rect" : [ 452.0, 220.5, 580.0, 22.0 ], "style" : "", "text" : "funnel 12 1" } } , { "box" : { "bgcolor" : [ 0.862, 0.862, 0.862, 1.0 ], "floatoutput" : 1, "id" : "obj-17", "maxclass" : "dial", "needlecolor" : [ 0.784314, 0.368627, 0.368627, 1.0 ], "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "outlinecolor" : [ 0.67451, 0.690196, 0.345098, 1.0 ], "parameter_enable" : 0, "patching_rect" : [ 656.0, 153.5, 40.0, 40.0 ], "size" : 1.0, "style" : "" } } , { "box" : { "bgcolor" : [ 0.862, 0.862, 0.862, 1.0 ], "floatoutput" : 1, "id" : "obj-12", "maxclass" : "dial", "needlecolor" : [ 0.784314, 0.368627, 0.368627, 1.0 ], "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "outlinecolor" : [ 0.67451, 0.690196, 0.345098, 1.0 ], "parameter_enable" : 0, "patching_rect" : [ 605.0, 153.5, 40.0, 40.0 ], "size" : 1.0, "style" : "" } } , { "box" : { "bgcolor" : [ 0.862, 0.862, 0.862, 1.0 ], "floatoutput" : 1, "id" : "obj-10", "maxclass" : "dial", "needlecolor" : [ 0.784314, 0.368627, 0.368627, 1.0 ], "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "outlinecolor" : [ 0.67451, 0.690196, 0.345098, 1.0 ], "parameter_enable" : 0, "patching_rect" : [ 554.0, 153.5, 40.0, 40.0 ], "size" : 1.0, "style" : "" } } , { "box" : { "bgcolor" : [ 0.862, 0.862, 0.862, 1.0 ], "floatoutput" : 1, "id" : "obj-2", "maxclass" : "dial", "needlecolor" : [ 0.784314, 0.368627, 0.368627, 1.0 ], "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "outlinecolor" : [ 0.67451, 0.690196, 0.345098, 1.0 ], "parameter_enable" : 0, "patching_rect" : [ 503.0, 153.5, 40.0, 40.0 ], "size" : 1.0, "style" : "" } } , { "box" : { "bgcolor" : [ 0.862, 0.862, 0.862, 1.0 ], "floatoutput" : 1, "id" : "obj-24", "maxclass" : "dial", "needlecolor" : [ 0.784314, 0.368627, 0.368627, 1.0 ], "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "outlinecolor" : [ 0.67451, 0.690196, 0.345098, 1.0 ], "parameter_enable" : 0, "patching_rect" : [ 452.0, 153.5, 40.0, 40.0 ], "size" : 1.0, "style" : "" } } , { "box" : { "id" : "obj-7", "maxclass" : "ezdac~", "numinlets" : 2, "numoutlets" : 0, "patching_rect" : [ 343.0, 547.0, 48.25, 48.25 ], "style" : "" } } , { "box" : { "fontface" : 0, "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-1", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 3, "outlettype" : [ "signal", "signal", "" ], "patching_rect" : [ 343.0, 424.0, 96.0, 22.0 ], "style" : "", "text" : "jsusfx~ gain.jsfx" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-13", 1 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 1 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 2 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "disabled" : 0, "hidden" : 0, "midpoints" : [ 461.5, 392.25, 352.5, 392.25 ], "source" : [ "obj-11", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 3 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-12", 0 ] } } , { "patchline" : { "destination" : [ "obj-7", 1 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-13", 1 ] } } , { "patchline" : { "destination" : [ "obj-7", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-13", 0 ] } } , { "patchline" : { "destination" : [ "obj-9", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-14", 1 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-15", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "disabled" : 0, "hidden" : 0, "midpoints" : [ 491.5, 392.5, 352.5, 392.5 ], "source" : [ "obj-16", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 4 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-17", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 5 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-18", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 1 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-2", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 7 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-22", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 6 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-23", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-24", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 11 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-25", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 10 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-26", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 9 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-27", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 8 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-28", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "disabled" : 0, "hidden" : 0, "midpoints" : [ 588.5, 392.75, 352.5, 392.75 ], "source" : [ "obj-3", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 1 ], "disabled" : 0, "hidden" : 0, "midpoints" : [ 413.5, 137.0, 429.5, 137.0 ], "source" : [ "obj-4", 1 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-4", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "disabled" : 0, "hidden" : 0, "midpoints" : [ 685.5, 393.25, 352.5, 393.25 ], "source" : [ "obj-5", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 1 ], "disabled" : 0, "hidden" : 0, "midpoints" : [ 413.5, 138.5, 429.5, 138.5 ], "source" : [ "obj-6", 1 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "disabled" : 0, "hidden" : 0, "midpoints" : [ 352.5, 273.5, 352.5, 273.5 ], "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-11", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-8", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "disabled" : 0, "hidden" : 0, "midpoints" : [ 159.5, 393.5, 352.5, 393.5 ], "source" : [ "obj-9", 0 ] } } ], "parameters" : { "obj-13" : [ "live.gain~[1]", "live.gain~", 0 ] } , "dependency_cache" : [ { "name" : "RUWA - Scared to Be Alone.mp3", "bootpath" : "C74:/packages/MaxIntroLessons/media", "type" : "Mp3 ", "implicit" : 1 } , { "name" : "brushes.aif", "bootpath" : "C74:/media/msp", "type" : "AIFF", "implicit" : 1 } , { "name" : "jsusfx~.mxo", "type" : "iLaX" } ], "embedsnapshot" : 0 } } jsusfx-0.4.0/max/jsusfx~.xcodeproj/000077500000000000000000000000001353477307700173565ustar00rootroot00000000000000jsusfx-0.4.0/max/jsusfx~.xcodeproj/project.pbxproj000066400000000000000000000257651353477307700224510ustar00rootroot00000000000000// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 22922AD30F38D67900B1EFEA /* commonsyms.c in Sources */ = {isa = PBXBuildFile; fileRef = 22922AD20F38D67900B1EFEA /* commonsyms.c */; }; 22CF115E0EE9A6F40054F513 /* jsusfx_max.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22CF115D0EE9A6F40054F513 /* jsusfx_max.cpp */; }; 22CF116E0EE9A7700054F513 /* MaxAudioAPI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22CF116D0EE9A7700054F513 /* MaxAudioAPI.framework */; }; 385AA8A4198685B8004F4164 /* fft.c in Sources */ = {isa = PBXBuildFile; fileRef = 385AA8A3198685B8004F4164 /* fft.c */; }; 385AA8AD198685C8004F4164 /* nseel-cfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = 385AA8A6198685C8004F4164 /* nseel-cfunc.c */; }; 385AA8AE198685C8004F4164 /* nseel-compiler.c in Sources */ = {isa = PBXBuildFile; fileRef = 385AA8A7198685C8004F4164 /* nseel-compiler.c */; }; 385AA8AF198685C8004F4164 /* nseel-eval.c in Sources */ = {isa = PBXBuildFile; fileRef = 385AA8A8198685C8004F4164 /* nseel-eval.c */; }; 385AA8B1198685C8004F4164 /* nseel-ram.c in Sources */ = {isa = PBXBuildFile; fileRef = 385AA8AA198685C8004F4164 /* nseel-ram.c */; }; 385AA8B2198685C8004F4164 /* nseel-yylex.c in Sources */ = {isa = PBXBuildFile; fileRef = 385AA8AB198685C8004F4164 /* nseel-yylex.c */; }; 385AA8B519868709004F4164 /* jsusfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 385AA8B319868709004F4164 /* jsusfx.cpp */; }; 385AA8B619868709004F4164 /* jsusfx.h in Headers */ = {isa = PBXBuildFile; fileRef = 385AA8B419868709004F4164 /* jsusfx.h */; }; 385AA8B919889AFD004F4164 /* maxmspsdk.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 22CF10220EE984600054F513 /* maxmspsdk.xcconfig */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 22922AD20F38D67900B1EFEA /* commonsyms.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = commonsyms.c; path = "../../MaxSDK-6.1.4/c74support/max-includes/common/commonsyms.c"; sourceTree = SOURCE_ROOT; }; 22CF10220EE984600054F513 /* maxmspsdk.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = maxmspsdk.xcconfig; sourceTree = SOURCE_ROOT; }; 22CF115D0EE9A6F40054F513 /* jsusfx_max.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jsusfx_max.cpp; sourceTree = SOURCE_ROOT; }; 22CF116D0EE9A7700054F513 /* MaxAudioAPI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MaxAudioAPI.framework; path = "../../MaxSDK-6.1.4/c74support/msp-includes/MaxAudioAPI.framework"; sourceTree = SOURCE_ROOT; }; 2FBBEAE508F335360078DB84 /* jsusfx~.mxo */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "jsusfx~.mxo"; sourceTree = BUILT_PRODUCTS_DIR; }; 385AA8A3198685B8004F4164 /* fft.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fft.c; path = ../WDL/fft.c; sourceTree = ""; }; 385AA8A6198685C8004F4164 /* nseel-cfunc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "nseel-cfunc.c"; path = "../WDL/eel2/nseel-cfunc.c"; sourceTree = ""; }; 385AA8A7198685C8004F4164 /* nseel-compiler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "nseel-compiler.c"; path = "../WDL/eel2/nseel-compiler.c"; sourceTree = ""; }; 385AA8A8198685C8004F4164 /* nseel-eval.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "nseel-eval.c"; path = "../WDL/eel2/nseel-eval.c"; sourceTree = ""; }; 385AA8AA198685C8004F4164 /* nseel-ram.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "nseel-ram.c"; path = "../WDL/eel2/nseel-ram.c"; sourceTree = ""; }; 385AA8AB198685C8004F4164 /* nseel-yylex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "nseel-yylex.c"; path = "../WDL/eel2/nseel-yylex.c"; sourceTree = ""; }; 385AA8B319868709004F4164 /* jsusfx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jsusfx.cpp; path = ../jsusfx.cpp; sourceTree = ""; }; 385AA8B419868709004F4164 /* jsusfx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jsusfx.h; path = ../jsusfx.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 2FBBEADC08F335360078DB84 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 22CF116E0EE9A7700054F513 /* MaxAudioAPI.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 089C166AFE841209C02AAC07 /* iterator */ = { isa = PBXGroup; children = ( 385AA8B319868709004F4164 /* jsusfx.cpp */, 385AA8B419868709004F4164 /* jsusfx.h */, 385AA8A21986858C004F4164 /* eel2 */, 22CF10220EE984600054F513 /* maxmspsdk.xcconfig */, 22922AD20F38D67900B1EFEA /* commonsyms.c */, 22CF115D0EE9A6F40054F513 /* jsusfx_max.cpp */, 22CF116D0EE9A7700054F513 /* MaxAudioAPI.framework */, 19C28FB4FE9D528D11CA2CBB /* Products */, ); name = iterator; sourceTree = ""; }; 19C28FB4FE9D528D11CA2CBB /* Products */ = { isa = PBXGroup; children = ( 2FBBEAE508F335360078DB84 /* jsusfx~.mxo */, ); name = Products; sourceTree = ""; }; 385AA8A21986858C004F4164 /* eel2 */ = { isa = PBXGroup; children = ( 385AA8A6198685C8004F4164 /* nseel-cfunc.c */, 385AA8A7198685C8004F4164 /* nseel-compiler.c */, 385AA8A8198685C8004F4164 /* nseel-eval.c */, 385AA8AA198685C8004F4164 /* nseel-ram.c */, 385AA8AB198685C8004F4164 /* nseel-yylex.c */, 385AA8A3198685B8004F4164 /* fft.c */, ); name = eel2; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 2FBBEAD708F335360078DB84 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 385AA8B619868709004F4164 /* jsusfx.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 2FBBEAD608F335360078DB84 /* max-external */ = { isa = PBXNativeTarget; buildConfigurationList = 2FBBEAE008F335360078DB84 /* Build configuration list for PBXNativeTarget "max-external" */; buildPhases = ( 2FBBEAD708F335360078DB84 /* Headers */, 2FBBEAD808F335360078DB84 /* Resources */, 2FBBEADA08F335360078DB84 /* Sources */, 2FBBEADC08F335360078DB84 /* Frameworks */, 2FBBEADF08F335360078DB84 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = "max-external"; productName = iterator; productReference = 2FBBEAE508F335360078DB84 /* jsusfx~.mxo */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 089C1669FE841209C02AAC07 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0460; }; buildConfigurationList = 2FBBEACF08F335010078DB84 /* Build configuration list for PBXProject "jsusfx~" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, ); mainGroup = 089C166AFE841209C02AAC07 /* iterator */; projectDirPath = ""; projectRoot = ""; targets = ( 2FBBEAD608F335360078DB84 /* max-external */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 2FBBEAD808F335360078DB84 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 385AA8B919889AFD004F4164 /* maxmspsdk.xcconfig in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ 2FBBEADF08F335360078DB84 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXRezBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 2FBBEADA08F335360078DB84 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 22CF115E0EE9A6F40054F513 /* jsusfx_max.cpp in Sources */, 22922AD30F38D67900B1EFEA /* commonsyms.c in Sources */, 385AA8A4198685B8004F4164 /* fft.c in Sources */, 385AA8AD198685C8004F4164 /* nseel-cfunc.c in Sources */, 385AA8AE198685C8004F4164 /* nseel-compiler.c in Sources */, 385AA8AF198685C8004F4164 /* nseel-eval.c in Sources */, 385AA8B1198685C8004F4164 /* nseel-ram.c in Sources */, 385AA8B2198685C8004F4164 /* nseel-yylex.c in Sources */, 385AA8B519868709004F4164 /* jsusfx.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 2FBBEAD008F335010078DB84 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Development; }; 2FBBEAD108F335010078DB84 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Deployment; }; 2FBBEAE108F335360078DB84 /* Development */ = { isa = XCBuildConfiguration; baseConfigurationReference = 22CF10220EE984600054F513 /* maxmspsdk.xcconfig */; buildSettings = { COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/../../../c74support/msp-includes\"", ); GCC_OPTIMIZATION_LEVEL = 0; OTHER_LDFLAGS = "$(C74_SYM_LINKER_FLAGS)"; }; name = Development; }; 2FBBEAE208F335360078DB84 /* Deployment */ = { isa = XCBuildConfiguration; baseConfigurationReference = 22CF10220EE984600054F513 /* maxmspsdk.xcconfig */; buildSettings = { COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/../../../c74support/msp-includes\"", ); OTHER_LDFLAGS = "$(C74_SYM_LINKER_FLAGS)"; }; name = Deployment; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 2FBBEACF08F335010078DB84 /* Build configuration list for PBXProject "jsusfx~" */ = { isa = XCConfigurationList; buildConfigurations = ( 2FBBEAD008F335010078DB84 /* Development */, 2FBBEAD108F335010078DB84 /* Deployment */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Development; }; 2FBBEAE008F335360078DB84 /* Build configuration list for PBXNativeTarget "max-external" */ = { isa = XCConfigurationList; buildConfigurations = ( 2FBBEAE108F335360078DB84 /* Development */, 2FBBEAE208F335360078DB84 /* Deployment */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Development; }; /* End XCConfigurationList section */ }; rootObject = 089C1669FE841209C02AAC07 /* Project object */; } jsusfx-0.4.0/max/jsusfx~.xcodeproj/project.xcworkspace/000077500000000000000000000000001353477307700233545ustar00rootroot00000000000000jsusfx-0.4.0/max/jsusfx~.xcodeproj/project.xcworkspace/contents.xcworkspacedata000066400000000000000000000002301353477307700303110ustar00rootroot00000000000000 jsusfx-0.4.0/max/jsusfx~.xcodeproj/project.xcworkspace/xcuserdata/000077500000000000000000000000001353477307700255175ustar00rootroot00000000000000jsusfx-0.4.0/max/jsusfx~.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatad/000077500000000000000000000000001353477307700311725ustar00rootroot00000000000000UserInterfaceState.xcuserstate000066400000000000000000004012261353477307700371540ustar00rootroot00000000000000jsusfx-0.4.0/max/jsusfx~.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatadbplist00#$X$versionX$objectsY$archiverT$topd)*+,-./0126<=STUVWXYZ[\vwxyz{|}~      !$*/378<=>DGJNOWXYZbcdnr  &*<HIJKQVZ^_cdhi{|}~ #$%-.>?@ABCDVWXYZ[\]^dekltuv| ./012345678>?@AEQ]^_`aftuz   %)*1456BGMNSWciopw{~ $059:BEFGSW^_cosyz}~&'()59:>?CDHIYZ[\]^_`fgltuvw          # & ) , / 2 5 8 ; > A D G J M P S V Y \ _ b e h k n q t w z }          " % ( + . 1 4 7 : = @ C F I L O R U X [ ^ a d g j m p s v y |          ! $ ' * - 0 5 A B F K L M W X Y ] m p N Q T W Z ] ` c f i l o r u x { ~          # & ) , / 2 5 8 ; > A D G J M P S V Y \ _ b e h k n q t w z }   "%(+.147:=@CFILORUX[^adgjmpsvy|&'()*+/?@ABCDE?BEHKNQTWZ]`cfilorux{~  #&),/258;>ADGJMPSVY\_behknqtwz}  "%(+.147:=@CFILORUX[^adgjmpsvy|  !$'+9:;<=>DEJRSTU]^_cgkpqr|}~z}  "%(+.147:=@CFILORUX[^adgjmpsvy|  !$'*-0369<?BEHKNQTWZ]`cfilorux{~ _cdhimnrswx|}#$%&'()*6789:;<=IJKWXYZ[\]^jklxyz{|}~ ,-./;<=IJKLXYZfghtuvw    9=>BCGHLMQRVW[\`aefjkoptuyz"./01789OPQRSTUVWXYZ[\]imnrswx|}     U$null WNS.keysZNS.objectsV$class ̀T_$C0C95447-67C1-405B-9A55-64ECFF131616_IDEWorkspaceDocument ( !" %&&  _^IDEWindowFrame_!IDEOrderedWorkspaceTabControllers_IDEWindowInFullscreenMode_,IDEWorkspaceWindowControllerUniqueIdentifier_IDEActiveWorkspaceTabController_>IDEWorkspaceTabController_B62A1820-0BC2-4D3B-B17C-4694FFE95179_IDEWindowToolbarIsVisible_IDEWindowTabBarIsVisible_{{-3, 66}, {1920, 991}} 35 789:Z$classnameX$classesWNSArray9;XNSObject >H(?@ABCDEFGI&KLMNO&Qր׀ށ̀_]IDEEditorArea_IDEShowNavigator[IDETabLabel_-IDEWorkspaceTabControllerUtilityAreaSplitView_IDENavigatorArea_IDEUserDefinedTabLabel_,IDEWorkspaceTabControllerDesignAreaSplitView_IDEShowUtilities_AssistantEditorsLayout ]i(^_`abcdefgh !"#$%&jkl&nnpqrs&':b..̀΀_ZlayoutTree_IDEEditorMode_Standard_IDEEditorMode_Genius]IDEShowEditorZEditorMode_VersionEditorSubmode_IDEEditorMode_Version_IDEDefaultDebugArea_ DefaultPersistentRepresentations_DebuggerSplitView_ShowDebuggerArea _rootLayoutTreeNode_geniusEditorContextNode_primaryEditorContextNode6(9 XchildrenVparent[contentType_ documentArchivableRepresentation[orientation68) n_DocumentLocation^IdentifierPath_DomainIdentifier_IndexOfDocumentIdentifier2+5*._/Xcode.IDENavigableItemDomain.WorkspaceStructure 5,0 nZIdentifierUIndex-./Zjsusfx.cpp78_IDEArchivableStringIndexPair;_IDEArchivableStringIndexPair n1./Wjsusfx~ [documentURLYtimestamp34_5file:///Users/asb2m10/Documents/src/jsusfx/jsusfx.cpp78_DVTDocumentLocation;_DVTDocumentLocation78_(IDENavigableItemArchivableRepresentation;_(IDENavigableItemArchivableRepresentation 78 5(78_'IDEWorkspaceTabControllerLayoutTreeNode;_'IDEWorkspaceTabControllerLayoutTreeNode78_#IDEWorkspaceTabControllerLayoutTree;_#IDEWorkspaceTabControllerLayoutTree (׀;ـ<__%EditorLayout_PersistentRepresentation (ހ=>_TMain ?@AnB.`T_)EditorLayout_StateSavingStateDictionaries_EditorLayout_Selected_EditorLayout_Geometry 5C (DEFGHIJKLU[-\]_\FileDataType[EditorState_ArchivableRepresentation_NavigableItemName_DocumentNavigableItemName_DocumentExtensionIdentifier[DocumentURL_public.c-plus-plus-source MNOP"QRST_PrimaryDocumentTimestamp_$PrimaryDocumentVisibleCharacterRange]HideAllIssues_%PrimaryDocumentSelectedCharacterRange#A \{6417, 1270}Y{6775, 0}78"#\NSDictionary"; %&nZV5*. +5,-WX n-./ 4nY./Wjsusfx~ 34_JsusFx::releaseCode()_&Xcode.IDEKit.EditorDocument.SourceCode? @BWNS.base[NS.relative^378EFUNSURLE;78HI_NSMutableDictionaryH"; K5La_{{0, 0}, {1400, 749}} PS(QRcdTUef_]SplitPosition_%EditorLayout_PersistentRepresentation"> [^(\]gh_`i_YAlternateTMain ei?@Ajnlj.T oqpk~ s{(DEFGHIJ|}~lmq{|\}__public.c-header MNOP"nopT#A5[{1503, 370}Z{1884, 66} nyr5. 5sv (tu__navigableItem_nameXjsusfx.h (wx_Zidentifier_(Xcode.IDEKit.GeniusCategory.Counterparts z4_3file:///Users/asb2m10/Documents/src/jsusfx/jsusfx.hXjsusfx.hXjsusfx.h? @B^z78^NSMutableArray9; q~_{{0, 0}, {1400, 374}} ?@Anʀ.T 5΀ (DEFGHIJK-\]_ MNOP"쀅T#A5[{1870, 680}Z{2146, 21} n5*. 5 n-./ n./Wjsusfx~ 34_DJsusFx::compileSection(int state, const char *code, int line_offset)  5 _{{0, 0}, {1400, 749}} (Rd_ (]h_ !?@A"n$.T '5( +3(DEFGHIJ569K-]_ =BMNOPCD"FT#A5\{1870, 1409}Z{2146, 21} LMn5*. R5ST n-./ [n./Wjsusfx~ 34_6Xcode.IDEKit.EditorDocument.SourceCodeComparisonEditor e5f_{{0, 0}, {1400, 749}} jr(klmnopqstuvwxyĀƀ̀__IDEDebugArea_SplitViewYRightViewWConsole_IDESplitViewDebugAreaYVariablesXLeftViewZLayoutMode (__DVTSplitViewItems q~ T]DVTIdentifier_DVTViewMagnitude]VariablesView#@ T[ConsoleArea#@ (n.__ConsoleFilterMode (n.__ConsoleFilterMode (__DVTSplitViewItems q€~ pĀT]DVTIdentifier_DVTViewMagnitude#@ lπÀT#@ (Ԁšn.__VariablesViewSelectedScope (ހǀȀɀʤ"n&.ˀ__VariablesViewShowsRawValues_VariablesViewSelectedScope_ VariablesViewViewSortDescriptors_VariablesViewShowsType 5 (_ (π_ qЀӀ~ рҀTYIDEEditor#@P    ԀՀT_IDEDebuggerArea#@bZjsusfx.cpp (؀_ qـ܀~  !ڀۀTP#@ &) +ڀ݀T#@q /6(012345߀789:;<"#__ Xcode.IDEKit.Navigator.Structure_ Xcode.IDEKit.Navigator.BatchFind_Xcode.IDEKit.Navigator.Symbol_Xcode.IDEKit.Navigator.Debug_SelectedNavigator_Xcode.IDEKit.Navigator.Issues EM(FGHIJKLN""Q"ST_^IDEVisibleRect_"IDEUnsavedDocumentFilteringEnabled_IDESCMStatusFilteringEnabled_IDEExpandedItemsTree_!IDERecentDocumentFilteringEnabled_IDESelectedTree_,IDENavigatorExpandedItemsBeforeFilteringTree_{{0, 0}, {259, 872}} _a`bT_IDEValuesAsTree fh(gi_Wjsusfx~ mp(nooo_XProductsP wy`zT }(g_ (-o_ `T (_ (""n&   . __,IDEBatchFindNavigatorReplaceAttributedString_)IDEBatchFindNavigatorFindAttributedString_!IDEBatchFindNavigatorShowsOptions_IDEBatchFindSearchFrameworks_IDEBatchFindNavigatorFindMode_IDEBatchFindMatchStyle_#IDEBatchFindNavigatorScrollPosition_IDEBatchFindIgnoreCase_'IDEBatchFindNavigatorSelectedRowIndexes_.IDEBatchFindNavigatorSelectedLocationsStateKey_$IDEBatchFindNavigatorCollapsedGroups_IDEBatchFindFindType XNSString YNS.string P78_NSMutableString;XNSString78_NSMutableAttributedString;_NSMutableAttributedString_NSAttributedString   Ё P ZNSLocation\NSRangeCountXNSLength78ZNSIndexSet;ZNSIndexSet `T (_ 78_NSMutableIndexSet;_NSMutableIndexSetZNSIndexSet ("&&&oˁ__$IDESymbolNavigatorShowContainersOnly_IDESymbolNavigatorShowHierarchy_#IDESymbolNavigatorShowWorkspaceOnly_!IDESymbolNavigatorShowClassesOnly_IDESymbolNamePatternString_!IDESymbolNavigatorSelectedSymbols_IDEExpandedItems q~  (    "n!.__IDEStackCompressionValue_IDEShowOnlyInterestingContent_DBGThreadOrQueueMode_ Xcode.IDEKit.Navigator.Structure #( !"$%&'()*+,"%&'")*",-.3__IDEErrorFilteringEnabled^IDEVisibleRect_IDECollapsedFiles_IDEExpandedIssues^IDEShowsByType_IDESelectedNavigables_IDECollapsedTypes_IDERecentFilteringEnabled_IDECollapsedGroups_{{0, 0}, {259, 843}} 9=:;</012_8max-external/Users/asb2m10/Documents/src/jsusfx/jsusfx.h_>max-external/Users/asb2m10/Documents/src/jsusfx/WDL/denormal.h_Imax-external/Users/asb2m10/Documents/src/jsusfx/WDL/eel2/nseel-compiler.c78BC\NSMutableSetBD;UNSSet F=GHIJKLMNO4IWet2 RW(STUV5678XYZ[9>FH__documentLocationsYsubissuesTtype[fullMessage b5cd:=ghij klmnoopqqs_startingColumnNumber_endingColumnNumber_characterRangeLen_locationEncoding_endingLineNumber_startingLineNumber_characterRangeLoc;<g _Ffile://localhost/Users/asb2m10/Documents/src/jsusfx/max/jsusfx_max.cpp78vw_DVTTextDocumentLocationxy;_DVTTextDocumentLocation_DVTDocumentLocationghij klmno|pqqs;< q?~ (STUV5678Z@EFG_ 5ACDghij klmpB <ɀ __file://localhost/Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_sysfile.hghij klmpqqB&+< ghij klmpqqB'< q~^Semantic Issue_Candidate function not viable: no known conversion from 't_handle *' (aka 'char ***') to 't_handle' (aka 'char **') for 2nd argument; remove &_7No matching function for call to 'sysfile_readtextfile' (STUV5678ZJNFV_ 5KMghij klmpƁL<M_Ffile://localhost/Users/asb2m10/Documents/src/jsusfx/max/jsusfx_max.cppghij klmpƁL < qρO~ (STUV5678ZہPTFU_ 5QSghij klmpR<59_\file://localhost/Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_path.hghij klmpR/4<m q~_uCandidate function not viable: no known conversion from 't_symbol **' (aka 'symbol **') to 'short *' for 2nd argument_4No matching function for call to 'path_frompathname' (STUV5678ZX\Fd_ 5Y[ghij klmpƁZ<_Ffile://localhost/Users/asb2m10/Documents/src/jsusfx/max/jsusfx_max.cppghij klmpƁZ< q]~ (STUV5678Z^bFc_ !5"#_aghij klm&p`<_\file://localhost/Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_path.hghij klm&,-p0`AF< 2q~_uCandidate function not viable: no known conversion from 't_symbol **' (aka 'symbol **') to 'short *' for 2nd argument_4No matching function for call to 'path_frompathname' 7<(STUV5678=>Z@fjFs_ C5DEgighij klmHoopJJLh< _Ffile://localhost/Users/asb2m10/Documents/src/jsusfx/max/jsusfx_max.cppghij klmHoPpJJLh< TqUk~ X](STUV5678^_ZalqFr_ d5efgmopghij klmjpllnn< H_\file://localhost/Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_path.hghij klmjrspJJvn%*<*ghij klmjrpJJvn< |q~_gCandidate function not viable: no known conversion from 'short *' to 'short' for 2nd argument; remove &_5No matching function for call to 'path_createsysfile' (STUV5678ZuyF_ 5vxghij klmoopw<f Q_Ffile://localhost/Users/asb2m10/Documents/src/jsusfx/max/jsusfx_max.cppghij klmopw< qz~ (STUV5678Z{F_ 5|~ghij klmp}<'__file://localhost/Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_sysfile.hghij klmrp}< i q~_Candidate function not viable: no known conversion from 'long *' to 't_ptr_size *' (aka 'unsigned long long *') for 2nd argument_1No matching function for call to 'sysfile_geteof' (TUV678́__documentLocations 5Ӂghij klmoopځ<i _Ffile://localhost/Users/asb2m10/Documents/src/jsusfx/max/jsusfx_max.cppghij klmo|pځ< q~ (TUV678_ 5ghij klmp<__file://localhost/Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_sysfile.hghij klmpV< q~^Semantic Issue_hCandidate function not viable: no known conversion from 'int' to 't_sysfile_text_flags' for 4th argument_7No matching function for call to 'sysfile_readtextfile'  (TUV678 _ 5ghij klmoopځ<_Ffile://localhost/Users/asb2m10/Documents/src/jsusfx/max/jsusfx_max.cppghij klmo|pځ< !q"~ %*(TUV678+,._ 1523ghij klm6p<__file://localhost/Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_sysfile.hghij klm6<=>pA?c#< Cq~_hCandidate function not viable: no known conversion from 'int' to 't_sysfile_text_flags' for 4th argument_7No matching function for call to 'sysfile_readtextfile' HM(STUV5678NOPQ_ T5Ughij klmXYYp[[]<q(_>file://localhost/Users/asb2m10/Documents/src/jsusfx/max/eel2.y `qa~ di(STUV5678jklm_ p5qghij klmtuupx <_Jfile://localhost/Users/asb2m10/Documents/src/jsusfx/WDL/eel2/nseel-yylex.c {q~_Clang LLVM 1.0 Notice_[In file included from /Users/asb2m10/Documents/src/jsusfx/max/../WDL/eel2/nseel-yylex.c:39:_Unused Entity Issue_Unused variable 'a' (VUT876__documentLocations 5ghij klmp< _>file://localhost/Users/asb2m10/Documents/src/jsusfx/jsusfx.cppghij klm|p<_9Unknown type name 'istream'; did you mean 'std::istream'?^Semantic Issue q~ (VUT876_ 5ghij klmp<Q_-file://localhost/usr/include/c++/4.2.1/iosfwd_'std::istream' declared here q~ q~ =2 =2P (ρ€_ qՁÁƁɀ~ ݁āŀT_IDENavigatorArea#@p@ ǁȀT]IDEEditorArea#@ ʁˀT_IDEUtilitiesArea#@p@ (΁ρЁсҁӁԁՁցׁث&n   ""ـ.*ABc__BreakpointsActivated_DefaultEditorStatesForURLs_DebuggingWindowBehavior\ActiveScheme_ActiveRunDestination_DefaultEditorFrameSizeForURLs_DocumentWindows_0LastCompletedPersistentSchemeBasedActivityReport_RecentEditorDocumentURLs_AppFocusInMiniDebugging_MiniDebuggingConsole  (9ځہ܀!"#$݁ҁ__7Xcode.Xcode3ProjectSupport.EditorDocument.Xcode3Project_&Xcode.IDEKit.EditorDocument.SourceCode_'Xcode.IDEKit.EditorDocument.LogDocument */(+,-.ށ0123ҁ_? @B8^_Afile:///Users/asb2m10/Documents/src/jsusfx/max/jsusfx9~.xcodeproj? @B=^_?file:///Users/asb2m10/Documents/src/jsusfx/max/index~.xcodeproj? @BB^_Afile:///Users/asb2m10/Documents/src/jsusfx/max/jsusfx~.xcodeproj/? @BG^_Xfile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/examples/audio/index~/index~.xcodeproj/ JQ(KLMNOPRSTUVW__-Xcode3ProjectEditorPreviousProjectEditorClass_(Xcode3ProjectEditor.sourceList.splitview_,Xcode3ProjectEditorPreviousTargetEditorClass_+Xcode3ProjectEditor_Xcode3ProjectInfoEditor_-Xcode3ProjectEditor_Xcode3BuildSettingsEditor_,Xcode3ProjectEditorSelectedDocumentLocations_Xcode3ProjectInfoEditor ac(bd__DVTSplitViewItems hqij~ mpnoNrT]DVTIdentifier_DVTViewMagnitude#@e@ x{noN}T#@0_Xcode3BuildSettingsEditor (_ (_ 5 Yselection_Jfile://localhost/Users/asb2m10/Documents/src/jsusfx/max/jsusfx9~.xcodeproj#A\ (_VEditorVTarget_"Xcode3BuildSettingsEditorLocations_Xcode3BuildSettingsEditor\max-external 5 (   nnny. .. ̀__Xcode3BuildSettingsEditorMode_Selected Build Properties_$Xcode3BuildSettingsEditorDisplayMode_#Xcode3BuildPropertyValueDisplayMode_#Collapsed Build Property Categories_"Xcode3BuildPropertyNameDisplayMode q~ q      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÁāŁƁǁȁɁʁˁ́́΁ρЁсҁӁԁՁցׁ؁فځہ܁݁ށ߁~  _Architectures||ADDITIONAL_SDKS  _Architectures||ARCHS  _Architectures||SDKROOT  _ Architectures||ONLY_ACTIVE_ARCH  _#Architectures||SUPPORTED_PLATFORMS  _Architectures||VALID_ARCHS  _Build Locations||SYMROOT  _Build Locations||OBJROOT  _%Build Locations||SHARED_PRECOMPS_DIR  _Build Options||BUILD_VARIANTS  _Build Options||GCC_VERSION  _(Build Options||DEBUG_INFORMATION_FORMAT Ł _'Build Options||GENERATE_PROFILING_CODE ȁ _@Build Options||PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR ˁ _)Build Options||RUN_CLANG_STATIC_ANALYZER ΁ _2Build Options||SCAN_ALL_SOURCE_FILES_FOR_INCLUDES с _ Build Options||VALIDATE_PRODUCT ԁ _%Code Signing||CODE_SIGN_ENTITLEMENTS ׁ _!Code Signing||CODE_SIGN_IDENTITY ځ _,Code Signing||CODE_SIGN_RESOURCE_RULES_PATH ݁ _$Code Signing||OTHER_CODE_SIGN_FLAGS  _Deployment||STRIPFLAGS  _Deployment||ALTERNATE_GROUP  _Deployment||ALTERNATE_OWNER  _Deployment||ALTERNATE_MODE  _(Deployment||ALTERNATE_PERMISSIONS_FILES  _!Deployment||COMBINE_HIDPI_IMAGES  _ Deployment||DEPLOYMENT_LOCATION  _&Deployment||DEPLOYMENT_POSTPROCESSING  _Deployment||INSTALL_GROUP  _Deployment||INSTALL_OWNER  _Deployment||INSTALL_MODE_FLAG   _Deployment||DSTROOT   _Deployment||INSTALL_PATH   _%Deployment||MACOSX_DEPLOYMENT_TARGET   _%Deployment||PRODUCT_DEFINITION_PLIST   _Deployment||SKIP_INSTALL   _$Deployment||STRIP_INSTALLED_PRODUCT   _Deployment||STRIP_STYLE   _Deployment||SEPARATE_STRIP   _Kernel Module||MODULE_NAME   _Kernel Module||MODULE_START   _Kernel Module||MODULE_STOP  " _Kernel Module||MODULE_VERSION  % _Linking||BUNDLE_LOADER  ( _%Linking||DYLIB_COMPATIBILITY_VERSION  + _Linking||DYLIB_CURRENT_VERSION  . _Linking||DEAD_CODE_STRIPPING  1 _'Linking||LINKER_DISPLAYS_MANGLED_NAMES  4 _,Linking||PRESERVE_DEAD_CODE_INITS_AND_TERMS  7 _Linking||LD_DYLIB_INSTALL_NAME  : _Linking||EXPORTED_SYMBOLS_FILE  = _Linking||LD_NO_PIE  @ _Linking||INIT_ROUTINE  C _&Linking||LINK_WITH_STANDARD_LIBRARIES  F _Linking||MACH_O_TYPE  I _Linking||ORDER_FILE  L _Linking||OTHER_LDFLAGS  O _%Linking||GENERATE_MASTER_OBJECT_FILE  R _Linking||PRELINK_LIBS  U _Linking||KEEP_PRIVATE_EXTERNS  X _!Linking||LD_RUNPATH_SEARCH_PATHS  [ _Linking||SEPARATE_SYMBOL_EDIT  ^ _Linking||PRELINK_FLAGS  a _Linking||SECTORDER_FLAGS  d _!Linking||UNEXPORTED_SYMBOLS_FILE  g _Linking||WARNING_LDFLAGS  j _Linking||LD_GENERATE_MAP_FILE  m _%Packaging||APPLY_RULES_IN_COPY_FILES  p _ Packaging||EXECUTABLE_EXTENSION  s _Packaging||EXECUTABLE_PREFIX  v _+Packaging||INFOPLIST_EXPAND_BUILD_SETTINGS  y _!Packaging||GENERATE_PKGINFO_FILE  | _Packaging||FRAMEWORK_VERSION   _Packaging||INFOPLIST_FILE   _.Packaging||INFOPLIST_OTHER_PREPROCESSOR_FLAGS   _#Packaging||INFOPLIST_OUTPUT_FORMAT   _.Packaging||INFOPLIST_PREPROCESSOR_DEFINITIONS   _#Packaging||INFOPLIST_PREFIX_HEADER   _ Packaging||INFOPLIST_PREPROCESS   _&Packaging||COPYING_PRESERVES_HFS_DATA   _'Packaging||PRIVATE_HEADERS_FOLDER_PATH   _Packaging||PRODUCT_NAME   _$Packaging||PLIST_FILE_OUTPUT_FORMAT   _&Packaging||PUBLIC_HEADERS_FOLDER_PATH   _(Packaging||STRINGS_FILE_OUTPUT_ENCODING   _Packaging||WRAPPER_EXTENSION   _'Search Paths||ALWAYS_SEARCH_USER_PATHS   _%Search Paths||FRAMEWORK_SEARCH_PATHS   _"Search Paths||HEADER_SEARCH_PATHS   _#Search Paths||LIBRARY_SEARCH_PATHS   _Search Paths||REZ_SEARCH_PATHS   _<Search Paths||EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES   _<Search Paths||INCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES   _'Search Paths||USER_HEADER_SEARCH_PATHS   _Unit Testing||OTHER_TEST_FLAGS   _Unit Testing||TEST_AFTER_BUILD  ā _Unit Testing||TEST_HOST  ǁ _Unit Testing||TEST_RIG  ʁ _$Versioning||CURRENT_PROJECT_VERSION  ́ _Versioning||VERSION_INFO_FILE  Ё _%Versioning||VERSION_INFO_EXPORT_DECL  Ӂ _ Versioning||VERSION_INFO_PREFIX  ց _ Versioning||VERSION_INFO_SUFFIX  ف _Versioning||VERSIONING_SYSTEM  ܁ _!Versioning||VERSION_INFO_BUILDER  ߁ _AApple LLVM compiler 4.2 - Code Generation||GCC_FAST_OBJC_DISPATCH   _HApple LLVM compiler 4.2 - Code Generation||CLANG_X86_VECTOR_INSTRUCTIONS   _>Apple LLVM compiler 4.2 - Code Generation||GCC_STRICT_ALIASING   _IApple LLVM compiler 4.2 - Code Generation||GCC_GENERATE_DEBUGGING_SYMBOLS   _=Apple LLVM compiler 4.2 - Code Generation||GCC_DYNAMIC_NO_PIC   _KApple LLVM compiler 4.2 - Code Generation||GCC_GENERATE_TEST_COVERAGE_FILES   _IApple LLVM compiler 4.2 - Code Generation||GCC_INLINES_ARE_PRIVATE_EXTERN   _KApple LLVM compiler 4.2 - Code Generation||GCC_INSTRUMENT_PROGRAM_FLOW_ARCS   _HApple LLVM compiler 4.2 - Code Generation||GCC_ENABLE_KERNEL_DEVELOPMENT   _3Apple LLVM compiler 4.2 - Code Generation||LLVM_LTO   _Apple LLVM compiler 4.2 - Language||GCC_ENABLE_OBJC_EXCEPTIONS  0 _8Apple LLVM compiler 4.2 - Language||GCC_ENABLE_TRIGRAPHS  3 _KApple LLVM compiler 4.2 - Language||GCC_ENABLE_FLOATING_POINT_LIBRARY_CALLS  6 _CApple LLVM compiler 4.2 - Language||GCC_USE_INDIRECT_FUNCTION_CALLS  9 _CApple LLVM compiler 4.2 - Language||GCC_USE_REGISTER_FUNCTION_CALLS  < _;Apple LLVM compiler 4.2 - Language||CLANG_LINK_OBJC_RUNTIME  ? _KApple LLVM compiler 4.2 - Language||GCC_INCREASE_PRECOMPILED_HEADER_SHARING  B _9Apple LLVM compiler 4.2 - Language||CLANG_ENABLE_OBJC_ARC  E _0Apple LLVM compiler 4.2 - Language||OTHER_CFLAGS  H _8Apple LLVM compiler 4.2 - Language||OTHER_CPLUSPLUSFLAGS  K _@Apple LLVM compiler 4.2 - Language||GCC_PRECOMPILE_PREFIX_HEADER  N _5Apple LLVM compiler 4.2 - Language||GCC_PREFIX_HEADER  Q _@Apple LLVM compiler 4.2 - Language||GCC_ENABLE_BUILTIN_FUNCTIONS  T _=Apple LLVM compiler 4.2 - Language||GCC_ENABLE_PASCAL_STRINGS  W _3Apple LLVM compiler 4.2 - Language||GCC_SHORT_ENUMS  Z _FApple LLVM compiler 4.2 - Language||GCC_USE_STANDARD_INCLUDE_SEARCHING  ] _EApple LLVM compiler 4.2 - Preprocessing||GCC_PREPROCESSOR_DEFINITIONS  ` _ZApple LLVM compiler 4.2 - Preprocessing||GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS  c _HApple LLVM compiler 4.2 - Warning Polices||GCC_WARN_INHIBIT_ALL_WARNINGS  f _V__Xcode3BuildSettingsEditor C5 D G H I_Ifile://localhost/Users/asb2m10/Documents/src/jsusfx/max/index~.xcodeproj/#A-' N R( Q S U__"Xcode3BuildSettingsEditorLocations_Xcode3BuildSettingsEditor Z5 [ ^ e(   n gyn jy.̀.̀_ nq~ qq r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÁāŁƁǁȁɁʁˁ́́΁ρЁр~  P _Architectures||ADDITIONAL_SDKS  S _Architectures||ARCHS  V _Architectures||SDKROOT  Y _ Architectures||ONLY_ACTIVE_ARCH  \ _#Architectures||SUPPORTED_PLATFORMS  _ _Architectures||VALID_ARCHS  b _Build Locations||SYMROOT  e _Build Locations||OBJROOT  h _%Build Locations||SHARED_PRECOMPS_DIR  k _Build Options||BUILD_VARIANTS  n _Build Options||GCC_VERSION  q _(Build Options||DEBUG_INFORMATION_FORMAT  t _'Build Options||GENERATE_PROFILING_CODE  w _@Build Options||PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR  z _)Build Options||RUN_CLANG_STATIC_ANALYZER  } _2Build Options||SCAN_ALL_SOURCE_FILES_FOR_INCLUDES   _ Build Options||VALIDATE_PRODUCT   _%Code Signing||CODE_SIGN_ENTITLEMENTS   _!Code Signing||CODE_SIGN_IDENTITY   _,Code Signing||CODE_SIGN_RESOURCE_RULES_PATH   _$Code Signing||OTHER_CODE_SIGN_FLAGS   _Deployment||STRIPFLAGS   _Deployment||ALTERNATE_GROUP   _Deployment||ALTERNATE_OWNER   _Deployment||ALTERNATE_MODE   _(Deployment||ALTERNATE_PERMISSIONS_FILES   _!Deployment||COMBINE_HIDPI_IMAGES   _ Deployment||DEPLOYMENT_LOCATION   _&Deployment||DEPLOYMENT_POSTPROCESSING   _Deployment||INSTALL_GROUP   _Deployment||INSTALL_OWNER   _Deployment||INSTALL_MODE_FLAG   _Deployment||DSTROOT   _Deployment||INSTALL_PATH   _%Deployment||MACOSX_DEPLOYMENT_TARGET   _%Deployment||PRODUCT_DEFINITION_PLIST   _Deployment||SKIP_INSTALL   _$Deployment||STRIP_INSTALLED_PRODUCT   _Deployment||STRIP_STYLE  Ł _Deployment||SEPARATE_STRIP  ȁ _Kernel Module||MODULE_NAME  ˁ _Kernel Module||MODULE_START  ΁ _Kernel Module||MODULE_STOP  с _Kernel Module||MODULE_VERSION  ԁ _Linking||BUNDLE_LOADER  ׁ _%Linking||DYLIB_COMPATIBILITY_VERSION  ځ _Linking||DYLIB_CURRENT_VERSION  ݁ _Linking||DEAD_CODE_STRIPPING   _'Linking||LINKER_DISPLAYS_MANGLED_NAMES   _,Linking||PRESERVE_DEAD_CODE_INITS_AND_TERMS   _Linking||LD_DYLIB_INSTALL_NAME   _Linking||EXPORTED_SYMBOLS_FILE   _Linking||LD_NO_PIE   _Linking||INIT_ROUTINE   _&Linking||LINK_WITH_STANDARD_LIBRARIES   _Linking||MACH_O_TYPE   _Linking||ORDER_FILE   _Linking||OTHER_LDFLAGS   _%Linking||GENERATE_MASTER_OBJECT_FILE   _Linking||PRELINK_LIBS   _Linking||KEEP_PRIVATE_EXTERNS   _!Linking||LD_RUNPATH_SEARCH_PATHS   _Linking||SEPARATE_SYMBOL_EDIT   _Linking||PRELINK_FLAGS   _Linking||SECTORDER_FLAGS   _!Linking||UNEXPORTED_SYMBOLS_FILE   _Linking||WARNING_LDFLAGS   _Linking||LD_GENERATE_MAP_FILE   _%Packaging||APPLY_RULES_IN_COPY_FILES   _ Packaging||EXECUTABLE_EXTENSION  " _Packaging||EXECUTABLE_PREFIX  % _+Packaging||INFOPLIST_EXPAND_BUILD_SETTINGS  ( _!Packaging||GENERATE_PKGINFO_FILE  + _Packaging||FRAMEWORK_VERSION  . _Packaging||INFOPLIST_FILE  1 _.Packaging||INFOPLIST_OTHER_PREPROCESSOR_FLAGS  4 _#Packaging||INFOPLIST_OUTPUT_FORMAT  7 _.Packaging||INFOPLIST_PREPROCESSOR_DEFINITIONS  : _#Packaging||INFOPLIST_PREFIX_HEADER  = _ Packaging||INFOPLIST_PREPROCESS  @ _&Packaging||COPYING_PRESERVES_HFS_DATA  C _'Packaging||PRIVATE_HEADERS_FOLDER_PATH  F _Packaging||PRODUCT_NAME  I _$Packaging||PLIST_FILE_OUTPUT_FORMAT  L _&Packaging||PUBLIC_HEADERS_FOLDER_PATH  O _(Packaging||STRINGS_FILE_OUTPUT_ENCODING  R _Packaging||WRAPPER_EXTENSION  U _'Search Paths||ALWAYS_SEARCH_USER_PATHS  X _%Search Paths||FRAMEWORK_SEARCH_PATHS  [ _"Search Paths||HEADER_SEARCH_PATHS  ^ _#Search Paths||LIBRARY_SEARCH_PATHS  a _Search Paths||REZ_SEARCH_PATHS  d _<Search Paths||EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES  g _<Search Paths||INCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES  j _'Search Paths||USER_HEADER_SEARCH_PATHS  m _Unit Testing||OTHER_TEST_FLAGS  p _Unit Testing||TEST_AFTER_BUILD  s _Unit Testing||TEST_HOST  v _Unit Testing||TEST_RIG  y _$Versioning||CURRENT_PROJECT_VERSION  | _Versioning||VERSION_INFO_FILE   _%Versioning||VERSION_INFO_EXPORT_DECL   _ Versioning||VERSION_INFO_PREFIX   _ Versioning||VERSION_INFO_SUFFIX   _Versioning||VERSIONING_SYSTEM   _!Versioning||VERSION_INFO_BUILDER   _AApple LLVM compiler 4.2 - Code Generation||GCC_FAST_OBJC_DISPATCH   _HApple LLVM compiler 4.2 - Code Generation||CLANG_X86_VECTOR_INSTRUCTIONS   _>Apple LLVM compiler 4.2 - Code Generation||GCC_STRICT_ALIASING   _IApple LLVM compiler 4.2 - Code Generation||GCC_GENERATE_DEBUGGING_SYMBOLS   _=Apple LLVM compiler 4.2 - Code Generation||GCC_DYNAMIC_NO_PIC   _KApple LLVM compiler 4.2 - Code Generation||GCC_GENERATE_TEST_COVERAGE_FILES   _IApple LLVM compiler 4.2 - Code Generation||GCC_INLINES_ARE_PRIVATE_EXTERN   _KApple LLVM compiler 4.2 - Code Generation||GCC_INSTRUMENT_PROGRAM_FLOW_ARCS   _HApple LLVM compiler 4.2 - Code Generation||GCC_ENABLE_KERNEL_DEVELOPMENT   _3Apple LLVM compiler 4.2 - Code Generation||LLVM_LTO   _Apple LLVM compiler 4.2 - Language||GCC_ENABLE_OBJC_EXCEPTIONS  ߁ _8Apple LLVM compiler 4.2 - Language||GCC_ENABLE_TRIGRAPHS   _KApple LLVM compiler 4.2 - Language||GCC_ENABLE_FLOATING_POINT_LIBRARY_CALLS   _CApple LLVM compiler 4.2 - Language||GCC_USE_INDIRECT_FUNCTION_CALLS   _CApple LLVM compiler 4.2 - Language||GCC_USE_REGISTER_FUNCTION_CALLS   _;Apple LLVM compiler 4.2 - Language||CLANG_LINK_OBJC_RUNTIME   _KApple LLVM compiler 4.2 - Language||GCC_INCREASE_PRECOMPILED_HEADER_SHARING   _9Apple LLVM compiler 4.2 - Language||CLANG_ENABLE_OBJC_ARC   _0Apple LLVM compiler 4.2 - Language||OTHER_CFLAGS   _8Apple LLVM compiler 4.2 - Language||OTHER_CPLUSPLUSFLAGS   _@Apple LLVM compiler 4.2 - Language||GCC_PRECOMPILE_PREFIX_HEADER   _5Apple LLVM compiler 4.2 - Language||GCC_PREFIX_HEADER  _@Apple LLVM compiler 4.2 - Language||GCC_ENABLE_BUILTIN_FUNCTIONS  _=Apple LLVM compiler 4.2 - Language||GCC_ENABLE_PASCAL_STRINGS  _3Apple LLVM compiler 4.2 - Language||GCC_SHORT_ENUMS   _FApple LLVM compiler 4.2 - Language||GCC_USE_STANDARD_INCLUDE_SEARCHING   _EApple LLVM compiler 4.2 - Preprocessing||GCC_PREPROCESSOR_DEFINITIONS  _ZApple LLVM compiler 4.2 - Preprocessing||GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS  _HApple LLVM compiler 4.2 - Warning Polices||GCC_WARN_INHIBIT_ALL_WARNINGS  _?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÁāŁƁǁȁɁʁˁ́́΁ρЁсҁӁԁՁցׁ؁فځہ܁݁ށ߁~ A _Architectures||ADDITIONAL_SDKS D _Architectures||ARCHS G _Architectures||SDKROOT J _ Architectures||ONLY_ACTIVE_ARCH M _#Architectures||SUPPORTED_PLATFORMS P _Architectures||VALID_ARCHS S _Build Locations||SYMROOT V _Build Locations||OBJROOT Y _%Build Locations||SHARED_PRECOMPS_DIR \ _Build Options||BUILD_VARIANTS _ _Build Options||GCC_VERSION b _(Build Options||DEBUG_INFORMATION_FORMAT e _/Build Options||EMBEDDED_CONTENT_CONTAINS_SWIFT h _'Build Options||GENERATE_PROFILING_CODE k _@Build Options||PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR n _.Build Options||APPLICATION_EXTENSION_API_ONLY q _2Build Options||SCAN_ALL_SOURCE_FILES_FOR_INCLUDES t _ Build Options||VALIDATE_PRODUCT w _%Code Signing||CODE_SIGN_ENTITLEMENTS z _!Code Signing||CODE_SIGN_IDENTITY } _,Code Signing||CODE_SIGN_RESOURCE_RULES_PATH  _$Code Signing||OTHER_CODE_SIGN_FLAGS  _#Code Signing||PROVISIONING_PROFILE  _Deployment||STRIPFLAGS  _Deployment||ALTERNATE_GROUP  _Deployment||ALTERNATE_OWNER  _Deployment||ALTERNATE_MODE  _(Deployment||ALTERNATE_PERMISSIONS_FILES  _!Deployment||COMBINE_HIDPI_IMAGES  _ Deployment||DEPLOYMENT_LOCATION  _&Deployment||DEPLOYMENT_POSTPROCESSING  _Deployment||INSTALL_GROUP  _Deployment||INSTALL_OWNER  _Deployment||INSTALL_MODE_FLAG  _Deployment||DSTROOT  _Deployment||INSTALL_PATH  _%Deployment||MACOSX_DEPLOYMENT_TARGET  _%Deployment||PRODUCT_DEFINITION_PLIST  _Deployment||SKIP_INSTALL  _$Deployment||STRIP_INSTALLED_PRODUCT  _Deployment||STRIP_STYLE  _Deployment||SEPARATE_STRIP  _Kernel Module||MODULE_NAME  _Kernel Module||MODULE_START Ł _Kernel Module||MODULE_STOP ȁ _Kernel Module||MODULE_VERSION ˁ _Linking||BUNDLE_LOADER ΁ _%Linking||DYLIB_COMPATIBILITY_VERSION с _Linking||DYLIB_CURRENT_VERSION ԁ _Linking||DEAD_CODE_STRIPPING ׁ _'Linking||LINKER_DISPLAYS_MANGLED_NAMES ځ _,Linking||PRESERVE_DEAD_CODE_INITS_AND_TERMS ݁ _Linking||LD_DYLIB_INSTALL_NAME  _!Linking||DYLIB_INSTALL_NAME_BASE  _Linking||EXPORTED_SYMBOLS_FILE  _Linking||LD_NO_PIE  _Linking||INIT_ROUTINE  _&Linking||LINK_WITH_STANDARD_LIBRARIES  _Linking||MACH_O_TYPE  _Linking||ORDER_FILE  _Linking||OTHER_LIBTOOLFLAGS  _Linking||OTHER_LDFLAGS  _!Linking||LD_DEPENDENCY_INFO_FILE  _%Linking||GENERATE_MASTER_OBJECT_FILE  _Linking||PRELINK_LIBS  _Linking||KEEP_PRIVATE_EXTERNS  _7Linking||LD_QUOTE_LINKER_ARGUMENTS_FOR_COMPILER_DRIVER   _!Linking||LD_RUNPATH_SEARCH_PATHS   _Linking||SEPARATE_SYMBOL_EDIT  _Linking||PRELINK_FLAGS  _Linking||SECTORDER_FLAGS  _!Linking||UNEXPORTED_SYMBOLS_FILE  _Linking||WARNING_LDFLAGS  _Linking||LD_GENERATE_MAP_FILE  _%Packaging||APPLY_RULES_IN_COPY_FILES " _.Packaging||CREATE_INFOPLIST_SECTION_IN_BINARY % _Packaging||DEFINES_MODULE ( _ Packaging||EXECUTABLE_EXTENSION + _Packaging||EXECUTABLE_PREFIX . _+Packaging||INFOPLIST_EXPAND_BUILD_SETTINGS 1 _!Packaging||GENERATE_PKGINFO_FILE 4 _Packaging||FRAMEWORK_VERSION 7 _Packaging||INFOPLIST_FILE : _.Packaging||INFOPLIST_OTHER_PREPROCESSOR_FLAGS = _#Packaging||INFOPLIST_OUTPUT_FORMAT @ _.Packaging||INFOPLIST_PREPROCESSOR_DEFINITIONS C _#Packaging||INFOPLIST_PREFIX_HEADER F _Packaging||MODULEMAP_FILE I _ Packaging||INFOPLIST_PREPROCESS L _&Packaging||COPYING_PRESERVES_HFS_DATA O _'Packaging||PRIVATE_HEADERS_FOLDER_PATH R _"Packaging||MODULEMAP_PRIVATE_FILE U _Packaging||PRODUCT_MODULE_NAME X _Packaging||PRODUCT_NAME [ _$Packaging||PLIST_FILE_OUTPUT_FORMAT ^ _&Packaging||PUBLIC_HEADERS_FOLDER_PATH a _(Packaging||STRINGS_FILE_OUTPUT_ENCODING d _Packaging||WRAPPER_EXTENSION g _'Search Paths||ALWAYS_SEARCH_USER_PATHS j _%Search Paths||FRAMEWORK_SEARCH_PATHS m _"Search Paths||HEADER_SEARCH_PATHS p _#Search Paths||LIBRARY_SEARCH_PATHS s _Search Paths||REZ_SEARCH_PATHS v _<Search Paths||EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES y _<Search Paths||INCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES | _'Search Paths||USER_HEADER_SEARCH_PATHS  _Testing||TEST_HOST  _2Testing||TREAT_MISSING_BASELINES_AS_TEST_FAILURES  _$Versioning||CURRENT_PROJECT_VERSION  _Versioning||VERSION_INFO_FILE  _%Versioning||VERSION_INFO_EXPORT_DECL  _ Versioning||VERSION_INFO_PREFIX  _ Versioning||VERSION_INFO_SUFFIX  _Versioning||VERSIONING_SYSTEM  _!Versioning||VERSION_INFO_BUILDER  _?Apple LLVM 6.1 - Code Generation||CLANG_DEBUG_INFORMATION_LEVEL  _?Apple LLVM 6.1 - Code Generation||CLANG_X86_VECTOR_INSTRUCTIONS  _5Apple LLVM 6.1 - Code Generation||GCC_STRICT_ALIASING  _@Apple LLVM 6.1 - Code Generation||GCC_GENERATE_DEBUGGING_SYMBOLS  _4Apple LLVM 6.1 - Code Generation||GCC_DYNAMIC_NO_PIC  _BApple LLVM 6.1 - Code Generation||GCC_GENERATE_TEST_COVERAGE_FILES  _@Apple LLVM 6.1 - Code Generation||GCC_INLINES_ARE_PRIVATE_EXTERN  _BApple LLVM 6.1 - Code Generation||GCC_INSTRUMENT_PROGRAM_FLOW_ARCS  _?Apple LLVM 6.1 - Code Generation||GCC_ENABLE_KERNEL_DEVELOPMENT  _*Apple LLVM 6.1 - Code Generation||LLVM_LTO  _3Apple LLVM 6.1 - Code Generation||GCC_REUSE_STRINGS  _6Apple LLVM 6.1 - Code Generation||GCC_NO_COMMON_BLOCKS  _AApple LLVM 6.1 - Code Generation||CLANG_OPTIMIZATION_PROFILE_FILE  _/Apple LLVM 6.1 - Code Generation||GCC_FAST_MATH ā _8Apple LLVM 6.1 - Code Generation||GCC_THREADSAFE_STATICS ǁ _Apple LLVM 6.1 - Language - Objective C||CLANG_ENABLE_OBJC_ARC $ _4Apple LLVM 6.1 - Preprocessing||ENABLE_NS_ASSERTIONS ' _:Apple LLVM 6.1 - Preprocessing||ENABLE_STRICT_OBJC_MSGSEND * _?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwx !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÁāŁƁǁȁɁʁˁ́́΁ρЁсҁӁԁՁցׁ؁فځہ܁݁ށ߁~ | _Architectures||ADDITIONAL_SDKS  _Architectures||ARCHS  _Architectures||SDKROOT  _ Architectures||ONLY_ACTIVE_ARCH  _#Architectures||SUPPORTED_PLATFORMS  _Architectures||VALID_ARCHS  _Build Locations||SYMROOT  _Build Locations||OBJROOT  _%Build Locations||SHARED_PRECOMPS_DIR  _Build Options||BUILD_VARIANTS  _Build Options||GCC_VERSION  _(Build Options||DEBUG_INFORMATION_FORMAT  _'Build Options||GENERATE_PROFILING_CODE  _@Build Options||PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR  _)Build Options||RUN_CLANG_STATIC_ANALYZER  _2Build Options||SCAN_ALL_SOURCE_FILES_FOR_INCLUDES  _ Build Options||VALIDATE_PRODUCT  _%Code Signing||CODE_SIGN_ENTITLEMENTS  _!Code Signing||CODE_SIGN_IDENTITY  _,Code Signing||CODE_SIGN_RESOURCE_RULES_PATH  _$Code Signing||OTHER_CODE_SIGN_FLAGS  _Deployment||STRIPFLAGS  _Deployment||ALTERNATE_GROUP  _Deployment||ALTERNATE_OWNER ā _Deployment||ALTERNATE_MODE ǁ _(Deployment||ALTERNATE_PERMISSIONS_FILES ʁ _!Deployment||COMBINE_HIDPI_IMAGES ́ _ Deployment||DEPLOYMENT_LOCATION Ё _&Deployment||DEPLOYMENT_POSTPROCESSING Ӂ _Deployment||INSTALL_GROUP ց _Deployment||INSTALL_OWNER ف _Deployment||INSTALL_MODE_FLAG ܁ _Deployment||DSTROOT ߁ _Deployment||INSTALL_PATH  _%Deployment||MACOSX_DEPLOYMENT_TARGET  _%Deployment||PRODUCT_DEFINITION_PLIST  _Deployment||SKIP_INSTALL  _$Deployment||STRIP_INSTALLED_PRODUCT  _Deployment||STRIP_STYLE  _Deployment||SEPARATE_STRIP  _Kernel Module||MODULE_NAME  _Kernel Module||MODULE_START  _Kernel Module||MODULE_STOP  _Kernel Module||MODULE_VERSION  _Linking||BUNDLE_LOADER  _%Linking||DYLIB_COMPATIBILITY_VERSION  _Linking||DYLIB_CURRENT_VERSION   _Linking||DEAD_CODE_STRIPPING   _'Linking||LINKER_DISPLAYS_MANGLED_NAMES  _,Linking||PRESERVE_DEAD_CODE_INITS_AND_TERMS  _Linking||LD_DYLIB_INSTALL_NAME  _Linking||EXPORTED_SYMBOLS_FILE  _Linking||LD_NO_PIE  _Linking||INIT_ROUTINE  _&Linking||LINK_WITH_STANDARD_LIBRARIES ! _Linking||MACH_O_TYPE $ _Linking||ORDER_FILE ' _Linking||OTHER_LDFLAGS * _%Linking||GENERATE_MASTER_OBJECT_FILE - _Linking||PRELINK_LIBS 0 _Linking||KEEP_PRIVATE_EXTERNS 3 _!Linking||LD_RUNPATH_SEARCH_PATHS 6 _Linking||SEPARATE_SYMBOL_EDIT 9 _Linking||PRELINK_FLAGS < _Linking||SECTORDER_FLAGS ? _!Linking||UNEXPORTED_SYMBOLS_FILE B _Linking||WARNING_LDFLAGS E _Linking||LD_GENERATE_MAP_FILE H _%Packaging||APPLY_RULES_IN_COPY_FILES K _ Packaging||EXECUTABLE_EXTENSION N _Packaging||EXECUTABLE_PREFIX Q _+Packaging||INFOPLIST_EXPAND_BUILD_SETTINGS T _!Packaging||GENERATE_PKGINFO_FILE W _Packaging||FRAMEWORK_VERSION Z _Packaging||INFOPLIST_FILE ] _.Packaging||INFOPLIST_OTHER_PREPROCESSOR_FLAGS ` _#Packaging||INFOPLIST_OUTPUT_FORMAT c _.Packaging||INFOPLIST_PREPROCESSOR_DEFINITIONS f _#Packaging||INFOPLIST_PREFIX_HEADER i _ Packaging||INFOPLIST_PREPROCESS l _&Packaging||COPYING_PRESERVES_HFS_DATA o _'Packaging||PRIVATE_HEADERS_FOLDER_PATH r _Packaging||PRODUCT_NAME u _$Packaging||PLIST_FILE_OUTPUT_FORMAT x _&Packaging||PUBLIC_HEADERS_FOLDER_PATH { _(Packaging||STRINGS_FILE_OUTPUT_ENCODING ~ _Packaging||WRAPPER_EXTENSION  _'Search Paths||ALWAYS_SEARCH_USER_PATHS  _%Search Paths||FRAMEWORK_SEARCH_PATHS  _"Search Paths||HEADER_SEARCH_PATHS  _#Search Paths||LIBRARY_SEARCH_PATHS  _Search Paths||REZ_SEARCH_PATHS  _<Search Paths||EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES  _<Search Paths||INCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES  _'Search Paths||USER_HEADER_SEARCH_PATHS  _Unit Testing||OTHER_TEST_FLAGS  _Unit Testing||TEST_AFTER_BUILD  _Unit Testing||TEST_HOST  _Unit Testing||TEST_RIG  _$Versioning||CURRENT_PROJECT_VERSION  _Versioning||VERSION_INFO_FILE  _%Versioning||VERSION_INFO_EXPORT_DECL  _ Versioning||VERSION_INFO_PREFIX  _ Versioning||VERSION_INFO_SUFFIX  _Versioning||VERSIONING_SYSTEM  _!Versioning||VERSION_INFO_BUILDER  _AApple LLVM compiler 4.2 - Code Generation||GCC_FAST_OBJC_DISPATCH  _HApple LLVM compiler 4.2 - Code Generation||CLANG_X86_VECTOR_INSTRUCTIONS  _>Apple LLVM compiler 4.2 - Code Generation||GCC_STRICT_ALIASING Á _IApple LLVM compiler 4.2 - Code Generation||GCC_GENERATE_DEBUGGING_SYMBOLS Ɓ _=Apple LLVM compiler 4.2 - Code Generation||GCC_DYNAMIC_NO_PIC Ɂ _KApple LLVM compiler 4.2 - Code Generation||GCC_GENERATE_TEST_COVERAGE_FILES ́ _IApple LLVM compiler 4.2 - Code Generation||GCC_INLINES_ARE_PRIVATE_EXTERN ρ _KApple LLVM compiler 4.2 - Code Generation||GCC_INSTRUMENT_PROGRAM_FLOW_ARCS ҁ _HApple LLVM compiler 4.2 - Code Generation||GCC_ENABLE_KERNEL_DEVELOPMENT Ձ _3Apple LLVM compiler 4.2 - Code Generation||LLVM_LTO ؁ _Apple LLVM compiler 4.2 - Language||GCC_ENABLE_OBJC_EXCEPTIONS   _8Apple LLVM compiler 4.2 - Language||GCC_ENABLE_TRIGRAPHS  _KApple LLVM compiler 4.2 - Language||GCC_ENABLE_FLOATING_POINT_LIBRARY_CALLS  _CApple LLVM compiler 4.2 - Language||GCC_USE_INDIRECT_FUNCTION_CALLS  _CApple LLVM compiler 4.2 - Language||GCC_USE_REGISTER_FUNCTION_CALLS  _;Apple LLVM compiler 4.2 - Language||CLANG_LINK_OBJC_RUNTIME  _KApple LLVM compiler 4.2 - Language||GCC_INCREASE_PRECOMPILED_HEADER_SHARING  _9Apple LLVM compiler 4.2 - Language||CLANG_ENABLE_OBJC_ARC   _0Apple LLVM compiler 4.2 - Language||OTHER_CFLAGS # _8Apple LLVM compiler 4.2 - Language||OTHER_CPLUSPLUSFLAGS & _@Apple LLVM compiler 4.2 - Language||GCC_PRECOMPILE_PREFIX_HEADER ) _5Apple LLVM compiler 4.2 - Language||GCC_PREFIX_HEADER , _@Apple LLVM compiler 4.2 - Language||GCC_ENABLE_BUILTIN_FUNCTIONS / _=Apple LLVM compiler 4.2 - Language||GCC_ENABLE_PASCAL_STRINGS 2 _3Apple LLVM compiler 4.2 - Language||GCC_SHORT_ENUMS 5 _FApple LLVM compiler 4.2 - Language||GCC_USE_STANDARD_INCLUDE_SEARCHING 8 _EApple LLVM compiler 4.2 - Preprocessing||GCC_PREPROCESSOR_DEFINITIONS ; _ZApple LLVM compiler 4.2 - Preprocessing||GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS > _HApple LLVM compiler 4.2 - Warning Polices||GCC_WARN_INHIBIT_ALL_WARNINGS A _?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]19AILTW^emux|āȁˁπ_? @Bb^_$file:///usr/include/c++/4.2.1/iosfwd? @Bg^_Lfile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/examples/maxmspsdk.xcconfig? @Bl^_Afile:///Users/asb2m10/Documents/src/jsusfx/WDL/eel2/eel_strings.h? @Bq^_@file:///Users/asb2m10/Documents/src/jsusfx/WDL/eel2/nseel-eval.c? @Bv^_;file:///Users/asb2m10/Documents/src/jsusfx/WDL/eel2/y.tab.c? @B{^_9file:///Users/asb2m10/Documents/src/jsusfx/WDL/denormal.h? @B^_?file:///Users/asb2m10/Documents/src/jsusfx/WDL/eel2/glue_port.h? @B^_.file:///usr/include/c++/4.2.1/bits/fstream.tcc? @B^_Gfile:///Users/asb2m10/Documents/src/jsusfx/WDL/eel2/asm-nseel-x86-gcc.c? @B^_Wfile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_critical.h? @B^_4file:///Users/asb2m10/Documents/src/jsusfx/WDL/fft.c? @B^_Sfile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_obex.h? @B^_Ufile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_sysmem.h? @B^ _Hfile:///Users/asb2m10/Downloads/MaxSDK-6.1.4/examples/maxmspsdk.xcconfig? @B^ _Ofile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/examples/audio/index~/index~.c? @B^_Sfile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_mess.h? @B^_=file:///Users/asb2m10/Documents/src/jsusfx/max/jsusfx_max.cpp? @B^_Bfile:///Users/asb2m10/Documents/src/jsusfx/WDL/eel2/nseel-caltab.c? @B^_Sfile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_path.h? @B^_?file:///Users/asb2m10/Documents/src/jsusfx/WDL/eel2/nseel-ram.c? @Bƀ^_Dfile:///Users/asb2m10/Documents/src/jsusfx/WDL/eel2/nseel-compiler.c? @Bˀ^_8file:///Users/asb2m10/Documents/src/jsusfx/WDL/heapbuf.h? @BЀ^_Afile:///Users/asb2m10/Documents/src/jsusfx/WDL/eel2/nseel-yylex.c? @BՀ^_Wfile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/msp-includes/z_sampletype.h? @Bڀ^ _Afile:///Users/asb2m10/Documents/src/jsusfx/max/maxmspsdk.xcconfig? @B߀^"_Tfile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_proto.h? @B^$_Vfile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext_sysfile.h? @B^&_Tfile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/max_types.h? @B^(_Bfile:///Users/asb2m10/Documents/src/jsusfx/WDL/eel2/nseel-lextab.c? @B^*_Nfile:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/ext.h? @B^,_Afile:///Users/asb2m10/Documents/src/jsusfx/WDL/eel2/nseel-cfunc.c? @B^._3file:///Users/asb2m10/Documents/src/jsusfx/jsusfx.h? @B^0_\file:///Users/asb2m10/Documents/src/MaxSDK-6.1.4/c74support/max-includes/common/commonsyms.c  ( 2345  "678__PrimaryDocumentTimestamp_$PrimaryDocumentVisibleCharacterRange]HideAllIssues_%PrimaryDocumentSelectedCharacterRange#AlM \{3668, 2759}Y{4945, 0} (:;<="!>?@__PrimaryDocumentTimestamp_$PrimaryDocumentVisibleCharacterRange]HideAllIssues_%PrimaryDocumentSelectedCharacterRange#AFSEZY{0, 2127}V{0, 0} +0(,-./BCDE12"4FGH__PrimaryDocumentTimestamp_$PrimaryDocumentVisibleCharacterRange]HideAllIssues_%PrimaryDocumentSelectedCharacterRange#Aiւud\{7821, 1543}W{21, 0} >C(MNOPDE"!JK@_#A8&%Y{0, 1794} LQ(MNOPMNOPRS"UQRS__PrimaryDocumentTimestamp_$PrimaryDocumentVisibleCharacterRange]HideAllIssues_%PrimaryDocumentSelectedCharacterRange#AjY{0, 2576}Y{2362, 0} _d(MNOPMNOPef"!UV@_#AĆY{0, 2233} mr(nopqXYZ[st"!\]@__PrimaryDocumentTimestamp_$PrimaryDocumentVisibleCharacterRange]HideAllIssues_%PrimaryDocumentSelectedCharacterRange#A]).]{28413, 1727} (_`ab"!cd@__PrimaryDocumentTimestamp_$PrimaryDocumentVisibleCharacterRange]HideAllIssues_%PrimaryDocumentSelectedCharacterRange#As\{7800, 1823} (fghi"jkl__PrimaryDocumentTimestamp_$PrimaryDocumentVisibleCharacterRange]HideAllIssues_%PrimaryDocumentSelectedCharacterRange#A5N?yY{0, 1411}Z{26444, 0} (nopq"rst__PrimaryDocumentTimestamp_$PrimaryDocumentVisibleCharacterRange]HideAllIssues_%PrimaryDocumentSelectedCharacterRange#A?l[{766, 1809}Z{1821, 34} (MNOP"!vw@_#A88Y{0, 1727} (,-./BCDE"΁yz{_#Ai_sa]{13726, 2624}[{15102, 32} (,-./BCDE"݁}~_#AiY{0, 1626}Y{414, 39} (MNOP"_#A&-\{6417, 1270}Y{6775, 0} ("!@__PrimaryDocumentTimestamp_$PrimaryDocumentVisibleCharacterRange]HideAllIssues_%PrimaryDocumentSelectedCharacterRange#AQY{0, 1537}  (:;<=  "!@_#AEG Y{0, 1856} (nopq"_#A1l/\{4850, 3488}Z{6682, 29} !&(MNOP'("*_#A8y$[\{5692, 1473}Z{1113, 46} 05(,-./BCDE67"!@_#Ak&}W{0, 17} >C(,-./BCDEDE"G_#Ak(\{8007, 2694}\{10440, 123} MR(MNOPST"!@_#A868Y{0, 1576} [`(MNOPab"!@_#A8k]{86462, 2078} in(nopqXYZ[op"r_#A]\{8215, 1567}Y{8962, 0} x}(MNOP~"_#A83RY{0, 1277}Y{1266, 0} (nopq"_#AGY{0, 2164}Y{284, 23} (MNOP"_#A7zY{0, 1977}X{766, 0} ("__PrimaryDocumentTimestamp_$PrimaryDocumentVisibleCharacterRange]HideAllIssues_%PrimaryDocumentSelectedCharacterRange#AX`Y{0, 2103}[{17072, 55} (,-./BCDE"!@_#AigY{0, 2548} (,-./BCDE"ρ_#AiۗGqC\{1661, 2248}Z{3452, 79} (,-./BCDE7"!Á@_#Ak& ("Łƀǀ_#AXDȬ[{453, 1473}Z{1822, 11} (MNOP"!Ɂʀ@_#A8}\{3013, 1158} (MNOP"́̀΀_#A5TND\{1503, 1262}Z{1884, 66} (MNOP"!Ёр@_#A8^X{0, 269} *( !"#$%&'()ӁՁׁفہ݁߁+,-./01234567  _? @B<^_2x-xcode-log://6E3CB8CA-FEBA-42D0-8ABC-BB458B114B89? @BA^_2x-xcode-log://6BC170BA-E398-46B6-A3D2-B899E1F54082? @BF^_2x-xcode-log://74DE2F39-3BB0-4C2F-BE15-F6BEE6D5D916? @BK^_2x-xcode-log://D2882272-94BF-4793-9C8B-12DAE2E80B1A? @BP^_2x-xcode-log://FE6257BB-4CCE-49FE-9AAE-67DA17B2F58F? @BU^_2x-xcode-log://C084F445-F0B3-4BF0-9BD5-5D11F727C88B? @BZ^_2x-xcode-log://5CF923AE-9A92-4D88-9425-8B1FF17BF28C? @B_^_2x-xcode-log://1E4BF32D-24C7-4A8C-A08B-2A9F8445D6C5? @Bd^_2x-xcode-log://83FDFA69-7F6A-4216-847E-DE1689BFB230? @Bi^_2x-xcode-log://773E378A-23C5-46C6-A4B9-4F22FFCDEDA4? @Bn^_2x-xcode-log://3EEDABA5-2F58-40C9-B82E-14836CC5BC6E? @Bs^_2x-xcode-log://E0B5FBCC-0E71-44B3-86B1-E838EC1860E1? @Bx^_2x-xcode-log://D6A08E30-D3F6-4C0B-BB16-7EB623A1E349 {}(|ˀ__SelectedDocumentLocations (|ˀ_ (ˀ__SelectedDocumentLocations (__SelectedDocumentLocations 5 <K_expandTranscriptYindexPathځ _NSIndexPathLength_NSIndexPathValue78[NSIndexPath;[NSIndexPath78_IDELogDocumentLocation;_IDELogDocumentLocation_DVTDocumentLocation (ˀ_ (__SelectedDocumentLocations 5 <UŁށ _NSIndexPathData WNS.dataB78]NSMutableData;VNSData (ց_ 5ځ <_2x-xcode-log://5CF923AE-9A92-4D88-9425-8B1FF17BF28C  B (ˀ__SelectedDocumentLocations (ˀ_ ( _ 5  <i     (|ˀ_ (ˀ__SelectedDocumentLocations (ˀ__SelectedDocumentLocations (] _ #((MNOP)*",_#A5ʔQU\{1870, 1466}Z{2146, 21} 2435T]IDENameString\max-external :D;<=>?@ABC !"#$E&""IJKL&%&'()TYtargetSDKZisEligible_targetDeviceIsWireless[isResizable_targetDeviceLocation_targetArchitecture_targetDeviceFamily_targetDeviceModelCode_targetDeviceIsConcrete[macosx10.10_"dvtdevice-local-computer:localhostVx86_64P^MacBookPro10,1 ^c(_`ab+-/1defg38;>_? @Bl^,_Jfile://localhost/Users/asb2m10/Documents/src/jsusfx/max/maxmspsdk.xcconfig? @Bq^._>file://localhost/Users/asb2m10/Documents/src/jsusfx/jsusfx.cpp? @Bv^0_Ffile://localhost/Users/asb2m10/Documents/src/jsusfx/max/jsusfx_max.cpp? @B{^2_Qfile://localhost/Users/asb2m10/Downloads/MaxSDK-6.1.4/examples/maxmspsdk.xcconfig ~4567TUwidthVheight#@#@` 459:T#@#@` 45<=T#@#@` 45?@T#@#@ q ~ (CDE#Fb__0IDEActivityReportCompletionSummaryStringSegments_IDEActivityReportOptions_IDEActivityReportTitle qGNRUY~ (āHIJȁKLM__&IDEActivityReportStringSegmentPriority_+IDEActivityReportStringSegmentBackSeparator_)IDEActivityReportStringSegmentStringValue#@c % Wjsusfx~ (āHIJ؁OPQ_#@Q XAssemble (āHIJKSTր_#@R: (āHIJVWX_#?c %  Okbplist00;Troot#-27EKR[boqsu $+.7>FSVXZ_gjo|?́ (HZ[J\]yyy^́_à̀__"IDEActivityReportStringSegmentType_"IDEActivityReportStringSegmentDate_'IDEActivityReportStringSegmentDateStyle_'IDEActivityReportStringSegmentTimeStyle#@ WNS.time#A5_/`78VNSDate;_2015-08-18 at 11:56 PM q0#8.-*:2]+/~_NSKeyedArchiver%&UState"+5:? &18=?AFHKMt+Z|'2;CHQR_rtvxz|~ 7fy6DOf~9;=?AZcjv!S\acegt  "$&^g}&)+-6`e*7:<?ACHU\^`bikmoq "$&3?ZnCQy   "$&(@iv~ !IN[`bdikmoy~(*,.09;=?ACLXcxz|~)+-/enw &(*,.024CEGIKMOQS`ikmoqz|~      _ h k m o !!!!!!!!!!,!.!0!2!4!6!8!:!<!I!R!T!V!X!Z!c!e!g!i!k!m!v!!!!!!!!!!!!!!!!!!!!!!!!""";"D"G"I"K"c"p""""""""""""""""""""""## ####"#$#&#:#C#H#J#L#N#[#`#b#d#i#k#m#o#}###################$ $$$$$!$#$7$D$G$I$L$N$P$d$m$r$t$v$x$$$$$$$$$$$$$$$$$$$$$$$%%%%#%0%9%;%=%?%A%J%L%N%P%R%T%r%%%%%%%%%%%%%%%&& &&&&&"&'&)&+&0&2&4&6&@&I&V&[&]&_&d&f&h&j&|&&&&&&&&&&&&&&&&&&&&&&&&&&&'''' ''','.'0'2'4'6'8'E'G'I'L'O'R'U'W'z''''(((,(.(0(2(4(6(8(:(I(K(M(O(Q(S(U(W(Y(h((((()()?)L)O)Q)T)V)X)j)w)z)|)))))))))))))))))))))))))))))))********'*(*)*+*8*Q*S*U*W*Y*[*^*a*d*g*j*m*p***************++*+I+i++++,,C,Z,c,l,o,r,{,,,,,,,,,,,---- -)-,---/-@-K-X-a-c-f-o-z------------------... .#.&.).,./.2.5.D.F.H.J.L.N.P.S.U.|...//)/</E/F/H/U/\/_/b/e/l/o/q/s/u//////0 0000000!0$0'0:0<0?0B0E0G0J0M0O0R0T0o0~00000011)12191<1?1B1E112 22#2*20292L2O2R2U2X2[2^2a2d2g2j2w2222222222222222222233(3=3Q3d3w333333333444"4<4R4{4~44444444444444444444444445555555"55555555555555556 666666667777 7 77777"7$7M7P7R7U7W7Y7\7777777777778888 88888 8"8+808386888a8d8f8i8l8n8q8888999999999999999999999:: : :::;:>:A:C::::::::::::::::::;;;;;;;;;F;I;L;N;;;;;;;;;;;UKURUUUXU[UbUeUhUkUmUtU{UUUUUUUUUUUUVVVVVVVVVV!V#VCV_VVVVWWWW XXXXXXXXXXXXXXXXXXXXYYYY Y YYYYYYY"Y%Y(Y+Y.Y1Y4Y7Y:Y=Y@YCYFYIYLYOYRYUYXY[Y^YaYdYgYjYmYpYsYvYyY|YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYZZZZ Z ZZZZZZZ!Z$Z'Z*Z-Z0Z3Z6Z9Z<Z?ZBZEZHZKZNZQZTZWZZZ]Z`ZcZfZiZlZoZrZuZxZ{Z~ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ[[[[ [[[[[[[ [#[&[)[,[/[2[5[8[;[>[A[D[G[J[M[P[S[V[X[a[d[[[[[[[[[[\\ \1\:\=\[\d\g\\\\\\\\\] ]]]6]?]B]m]v]y]]]]]]^*^3^6^k^t^w^^^^^^^__ _9_B_E_l_u_x_________````I`R`U`y````````aaaa/a8a;a\aeahaaaaaaaaabbbb7b@bCbjbsbvbbbbbbbbbcccc:cCcFcgcpcscccccccccdd$d'dQdZd]ddddddddde eee/e8e;edemepeeeeeeeeeffff*f3f6fWf`fcfffffffffgg gg2g;g>gZgcgfggggggggghhh"hPhYh\hhhhhhhhhiiiiDiMiPiiiiiiiiijj j#jMjVjYjtj}jjjjjjjkkkk?kHkKkuk~kkkkkkkl lll:lClFllllllmmmm4m=m@mbmkmnmmmmmmmmmnnnnCnLnOnrn{n~nnnnnnnoo oNoWoZoooooopJpSpVppppppqHqQqTqqqqrrr;rDrGrrrrrrss$s'skstswssst tttUt^tattttttu6u?uBuzuuuuuvv vvOvXv[vvvvvvw4w=w@w{wwwwwx'x0x3xyxxxxxyy&y)yeynyqyyyyyyz:zCzFz~zzzzz{{"{%{[{d{g{{{|| ||m|v|y|||}}}}e}n}q}}}~.~7~:~~~~~~<EH ]fi(+FOR"w,58iruCLO Xad dmp"%qz})25}KTW"%R[^qz}>GJy\eh cloenq"%AJMXa"$58;>A$147:=@CPRUWY\^`ijlu.147:=@CFILORUX[^adgjmpsvy| !$'*-0369<?BEHKNQTWZ]`cfilorux{~  #&),/258;>ADGJMPSVY\_behknqtwz}9BEhqt HQTu~ [dg 7@Cgps&/2QZ]{FORox{DMPx$-0NWZy*36Xad#,/QZ]s| :CFnwz&)CLOktw$-0S\_!>GJ{%(KTWENQ|CLOu~9BEox{!$KTWx 7@Cgps[dg Ybe bkn=FI(14r{~QZ]'03lux PY\>GJ,58 T]`6?B"%mvy-69x1:=S\_iru"+.PY\¯¸»$'ÈË1:=ĕĞġYbeGPSƬƵƸ for"%u~ȁ(14ɂɋɎ4=@ʒʛʞIRU˴˽(+̂̋̎]fiͻ#&w΀΃#&\ehϧϰϳ ),qz}#,/vт#,/wҀ҃*36ӂӋӎKTWԪԳԶdmp4_֎ֽ !#,1479FKMOTWZ\׀׉זכםןפצש׫״!$+.146=Di؅ؒ؛؞ءأذؽ.U{ٛۺ۽  #&),/258;>ADGJMPSVY\_behknqtwz}܀܃܆܉܌܏ܒܕܘܛܞܡܤܧܪܭܹܼܰܳܶܿ "%(+.147:=@CFILORUX[^adgjmpsvy|݂݈݅݋ݎݑݔݗݚݝݠݣݦݩݬݯݲݵݸݻݾ !$'*-0369<?BEHKNQTWZ]`cfilorux{~ށބއފލސޓޖޙޜޟޡުޭ"%HQTz߃߆ߤ߭߰(14U^a*36y&/2Zcf*36PY\{7@Cfor#&=FIenq(14OX[y%.1KTWJSVx&)R[^v#&NWZs|"CLOiru"JSV ENQu~9BEv 5>Aktw$-0Ybe&/2W`c MVY"%FORz5>A!dmpGPS(+ajm4=@{V_b)25lux(14dmp<EHT]`%(gps4=@/8;&)`ilT]`4=@FOR9BE?HKCLOOX[    e n q       _ h k    2 ; >       P Y \       I R U      :CF,58}&)u~1:=T]` `il"%}>GJ"+.mvy #jsv OX[  W`c Ybe t}5>ALUXs| "%(+.0[ #&)+?HMPSUbgjmruxz        ! 2 5 8 ; >             !!(!1!4!7!9!F!S!V!Y!\!_!b!e!r!u!x!z!|!~!!!!!""1"V"_$$!$$$'$*$-$0$3$6$9$<$?$B$E$H$K$N$Q$T$W$Z$]$`$c$f$i$l$o$r$u$x${$~$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%% %%%%%%% %#%&%)%,%/%2%5%8%;%>%A%D%G%J%M%P%S%V%Y%\%_%b%e%h%k%n%q%t%w%z%}%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&&& & &&&&&&&"&%&(&+&.&1&4&7&:&=&@&C&F&I&L&O&R&U&X&[&^&a&d&g&j&m&p&s&v&y&|&&&&&&&&&&&&&&&&&&&&&&&&&&' '''2';'>'a'j'm'''''''''( (((A(J(M(n(w(z(((((())))T)])`)))))))***0*9*<*`*i*l********+++(+++J+S+V+t+}+++++++, ,,,?,H,K,h,q,t,,,,,,,,,- ---=-F-I-q-z-}---------..&.).G.P.S.r.{.~........./#/,///Q/Z/]/}////////00%0(0J0S0V0l0u0x0000000001 11131<1?1g1p1s111111111222"2<2E2H2d2m2p22222222233&3)3L3U3X3x33333333444474@4C4t4}4444444555!5D5M5P5y555555556 666>6G6J6u6~66666667 777<7E7H7n7w7z777777828;8>8h8q8t8888888889999D9M9P9q9z9}999999:: ::0:9:<:`:i:l:::;;;;T;];`;;;;<<6>?>B>}>>>>>?!?*?-?k?t?w???@@ @ @J@S@V@@@@@@A A)A,AeAnAqAAAABBBIBRBUBBBBBBC7C@CCCCCCCCD%D.D1DDDDDDEEEEMEVEYEEEEEEF/F8F;F{FFFFFGGGGfGoGrGGGH&H/H2HqHzH}HHHI*I3I6IIIIIIJLJUJXJJJJKK KbKkKnKKKLL$L'LLLLLLMIMRMUMMMNNN NxNNNNNO*O3O6OOOOOOPRP[P^PPPQ@QIQLQQQRR RR_RhRkRRRSSSSnSwSzSSST!T*T-T{TTTTTU-U6U9UUUUUUVBVKVNVVVWW!W$W{WWWWWXVX_XbXXXYYYYpYyY|YYYZZZZUZ^ZaZZZZZZ[["[%[j[s[v[[[\\%\(\o\x\{\\\]]%](]p]y]|]]]^#^,^/^{^^^^^_D_M_P____`` `]`f`i``````aaaa>aGaHaJaWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbJbMbPbSbVbYb\b_bbbebhbkbnbqbtbwbzb}bbbbbbbbbbbbbbbbbbbbbbbbbbccPc]c_cacdccccccd ddddQd^d`dbdeddddddeeee e<eIeKeMePeeeeeffffffSf`fbfdfgfffffg)g6g8g:g=ggggggggghhXhehghihlhhhhhiiiiiioi|i~iiiiiiij j-j/j1j4joj|j~jjjjjjjk5kBkDkFkIkkkkkklll l lelrltlvlylllllm)m6m8m:m=mmmmmmmmmmn0n=n?nAnDnnnnnnnnnnnnnnoo+oSo\oiosooooooooooooooop#p,p6p=pJpSpVpYp\p_phpkpnpppspupppppqq qq!q#q%q'q)q2q5q8q:q=q?qHqRq_qhqkqnqqqtq}qqqqqqqqrr rrr,r5r8r;r>rArJrMrPrRrUrWr`rjrwrrrrrrrrrrrrrrss#s1s>sGsJsMsPsSs\s_sbsdsgsisssssstt ttttt"t%t(t*t-t/tJtqtttttttttttttttttuu?uMuuu~uuuuuuuuuuuuuuuuuuuuuuvv v vvvvv+v7vDvMvPvSvVvYvbvevhvjvmvovxvvvvvvvvvvvvvvvvvvvvvvww wwwwww3wZwhwwwwwwwwwwwwwwwwwwxxx x xxxxx!x$x&x/x<xGxTx]x_xaxcxexnxqxtxvxyx{xxxxxxxxxxxxxxxxxxxxyyyyyyyyyy&y3y@yMyVyXyZy\y^ygyjymyoyryty}yyyyyyyyyyyyyyyyyyyyyyzzzzz zz z*z7z@zBzDzFzHzQzTzWzYz\z^zgzqz{zzzzzzzzzzzzzzzzzzzzzzzzz{{{ {{ {-{6{9{<{?{B{K{N{Q{S{V{X{s{{{{{{{||| ||||| |"|%|'|0|:|G|P|S|V|Y|\|e|h|k|m|p|r|{||||||||||||||||||||||}}}} } }}!},}9}B}D}F}H}J}S}V}Y}[}^}`}i}v}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~9~<~?~B~E~H~K~N~Q~T~W~Z~]~`~{~~~~~~~~~~~~~~~~~~~~~~~6CEGJ "%Zgikn5BDFI~!$Yfiloqs"%'<OY\^_ber),/246CFILOQmvy|~ $'*,ADFGJM   58:;>ANQ^adgikx{~    #%.;FSVY\_ao|4I^v !$q~#0247#&)+4=JORUZ]`bkt}#.147:=?LSVY\cfiln  #&-0368ACLY`cfipsvxz=@MZ]`cfily|~(1:BKNW^c|~'WorkspaceSettings.xcsettings000066400000000000000000000005151353477307700367100ustar00rootroot00000000000000jsusfx-0.4.0/max/jsusfx~.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatad HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges SnapshotAutomaticallyBeforeSignificantChanges jsusfx-0.4.0/max/jsusfx~.xcodeproj/xcuserdata/000077500000000000000000000000001353477307700215215ustar00rootroot00000000000000jsusfx-0.4.0/max/jsusfx~.xcodeproj/xcuserdata/asb2m10.xcuserdatad/000077500000000000000000000000001353477307700251745ustar00rootroot00000000000000jsusfx-0.4.0/max/jsusfx~.xcodeproj/xcuserdata/asb2m10.xcuserdatad/xcdebugger/000077500000000000000000000000001353477307700273135ustar00rootroot00000000000000jsusfx-0.4.0/max/jsusfx~.xcodeproj/xcuserdata/asb2m10.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist000066400000000000000000000001331353477307700337020ustar00rootroot00000000000000 jsusfx-0.4.0/max/jsusfx~.xcodeproj/xcuserdata/asb2m10.xcuserdatad/xcschemes/000077500000000000000000000000001353477307700271565ustar00rootroot00000000000000jsusfx-0.4.0/max/jsusfx~.xcodeproj/xcuserdata/asb2m10.xcuserdatad/xcschemes/max-external.xcscheme000066400000000000000000000040051353477307700333030ustar00rootroot00000000000000 jsusfx-0.4.0/max/jsusfx~.xcodeproj/xcuserdata/asb2m10.xcuserdatad/xcschemes/xcschememanagement.plist000066400000000000000000000007441353477307700340740ustar00rootroot00000000000000 SchemeUserState max-external.xcscheme orderHint 0 SuppressBuildableAutocreation 2FBBEAD608F335360078DB84 primary jsusfx-0.4.0/max/maxmspsdk.xcconfig000066400000000000000000000053511353477307700173770ustar00rootroot00000000000000// Xcode target configuration settings for the Max 6 SDK // Used as the basis for Xcode projects to build Max externals. // // Changes to the settings in this file will be applied to all SDK examples // To change settings for only one of the examples, override the settings using // Xcode's target inspector. // // by Timothy Place // Copyright © 2012, Cycling '74 // Name & Version PRODUCT_NAME = $(PROJECT_NAME) PRODUCT_VERSION = 6.1.4 ARCHS = i386 x86_64 // Paths C74SUPPORT = $(SRCROOT)/../../MaxSDK-6.1.4/c74support HEADER_SEARCH_PATHS = "$(C74SUPPORT)/max-includes" "$(C74SUPPORT)/msp-includes" "$(C74SUPPORT)/jit-includes" FRAMEWORK_SEARCH_PATHS = "$(C74SUPPORT)/max-includes" "$(C74SUPPORT)/msp-includes" "$(C74SUPPORT)/jit-includes" DSTROOT = $(SRCROOT) // (This next path is relative to DSTROOT) INSTALL_PATH = / // Special Files GCC_PREFIX_HEADER = $(C74SUPPORT)/max-includes/macho-prefix.pch INFOPLIST_FILE = $(SRCROOT)/Info.plist // Architecture and Deployment ARCHS = i386 x86_64 // The following section sets the Mac SDK version to be used. // For most projects this has little to no impact because there are no direct dependencies on OS function calls. // In those projects with OS function calls, it should be okay to use the most recent SDK version because the // MACOSX_DEPLOYMENT_TARGET will disable functionality that is unavailable in the older target OS. // For this reason, the SDKROOT variable is commented out, telling Xcode to use the default (which is the most recent SDK). // // If you do need to define the SDKROOT, different versions of Xcode have varying syntax and varying versions of the SDK present. // Xcode 3.x // SDKROOT = $(DEVELOPER_DIR)/SDKs/MacOSX10.5.sdk // Xcode 4.0 - Xcode 4.2 // SDKROOT = $(DEVELOPER_DIR)/SDKs/MacOSX10.6.sdk // Xcode 4.3+ // SDKROOT = macosx10.6 MACOSX_DEPLOYMENT_TARGET = 10.6 // Compiler Version -- leave them all commented out to get the default version provided by Xcode // GCC_VERSION = 4.2 // GCC_VERSION = com.apple.compilers.llvmgcc42 // GCC_VERSION = com.apple.compilers.llvm.clang.1_0 // Preprocessor Defines GCC_PREPROCESSOR_DEFINITIONS = "DENORM_WANT_FIX = 1" "NO_TRANSLATION_SUPPORT = 1" "WDL_FFT_REALSIZE = 8" "EEL_TARGET_PORTABLE" // Static Configuration (don't change these) WRAPPER_EXTENSION = mxo; WARNING_CFLAGS = -Wmost -Wno-four-char-constants -Wno-unknown-pragmas DEPLOYMENT_LOCATION = YES GENERATE_PKGINFO_FILE = YES // Flags to enforce some build-time checks for the symbols used while not actually performing a hard link C74_SYM_LINKER_FLAGS = @$(C74SUPPORT)/max-includes/c74_linker_flags.txt // hide all symbols by default // mark a function to be exported with the C74_EXPORT macro -- most likely this will only apply to the main() function OTHER_CFLAGS = -fvisibility=hidden jsusfx-0.4.0/pd/000077500000000000000000000000001353477307700134605ustar00rootroot00000000000000jsusfx-0.4.0/pd/CMakeLists.txt000066400000000000000000000031711353477307700162220ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.7) project (jsusfx_pd) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_SUPPRESS_REGENERATION true) set(CMAKE_MACOSX_RPATH Off) #set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7) set(CMAKE_OSX_ARCHITECTURES "i386;x86_64") add_subdirectory(${PROJECT_SOURCE_DIR}/../src ${PROJECT_SOURCE_DIR}/../src) include(pd.build/pd.cmake) include_directories(${PROJECT_SOURCE_DIR}/../src) if (WIN32) set_pd_sources(C:/Apps/pd/src) else() set_pd_sources(/Applications/Pd.app/Contents/Resources/src/) endif() set_pd_external_path(${PROJECT_SOURCE_DIR}) add_pd_external(jsusfx_pd_project jsusfx~ jsusfx_pd.cpp) target_link_libraries(jsusfx_pd_project jsusfx) # === Installation stuff === set(DIST ${PROJECT_SOURCE_DIR}/dist) file(GLOB JSSCRIPT "${PROJECT_SOURCE_DIR}/../scripts/liteon/*.jsfx") foreach(script ${JSSCRIPT}) install(FILES ${script} DESTINATION ${DIST}/externals) install(CODE "execute_process(COMMAND python ${PROJECT_SOURCE_DIR}/jsfx2abstract.py ${script} WORKING_DIRECTORY ${DIST}/externals)" ) endforeach() install(TARGETS jsusfx_pd_project DESTINATION ${DIST}/externals) file(GLOB PDHELP "${PROJECT_SOURCE_DIR}/*-help.pd") install(FILES ${PDHELP} DESTINATION ${DIST}/externals) if (UNIX AND APPLE) install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ./jsusfx~.pd_darwin ${DIST}/externals/jsusfx~.pd_darwin)") else() install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ./jsusfx~.pd_linux ${DIST}/externals/jsusfx~.pd_linux)") endif() install(FILES ${PROJECT_SOURCE_DIR}/jsfx2abstract.py DESTINATION ${DIST}) install(FILES ${PROJECT_SOURCE_DIR}/README.md DESTINATION ${DIST}) jsusfx-0.4.0/pd/README.md000066400000000000000000000054451353477307700147470ustar00rootroot00000000000000jsusfx_pd - Jesusonic FX for Pure Data ====================================== The jsusfx implementation is done through 2 externals called `jsfx~` and `jsusfx~`. jsfx~ ----- `jsfx~` is the runtime object to expose JSFX scripts in pure-data. It expect as object creation argument the script to use that should be in the pd path. Upon object creation, each of the sliders will be exposed as an inlet. Any midi message generated from the script will be sent with the last outlet. * To change a slider, send message `[slider <0..1 value>(`; the values are normalized from 0 to 1 * For un-normalized values, send message `[uslider (` * Use `[midi (` to send midi data to script * Use `[describe(` to output the associated sliders * Use `[dumpvars(` to dump the current variables values * Use `[bypass 0/1(` to bypass the effect jsusfx~ ------- `jsusfx~` is used for script development and can switch script with the command compile. All the slider parameter are read trought the slider message. At object creation, you can also put the number of inlet/outlet the script is expected to use. If you don't specify it, it will count the number of time in_pin and out_pin is used. Any midi message generated from the script will be sent with the last outlet. * To change a slider, send message `[slider <0..1 value>(`; the values are normalized from 0 to 1 * For un-normalized values, send message `[uslider (` * Use `[midi (` to send midi data to script * Use `[compile(` message to recompile your script. Optionally you can specify a new script to compile * Use `[describe(` to output the associated sliders * Use `[dumpvars(` to dump the current variables values * Use `[bypass 0/1(` to bypass the effect Version 0.4 ----------- * PD Loader support * Multi-channel support * Native ARM support (Raspberry Pi) * Windows build support * File API support * @import support * Midi in/out support * Subpatch wrapper generator (see jsfx2abstract.py) * More support of extended sliders * Various bug fixes * CMake now global build system Subpatch generator ------------------ Since jsusfx_pd doesn't support pd_loader, a Python script can be use to generate a patch based on the content of a JSFX script. This patch can then be used as an abstraction wrapper to ease the integration. To run the script, run the command below. Once it is done, it should generate a .pd file with same name as the script. ``` $ python jsfx2abstract.py ``` Limitations ----------- * @gfx, @serialize section is ignored Building -------- * cmake is required to build the external * php and nasm is required to build native x86_64 support code ``` $ git clone --recurse-submodules https://github.com/asb2m10/jsusfx.git $ cd jsusfx/pd $ cmake . $ make install ``` jsusfx-0.4.0/pd/gain.jsfx000066400000000000000000000002571353477307700152760ustar00rootroot00000000000000desc:gain testing out_pin:sig1 out_pin:sig2 out_pin:sig3 slider1:1<0,5,0.01>GAINL slider2:1<0,5,0.01>GAINR @init gg=0 @sample spl0=spl0*slider1; spl2=spl1*slider2; spl1=0jsusfx-0.4.0/pd/jsfx2abstract.py000066400000000000000000000130511353477307700166120ustar00rootroot00000000000000""" * Copyright 2018 Pascal Gauthier * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * *distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. """ import os; import os.path; import sys; import datetime; class Patch : def __init__(self, scriptName) : self.items = [] print("Processing %s" % os.path.abspath(scriptName)) filename = scriptName.split(".")[0] self.fd = open("%s.pd" % filename, "w") self.fd.write("#N canvas 50 50 605 405 10;\r\n") def add(self, x, y, obj) : self.items.append(obj) self.fd.write("#X obj %d %d %s;\r\n" % (x, y, obj.args)) obj.objnum = len(self.items) def addText(self, x, y, msg) : self.items.append(None) self.fd.write("#X text %d %d %s;\r\n" % (x, y, msg)) def addMsg(self, x, y, msg) : self.items.append(msg) self.fd.write("#X msg %d %d %s;\r\n" % (x, y, msg.args)) def connect(self, source, outlet, dest, inlet) : srcId = self.items.index(source); destId = self.items.index(dest); self.fd.write("#X connect %d %d %d %d;\r\n" % (srcId, outlet, destId, inlet)); def close(self) : self.fd.close(); class PdObj : def __init__(self, args) : self.args = args; class PdMsg : def __init__(self, args) : self.args = args; def makeSlider(name, mn, mx, default, id) : name = name.replace(" ", "_"); if name == "" : name = "undefined"; obj = PdObj("hsl 128 15 %d %d 0 1 empty empty %s -2 -6 0 8 -262144 -1 -1 %d 1" % (mn, mx, name, default)); obj.id = id return obj def makeRadio(name, step, default, id) : name = name.replace(" ", "_") if name == "" : name = "undefined" obj = PdObj("hradio 15 1 0 %d empty empty %s 0 -8 0 8 -262144 -1 -1 %d" % (step, name, default)); obj.id = id return obj if __name__ == "__main__" : if len(sys.argv) < 2 : print("Missing jsfx file"); sys.exit(1); script = os.path.basename(sys.argv[1]); patch = Patch(script); sliders = []; desc = ""; pinIns = []; pinOuts = []; extraSliders = []; for i in open(sys.argv[1], "r").readlines() : if i[0] == '@': break if i.startswith("slider") : slider = i.split(":"); id = int(slider[0][6:]); if len(slider[1].split(">")) > 1 : name = slider[1].split(">")[1].rstrip("\r\n"); else : name = "undefined"; sliderRange = slider[1].split("<")[1].split(">")[0].split(","); try: default = slider[1].split("<")[0] if '=' in default : default = float(default.split("=")[1]); else : default = float(default); except : default = float(sliderRange[0]); if len(sliderRange) > 2 : stepper = sliderRange[2]; if '{' in stepper : stepper = stepper.split("{")[0]; try : stepper = float(stepper); except : stepper = -1; else : stepper = -1; mn = float(sliderRange[0]); mx = float(sliderRange[1]); if stepper == 1 and mn == 0 and mx <= 8 : sliders.append(makeRadio(name, mx+1, int(default), id)) else : steps = 127.0 / (-mn + mx); default = (default + -mn) * steps * 100; sliders.append(makeSlider(name, mn, mx, int(default), id)); elif i.startswith("desc") : patch.addText(10, 5, "JSFX:%s" % i[5:].rstrip("\r\n")); elif i.startswith("in_pin") : if pinIns != None : pinIns.append(i[8:]); elif i.startswith("in_pin:none") : pinIns = None; elif i.startswith("out_pin") : if pinOuts != None : pinOuts.append(i[9:]); elif i.startswith("out_pin:none") : pinOuts = None; patch.addText(10, 20, "Generated from jsfx2abstract.py on %s" % datetime.date.today()) patch.addText(10, 35, "================================================") sliderX = -137; sliderY = 80; if pinIns == None : pinIns = []; elif len(pinIns) == 0 : pinIns.append("input_l"); pinIns.append("input_r"); if pinOuts == None : pinOuts = []; elif len(pinOuts) == 0 : pinOuts.append("output_l"); pinOuts.append("output_r"); for idx, val in enumerate(sliders) : if sliderX > 450 : sliderY += 50; sliderX = 13; else : sliderX += 150; patch.add(sliderX, sliderY, val); # PD has a limitation of 17 inlet, we have to "front" the other ones... if idx + len(pinIns) > 17 : msg = PdMsg("uslider %d \\$1" % val.id); patch.addMsg(sliderX, sliderY + 17, msg); extraSliders.append(msg); fxobj = PdObj("jsfx~ %s" % script); patch.add(30, sliderY + 65, fxobj); inlets = []; for i in range(len(pinIns)) : dspInlet = PdObj("inlet~"); inlets.append(dspInlet); patch.add(30, sliderY + 42, dspInlet); midiin = PdObj("inlet"); patch.add(80, sliderY + 42, midiin); outlets = [] for i in range(len(pinOuts)) : dspOutlet = PdObj("outlet~"); outlets.append(dspOutlet); patch.add(30, sliderY + 88, dspOutlet); midiout = PdObj("outlet") patch.add(80, sliderY + 88, midiout) patch.connect(midiin, 0, fxobj, 0) patch.connect(fxobj, len(outlets), midiout, 0) extraIdx = 0; for idx, i in enumerate(sliders) : if idx+len(pinIns) > 17 : patch.connect(i, 0, extraSliders[extraIdx], 0); patch.connect(extraSliders[extraIdx], 0, fxobj, 0); extraIdx += 1; else : patch.connect(i, 0, fxobj, len(pinOuts) + idx); for i in inlets : patch.connect(i, 0, fxobj, inlets.index(i)); for i in outlets : patch.connect(fxobj, outlets.index(i), i, 0); patch.close(); jsusfx-0.4.0/pd/jsfx~-help.pd000066400000000000000000000033521353477307700161060ustar00rootroot00000000000000#N canvas 636 177 653 554 10; #X obj 25 381 dac~; #X msg 52 141 describe; #X msg 78 169 dumpvars; #X msg 27 113 bypass \$1; #X text 118 141 describe outputs the assigned slider to the pd console ; #X text 144 170 dumpvars output all the variable output to the pd console ; #X obj 25 347 jsfx~ moog24db; #X text 103 113 bypass is used to mute the fx processing; #X text 121 341 Specify the script to load. The sliders are maps to inlets (the first inlets are DSP inlets); #N canvas 745 75 450 300 test_tones 0; #X obj 52 246 outlet~; #X obj 53 184 phasor~; #X obj 55 125 *~ 110; #X obj 54 154 +~ 220; #X obj 54 89 phasor~ 0.1; #X obj 53 213 *~ 0.25; #X connect 1 0 5 0; #X connect 2 0 3 0; #X connect 3 0 1 0; #X connect 4 0 2 0; #X connect 5 0 0 0; #X restore 84 200 pd test_tones; #X obj 149 280 hsl 128 15 0 100 0 1 empty empty Cutoff_(Scale) -2 -6 0 8 -262144 -1 -1 7800 1; #X obj 299 280 hsl 128 15 0 0 0 1 empty empty Res_(Min/Max) -2 -6 0 8 -262144 -1 -1 10600 1; #X obj 27 82 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1 ; #X text 121 390 The last inlet is used if the script is sending midi messages; #X obj 106 424 midiout; #X obj 86 240 midiin; #X text 10 10 jsfx~ : is the runtime object to expose JSFX scripts in pure-data. All slider will be exposed as inlets ============================================================see: https://github.com/asb2m10/jsusfx; #X text 134 231 midi message with float or list sent to first inlet is considered as midi data; #X msg 86 264 midi \$1; #X connect 1 0 6 0; #X connect 2 0 6 0; #X connect 3 0 6 0; #X connect 6 0 0 0; #X connect 6 1 0 1; #X connect 6 2 14 0; #X connect 9 0 6 0; #X connect 9 0 6 1; #X connect 10 0 6 4; #X connect 11 0 6 5; #X connect 12 0 3 0; #X connect 15 0 18 0; #X connect 18 0 6 0; jsusfx-0.4.0/pd/jsusfx_pd.cpp000066400000000000000000000446771353477307700162130ustar00rootroot00000000000000/* * Copyright 2014-2019 Pascal Gauthier * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * *distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "WDL/mutex.h" #include "jsusfx.h" extern "C" { #ifdef __linux__ #include "pd/m_pd.h" #include "pd/s_stuff.h" #else #include "m_pd.h" #include "s_stuff.h" #endif } #define REAPER_GET_INTERFACE(opaque) ((opaque) ? ((JsusFxPd*)opaque) : nullptr) using namespace std; // The maximum of signal inlet/outlet; PD seems to have a limitation to 18 inlets ... const int MAX_SIGNAL_PORT = 8; class JsusFxPdPath : public JsusFxPathLibrary_Basic { public: JsusFxPdPath(const char * _dataRoot) : JsusFxPathLibrary_Basic(_dataRoot) { } bool resolveImportPath(const string &importPath, const string &parentPath, string &resolvedPath) { const size_t pos = parentPath.rfind('/', '\\'); if ( pos != string::npos ) resolvedPath = parentPath.substr(0, pos + 1); if ( fileExists(resolvedPath + importPath) ) { resolvedPath = resolvedPath + importPath; return true; } string searchDir; // check if the import parentPath is a script and remove the extension (if needed) // usually the directory should contain the import script const size_t dotPos = parentPath.rfind("."); if ( dotPos != string::npos && dotPos > pos ) { searchDir = parentPath.substr(0, dotPos); } else { searchDir = dataRoot; } char result[1024]; char *bufptr; int fd = open_via_path(searchDir.c_str(), importPath.c_str(), "", result, &bufptr, 1023, 1); if ( fd < 0 || result[0] == 0 ) { return false; } sys_close(fd); resolvedPath = result; resolvedPath += '/'; resolvedPath += importPath; return true; } bool resolveDataPath(const string &importPath, string &resolvedPath) { char result[1024]; char *bufptr; int fd = open_via_path(dataRoot.c_str(), importPath.c_str(), "", result, &bufptr, 1023, 1); if ( fd < 0 || result[0] == 0 ) { return false; } sys_close(fd); resolvedPath = result; resolvedPath += '/'; resolvedPath += importPath; return true; } }; static EEL_F NSEEL_CGEN_CALL midisend(void *opaque, INT_PTR np, EEL_F **parms); class JsusFxPd : public JsusFx { public: static const int kMidiBufferSize = 4096; uint8_t midiHead[kMidiBufferSize]; uint8_t midiPreStream[4]; int midiPre = 0, midiExpt = 0; uint8_t midiOutBuffer[kMidiBufferSize]; int midiOutSize = 0; // this is used to indicate if dsp is on (and midi parsing should be done) bool dspOn; WDL_Mutex dspLock; JsusFxPd(JsusFxPathLibrary &pathLibrary) : JsusFx(pathLibrary) { midi = &midiHead[0]; NSEEL_addfunc_varparm("midisend",3,NSEEL_PProc_THIS,&midisend); } ~JsusFxPd() { } // we pre-stream the byte messages since it might come in between dsp cycles void midiin(uint8_t b) { // midi is read in the dsp thread. Do accumulate stuff if you don't read it if ( ! dspOn ) return; // in sysex stream, ignore everything if ( midiExpt == -1) { if ( b == 0xf0 ) { midiExpt = 0; return; } } // nothing is expected; new midi message if ( midiExpt == 0 ) { if ((b & 0xf0) == 0xf0) { midiExpt = -1; return; } midiPre = 1; midiPreStream[0] = b; switch(b & 0xf0) { case 0xc0: case 0xd0: midiExpt = 2; break; default: midiExpt = 3; } return; } midiPreStream[midiPre++] = b; if ( midiPre >= midiExpt) { if ( midiSize + midiExpt >= kMidiBufferSize ) { post("jsusfx~: midi buffer full"); dspOn = false; return; } for(int i=0;imidiOutSize + 3 ) { return 1; } ctx->midiOutBuffer[ctx->midiOutSize++] = *parms[1]; if ( np >= 4 ) { ctx->midiOutBuffer[ctx->midiOutSize++] = *parms[2]; ctx->midiOutBuffer[ctx->midiOutSize++] = *parms[3]; } else { int v = *parms[2]; ctx->midiOutBuffer[ctx->midiOutSize++] = v % 256; ctx->midiOutBuffer[ctx->midiOutSize++] = v / 256; } return 0; } typedef struct _jsusfx { t_object x_obj; t_float x_f; JsusFxPd *fx; JsusFxPdPath *path; char scriptpath[1024]; t_clock *x_clock; bool bypass; bool user_bypass; int pinIn, pinOut; t_int **dspVect; t_outlet *midiout; } t_jsusfx; static t_class *jsusfx_class; static t_class *jsfx_class; static t_class *slider_proxy; typedef struct _inlet_proxy { t_object x_obj; t_jsusfx *peer; int idx; } t_inlet_proxy; string getFileName(const string &s) { char sep = '/'; size_t i = s.rfind(sep, s.length()); if (i != string::npos) { return s.substr(i+1, s.length() - i); } return s; } void jsusfx_describe(t_jsusfx *x) { post("jsusfx~ script %s : %s", x->scriptpath, x->fx->desc); for(int i=0;i<64;i++) { if ( x->fx->sliders[i].exists ) { JsusFx_Slider *s = &(x->fx->sliders[i]); if ( s->inc == 0 ) post(" slider%d: %g %g %s [%g]", i, s->min, s->max, s->desc, *(s->owner)); else post(" slider%d: %g %g (%g) %s [%g]", i, s->min, s->max, s->inc, s->desc, *(s->owner)); } } } void jsusfx_dumpvars(t_jsusfx *x) { post("jsusfx~ vars for: %s =========", x->fx->desc); if ( x->fx != NULL ) x->fx->dumpvars(); } void jsusfx_compile(t_jsusfx *x, t_symbol *newFile) { x->bypass = true; string filename = string(newFile->s_name); if ( newFile != NULL && newFile->s_name[0] != 0) { string result; // find if the file exists with the .jsfx suffix if ( ! x->path->resolveDataPath(string(filename), result) ) { // maybe it isn't specified, try with the .jsfx filename += ".jsfx"; if ( ! x->path->resolveDataPath(string(filename), result) ) { error("jsusfx~: unable to find script %s", newFile->s_name); return; } } strncpy(x->scriptpath, filename.c_str(), 1023); } else { if ( x->scriptpath[0] == 0 ) return; } x->fx->dspLock.Enter(); if ( x->fx->compile(*(x->path), x->scriptpath, 0) ) { if ( x->fx->srate != 0 ) x->fx->prepare(*(x->fx->srate), *(x->fx->samplesblock)); x->bypass = false; } else { x->bypass = true; } x->fx->dspLock.Leave(); } void jsusfx_slider(t_jsusfx *x, t_float id, t_float value) { int i = (int) id; if ( i > 64 || i < 0 ) return; if ( ! x->fx->sliders[i].exists ) { error("jsusfx~: slider number %d is not assigned for this effect", i); return; } x->fx->moveSlider(i, value, 1); } void jsusfx_uslider(t_jsusfx *x, t_float id, t_float value) { int i = (int) id; if ( i > 64 || i < 0 ) return; if ( ! x->fx->sliders[i].exists ) { error("jsusfx~: slider number %d is not assigned for this effect", i); return; } x->fx->moveSlider(i, value, 0); } void jsusfx_bypass(t_jsusfx *x, t_float id) { x->user_bypass = id != 0; } t_int *jsusfx_perform(t_int *w) { const float *ins[MAX_SIGNAL_PORT]; float *outs[MAX_SIGNAL_PORT]; int argc = 2; t_jsusfx *x = (t_jsusfx *)(w[1]); for(int i=0;ipinIn;i++) ins[i] = (float *)(w[argc++]); for(int i=0;ipinOut;i++) outs[i] = (float *)(w[argc++]); int n = (int)(w[argc++]); if ( (x->bypass || x->user_bypass) || x->fx->dspLock.TryEnter() ) { //x->fx->displayMsg("system is bypassed"); if ( x->pinIn == x->pinOut ) { for(int i=0;ipinOut;i++) { for(int j=0;jpinOut;i++) { for(int j=0;jfx->process(ins, outs, n, x->pinIn, x->pinOut); x->fx->dspLock.Leave(); } if ( x->fx->midiOutSize != 0 ) clock_delay(x->x_clock, 0); x->fx->flushMidi(); return (w+argc); } void jsusfx_dsp(t_jsusfx *x, t_signal **sp) { x->fx->prepare(sp[0]->s_sr, sp[0]->s_n); x->dspVect[0] = (t_int *) x; int i, j; for (i=0; ipinIn; i++) { x->dspVect[i+1] = (t_int*)sp[i]->s_vec; //post("jsusfx~ dsp-vecin: %x", x->dspVect[i+1]); } for (j=0;jpinOut; j++) { x->dspVect[i+j+1] = (t_int*)sp[i+j]->s_vec; //post("jsusfx~ dsp-vecout: %x", x->dspVect[i+j+1]); } x->dspVect[i+j+1] = (t_int *) ((long)sp[0]->s_n); x->fx->dspOn = true; dsp_addv(jsusfx_perform, x->pinIn + x->pinOut + 2, (t_int*)x->dspVect); } static void jsusfx_midiout(t_jsusfx *x) { if ( x->fx->midiOutSize >= JsusFxPd::kMidiBufferSize ) { post("jsusfx~: midiout buffer full"); } else { for(int i=0;ifx->midiOutSize;i++) { outlet_float(x->midiout, x->fx->midiOutBuffer[i]); } } x->fx->midiOutSize = 0; } void *jsusfx_new(t_symbol *notused, long argc, t_atom *argv) { t_jsusfx *x = (t_jsusfx *)pd_new(jsusfx_class); x->path = new JsusFxPdPath(canvas_getcurrentdir()->s_name); x->bypass = true; x->user_bypass = false; x->scriptpath[0] = 0; x->fx = new JsusFxPd(*(x->path)); x->x_clock = clock_new(x, (t_method)jsusfx_midiout); x->pinIn = 2; x->pinOut = 2; if ( argc < 1 ) { post("jsusfx~: missing script"); x->scriptpath[0] = 0; } else { int argPos = 0; if ( (argv[0]).a_type == A_SYMBOL ) { t_symbol *s = atom_getsymbol(argv); jsusfx_compile(x, s); if (! x->bypass) { jsusfx_describe(x); // the first compile will permantly set the number of pins for this instance. (unless it is // specified in the pd object arguments) x->pinIn = x->fx->numInputs; x->pinOut = x->fx->numOutputs; } argPos++; } if ( argc > argPos ) { if ( (argv[argPos]).a_type == A_FLOAT ) x->pinIn = atom_getfloat(&argv[argPos]); } argPos++; if ( argc > argPos ) { if ( (argv[argPos]).a_type == A_FLOAT ) x->pinOut = atom_getfloat(&argv[argPos]); } } if ( x->pinIn > MAX_SIGNAL_PORT ) x->pinIn = MAX_SIGNAL_PORT; // we cannot set an object without signal inlet since it is created by default // There is probably a better to do this. if ( x->pinIn < 1 ) x->pinIn = 1; if ( x->pinOut > MAX_SIGNAL_PORT ) x->pinOut = MAX_SIGNAL_PORT; if ( x->pinOut < 0 ) x->pinOut = 0; for(int i=1;ipinIn;i++) signalinlet_new(&x->x_obj, 0); for(int i=0;ipinOut;i++) outlet_new(&x->x_obj, gensym("signal")); x->dspVect = (t_int **)t_getbytes(sizeof(t_int *) * (x->pinIn + x->pinOut + 2)); x->midiout = outlet_new(&x->x_obj, &s_float); return (x); } void jsusfx_free(t_jsusfx *x) { clock_free(x->x_clock); t_freebytes(x->dspVect, sizeof(t_int) * (x->pinIn + x->pinOut + 2)); delete x->fx; delete x->path; } void *jsfx_new(t_symbol *objectname, long argc, t_atom *argv) { t_symbol *script = NULL; if ( argc < 1 ) { if ( gensym("jsfx~") != objectname ) { script = objectname; } } else { if ( (argv[0]).a_type == A_SYMBOL ) { script = atom_getsymbol(argv); } } if ( script == NULL || script->s_name[0] == 0) { error("jsfx~: missing script"); return NULL; } t_jsusfx *x = (t_jsusfx *)pd_new(jsusfx_class); x->path = new JsusFxPdPath(canvas_getcurrentdir()->s_name); x->bypass = true; x->user_bypass = false; x->scriptpath[0] = 0; x->fx = new JsusFxPd(*(x->path)); x->x_clock = clock_new(x, (t_method)jsusfx_midiout); x->pinIn = 2; x->pinOut = 2; jsusfx_compile(x, script); if (x->bypass == true) { //something went wrong with the compilation. bailout delete x->fx; delete x->path; return NULL; } if ( x->pinIn > MAX_SIGNAL_PORT ) x->pinIn = MAX_SIGNAL_PORT; if ( x->pinIn < 1 ) x->pinIn = 1; if ( x->pinOut > MAX_SIGNAL_PORT ) x->pinOut = MAX_SIGNAL_PORT; if ( x->pinOut < 0 ) x->pinOut = 0; for(int i=1;ipinIn;i++) signalinlet_new(&x->x_obj, 0); for(int i=0;ipinOut;i++) outlet_new(&x->x_obj, gensym("signal")); x->dspVect = (t_int **)t_getbytes(sizeof(t_int *) * (x->pinIn + x->pinOut + 2)); for(int i=1;i<64;i++) { if ( x->fx->sliders[i].exists ) { t_inlet_proxy *proxy = (t_inlet_proxy *) pd_new(slider_proxy); proxy->idx = i; proxy->peer = x; inlet_new(&x->x_obj, &proxy->x_obj.ob_pd, 0, 0); } } x->midiout = outlet_new(&x->x_obj, &s_float); return (x); } void jsfx_free(t_jsusfx *x) { clock_free(x->x_clock); delete x->fx; delete x->path; // delete also the inlet proxy or it is done automatically ? } static void slider_float(t_inlet_proxy *proxy, t_float f) { proxy->peer->fx->moveSlider(proxy->idx, f, 0); } static void jsusfx_midi(t_jsusfx *x, t_float f) { x->fx->midiin(f); } static void jsusfx_list(t_jsusfx *x, t_symbol *c, int ac, t_atom *av) { for(int i=0;ifx->midiin(atom_getfloat(&(av[i]))); } } static int jsusfx_loader_pathwise(t_canvas *unused, const char *objectname, const char *path) { char dirbuf[MAXPDSTRING]; char *ptr; int fd; if(!path) return 0; fd = sys_trytoopenone(path, objectname, ".jsfx", dirbuf, &ptr, MAXPDSTRING, 1); if (fd>0) { sys_close(fd); class_addcreator((t_newmethod) jsfx_new, gensym(objectname), A_GIMME, 0); return 1; } return 0; } extern "C" { void jsusfx_tilde_setup(void) { t_symbol *midi = gensym("midi"); jsusfx_class = class_new(gensym("jsusfx~"), (t_newmethod)jsusfx_new, (t_method)jsusfx_free, sizeof(t_jsusfx), 0L, A_GIMME, 0); class_addmethod(jsusfx_class, (t_method)jsusfx_dsp, gensym("dsp"), A_CANT, 0); class_addmethod(jsusfx_class, (t_method)jsusfx_slider, gensym("slider"), A_FLOAT, A_FLOAT, 0); class_addmethod(jsusfx_class, (t_method)jsusfx_uslider, gensym("uslider"), A_FLOAT, A_FLOAT, 0); class_addmethod(jsusfx_class, (t_method)jsusfx_compile, gensym("compile"), A_DEFSYMBOL, 0); class_addmethod(jsusfx_class, (t_method)jsusfx_describe, gensym("describe"), A_NULL, 0); class_addmethod(jsusfx_class, (t_method)jsusfx_dumpvars, gensym("dumpvars"), A_NULL, 0); class_addmethod(jsusfx_class, (t_method)jsusfx_bypass, gensym("bypass"), A_FLOAT, 0); class_addmethod(jsusfx_class, (t_method)jsusfx_midi, midi, A_FLOAT, 0); class_addmethod(jsusfx_class, (t_method)jsusfx_list, midi, A_GIMME, 0); class_addlist(jsusfx_class, (t_method)jsusfx_list); CLASS_MAINSIGNALIN(jsusfx_class, t_jsusfx, x_f); jsfx_class = class_new(gensym("jsfx~"), (t_newmethod)jsfx_new, (t_method)jsfx_free, sizeof(t_jsusfx), 0L, A_GIMME, 0); class_addmethod(jsfx_class, (t_method)jsusfx_slider, gensym("slider"), A_FLOAT, A_FLOAT, 0); class_addmethod(jsfx_class, (t_method)jsusfx_uslider, gensym("uslider"), A_FLOAT, A_FLOAT, 0); class_addmethod(jsfx_class, (t_method)jsusfx_dsp, gensym("dsp"), A_CANT, 0); class_addmethod(jsfx_class, (t_method)jsusfx_bypass, gensym("bypass"), A_FLOAT, 0); class_addmethod(jsfx_class, (t_method)jsusfx_describe, gensym("describe"), A_NULL, 0); class_addmethod(jsfx_class, (t_method)jsusfx_dumpvars, gensym("dumpvars"), A_NULL, 0); class_addmethod(jsusfx_class, (t_method)jsusfx_midi, midi, A_FLOAT, 0); class_addmethod(jsusfx_class, (t_method)jsusfx_list, midi, A_GIMME, 0); class_addlist(jsfx_class, (t_method)jsusfx_list); CLASS_MAINSIGNALIN(jsfx_class, t_jsusfx, x_f); slider_proxy = class_new(gensym("slider_proxy"), NULL, NULL, sizeof(t_inlet_proxy), CLASS_PD|CLASS_NOINLET, A_NULL); class_addfloat(slider_proxy, (t_method)slider_float); int maj=0,min=0,bug=0; sys_getversion(&maj,&min,&bug); if((maj==0) && (min>46)) { sys_register_loader((loader_t)jsusfx_loader_pathwise); } JsusFx::init(); } void jsfx_tilde_setup(void) { jsusfx_tilde_setup(); } } jsusfx-0.4.0/pd/jsusfx_test.pd000066400000000000000000000072311353477307700163710ustar00rootroot00000000000000#N canvas 828 179 701 545 10; #X obj 82 449 dac~; #X obj 14 508 hsl 128 15 0 1 0 0 slider2 slider2 slider2 -2 -8 0 10 -262144 -1 -1 0 1; #X obj 15 472 hsl 128 15 0 1 0 0 slider1 slider1 slider1 -2 -8 0 10 -262144 -1 -1 0 1; #X msg 261 249 describe; #X obj 164 472 hsl 128 15 0.011 1 0 0 slider3 slider3 slider3 -2 -8 0 10 -262144 -1 -1 0 1; #X obj 163 508 hsl 128 15 0.011 1 0 0 slider4 slider4 slider4 -2 -8 0 10 -262144 -1 -1 0 1; #X obj 314 473 hsl 128 15 0.011 1 0 0 slider5 slider5 slider5 -2 -8 0 10 -262144 -1 -1 0 1; #N canvas 489 423 644 279 slider_r 0; #X obj 311 245 outlet; #X obj 45 33 r slider1; #X obj 114 34 r slider2; #X obj 180 37 r slider3; #X obj 245 30 r slider4; #X msg 44 87 slider 1 \$1; #X obj 308 37 r slider5; #X msg 307 92 slider 5 \$1; #X msg 242 114 slider 4 \$1; #X msg 180 89 slider 3 \$1; #X msg 111 114 slider 2 \$1; #X obj 382 31 r slider6; #X msg 383 113 slider 6 \$1; #X obj 467 30 r slider7; #X msg 468 91 slider 7 \$1; #X obj 549 33 r slider8; #X msg 549 112 slider 8 \$1; #X connect 1 0 5 0; #X connect 2 0 10 0; #X connect 3 0 9 0; #X connect 4 0 8 0; #X connect 5 0 0 0; #X connect 6 0 7 0; #X connect 7 0 0 0; #X connect 8 0 0 0; #X connect 9 0 0 0; #X connect 10 0 0 0; #X connect 11 0 12 0; #X connect 12 0 0 0; #X connect 13 0 14 0; #X connect 14 0 0 0; #X connect 15 0 16 0; #X connect 16 0 0 0; #X restore 132 294 pd slider_r; #X msg 266 295 dumpvars; #X msg 53 166 compile gain.jsfx; #X obj 315 508 hsl 128 15 0.011 1 0 0 slider6 slider6 slider6 -2 -8 0 10 -262144 -1 -1 0 1; #X obj 463 508 hsl 128 15 0.011 1 0 0 slider8 slider8 slider8 -2 -8 0 10 -262144 -1 -1 0 1; #X msg 73 232 compile octaveup; #X msg 54 203 compile butterworth24db; #X obj 464 473 hsl 128 15 0.011 1 0 0 slider7 slider7 slider7 -2 -8 0 10 -262144 -1 -1 0 1; #X obj 229 339 s jsfxmsg; #X obj 137 323 r jsfxmsg; #X msg 229 214 bypass \$1; #X obj 229 174 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X text 309 216 bypass is used to bypass the fx processing; #X text 10 10 jsusfx~ : Jesusonic for pure-data ============================================================ ; #X text 126 110 Use compile to recompile (or change) the current script. Optionally \, you can specify another jsfx script.; #X text 9 44 jsusfx~ takes as an argument the jsfx script to load. The file will be searched in the pd path.; #X text 277 272 describe outputs the assigned slider to the pd console ; #X text 277 319 dumpvars output all the variable output to the pd console ; #X text 193 411 slider is used to change the value of a parameter of the jsfx script.; #X obj 22 365 jsusfx~ gain.jsfx; #X obj 54 98 openpanel; #X obj 55 73 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 46 142 compile \$1; #N canvas 746 75 450 300 test_tones 0; #X obj 52 246 outlet~; #X obj 53 184 phasor~; #X obj 55 125 *~ 110; #X obj 54 154 +~ 220; #X obj 54 89 phasor~ 0.1; #X obj 53 213 *~ 0.25; #X obj 175 131 readsf~; #X msg 170 70 open ~/Desktop/menage/vinyls/broker-dealer/tracky1-2.wav ; #X msg 211 101 1; #X msg 180 33 open ~/Desktop/menage/vinyls/broker-dealer/01-broker_dealer-110704_0012.wav ; #X connect 1 0 5 0; #X connect 2 0 3 0; #X connect 3 0 1 0; #X connect 4 0 2 0; #X connect 6 0 0 0; #X connect 7 0 6 0; #X connect 8 0 6 0; #X connect 9 0 6 0; #X restore 86 258 pd test_tones; #X obj 42 410 tilteq; #X connect 3 0 15 0; #X connect 7 0 26 0; #X connect 8 0 15 0; #X connect 9 0 26 0; #X connect 12 0 26 0; #X connect 13 0 26 0; #X connect 16 0 26 0; #X connect 17 0 15 0; #X connect 18 0 17 0; #X connect 26 0 31 0; #X connect 26 1 31 1; #X connect 27 0 29 0; #X connect 28 0 27 0; #X connect 29 0 26 0; #X connect 30 0 26 0; #X connect 30 0 26 1; #X connect 31 0 0 0; #X connect 31 1 0 1; jsusfx-0.4.0/pd/jsusfx~-help.pd000066400000000000000000000070111353477307700164520ustar00rootroot00000000000000#N canvas 143 45 653 554 10; #X obj 25 381 dac~; #X obj 17 490 hsl 128 15 0 1 0 0 slider2 slider2 slider2 -2 -8 0 10 -262144 -1 -1 0 1; #X obj 18 454 hsl 128 15 0 1 0 0 slider1 slider1 slider1 -2 -8 0 10 -262144 -1 -1 0 1; #X msg 90 202 describe; #X obj 167 454 hsl 128 15 0.011 1 0 0 slider3 slider3 slider3 -2 -8 0 10 -262144 -1 -1 0 1; #X obj 166 490 hsl 128 15 0.011 1 0 0 slider4 slider4 slider4 -2 -8 0 10 -262144 -1 -1 0 1; #X obj 317 455 hsl 128 15 0.011 1 0 0 slider5 slider5 slider5 -2 -8 0 10 -262144 -1 -1 0 1; #N canvas 489 423 644 279 slider_r 0; #X obj 311 245 outlet; #X obj 45 33 r slider1; #X obj 114 34 r slider2; #X obj 180 37 r slider3; #X obj 245 30 r slider4; #X msg 44 87 slider 1 \$1; #X obj 308 37 r slider5; #X msg 307 92 slider 5 \$1; #X msg 242 114 slider 4 \$1; #X msg 180 89 slider 3 \$1; #X msg 111 114 slider 2 \$1; #X obj 382 31 r slider6; #X msg 383 113 slider 6 \$1; #X obj 467 30 r slider7; #X msg 468 91 slider 7 \$1; #X obj 549 33 r slider8; #X msg 549 112 slider 8 \$1; #X connect 1 0 5 0; #X connect 2 0 10 0; #X connect 3 0 9 0; #X connect 4 0 8 0; #X connect 5 0 0 0; #X connect 6 0 7 0; #X connect 7 0 0 0; #X connect 8 0 0 0; #X connect 9 0 0 0; #X connect 10 0 0 0; #X connect 11 0 12 0; #X connect 12 0 0 0; #X connect 13 0 14 0; #X connect 14 0 0 0; #X connect 15 0 16 0; #X connect 16 0 0 0; #X restore 187 322 pd slider_r; #X msg 103 225 dumpvars; #X obj 318 490 hsl 128 15 0.011 1 0 0 slider6 slider6 slider6 -2 -8 0 10 -262144 -1 -1 0 1; #X obj 466 490 hsl 128 15 0.011 1 0 0 slider8 slider8 slider8 -2 -8 0 10 -262144 -1 -1 0 1; #X obj 467 455 hsl 128 15 0.011 1 0 0 slider7 slider7 slider7 -2 -8 0 10 -262144 -1 -1 0 1; #X msg 82 178 bypass \$1; #X text 154 179 bypass is used to bypass the fx processing; #X text 160 205 describe outputs the assigned slider to the pd console ; #X text 180 231 dumpvars output all the variable output to the pd console ; #X obj 26 98 openpanel; #X obj 26 71 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 26 124 compile \$1; #X obj 25 347 jsusfx~ 2 2; #X text 265 315 slider is used to change the value of a parameter of the jsfx script. It is normalized from 0 to 1; #X text 108 117 Use compile to recompile the current script or specify a new one. the current script.; #X text 107 343 You can specify the script to load and also the number of DSP io pins; #N canvas 745 75 450 300 test_tones 0; #X obj 52 246 outlet~; #X obj 53 184 phasor~; #X obj 55 125 *~ 110; #X obj 54 154 +~ 220; #X obj 54 89 phasor~ 0.1; #X obj 53 213 *~ 0.25; #X connect 1 0 5 0; #X connect 2 0 3 0; #X connect 3 0 1 0; #X connect 4 0 2 0; #X connect 5 0 0 0; #X restore 82 309 pd test_tones; #X obj 105 249 midiin; #X text 96 382 The last inlet is used if the script is sending midi messages; #X obj 87 412 midiout; #X text 9 10 jsusfx~ : Used for JSFX script development and can switch script with the command compile ============================================================see: https://github.com/asb2m10/jsusfx; #X obj 184 153 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X msg 56 151 compile moog24db; #X text 167 256 Midi message with float or list sent to first inlet is considered as midi data; #X msg 104 272 midi \$1; #X connect 3 0 19 0; #X connect 7 0 19 0; #X connect 8 0 19 0; #X connect 12 0 19 0; #X connect 16 0 18 0; #X connect 17 0 16 0; #X connect 18 0 19 0; #X connect 19 0 0 0; #X connect 19 1 0 1; #X connect 19 2 26 0; #X connect 23 0 19 0; #X connect 23 0 19 1; #X connect 24 0 31 0; #X connect 28 0 12 0; #X connect 29 0 19 0; #X connect 31 0 19 0; jsusfx-0.4.0/pd/pd.build/000077500000000000000000000000001353477307700151615ustar00rootroot00000000000000jsusfx-0.4.0/scripts/000077500000000000000000000000001353477307700145445ustar00rootroot00000000000000jsusfx-0.4.0/scripts/liteon/000077500000000000000000000000001353477307700160365ustar00rootroot00000000000000jsusfx-0.4.0/scripts/liteon/3bandpeakfilter.jsfx000066400000000000000000000352171353477307700220000ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . //****************************************************************************** // Stanley A. White // Design of a digital biquadratic peaking or notch filters // for digital audio equalization // JAES, Vol. 34, No. 6, 1986 June // // HP, LP (AppleFilter) based on au unit tutorial (apple.com) //****************************************************************************** desc: 3Bands: PF-3A, PF-3B, Apple: HP, LP slider1:0<0,1,1{Stereo,Mono}>Processing slider2:0<0,100,0.01>******* HP Filter [ 12dB ] slider3:0<0,1,1{PF-3A,PF-3B}>Peak Filter Type slider4:50<0,100,0.01>******* Frequency - [ 1 ] slider5:0.3<0.005,1,0.00005>BW - [ 1 ] slider6:0<-18,18,0.01>Gain - [ 1 ] slider7:50<0,100,0.01>******* Frequency - [ 2 ] slider8:0.3<0.005,1,0.00005>BW - [ 2 ] slider9:0<-18,18,0.01>Gain - [ 2 ] slider10:50<0,100,0.01>******* Frequency - [ 3 ] slider11:0.3<0.005,1,0.00005>BW - [ 3 ] slider12:0<-18,18,0.05>Gain - [ 3 ] slider13:100<0,100,0.01>******* LP Filter [ 12db ] slider14:0<0,100,0.05>Saturation (%) slider15:0<-24,24,0.01>Output slider16:0<0,1,1{Off,On}>Oversample (x2) //============================================================= @init //fir restoration fc1 = 1; fc2 = -0.75; fc3 = 0.17; fgain = 4.5; //fir bandlimit bl_c1 = 0.52; bl_c2 = 0.54; bl_c3 = -0.02; //denorm denorm = 10^-30; //============================================================= @slider os = slider16; drive = slider14/350; drv2_k = drive/(1-drive); outv = 10^(slider15/20); noisefloor = 10^(slider14/100)/10^6; //hpf //-------------------------------- sx = 16+slider2*1.20103; cx_hp = floor(exp(sx*log(1.059))*8.17742); cutoff_hp = 2*cx_hp/srate; k = 0.5*sin($pi*cutoff_hp); c1 = 0.5*(1-k)/(1+k); c2 = (0.5+c1)*cos($pi*cutoff_hp); c3 = (0.5+c1+c2)*0.25; a0_hp = 2*c3; a1_hp = -4*c3; a2_hp = 2*c3; b1_hp = -2*c2; b2_hp = 2*c1; //lpf //-------------------------------- sx = 16+slider13*1.20103; cx_lp = floor(exp(sx*log(1.059))*8.17742); cutoff_lp = 2*cx_lp/srate; k = 0.5*sin($pi*cutoff_lp); c1 = 0.5*(1-k)/(1+k); c2 = (0.5+c1)*cos($pi*cutoff_lp); c3 = (0.5+c1-c2)*0.25; a0_lp = 2*c3; a1_lp = 4*c3; a2_lp = 2*c3; b1_lp = -2*c2; b2_lp = 2*c1; //pf1 //-------------------------------- sx = 16+slider4*1.20103; freq1 = floor(exp(sx*log(1.059))*8.17742); //if gain slider5 != 0 ? ( //type a //------------- slider3 == 0 ? ( gdb = slider6; bw = slider5; k = 10^(gdb/20); w = 2*$pi*freq1/srate; bwr = bw*w; gdb < 0 ? ( bw_inv = min(2*freq1+1500, 20000); bwr = 2*$pi*(bw_inv)*(bw)/srate; ); abw = (1-tan(bwr/2))/(1+tan(bwr/2)); gain = 0.5*(1+k+abw-k*abw); cx1 = gain; cx11 = gain*(-2*cos(w)*(1+abw))/(1+k+abw-k*abw); cx12 = gain*(abw+k*abw+1-k)/(abw-k*abw+1+k); cy11 = 2*cos(w)/(1+tan(bwr/2)); cy12 = -abw; ) : ( //type b //------------- m = 10^(slider6/20); bw = slider5; w0 = 2*$pi*freq1; om = bw*w0; ta = tan(om/srate/2); p = 1.2; slider6 < 0 ? p = 0.2; d = ta+p; cx1 = (p+m*ta)/d; cx11 = -2*p*cos(w0/srate)/d; cx12 = (p-m*ta)/d; cy11 = 2*p*cos(w0/srate)/d; cy12 = -(p-ta)/d; ); ); //pf2 //-------------------------------- sx = 16+slider7*1.20103; freq2 = floor(exp(sx*log(1.059))*8.17742); //if gain slider9 != 0 ? ( //type a //------------- slider3 == 0 ? ( gdb = slider9; bw = slider8; k = 10^(gdb/20); w = 2*$pi*freq2/srate; bwr = bw*w; gdb < 0 ? ( bw_inv = min(2*freq2+1500, 20000); bwr = 2*$pi*(bw_inv)*(bw)/srate; ); abw = (1-tan(bwr/2))/(1+tan(bwr/2)); gain = 0.5*(1+k+abw-k*abw); cx2 = gain; cx21 = gain*(-2*cos(w)*(1+abw))/(1+k+abw-k*abw); cx22 = gain*(abw+k*abw+1-k)/(abw-k*abw+1+k); cy21 = 2*cos(w)/(1+tan(bwr/2)); cy22 = -abw; ) : ( //type b //------------- m = 10^(slider9/20); bw = slider8; w0 = 2*$pi*freq2; om = bw*w0; ta = tan(om/srate/2); p = 1.2; slider9 < 0 ? p = 0.2; d = ta+p; cx2 = (p+m*ta)/d; cx21 = -2*p*cos(w0/srate)/d; cx22 = (p-m*ta)/d; cy21 = 2*p*cos(w0/srate)/d; cy22 = -(p-ta)/d; ); ); //pf3 //-------------------------------- sx = 16+slider10*1.20103; freq3 = floor(exp(sx*log(1.059))*8.17742); //if gain slider12 != 0 ? ( //type a //------------- slider3 == 0 ? ( gdb = slider12; bw = slider11; k = 10^(gdb/20); w = 2*$pi*freq3/srate; bwr = bw*w; gdb < 0 ? ( bw_inv = min(2*freq3+1500, 20000); bwr = 2*$pi*(bw_inv)*(bw)/srate; ); abw = (1-tan(bwr/2))/(1+tan(bwr/2)); gain = 0.5*(1+k+abw-k*abw); cx3 = gain; cx31 = gain*(-2*cos(w)*(1+abw))/(1+k+abw-k*abw); cx32 = gain*(abw+k*abw+1-k)/(abw-k*abw+1+k); cy31 = 2*cos(w)/(1+tan(bwr/2)); cy32 = -abw; ) : ( //type b //------------- m = 10^(slider12/20); bw = slider11; w0 = 2*$pi*freq3; om = bw*w0; ta = tan(om/srate/2); p = 1.2; slider12 < 0 ? p = 0.2; d = ta+p; cx3 = (p+m*ta)/d; cx31 = -2*p*cos(w0/srate)/d; cx32 = (p-m*ta)/d; cy31 = 2*p*cos(w0/srate)/d; cy32 = -(p-ta)/d; ); ); //============================================================= @sample linl = spl0; linr = spl1; //mono //----------------------------------------------- slider1 == 1 ? ( //hp //-------------------------------- slider2 > 0 ? ( out_hp_l_1 = a0_hp*linl+a1_hp*mem_hp_l_11+a2_hp*mem_hp_l_12-b1_hp*mem_hp_l_13-b2_hp*mem_hp_l_14; mem_hp_l_12 = mem_hp_l_11; mem_hp_l_11 = linl; mem_hp_l_14 = mem_hp_l_13; mem_hp_l_13 = out_hp_l_1; linl = linr = out_hp_l_1; ); //f1 //-------------------------------- slider6 != 0 ? ( x1l = (linl+linr)/2; y1l = cx1*x1l+cx11*x11l+cx12*x12l+cy11*y11l+cy12*y12l; x12l = x11l; x11l = x1l; y12l = y11l; y11l = y1l; f1outl = y1l; ) : ( f1outl = (linl+linr)/2; ); //f2 //-------------------------------- slider9 != 0 ? ( x2l = f1outl; y2l = cx2*x2l+cx21*x21l+cx22*x22l+cy21*y21l+cy22*y22l; x22l = x21l; x21l = x2l; y22l = y21l; y21l = y2l; f2outl = y2l; ) : ( f2outl = f1outl; ); //f3 //-------------------------------- slider12 != 0 ? ( x3l = f2outl; y3l = cx3*x3l+cx31*x31l+cx32*x32l+cy31*y31l+cy32*y32l; x32l = x31l; x31l = x3l; y32l = y31l; y31l = y3l; f3outl=y3l+denorm; f3outr=y3l+denorm; ) : ( f3outl=f2outl+denorm; f3outr=f2outl+denorm; ); //lp //----------------------------------- slider13 < 100 ? ( out_lp_l_1 = a0_lp*f3outl+a1_lp*mem_lp_l_11+a2_lp*mem_lp_l_12-b1_lp*mem_lp_l_13-b2_lp*mem_lp_l_14; mem_lp_l_12 = mem_lp_l_11; mem_lp_l_11 = f3outl; mem_lp_l_14 = mem_lp_l_13; mem_lp_l_13 = out_lp_l_1; f3outl = out_lp_l_1; f3outr = out_lp_l_1; ); //saturation //----------------------------------- linl = f3outl; linr = f3outr; slider14 > 0 ? ( (spl0 != 0 || spl1 != 0) ? ( whitel = (rand(2)-1)*noisefloor; linl += whitel; ); //oversampling? os == 1 ? ( //--------------------------- //power series in ps_out1l = 0.5*(linl+ps_out2l); ps_out2l = 0.5*ps_out1l; //--------------------------- //drive o_in1l = (1+drv2_k)*ps_out1l/(1+drv2_k*abs(ps_out1l)); o_in2l = (1+drv2_k)*ps_out2l/(1+drv2_k*abs(ps_out2l)); //--------------------------- //bandlimit bl3_1 = bl2_1; bl3_2 = bl2_2; bl2_1 = bl1_1; bl2_2 = bl1_2; bl1_1 = o_in1l; bl1_2 = o_in2l; bl_out1 = (bl1_1*bl_c1 + bl2_1*bl_c2 + bl3_1*bl_c3); bl_out2 = (bl1_2*bl_c1 + bl2_2*bl_c2 + bl3_2*bl_c3); //--------------------------- //power series out o_out1l = 0.5*(bl_out1+o_out2l); o_out2l = 0.5*(bl_out2+o_out1l); //--------------------------- //fir restoration s3l = s2l; s2l = s1l; s1l = o_out1l; o_outl = (s1l*fc1+s2l*fc2+s3l*fc3)*fgain; ) : ( o_outl = (1+drv2_k)*linl/(1+drv2_k*abs(linl)); ); //out spl0 = (o_outl)*outv+denorm; spl1 = (o_outl)*outv+denorm; ) : ( spl0 = (linl)*outv+denorm; spl1 = (linl)*outv+denorm; ); ) : ( //stereo //----------------------------------------------- //hp //-------------------------------- slider2 > 0 ? ( out_hp_l_1 = a0_hp*linl+a1_hp*mem_hp_l_11+a2_hp*mem_hp_l_12-b1_hp*mem_hp_l_13-b2_hp*mem_hp_l_14; mem_hp_l_12 = mem_hp_l_11; mem_hp_l_11 = linl; mem_hp_l_14 = mem_hp_l_13; mem_hp_l_13 = out_hp_l_1; out_hp_r_1 = a0_hp*linr+a1_hp*mem_hp_r_11+a2_hp*mem_hp_r_12-b1_hp*mem_hp_r_13-b2_hp*mem_hp_r_14; mem_hp_r_12 = mem_hp_r_11; mem_hp_r_11 = linr; mem_hp_r_14 = mem_hp_r_13; mem_hp_r_13 = out_hp_r_1; linl = out_hp_l_1; linr = out_hp_r_1; ); //f1 //-------------------------------- slider6 != 0 ? ( x1l = linl; x1r = linr; y1l = cx1*x1l+cx11*x11l+cx12*x12l+cy11*y11l+cy12*y12l; y1r = cx1*x1r+cx11*x11r+cx12*x12r+cy11*y11r+cy12*y12r; x12l = x11l; x12r = x11r; x11l = x1l; x11r = x1r; y12l = y11l; y12r = y11r; y11l = y1l; y11r = y1r; f1outl = y1l; f1outr = y1r; ) : ( f1outl = linl; f1outr = linr; ); //f2 //-------------------------------- slider9 != 0 ? ( x2l = f1outl; x2r = f1outr; y2l = cx2*x2l+cx21*x21l+cx22*x22l+cy21*y21l+cy22*y22l; y2r = cx2*x2r+cx21*x21r+cx22*x22r+cy21*y21r+cy22*y22r; x22l = x21l; x22r = x21r; x21l = x2l; x21r = x2r; y22l = y21l; y22r = y21r; y21l = y2l; y21r = y2r; f2outl = y2l; f2outr = y2r; ) : ( f2outl = f1outl; f2outr = f1outr; ); //f3 //-------------------------------- slider12 != 0 ? ( x3l = f2outl; x3r = f2outr; y3l = cx3*x3l+cx31*x31l+cx32*x32l+cy31*y31l+cy32*y32l; y3r = cx3*x3r+cx31*x31r+cx32*x32r+cy31*y31r+cy32*y32r; x32l = x31l; x32r = x31r; x31l = x3l; x31r = x3r; y32l = y31l; y32r = y31r; y31l = y3l; y31r = y3r; f3outl=y3l+denorm; f3outr=y3r+denorm; ) : ( f3outl=f2outl+denorm; f3outr=f2outr+denorm; ); //lp //----------------------------------- slider13 < 100 ? ( out_lp_l_1 = a0_lp*f3outl+a1_lp*mem_lp_l_11+a2_lp*mem_lp_l_12-b1_lp*mem_lp_l_13-b2_lp*mem_lp_l_14; mem_lp_l_12 = mem_lp_l_11; mem_lp_l_11 = f3outl; mem_lp_l_14 = mem_lp_l_13; mem_lp_l_13 = out_lp_l_1; out_lp_r_1 = a0_lp*f3outr+a1_lp*mem_lp_r_11+a2_lp*mem_lp_r_12-b1_lp*mem_lp_r_13-b2_lp*mem_lp_r_14; mem_lp_r_12 = mem_lp_r_11; mem_lp_r_11 = f3outr; mem_lp_r_14 = mem_lp_r_13; mem_lp_r_13 = out_lp_r_1; f3outl = out_lp_l_1; f3outr = out_lp_r_1; ); //saturation //----------------------------------- linl = f3outl; linr = f3outr; slider14 > 0 ? ( (spl0 != 0 || spl1 != 0) ? ( whitel = (rand(2)-1)*noisefloor; whiter = (rand(2)-1)*noisefloor; linl += whitel; linr += whiter; ); //oversample? os == 1 ? ( //--------------------------- //power series in ps_out1l = 0.5*(linl+ps_out2l); ps_out2l = 0.5*ps_out1l; ps_out1r = 0.5*(linr+ps_out2r); ps_out2r = 0.5*ps_out1r; //--------------------------- //drive o_in1l = (1+drv2_k)*ps_out1l/(1+drv2_k*abs(ps_out1l)); o_in2l = (1+drv2_k)*ps_out2l/(1+drv2_k*abs(ps_out2l)); o_in1r = (1+drv2_k)*ps_out1r/(1+drv2_k*abs(ps_out1r)); o_in2r = (1+drv2_k)*ps_out2r/(1+drv2_k*abs(ps_out2r)); //--------------------------- //bandlimit bl3_l1 = bl2_l1; bl3_r1 = bl2_r1; bl3_l2 = bl2_l2; bl3_r2 = bl2_r2; bl2_l1 = bl1_l1; bl2_r1 = bl1_r1; bl2_l2 = bl1_l2; bl2_r2 = bl1_r2; bl1_l1 = o_in1l; bl1_r1 = o_in1r; bl1_l2 = o_in2l; bl1_r2 = o_in2r; bl_out1l = (bl1_l1*bl_c1 + bl2_l1*bl_c2 + bl3_l1*bl_c3); bl_out1r = (bl1_r1*bl_c1 + bl2_r1*bl_c2 + bl3_r1*bl_c3); bl_out2l = (bl1_l2*bl_c1 + bl2_l2*bl_c2 + bl3_l2*bl_c3); bl_out2r = (bl1_r2*bl_c1 + bl2_r2*bl_c2 + bl3_r2*bl_c3); //--------------------------- //power series out o_out1l = 0.5*(bl_out1l+o_out2l); o_out2l = 0.5*(bl_out2l+o_out1l); o_out1r = 0.5*(bl_out1r+o_out2r); o_out2r = 0.5*(bl_out2r+o_out1r); //--------------------------- //fir restoration s3l = s2l; s2l = s1l; s1l = o_out1l; s3r = s2r; s2r = s1r; s1r = o_out1r; o_outl = (s1l*fc1+s2l*fc2+s3l*fc3)*fgain; o_outr = (s1r*fc1+s2r*fc2+s3r*fc3)*fgain; ) : ( o_outl = (1+drv2_k)*linl/(1+drv2_k*abs(linl)); o_outr = (1+drv2_k)*linr/(1+drv2_k*abs(linr)); ); //out spl0 = (o_outl)*outv+denorm; spl1 = (o_outr)*outv+denorm; ) : ( spl0 = (linl)*outv+denorm; spl1 = (linr)*outv+denorm; ); ); //============================================================= @gfx 100 53 gfx_x=gfx_y=5; gfx_lineto(gfx_x, gfx_y,0); //hp //--------------------------------- slider2 > 0 ? ( gfx_r=0.7; gfx_b=0.1; gfx_g=1; gfx_a=1; ) : ( gfx_r=0.3; gfx_b=0.3; gfx_g=0.3; gfx_a=1; ); gfx_drawchar($'H'); gfx_drawchar($'P'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(cx_hp,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); gfx_y += 15; gfx_x = 5; gfx_a=1; //f1 //--------------------------------- slider6 != 0 ? ( slider3 == 0 ? ( gfx_r=1; gfx_b=0; gfx_g=0.8; ) : ( gfx_r=0; gfx_b=1; gfx_g=0.8; ); ) : ( gfx_r=0.6; gfx_b=0.6; gfx_g=0.6; gfx_a=1; ); gfx_drawchar($'F'); gfx_drawchar($'1'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(freq1,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); gfx_y += 15; gfx_x = 5; //f2 //--------------------------------- slider9 != 0 ? ( slider3 == 0 ? ( gfx_r=1; gfx_b=0; gfx_g=0.8; ) : ( gfx_r=0; gfx_b=1; gfx_g=0.8; ); ) : ( gfx_r=0.6; gfx_b=0.6; gfx_g=0.6; gfx_a=1; ); gfx_drawchar($'F'); gfx_drawchar($'2'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(freq2,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); gfx_y += 15; gfx_x = 5; //f3 //--------------------------------- slider12 != 0 ? ( slider3 == 0 ? ( gfx_r=1; gfx_b=0; gfx_g=0.8; ) : ( gfx_r=0; gfx_b=1; gfx_g=0.8; ); ) : ( gfx_r=0.6; gfx_b=0.6; gfx_g=0.6; gfx_a=1; ); gfx_drawchar($'F'); gfx_drawchar($'3'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(freq3,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); gfx_y += 15; gfx_x = 5; //lp //--------------------------------- slider13 < 100 ? ( gfx_r=0.7; gfx_b=0.1; gfx_g=1; gfx_a=1; ) : ( gfx_r=0.3; gfx_b=0.3; gfx_g=0.3; gfx_a=1; ); gfx_drawchar($'L'); gfx_drawchar($'P'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(cx_lp,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); jsusfx-0.4.0/scripts/liteon/LICENSE000066400000000000000000000423111353477307700170440ustar00rootroot00000000000000GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. one line to give the program's name and an idea of what it does. Copyright (C) yyyy name of author This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. jsusfx-0.4.0/scripts/liteon/README.md000066400000000000000000000376551353477307700173350ustar00rootroot00000000000000### Liteon's plugin pack for the JesuSonic platform. # DISCUSSION http://forum.cockos.com/showthread.php?t=27764 # PLUGIN LIST * SonicEnhancer (sonic_enhancer) Modeled after a popular unit for sonic enhancement. Produces an all pass filter near 700hz, progressively delays all lower frequencies and also has a DC filter. - input/output gain - low contour - adds a low end shelf - process - adds a high end shelf - cv - program dependent control voltage for the process amount - noise floor - adds noise floor at around -96dBFS * TubeHarmonics (tubeharmonics/tubeharmonics_amp) A rough model of a dual tube circuit stage. Not an exact tube model, but perhaps closer to the triode family. Adds controllable and transient aware amount of odd and even harmonics to the signal. The effect can be very subtle or quite drastic. For testing purposes use a periodic signal. The "amp" version of the fx is a tube pre-amp stage. - separate odd / even harmonics amount - fluctuation - circuit instability also controls the transient awareness - TS input - tube stage input in decibels (level of input signal) - TS ouput - tube stage ouput in decibels (level of harmonics) - output - master out * Lo-Fi (lo-fi) A mono/stereo bitcrusher, sample rate reducer with post filter. - bitcrusher/sample rate reducer - 2 point linear interpolation - 12db/oct low-pass filter - pre amp - outgain * PhaseMeter (phasemeter) A goniometer with precision amount, scaling and color schemes. - 3 (funky) color schemes - precision (cpu usage related) - positive scale amount * StereoTilt (stereotilt) Mono-to-stereo filter. Spectrum on left channel is tilted in one direction, while the spectum on the right channel is flipped in the other. - center frequency - tilt amount - balance - outgain * FARModulator (farmodulator) FM, AM/RM effect, which can use 2 sine waves as carrier/modulator, but also any other input signal as modulator. Can produce a wide palette of sounds. - operation modes - FM, M1(mixed), M2(mixed) - modulator signal selection - separate modulator/carrier gain - output gain Note: the effect is mono * PRNG-Plot (prngplot) A plotter algorithm for generated pseudo-random numbers. * Non-Linear Processor (nonlinear) Simple non-linear processor. Roughly mimics analog circuit behaviour. - saturation amount - sinusoidal waveshaper. adds "odd" harmonics. - fluctuation amount - adds probability to all parameters in the model. - floor reduction - adds filtered white noise at a defined range, calculated from bit depth. - output gain -24/+24db The effect also models a basic frequency response from an analog prototype. Two slopes at the bottom and low end are present and also a positive low-shelf, around 300hz. But the probability also affect the filter parameters. The result from this could be characterized as "dynamic", as opposed to "static" where a transfer function is time invariant. The amount of probability is material dependant and slightly increases for transients, found in the signal. * Tilt EQ (tilteq) Simple "tilt" equalizer circuit. It has only two controls: Boost/Cut and a center frequency. While boosting or cutting volume with a shelving filter above the center frequency, it does the opposite with the range below the center frequency. This can produce very quick changes on the spectrum. For extreme settings: -6db will result a lowpass, +6db will result a highpass. * NP1136 (np1136peaklimiter) Program dependant peak limiter. Full documentation here: http://sites.google.com/site/neolit123/Home/np1136_manual.pdf * De-Esser (deesser) De-Esser which uses "splt-band" compression. The crossover is constructed with second order Linkwitz-Riley filters. - stereo/mono processing - target type - compress a band or the whole top end. - monitor on/off - listen to the compressed signal - frequency range - 20 - 20khz - bandwidth in ocvaves - 0.1 - 3.1oct - threshold - 0 to -80db - ratio - 1:1 - 20:1 - 3 time constants. - output -inf/24dB - output gain * Pseudo-Stereo (pseudostereo) Pseudo-Stereo fx based on 'mdaStereo' by Paul Kellet. Can be used for mono-to-stereo conversations. Uses one feedback delay on R ('Haas fx' mode) or 2 separate feedback delays for L & R ('Comb' mode). Very light on the CPU. - fx amount (%) - haas / comb - delay (ms) - feedback delay in milliseconds - balance - L / R channel amount - output -20/20dB - output volume * RingModulator (ringmodulator) A simple ring modulator circuit emulation. Uses a sinewave as the modulation signal, which can be 'waveshaped' with a diode, so that only the positive semi-periods of time sinewave pass trought. Has feedback and non-linearities. - stereo/mono processing - mod-signal diode - on/off - mod-signal frequency - 20-20khz - feedback - 0-100% - lets the signal be processed multiple times by the RM - non-linearities - 0-100% - adds small variations to the mod-frequency and feedback amount. - mix - 0-100% - mixes the orginal signal with the processed signal. - output -inf/40dB - output volume - oversampling (on/off) * StateVarible (morphing) filter (statevariable) Filter which uses x,y pads to morph between different states - LP, HP, BP, BR. - stereo/mono processing - lp,hp,bp,br modes - frequency range - 20-20000hz - res - resonance amount - filter amount - mixes the original signal with the filtered one. * AppleFilter v.2 (applefilter72db) Original filter from apple.com AU tutorial. Modification allows up to 12pole cascade (HP, LP). - stereo/mono processing - slope - off/12db-72db per octave - frequency range - 20-20000hz - res - resonance amount -16/+16db - output gain control -24/+24db * 3BandPeakFilter (3bandpeakfilter) Filter bank containing two biquad peak filters from Stanley A. White's algorithms (JAES versions). Each filter provides three fully parametric bands. The plugin can be used as a three band EQ. Saturation control is also available. - two filter types: PF-3A, PF-3B. The two filters have similar behavior in the midrange, but quite different at the low and high end. - stereo/mono processing - frequency ranges - 20-20000hz - gain -18/+18db - 12db lowpass, highpass - output gain control -24/+24db - saturation amount - 0-100% - adds harmonics and noise floor to the signal. - oversampling (on/off) * VUMeterGFX / VUMeterGFXSum (vumetergfx/vumetergfxsum) Vintage-style VU meter with response and release controls. Uses the GFX section to draw all graphics in realtime. Summed (L+R) and stereo versions. - response control (MS) - RMS and peak meter response. - release - needle fallback time. * LorenzAttractor (lorenzattractor) Synthesizer based on Lorenz Attractor formulas. Has two oscillators: one sine wave, one square wave. There are various parameters that control both the sound and the plotted graphics. Can be used to produce ambient sounds. - rate - controls the rate at which the plotter/modulation is working. - plot osc 1+2/1 - when 'lines' is selected plotter outputs lines and the sound is a mix between osc 1 and 2 (sine+square). Otherwise when 'dots' is selected the output is a sine-wave only. - prandtl number - first parameter controling the attractor. - reileght number - second parameter. - color - changes the pallette of the plotter. When set to the farleft, modulation amount of osc1 is minimum. Otherwise its set to maximum. - tune - tunage of osc1 and osc2. - output gain control -inf/+25dB * ShelvingFilter (shelvingfilter) Plugin with LowShelf and HighShelf biquad filters based on James A. Moorer's formulas. - stereo/mono processing - frequency ranges - 20-20000hz - gain -12/+12db - output gain control -24/+24db * PresenceEQ (presenceeq) Topend EQ based on James A. Moorer's formulas. Can add presence to the top end of sounds. Bandwidth of the boost is somehow smart and frequency dependant. Good sound. - stereo/mono processing - frequency range - 3100hz-1850hz - cut/boost - -15/+15db - BW - bandwidth of the boost - output gain control -24/+24db * BassManager (filename: bassmanager) This is a plugin for managing your bass samples. The idea behind this plugin is to make bass samples more present in the mix. It has full control over the low end. Sounds can be processed in stereo or mono. It has a 2pole lowshelf filter for boosting frequencies. Also a build in saturator, a control for high-end muffle and a limiter. - stereo/mono processing - spread - controls the width of the lowshelf - frequency - 30-250hz - boost - amount of boost for the low end - 0/24db - drive - adds saturation - muffle - "muffles" sharp highend frequencies. - output - controls the output gain -24/+24db - hipass - hipass filter for the low end at given frequency. - limiter(on/off) - to limit the output from the plugin - oversampling (on/off) * Butterworth Filter (filename: butterworth24db) Classic sounding 24db filter model! - stereo/mono processing - filter mode - LP/HP - cutoff frequency - 20-20000hz - resonance amount - 0-0.9 - limiter(on/off) - to limit the output from the plugin - output gain control -24/+24db ! This plugin comes with a warning ! Due to the internal filter architecture this pluging may behave as unstable when cutoff frequency is automated very fast in the low end. A limiter will automatically kick-in in such cases so that user speakers aren't blown out. :) * Chebyshev Filter - Type1 (filename: cheby24db) Classic sounding 24db filter model! With a very specific resonance. - stereo/mono processing - filter mode - LP/HP/BP - cutoff frequency - 20-20000hz - passband ripple amount - 0-0.9 (Produces two noticeable peaks on the spectrum) - limiter(on/off) - to limit the output from the plugin - output gain control -24/+24db * Moog Filter (filename: moog24db) Classic sounding 24db filter plugin modeled after the infamous Moog Filter. - stereo/mono processing - filter mode - LP/HP/BP - cutoff frequency - 20-20000hz - resonance amount - 0-0.85 - drive - adds saturation to the signal - limiter(on/off) - to limit the output from the plugin - output gain control -24/+24db - oversampling (on/off) * Pink Noise Generator (filename: pinknoisegen) A simple pink noise generator with mono/stereo output. - stereo/mono - one/two channels noise output - output gain control -24/+24db * RBJ Stereo Filter (filename: rbjstereofilter12db) A filter that controls only the stereo image of a sound. Useful for precise sound modeling. Based on RBJ filters cookbook. Includes saturation. - filter amount - controls mix between original signal and filtered one. - HP - 12db hipass for the stereo image at given frequency. - LP - 12db lowpass for the stereo image at given frequency. - drive - saturation for the stereo image. - side - stereo image width. - mid - mid amount. - output gain control (m+s) -24/+24db - oversampling (on/off) * Simple 6db LP Filter (filename: simplelp6db) A simple 6db LP filter. Good for less steeper cuts of high end sounds. CPU friendly and good for automation. No resonance control. - mono/stereo processing - cutoff frequency - 20-20000hz - output gain control -24/+24db * WaveshaperMulti (filename: waveshapermulti) A waveshaper bank with different waveshaper formulas. - mono/stereo processing - type - selected waveshaper formula - drive - controls amount of saturation - muffle - "muffles" sharp highend frequencies. - output gain control -24/+24db - limiter(on/off) - to limit the output from the plugin - oversampling (on/off) # TERMS OF USE: NO WARRANTY IS GRANTED. THESE PLUG-INS ARE PROVIDED WITHOUT WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING OUT OF THE USE OR INABILITY TO USE THESE PLUG-IN, COMPUTER FAILTURE OF MALFUNCTION INCLUDED. THE USE OF ANY SOURCE CODE, EITHER PARTIALLY OR IN TOTAL, IS GRANTED. FURTHERMORE ARE THESE PLUG-INS A THIRD PARTY CONTRIBUTION EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR ITS AFFILIATES HAVE NOTHING TO DO WITH THEM. LAST BUT NOT LEAST, BY USING THE PLUG-INS YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO ENTRUST SOMEBODY ELSE WITH DOING SO. # LICENSE THE PLUGINS ARE RELEASED UNDER GPL. SEE THE GNU GENERAL PUBLIC LICENSE FOR MORE DETAILS. YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE ALONG WITH THIS PACKAGE. IF NOT, VISIT: http://www.gnu.org/licenses/ # REFERENCES EACH PLUGIN MAY INCLUDE SOURCE CODE OR FORMULAS WHICH ARE PROVIDED FOR PUBLIC USE BY THEIR ORIGINAL AUTHORS. SOME PLUGINS MAY REFER TO ORIGINAL SOURCE CODE OR PAPERS IF THERE ARE ANY. PLUGINS IN THE PACK MAY INCLUDE CODE OR FORMULAS WHICH ORIGINATED FROM THIS AUTHOR. USING SUCH IN THIRD PARTY OPEN SOURCE OR ANY COMMERCIAL PROJECTS IS FULLY GRANTED UNDER THE TERMS OF THE GPL LICENSE. REDISTRIBUTION IN ANY FORM, WITHOUT THE PERMISSION OF THE AUTHOR IS PROHIBITED. # AUTHOR Lubomir I. Ivanov (liteon) neolit123@gmail.com http://neolit123.blogspot.com 23.02.12 - added sonic_enhancer 31.03.11 - some fixes 20.07.10 - fix in vumetergfxsum to show better rms values 28.05.10 - small tweaks - clarification in moog, cheby, butter that some of the filter modes are 6db/oct 28.11.09 - added tubeharmonics_amp 24.11.09 - added tubeharmonics - fix for pdc in nonlinear - added input gain for nonlinear - small tweak in vumetergfxsum 06.10.09 - added stereotilt - added lo-fi - added phasemetergfx 04.09.09 - added farmodulator - added prngplot 06.07.09 - shelvingfilter - changed to -24/+24db range. 03.07.09 - added nonlinear processor - various minor tweaks here and there 10.06.09 - np1136 - improved 'british mode'. - deesser - small tweak for the time constants. 29.05.09 - added tilteq - added np1136 - added deesser - minor fix for pseudo stereo gain. 15.04.09 - OSx2 bandlimit fir filter - various small fixes 14.04.09 - added pseudostereo - small fix for 3bandpeakfilter's LP. - OSx2 on/off switch for plugins 05.04.09 - VUMeterGFX - added inertial fallback, gfx height fix for Reaper3. - SimpleLP6db - added HP,LP switch - WaveshaperMulti - added 2x oversampling - Moog - added 2x oversamling, parameter interpolation - Cheby - added parameter interpolation - BassManager - added 2x oversamling - 3BandPeakFilter - added 2x oversamling - RingModulator - added 2x oversamling (with on/off switch) - RBJStereoFilter - added 2x oversamling, separate mid/side amounts 15.03.09 - added ring modulator 06.03.09 - VUMeterGFXsum small fix 02.03.09 - small fix for StateVarible - update paramenters 02.03.09 - added StateVarible 13.02.09 - replaced applefilter with v.2 - up to 12pole hp, lp - 3bandpeakfilter: reduced noise floor from the 'saturation' control - 3bandpeakfilter: added 12db hp, lp - same as apple filter - vu meter: default response time - 50ms - pinknoisegen: should work with all samplerates now 23.01.09 - added 3BandPeakFilter - added VUMeterGFXSum (L+R) version. Also RMS window and Release/Response controls. - small fix for BassManager's HP filter. (Can cut up to 300hz now) 29.12.08 - added VUMeterGFX 20.12.08 - added -15db cut to the PresenceEQ 08.12.08 - added LorenzAttractor 14.11.08 - added ShelvingFilter 09.11.08 - small fix for the applefilter - output gain 06.11.08 - added exponential control to all full range frequency sliders (20-20k) "F = xxxxx" text in the GFX section to display the actual frequency. - added smoothing (ctrl+mouse drag) - added output gain control (-25/25db) to all filters 27.10.08 - added PresenceEQ & AppleFilter 24.10.08 - first packed release. jsusfx-0.4.0/scripts/liteon/applefilter12db.jsfx000066400000000000000000000051201353477307700217100ustar00rootroot00000000000000// (C) 2008, Lubomir Ivanov // // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // //****************************************************************************** //Reference : Apple.com AU tutorial (port from C++) //****************************************************************************** desc: AppleFilter LP 12db slider1:0<0,1,1{Stereo,Mono}> Processing slider2:100<0,100,0.05>Cutoff (Scale) slider3:0<-25,25,0.05>Res (dB) slider4:0<-25,25,0.05>Output (dB) @init mX1l=mX2l=mY1l=mY2l=mX1r=mX2r=mY1r=mY2r=0; @slider mono = slider1; sx = 16+slider2*1.20103; cx = floor(exp(sx*log(1.059))*8.17742); res = slider3; outgain = 10^(slider4/40); //coeffcients cutoff = 2 * cx / srate; res = pow(10, 0.05 * -res); k = 0.5 * res * sin($pi * cutoff); c1 = 0.5 * (1 - k) / (1 + k); c2 = (0.5 + c1) * cos($pi * cutoff); c3 = (0.5 + c1 - c2) * 0.25; mA0 = 2 * c3; mA1 = 2 * 2 * c3; mA2 = 2 * c3; mB1 = 2 * -c2; mB2 = 2 * c1; @sample //mono mono == 1 ? ( inputl = (spl0+spl1)/2; outputl = mA0*inputl + mA1*mX1l + mA2*mX2l - mB1*mY1l - mB2*mY2l; mX2l = mX1l; mX1l = inputl; mY2l = mY1l; mY1l = outputl; spl0=spl1 = outputl*outgain; //stereo ) : ( inputl = spl0; inputr = spl1; outputl = mA0*inputl + mA1*mX1l + mA2*mX2l - mB1*mY1l - mB2*mY2l; mX2l = mX1l; mX1l = inputl; mY2l = mY1l; mY1l = outputl; outputr = mA0*inputr + mA1*mX1r + mA2*mX2r - mB1*mY1r - mB2*mY2r; mX2r = mX1r; mX1r = inputr; mY2r = mY1r; mY1r = outputr; spl0 = outputl*outgain; spl1 = outputr*outgain; ); @gfx 100 10 gfx_x=gfx_y=5; gfx_lineto(gfx_x, gfx_y,0); gfx_r=gfx_b=0; gfx_g=gfx_a=1; gfx_drawchar($'F'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(cx,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); jsusfx-0.4.0/scripts/liteon/applefilter72db.jsfx000066400000000000000000000317461353477307700217330ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . // //****************************************************************************** // butterworth filter implementation - // original port from apple.com au tutorial (c+) // added HP version // added 12 poles cascade // * see note below about efficiency //****************************************************************************** desc: AppleFilter v.2 (72dB LP/HP) slider1:0<0,1,1{Stereo,Mono}>Processing slider2:0<0,1,1{Off,12dB,24dB,36dB,48dB,60dB,72dB}>HP Slope (dB/oct) slider3:0<0,100,0.01>HP Cut (Scale) slider4:0<-16,16,0.01>HP Res (dB) slider5:0<0,1,1{Off,12dB,24dB,36dB,48dB,60dB,72dB}>LP Slope (dB/oct) slider6:100<0,100,0.01>LP Cut (Scale) slider7:0<-16,16,0.01>LP Res (dB) slider8:0<-24,24,0.01>Output (dB) @slider mono = slider1; outgain = 10^(slider8/20); //**************************** //hp n_hp = slider2; sx = 16+slider3*1.20103; cx_hp = floor(exp(sx*log(1.059))*8.17742); cutoff_hp = 2*cx_hp/srate; res_hp = 10^(0.05*(-slider4/n_hp+1.5)); k = 0.5*res_hp*sin($pi*cutoff_hp); c1 = 0.5*(1-k)/(1+k); c2 = (0.5+c1)*cos($pi*cutoff_hp); c3 = (0.5+c1+c2)*0.25; a0_hp = 2*c3; a1_hp = -4*c3; a2_hp = 2*c3; b1_hp = -2*c2; b2_hp = 2*c1; //**************************** //lp n_lp = slider5; sx = 16+slider6*1.20103; cx_lp = floor(exp(sx*log(1.059))*8.17742); cutoff_lp = 2*cx_lp/srate; res_lp = 10^(0.05*(-slider7/n_lp+1.5)); k = 0.5*res_lp*sin($pi*cutoff_lp); c1 = 0.5*(1-k)/(1+k); c2 = (0.5+c1)*cos($pi*cutoff_lp); c3 = (0.5+c1-c2)*0.25; a0_lp = 2*c3; a1_lp = 4*c3; a2_lp = 2*c3; b1_lp = -2*c2; b2_lp = 2*c1; @sample // *NOTE: You can use 'loop' for the cascade (see example below) // however its many times less efficient ! // // comparison for - mono, lp, 72db: // -------------------- // using loop - 13.8% cpu // long version - 3.3% cpu /* i = 0; inl = (spl0+spl1)/2; loop(n_lp, outl = a0_lp*inl+a1_lp*mem[4*i+1]+a2_lp*mem[4*i+2]-b1_lp*mem[4*i+3]-b2_lp*mem[4*i+4]; mem[4*i+2] = mem[4*i+1]; mem[4*i+1] = inl; mem[4*i+4] = mem[4*i+3]; mem[4*i+3] = outl; inl = outl; i += 1; ); spl0=spl1=outl; */ //*************************************************************************** //mono mono == 1 ? ( inl = (spl0+spl1)/2; //********************************************* //hp n_hp > 0 ? ( out_hp_l_1 = a0_hp*inl+a1_hp*mem_hp_l_11+a2_hp*mem_hp_l_12-b1_hp*mem_hp_l_13-b2_hp*mem_hp_l_14; mem_hp_l_12 = mem_hp_l_11; mem_hp_l_11 = inl; mem_hp_l_14 = mem_hp_l_13; mem_hp_l_13 = out_hp_l_1; out_hp_l = out_hp_l_1; n_hp > 1 ? ( out_hp_l_2 = a0_hp*out_hp_l_1+a1_hp*mem_hp_l_21+a2_hp*mem_hp_l_22-b1_hp*mem_hp_l_23-b2_hp*mem_hp_l_24; mem_hp_l_22 = mem_hp_l_21; mem_hp_l_21 = out_hp_l_1; mem_hp_l_24 = mem_hp_l_23; mem_hp_l_23 = out_hp_l_2; out_hp_l = out_hp_l_2; ); n_hp > 2 ? ( out_hp_l_3 = a0_hp*out_hp_l_2+a1_hp*mem_hp_l_31+a2_hp*mem_hp_l_32-b1_hp*mem_hp_l_33-b2_hp*mem_hp_l_34; mem_hp_l_32 = mem_hp_l_31; mem_hp_l_31 = out_hp_l_2; mem_hp_l_34 = mem_hp_l_33; mem_hp_l_33 = out_hp_l_3; out_hp_l = out_hp_l_3; ); n_hp > 3 ? ( out_hp_l_4 = a0_hp*out_hp_l_3+a1_hp*mem_hp_l_41+a2_hp*mem_hp_l_42-b1_hp*mem_hp_l_43-b2_hp*mem_hp_l_44; mem_hp_l_42 = mem_hp_l_41; mem_hp_l_41 = out_hp_l_3; mem_hp_l_44 = mem_hp_l_43; mem_hp_l_43 = out_hp_l_4; out_hp_l = out_hp_l_4; ); n_hp > 4 ? ( out_hp_l_5 = a0_hp*out_hp_l_4+a1_hp*mem_hp_l_51+a2_hp*mem_hp_l_52-b1_hp*mem_hp_l_53-b2_hp*mem_hp_l_54; mem_hp_l_52 = mem_hp_l_51; mem_hp_l_51 = out_hp_l_4; mem_hp_l_54 = mem_hp_l_53; mem_hp_l_53 = out_hp_l_5; out_hp_l = out_hp_l_5; ); n_hp > 5 ? ( out_hp_l_6 = a0_hp*out_hp_l_5+a1_hp*mem_hp_l_61+a2_hp*mem_hp_l_62-b1_hp*mem_hp_l_63-b2_hp*mem_hp_l_64; mem_hp_l_62 = mem_hp_l_61; mem_hp_l_61 = out_hp_l_5; mem_hp_l_64 = mem_hp_l_63; mem_hp_l_63 = out_hp_l_6; out_hp_l = out_hp_l_6; ); ) : ( out_hp_l = inl; ); //********************************************* //lp n_lp > 0 ? ( out_lp_l_1 = a0_lp*out_hp_l+a1_lp*mem_lp_l_11+a2_lp*mem_lp_l_12-b1_lp*mem_lp_l_13-b2_lp*mem_lp_l_14; mem_lp_l_12 = mem_lp_l_11; mem_lp_l_11 = out_hp_l; mem_lp_l_14 = mem_lp_l_13; mem_lp_l_13 = out_lp_l_1; out_lp_l = out_lp_l_1; n_lp > 1 ? ( out_lp_l_2 = a0_lp*out_lp_l_1+a1_lp*mem_lp_l_21+a2_lp*mem_lp_l_22-b1_lp*mem_lp_l_23-b2_lp*mem_lp_l_24; mem_lp_l_22 = mem_lp_l_21; mem_lp_l_21 = out_lp_l_1; mem_lp_l_24 = mem_lp_l_23; mem_lp_l_23 = out_lp_l_2; out_lp_l = out_lp_l_2; ); n_lp > 2 ? ( out_lp_l_3 = a0_lp*out_lp_l_2+a1_lp*mem_lp_l_31+a2_lp*mem_lp_l_32-b1_lp*mem_lp_l_33-b2_lp*mem_lp_l_34; mem_lp_l_32 = mem_lp_l_31; mem_lp_l_31 = out_lp_l_2; mem_lp_l_34 = mem_lp_l_33; mem_lp_l_33 = out_lp_l_3; out_lp_l = out_lp_l_3; ); n_lp > 3 ? ( out_lp_l_4 = a0_lp*out_lp_l_3+a1_lp*mem_lp_l_41+a2_lp*mem_lp_l_42-b1_lp*mem_lp_l_43-b2_lp*mem_lp_l_44; mem_lp_l_42 = mem_lp_l_41; mem_lp_l_41 = out_lp_l_3; mem_lp_l_44 = mem_lp_l_43; mem_lp_l_43 = out_lp_l_4; out_lp_l = out_lp_l_4; ); n_lp > 4 ? ( out_lp_l_5 = a0_lp*out_lp_l_4+a1_lp*mem_lp_l_51+a2_lp*mem_lp_l_52-b1_lp*mem_lp_l_53-b2_lp*mem_lp_l_54; mem_lp_l_52 = mem_lp_l_51; mem_lp_l_51 = out_lp_l_4; mem_lp_l_54 = mem_lp_l_53; mem_lp_l_53 = out_lp_l_5; out_lp_l = out_lp_l_5; ); n_lp > 5 ? ( out_lp_l_6 = a0_lp*out_lp_l_5+a1_lp*mem_lp_l_61+a2_lp*mem_lp_l_62-b1_lp*mem_lp_l_63-b2_lp*mem_lp_l_64; mem_lp_l_62 = mem_lp_l_61; mem_lp_l_61 = out_lp_l_5; mem_lp_l_64 = mem_lp_l_63; mem_lp_l_63 = out_lp_l_6; out_lp_l = out_lp_l_6; ); ) : ( out_lp_l = out_hp_l; ); //out mono spl0 = spl1 = out_lp_l*outgain; //***************************************************************************** //stereo ) : ( inl = spl0; inr = spl1; //********************************************* //hp n_hp > 0 ? ( out_hp_l_1 = a0_hp*inl+a1_hp*mem_hp_l_11+a2_hp*mem_hp_l_12-b1_hp*mem_hp_l_13-b2_hp*mem_hp_l_14; mem_hp_l_12 = mem_hp_l_11; mem_hp_l_11 = inl; mem_hp_l_14 = mem_hp_l_13; mem_hp_l_13 = out_hp_l_1; out_hp_l = out_hp_l_1; out_hp_r_1 = a0_hp*inr+a1_hp*mem_hp_r_11+a2_hp*mem_hp_r_12-b1_hp*mem_hp_r_13-b2_hp*mem_hp_r_14; mem_hp_r_12 = mem_hp_r_11; mem_hp_r_11 = inr; mem_hp_r_14 = mem_hp_r_13; mem_hp_r_13 = out_hp_r_1; out_hp_r = out_hp_r_1; n_hp > 1 ? ( out_hp_l_2 = a0_hp*out_hp_l_1+a1_hp*mem_hp_l_21+a2_hp*mem_hp_l_22-b1_hp*mem_hp_l_23-b2_hp*mem_hp_l_24; mem_hp_l_22 = mem_hp_l_21; mem_hp_l_21 = out_hp_l_1; mem_hp_l_24 = mem_hp_l_23; mem_hp_l_23 = out_hp_l_2; out_hp_l = out_hp_l_2; out_hp_r_2 = a0_hp*out_hp_r_1+a1_hp*mem_hp_r_21+a2_hp*mem_hp_r_22-b1_hp*mem_hp_r_23-b2_hp*mem_hp_r_24; mem_hp_r_22 = mem_hp_r_21; mem_hp_r_21 = out_hp_r_1; mem_hp_r_24 = mem_hp_r_23; mem_hp_r_23 = out_hp_r_2; out_hp_r = out_hp_r_2; ); n_hp > 2 ? ( out_hp_l_3 = a0_hp*out_hp_l_2+a1_hp*mem_hp_l_31+a2_hp*mem_hp_l_32-b1_hp*mem_hp_l_33-b2_hp*mem_hp_l_34; mem_hp_l_32 = mem_hp_l_31; mem_hp_l_31 = out_hp_l_2; mem_hp_l_34 = mem_hp_l_33; mem_hp_l_33 = out_hp_l_3; out_hp_l = out_hp_l_3; out_hp_r_3 = a0_hp*out_hp_r_2+a1_hp*mem_hp_r_31+a2_hp*mem_hp_r_32-b1_hp*mem_hp_r_33-b2_hp*mem_hp_r_34; mem_hp_r_32 = mem_hp_r_31; mem_hp_r_31 = out_hp_r_2; mem_hp_r_34 = mem_hp_r_33; mem_hp_r_33 = out_hp_r_3; out_hp_r = out_hp_r_3; ); n_hp > 3 ? ( out_hp_l_4 = a0_hp*out_hp_l_3+a1_hp*mem_hp_l_41+a2_hp*mem_hp_l_42-b1_hp*mem_hp_l_43-b2_hp*mem_hp_l_44; mem_hp_l_42 = mem_hp_l_41; mem_hp_l_41 = out_hp_l_3; mem_hp_l_44 = mem_hp_l_43; mem_hp_l_43 = out_hp_l_4; out_hp_l = out_hp_l_4; out_hp_r_4 = a0_hp*out_hp_r_3+a1_hp*mem_hp_r_41+a2_hp*mem_hp_r_42-b1_hp*mem_hp_r_43-b2_hp*mem_hp_r_44; mem_hp_r_42 = mem_hp_r_41; mem_hp_r_41 = out_hp_r_3; mem_hp_r_44 = mem_hp_r_43; mem_hp_r_43 = out_hp_r_4; out_hp_r = out_hp_r_4; ); n_hp > 4 ? ( out_hp_l_5 = a0_hp*out_hp_l_4+a1_hp*mem_hp_l_51+a2_hp*mem_hp_l_52-b1_hp*mem_hp_l_53-b2_hp*mem_hp_l_54; mem_hp_l_52 = mem_hp_l_51; mem_hp_l_51 = out_hp_l_4; mem_hp_l_54 = mem_hp_l_53; mem_hp_l_53 = out_hp_l_5; out_hp_l = out_hp_l_5; out_hp_r_5 = a0_hp*out_hp_r_4+a1_hp*mem_hp_r_51+a2_hp*mem_hp_r_52-b1_hp*mem_hp_r_53-b2_hp*mem_hp_r_54; mem_hp_r_52 = mem_hp_r_51; mem_hp_r_51 = out_hp_r_4; mem_hp_r_54 = mem_hp_r_53; mem_hp_r_53 = out_hp_r_5; out_hp_r = out_hp_r_5; ); n_hp > 5 ? ( out_hp_l_6 = a0_hp*out_hp_l_5+a1_hp*mem_hp_l_61+a2_hp*mem_hp_l_62-b1_hp*mem_hp_l_63-b2_hp*mem_hp_l_64; mem_hp_l_62 = mem_hp_l_61; mem_hp_l_61 = out_hp_l_5; mem_hp_l_64 = mem_hp_l_63; mem_hp_l_63 = out_hp_l_6; out_hp_l = out_hp_l_6; out_hp_r_6 = a0_hp*out_hp_r_5+a1_hp*mem_hp_r_61+a2_hp*mem_hp_r_62-b1_hp*mem_hp_r_63-b2_hp*mem_hp_r_64; mem_hp_r_62 = mem_hp_r_61; mem_hp_r_61 = out_hp_r_5; mem_hp_r_64 = mem_hp_r_63; mem_hp_r_63 = out_hp_r_6; out_hp_r = out_hp_r_6; ); ) : ( out_hp_l = inl; out_hp_r = inr; ); //********************************************* //lp n_lp > 0 ? ( out_lp_l_1 = a0_lp*out_hp_l+a1_lp*mem_lp_l_11+a2_lp*mem_lp_l_12-b1_lp*mem_lp_l_13-b2_lp*mem_lp_l_14; mem_lp_l_12 = mem_lp_l_11; mem_lp_l_11 = out_hp_l; mem_lp_l_14 = mem_lp_l_13; mem_lp_l_13 = out_lp_l_1; out_lp_l = out_lp_l_1; out_lp_r_1 = a0_lp*out_hp_r+a1_lp*mem_lp_r_11+a2_lp*mem_lp_r_12-b1_lp*mem_lp_r_13-b2_lp*mem_lp_r_14; mem_lp_r_12 = mem_lp_r_11; mem_lp_r_11 = out_hp_r; mem_lp_r_14 = mem_lp_r_13; mem_lp_r_13 = out_lp_r_1; out_lp_r = out_lp_r_1; n_lp > 1 ? ( out_lp_l_2 = a0_lp*out_lp_l_1+a1_lp*mem_lp_l_21+a2_lp*mem_lp_l_22-b1_lp*mem_lp_l_23-b2_lp*mem_lp_l_24; mem_lp_l_22 = mem_lp_l_21; mem_lp_l_21 = out_lp_l_1; mem_lp_l_24 = mem_lp_l_23; mem_lp_l_23 = out_lp_l_2; out_lp_l = out_lp_l_2; out_lp_r_2 = a0_lp*out_lp_r_1+a1_lp*mem_lp_r_21+a2_lp*mem_lp_r_22-b1_lp*mem_lp_r_23-b2_lp*mem_lp_r_24; mem_lp_r_22 = mem_lp_r_21; mem_lp_r_21 = out_lp_r_1; mem_lp_r_24 = mem_lp_r_23; mem_lp_r_23 = out_lp_r_2; out_lp_r = out_lp_r_2; ); n_lp > 2 ? ( out_lp_l_3 = a0_lp*out_lp_l_2+a1_lp*mem_lp_l_31+a2_lp*mem_lp_l_32-b1_lp*mem_lp_l_33-b2_lp*mem_lp_l_34; mem_lp_l_32 = mem_lp_l_31; mem_lp_l_31 = out_lp_l_2; mem_lp_l_34 = mem_lp_l_33; mem_lp_l_33 = out_lp_l_3; out_lp_l = out_lp_l_3; out_lp_r_3 = a0_lp*out_lp_r_2+a1_lp*mem_lp_r_31+a2_lp*mem_lp_r_32-b1_lp*mem_lp_r_33-b2_lp*mem_lp_r_34; mem_lp_r_32 = mem_lp_r_31; mem_lp_r_31 = out_lp_r_2; mem_lp_r_34 = mem_lp_r_33; mem_lp_r_33 = out_lp_r_3; out_lp_r = out_lp_r_3; ); n_lp > 3 ? ( out_lp_l_4 = a0_lp*out_lp_l_3+a1_lp*mem_lp_l_41+a2_lp*mem_lp_l_42-b1_lp*mem_lp_l_43-b2_lp*mem_lp_l_44; mem_lp_l_42 = mem_lp_l_41; mem_lp_l_41 = out_lp_l_3; mem_lp_l_44 = mem_lp_l_43; mem_lp_l_43 = out_lp_l_4; out_lp_l = out_lp_l_4; out_lp_r_4 = a0_lp*out_lp_r_3+a1_lp*mem_lp_r_41+a2_lp*mem_lp_r_42-b1_lp*mem_lp_r_43-b2_lp*mem_lp_r_44; mem_lp_r_42 = mem_lp_r_41; mem_lp_r_41 = out_lp_r_3; mem_lp_r_44 = mem_lp_r_43; mem_lp_r_43 = out_lp_r_4; out_lp_r = out_lp_r_4; ); n_lp > 4 ? ( out_lp_l_5 = a0_lp*out_lp_l_4+a1_lp*mem_lp_l_51+a2_lp*mem_lp_l_52-b1_lp*mem_lp_l_53-b2_lp*mem_lp_l_54; mem_lp_l_52 = mem_lp_l_51; mem_lp_l_51 = out_lp_l_4; mem_lp_l_54 = mem_lp_l_53; mem_lp_l_53 = out_lp_l_5; out_lp_l = out_lp_l_5; out_lp_r_5 = a0_lp*out_lp_r_4+a1_lp*mem_lp_r_51+a2_lp*mem_lp_r_52-b1_lp*mem_lp_r_53-b2_lp*mem_lp_r_54; mem_lp_r_52 = mem_lp_r_51; mem_lp_r_51 = out_lp_r_4; mem_lp_r_54 = mem_lp_r_53; mem_lp_r_53 = out_lp_r_5; out_lp_r = out_lp_r_5; ); n_lp > 5 ? ( out_lp_l_6 = a0_lp*out_lp_l_5+a1_lp*mem_lp_l_61+a2_lp*mem_lp_l_62-b1_lp*mem_lp_l_63-b2_lp*mem_lp_l_64; mem_lp_l_62 = mem_lp_l_61; mem_lp_l_61 = out_lp_l_5; mem_lp_l_64 = mem_lp_l_63; mem_lp_l_63 = out_lp_l_6; out_lp_l = out_lp_l_6; out_lp_r_6 = a0_lp*out_lp_r_5+a1_lp*mem_lp_r_61+a2_lp*mem_lp_r_62-b1_lp*mem_lp_r_63-b2_lp*mem_lp_r_64; mem_lp_r_62 = mem_lp_r_61; mem_lp_r_61 = out_lp_r_5; mem_lp_r_64 = mem_lp_r_63; mem_lp_r_63 = out_lp_r_6; out_lp_r = out_lp_r_6; ); ) : ( out_lp_l = out_hp_l; out_lp_r = out_hp_r; ); //out stereo spl0 = out_lp_l*outgain; spl1 = out_lp_r*outgain; ); @gfx 100 10 gfx_x=gfx_y=5; gfx_lineto(gfx_x, gfx_y,0); gfx_r=0.7; gfx_b=0.1; gfx_g=1; gfx_a=1; gfx_drawchar($'H'); gfx_drawchar($'P'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(cx_hp,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); gfx_y += 15; gfx_x = 5; gfx_drawchar($'L'); gfx_drawchar($'P'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(cx_lp,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); jsusfx-0.4.0/scripts/liteon/bassmanager.jsfx000066400000000000000000000200571353477307700212210ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . //****************************************************************************** // References: // 2nd order filter coefficients by Fabio Bizzetti and Robert Bristow-Johnson // waveshaper formula by Partice Tarrabia and Bram de Jong //****************************************************************************** desc: BassManager (plugin for boosting bass) slider1:0<0,1,1{Stereo,Mono}>Processing slider2:0<0,1,1{Wide,Narrow}>Spread slider3:90<30,250,0.05>Frequency (Hz) slider4:0<0,24,0.01>Boost (dB) slider5:0<0,100,0.05>Drive (%) slider6:0<0,100,0.05>Muffle (%) slider7:0<-24,24,0.05>Output (dB) slider8:0<0,4,1{Off,30,50,70,90,150,200,300}>Hipass (Hz) slider9:0<0,1,1{On,Off}>Limiter slider10:0<0,1,1{Off,On}>Oversample (x2) @init lp_output = 0; nrml=nrml=onrml=onrml=nrmr=nrmr=onrmr=onrmr=0; @slider os = slider10; //fir restoration c1 = 1; c2 = -0.75; c3 = 0.17; fgain = 4.5; //fir bandlimit bl_c1 = 0.52; bl_c2 = 0.54; bl_c3 = -0.02; //channels mono = slider1; //spread slider2 == 0 ? ( S = slider2+0.3; ) : ( S = slider2; ); //drive drive = 0+slider5/99-0.07; drv_k = drive/(1-drive); //outgain outgain = 10^(slider7/20); //ls slider4 > 0 ? ( A = 10^(slider4/20); omega = (2*$pi * slider3) / srate; sn = sin(omega); cs = cos(omega); temp1 = A + 1.0; temp2 = A - 1.0; temp3 = temp1 * cs; temp4 = temp2 * cs; beta = sn * sqrt((A * A + 1.0 )/ S - temp2 * temp2 ); s_a0 = 1.0 / (temp1 + temp4 + beta); s_a1 = (-2.0 * (temp2 + temp3)) * s_a0; s_a2 = (temp1 + temp4 - beta) * s_a0; s_b0 = (A * (temp1 - temp4 + beta)) * s_a0; s_b1 = (2.0 * A * (temp2 - temp3)) * s_a0; s_b2 = (A * (temp1 - temp4 - beta)) * s_a0; ); //hp slider8 > 0 ? ( HPF = 10+40*slider8; omega = (2*$pi * HPF ) / srate; sn = sin(omega); cs = cos(omega); alpha = sn / (2.0 * 1); // q static = 1 h_a0 = 1.0 / (1.0 + alpha); h_a1 = (-2.0 * cs) * h_a0; h_a2 = (1.0 - alpha) * h_a0; h_b1 = -(1.0 + cs) * h_a0 * 1; // gain = 1 h_b0 = -h_b1 * 0.5; ); //lp slider6 > 0 ? ( muffle = 20000-(slider6*100+9000); lp_cut = 2*$pi*muffle; lp_n = 1/(lp_cut+ 2*srate); lp_b1 = (2*srate - lp_cut)*lp_n; lp_a0 = lp_a1 = lp_cut*lp_n; ); @sample //=================================== //stereo mono == 0 ? ( //ls slider4 > 0 ? ( s_input_l = spl0; s_output_l = s_b0*s_input_l + s_b1*s_i1_l + s_b2*s_i2_l - s_a1*s_o1_l - s_a2*s_o2_l; s_o2_l=s_o1_l; s_o1_l=s_output_l; s_i2_l=s_i1_l; s_i1_l=s_input_l; s_input_r = spl1; s_output_r = s_b0*s_input_r + s_b1*s_i1_r + s_b2*s_i2_r - s_a1*s_o1_r - s_a2*s_o2_r; s_o2_r=s_o1_r; s_o1_r=s_output_r; s_i2_r=s_i1_r; s_i1_r=s_input_r; ) : ( s_output_l = spl0; s_output_r = spl1; ); slider5 > 0 ? ( os == 1 ? ( //--------------------------------------- //power series in ps_out1l = 0.5*(s_output_l+ps_out2l); ps_out2l = 0.5*ps_out1l; ps_out1r = 0.5*(s_output_r+ps_out2r); ps_out2r = 0.5*ps_out1r; //--------------------------------------- //drive o_in1l = (1+drv_k)*ps_out1l/(1+drv_k*abs(ps_out1l)); o_in2l = (1+drv_k)*ps_out2l/(1+drv_k*abs(ps_out2l)); o_in1r = (1+drv_k)*ps_out1r/(1+drv_k*abs(ps_out1r)); o_in2r = (1+drv_k)*ps_out2r/(1+drv_k*abs(ps_out2r)); //--------------------------------------- //bandlimit bl3_l1 = bl2_l1; bl3_r1 = bl2_r1; bl3_l2 = bl2_l2; bl3_r2 = bl2_r2; bl2_l1 = bl1_l1; bl2_r1 = bl1_r1; bl2_l2 = bl1_l2; bl2_r2 = bl1_r2; bl1_l1 = o_in1l; bl1_r1 = o_in1r; bl1_l2 = o_in2l; bl1_r2 = o_in2r; bl_out1l = (bl1_l1*bl_c1 + bl2_l1*bl_c2 + bl3_l1*bl_c3); bl_out1r = (bl1_r1*bl_c1 + bl2_r1*bl_c2 + bl3_r1*bl_c3); bl_out2l = (bl1_l2*bl_c1 + bl2_l2*bl_c2 + bl3_l2*bl_c3); bl_out2r = (bl1_r2*bl_c1 + bl2_r2*bl_c2 + bl3_r2*bl_c3); //--------------------------------------- //power series out o_out1l = 0.5*(bl_out1l+o_out2l); o_out2l = 0.5*(bl_out2l+o_out1l); o_out1r = 0.5*(bl_out1r+o_out2r); o_out2r = 0.5*(bl_out2r+o_out1r); //--------------------------------------- //fir restoration s3l = s2l; s3r = s2r; s2l = s1l; s2r = s1r; s1l = o_out1l; s1r = o_out1r; drv_output_l = (s1l*c1+s2l*c2+s3l*c3)*fgain; drv_output_r = (s1r*c1+s2r*c2+s3r*c3)*fgain; ) : ( drv_output_l = (1+drv_k)*s_output_l/(1+drv_k*abs(s_output_l)); drv_output_r = (1+drv_k)*s_output_r/(1+drv_k*abs(s_output_r)); ); ) : ( drv_output_l = s_output_l; drv_output_r = s_output_r; ); //hp slider8 > 0 ? ( h_input_l = drv_output_l; h_output_l = h_b0*h_input_l + h_b1*h_i1_l + h_b0*h_i2_l - h_a1*h_o1_l - h_a2*h_o2_l; h_o2_l=h_o1_l; h_o1_l=h_output_l; h_i2_l=h_i1_l; h_i1_l=h_input_l; h_input_r = drv_output_r; h_output_r = h_b0*h_input_r + h_b1*h_i1_r + h_b0*h_i2_r - h_a1*h_o1_r - h_a2*h_o2_r; h_o2_r=h_o1_r; h_o1_r=h_output_r; h_i2_r=h_i1_r; h_i1_r=h_input_r; ) : ( h_output_l = drv_output_l; h_output_r = drv_output_r; ); //lp slider6 > 0 ? ( lp_in_l = h_output_l; lp_output_l = lp_in_l*lp_a0 + lp_in_l*lp_a1 + lp_output_l*lp_b1; lp_in_r = h_output_r; lp_output_r = lp_in_r*lp_a0 + lp_in_r*lp_a1 + lp_output_r*lp_b1; ) : ( lp_output_l = h_output_l; lp_output_r = h_output_r; ); //output output_l = lp_output_l*outgain; output_r = lp_output_r*outgain; slider9 == 0 ? ( output_l = min(max(output_l,-0.98),0.98); output_r = min(max(output_r,-0.98),0.98); ); spl0=output_l; spl1=output_r; //=================================== //mono ) : ( //ls slider4 > 0 ? ( s_input = (spl0+spl1)/2; s_output = s_b0*s_input + s_b1*s_i1 + s_b2*s_i2 - s_a1*s_o1 - s_a2*s_o2; s_o2=s_o1; s_o1=s_output; s_i2=s_i1; s_i1=s_input; ) : ( s_output = (spl0+spl1)/2; ); slider5 > 0 ? ( os == 1 ? ( //power series in ps_out1l = 0.5*(s_output+ps_out2l); ps_out2l = 0.5*ps_out1l; //drive o_in1l = (1+drv_k)*ps_out1l/(1+drv_k*abs(ps_out1l)); o_in2l = (1+drv_k)*ps_out2l/(1+drv_k*abs(ps_out2l)); //--------------------------- //bandlimit bl3_1 = bl2_1; bl3_2 = bl2_2; bl2_1 = bl1_1; bl2_2 = bl1_2; bl1_1 = o_in1l; bl1_2 = o_in2l; bl_out1 = (bl1_1*bl_c1 + bl2_1*bl_c2 + bl3_1*bl_c3); bl_out2 = (bl1_2*bl_c1 + bl2_2*bl_c2 + bl3_2*bl_c3); //power series out o_out1l = 0.5*(bl_out1+o_out2l); o_out2l = 0.5*(bl_out2+o_out1l); //fir restoration s3l = s2l; s2l = s1l; s1l = o_out1l; drv_output = (s1l*c1+s2l*c2+s3l*c3)*fgain; ) : ( drv_output = (1+drv_k)*s_output/(1+drv_k*abs(s_output)); ); ) : ( drv_output = s_output; ); //hp slider8 > 0 ? ( h_input = drv_output; h_output = h_b0*h_input + h_b1*h_i1 + h_b0*h_i2 - h_a1*h_o1 - h_a2*h_o2; h_o2=h_o1; h_o1=h_output; h_i2=h_i1; h_i1=h_input; ) : ( h_output = drv_output; ); //lp slider6 > 0 ? ( lp_in = h_output; lp_output = lp_in*lp_a0 + lp_in*lp_a1 + lp_output*lp_b1; ) : ( lp_output = h_output; ); //output output = lp_output*outgain; slider9 == 0 ? ( output = min(max(output,-0.98),0.98); ); spl0=spl1=output; ); jsusfx-0.4.0/scripts/liteon/butterworth24db.jsfx000066400000000000000000000111701353477307700217770ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . //****************************************************************************** // Reference: posted by Zxform - baltrax@hotmail.com // Warning: Automate the cutoff of this filter at your own risk !!! // Note: Limiter automatically kicks in below 300hz for speaker protection! //****************************************************************************** desc:Butterworth Filter slider1:0<0,1,1{Stereo,Mono}>Processing slider2:0<0,1,1{LP (24dB/oct),HP (6dB/oct)}>Filter Type slider3:100<0,100,0.05>Cutoff (Scale) slider4:0<0,0.9>Resonance (Mix/Max) slider5:0<-25,25,0.05>Output (dB) slider6:0<0,1,1{On,Off}>Limiter @init mv=2^(-0.2/6); history1=history2=history3=history4=0; history1l=history2l=history3l=history4l=0; history1r=history2r=history3r=history4r=0; new_hist=new_histl=new_histr=0; bq = 6; pi = 22/7; fs = srate; t0 = 4*fs*fs; t1 = 8*fs*fs; t2 = 2*fs; t3 = pi/fs; @slider ftype = slider2; mono = slider1; limiter = slider6; sx = 16+slider3*1.20103; cutoff = floor(exp(sx*log(1.059))*8.17742); res = slider3; outgain = 10^(slider5/20); wp = t2*tan(t3*cutoff); cutoff > 150 ? ( q = (slider4*bq)+1; ) : ( q = (0.1*bq)+1; ); b1 = (0.765367/q)/wp; b2 = 1/(wp*wp); bd_tmp = t0*b2+1; bd = 1/(bd_tmp+t2*b1); //bd = 1/(b1+t2*bd_tmp); gain = bd; coef2 = (2-t1*b2); coef0 = coef2*bd; coef1 = (bd_tmp-t2*b1)*bd; b1 = (1.847759/q)/wp; bd = 1/(bd_tmp+t2*b1); //bd = 1/(b1+t2*bd_tmp); gain *= bd; coef2 *= bd; coef3 = (bd_tmp-t2*b1)*bd; @sample //stereo mono == 0 ? ( //filter inputl = spl0; inputr = spl1; outputl = inputl*gain; outputr = inputr*gain; outputl -= history1l*coef0; outputr -= history1r*coef0; new_histl = outputl-history2l*coef1; new_histr = outputr-history2r*coef1; outputl = new_histl+history1l*2; outputr = new_histr+history1r*2; outputl += history2l; outputr += history2r; history2l = history1l; history2r = history1r; history1l = new_histl; history1r = new_histr; outputl -= history3l*coef2; outputr -= history3r*coef2; new_histl = outputl-history4l*coef3; new_histr = outputr-history4r*coef3; outputl = new_histl+history3l*2; outputr = new_histr+history3r*2; outputl += history4l; outputr += history4r; history4l = history3l; history4r = history3r; history3l = new_histl; history3r = new_histr; ftype == 1 ? ( outputl = inputl-outputl; outputr = inputr-outputr; ); //auto limit below 300hz cutoff < 300 ? ( outputl = min(max((outputl),-mv),mv); outputr = min(max((outputr),-mv),mv); ); outputl = outputl*outgain; outputr = outputr*outgain; //limiter limiter == 0 ? ( spl0 = min(max((outputl),-mv),mv); spl1 = min(max((outputr),-mv),mv); ) : ( spl0 = outputl; spl1 = outputr; ); //mono ) : ( //filter input = (spl0+spl1)/2; hp_bp = input*gain+history1*coef0; output = input*gain; output -= history1*coef0; new_hist = output-history2*coef1; output = new_hist+history1*2; output += history2; history2 = history1; history1 = new_hist; output -= history3*coef2; new_hist = output-history4*coef3; output = new_hist+history3*2; output += history4; history4 = history3; history3 = new_hist; //filter type ftype == 1 ? ( output = input-output; ); //auto limit below 300hz cutoff < 300 ? ( output = min(max((output),-mv),mv); ); output = output*outgain; //limiter limiter == 0 ? ( spl0 = spl1 = min(max((output),-mv),mv); ) : ( spl0 = spl1 = (output); ); ); @gfx 100 10 gfx_x=gfx_y=5; gfx_lineto(gfx_x, gfx_y,0); gfx_r=gfx_b=0; gfx_g=gfx_a=1; gfx_drawchar($'F'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(cutoff,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); jsusfx-0.4.0/scripts/liteon/cheby24db.jsfx000066400000000000000000000120001353477307700204710ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . //********************************************************** // Cheby Type I // References: // Christian W. Budde, Cockos, Wiki //********************************************************** desc:Chebyshev Filter slider1:0<0,1,1{Stereo,Mono}>Processing slider2:0<0,2,1{LP (24dB/oct),HP (6dB/oct),BP (6dB/oct)}>Filter Type slider3:100<0,100,0.05>Cutoff (Scale) slider4:0.3<0,0.9,0.0005>Passband ripple (Less/More) slider5:0<-25,25,0.05>Output (dB) slider6:0<0,1,1{On,Off}>Limiter @init //cDenorm = 10^-30; cDenorm = 0; mv=2^(-0.2/6); e = 2.718281828459045; pi = 3.141592653589793; cutoff = 20000; @slider mono = slider1; ftype = slider2; fs = srate; outgain = 10^(slider5/20); limiter = slider6; sx = 16+slider3*1.20103; cutoff = floor(exp(sx*log(1.059))*8.17742); cutoff < 90 ? ( pbr = 0.5; ) : ( pbr = 1.03-0.1-slider4; ); K = tan(pi*cutoff/srate); sg = (e^pbr-e^(-pbr))/2; cg = (e^pbr+e^(-pbr))/2; cg *= cg; Coeff0 = 1/(cg-0.85355339059327376220042218105097); Coeff1 = K*Coeff0*sg*1.847759065022573512256366378792; Coeff2 = 1/(cg-0.14644660940672623779957781894758); Coeff3 = K*Coeff2*sg*0.76536686473017954345691996806; K *= K; tgt_a0 = 1/(Coeff1+K+Coeff0); tgt_a1 = 2*(Coeff0-K)*tgt_a0; tgt_a2 = (Coeff1-K-Coeff0)*tgt_a0; tgt_b0 = tgt_a0*K; tgt_b1 = 2*tgt_b0; tgt_b2 = tgt_b0; tgt_a3 = 1/(Coeff3+K+Coeff2); tgt_a4 = 2*(Coeff2-K)*tgt_a3; tgt_a5 = (Coeff3-K-Coeff2)*tgt_a3; tgt_b3 = tgt_a3*K; tgt_b4 = 2*tgt_b3; tgt_b5 = tgt_b3; @block //interpolate all coeffs d_a1 = (tgt_a1-src_a1)/samplesblock; a1 = src_a1; src_a1 = tgt_a1; d_a2 = (tgt_a2-src_a2)/samplesblock; a2 = src_a2; src_a2 = tgt_a2; d_a4 = (tgt_a4-src_a4)/samplesblock; a4 = src_a4; src_a4 = tgt_a4; d_a5 = (tgt_a5-src_a5)/samplesblock; a5 = src_a5; src_a5 = tgt_a5; d_b0 = (tgt_b0-src_b0)/samplesblock; b0 = src_b0; src_b0 = tgt_b0; d_b1 = (tgt_b1-src_b1)/samplesblock; b1 = src_b1; src_b1 = tgt_b1; d_b2 = (tgt_b2-src_b2)/samplesblock; b2 = src_b2; src_b2 = tgt_b2; d_b3 = (tgt_b3-src_b3)/samplesblock; b3 = src_b3; src_b3 = tgt_b3; d_b4 = (tgt_b4-src_b4)/samplesblock; b4 = src_b4; src_b4 = tgt_b4; d_b5 = (tgt_b5-src_b5)/samplesblock; b5 = src_b5; src_b5 = tgt_b5; @sample //interpolate a1 += d_a1; a2 += d_a2; a4 += d_a4; a5 += d_a5; b0 += d_b0; b1 += d_b1; b2 += d_b2; b3 += d_b3; b4 += d_b4; b5 += d_b5; //stereo mono == 0 ? ( InputL = spl0; InputR = spl1; Stage1L = b0*InputL + State0L; Stage1R = b0*InputR + State0R; State0L = b1*InputL + a1*Stage1L + State1L; State0R = b1*InputR + a1*Stage1R + State1R; State1L = b2*InputL + a2*Stage1L; State1R = b2*InputR + a2*Stage1R; OutputL = b3*Stage1L + State2L; OutputR = b3*Stage1R + State2R; State2L = b4*Stage1L + a4*OutputL + State3L; State2R = b4*Stage1R + a4*OutputR + State3R; State3L = b5*Stage1L + a5*OutputL; State3R = b5*Stage1R + a5*OutputR; ftype == 0 ? ( outl = OutputL; outr = OutputR; ); ftype == 1 ? ( outl = InputL-OutputL; outr = InputR-OutputR; ); ftype == 2 ? ( outl = 2*(Stage1L-OutputL); outr = 2*(Stage1R-OutputR); ); outl = outl*outgain; outr = outr*outgain; //limiter limiter == 0 ? ( spl0 = min(max((outl+cDenorm),-mv),mv); spl1 = min(max((outr+cDenorm),-mv),mv); ) : ( spl0 = outl; spl1 = outr; ); //mono ) : ( Input = ((spl0+spl1)/2); Stage1 = b0*Input + State0; State0 = b1*Input + a1*Stage1 + State1; State1 = b2*Input + a2*Stage1; Output = b3*Stage1 + State2; State2 = b4*Stage1 + a4*Output + State3; State3 = b5*Stage1 + a5*Output; ftype == 0 ? ( out = output; ); ftype == 1 ? ( out = Input-Output; ); ftype == 2 ? ( out = 2*(Stage1-Output); ); out = out*outgain; //limiter limiter == 0 ? ( spl0 = min(max((out+cDenorm),-mv),mv); spl1 = min(max((out+cDenorm),-mv),mv); ) : ( spl0 = out; spl1 = out; ); ); @gfx 100 10 gfx_x=gfx_y=5; gfx_lineto(gfx_x, gfx_y,0); gfx_r=gfx_b=0; gfx_g=gfx_a=1; gfx_drawchar($'F'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(cutoff,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); jsusfx-0.4.0/scripts/liteon/deesser.jsfx000066400000000000000000000371631353477307700203760ustar00rootroot00000000000000// (C) 2009, Lubomir I. Ivanov // // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . // //****************************************************************************** // Includes optimized version of Linkwitz-Riley (LR2) filters // by T. Lossius - ttblue project //****************************************************************************** //============================================================================== // init //============================================================================== desc: De-Esser slider1:1<0,1,1{Stereo,Mono}>Processing slider2:1<0,1,1{Bandpass,Hipass}>Target Type slider3:0<0,1,1{Off,On}>Monitor slider4:4000<1500,12000,1>Frequency (Hz) slider5:1.5<0.1,3.1,0.0005>Bandwidth (Oct) slider6:-25<-80,0,0.01>Threshold (dB) slider7:4<1,20,0.01>Ratio slider8:0<0,1,1{A: 3 µs - R: 50 ms,A: 30 µs - R: 100 ms,A: 100 µs - R: 300 ms}>Time Constants slider9:0<-24,24,0.001>Gain (-inf/+24dB) @init n = 0; sqrt2 = sqrt(2); s2 = sqrt2/2; cgain = 1; cdenorm = 10^-30; e10 = 10^-10; g_meter = gr_meter = g_reset = 1; gr_meter_decay = exp(1/(1*srate)); //============================================================================== @slider //============================================================================== //------------------------------------------------------------------------------ // settings //------------------------------------------------------------------------------ mono = slider1; target = slider2; monitor = slider3; fc = slider4; bw = slider5; //comp thr = pow(10, 2 * (slider6/80+1) - 2); rat = (slider7-1)/19; slider8 == 0 ? ( att = pow(10, -0.002 - 3.97772619*(0/100)); rel = pow(10, -3.11 - 1.8698*(21.20/100)); ); slider8 == 1 ? ( att = pow(10, -0.002 - 3.97772619*(9.71/100)); rel = pow(10, -3.11 - 1.8698*(37.19/100)); ); slider8 == 2 ? ( att = pow(10, -0.002 - 3.97772619*(20.97/100)); rel = pow(10, -3.11 - 1.8698*(62.61/100)); ); //outgain slider9 == -24 ? ( outgain = 0; ) : ( outgain = 10^(slider9/20); ); //------------------------------------------------------------------------------ // crossover type: 2 or 3 bands // this is a bit confusing, but optimized for js ! //------------------------------------------------------------------------------ target == 0 ? ( fh = min((fc + fc*bw/2),20000); //------------------------------ // high-band split - s1 (at fh) //------------------------------ fpi = $pi*fh; wc = 2*fpi; wc2 = wc*wc; wc22 = 2*wc2; k = wc/tan(fpi/srate); k2 = k*k; k22 = 2*k2; wck2 = 2*wc*k; tmpk = (k2+wc2+wck2); tgt_b1_s1 = (-k22+wc22)/tmpk; tgt_b2_s1 = (-wck2+k2+wc2)/tmpk; //--------------- // low-pass (s1) //--------------- tgt_a0_s1_lp = (wc2)/tmpk; tgt_a1_s1_lp = (wc22)/tmpk; tgt_a2_s1_lp = (wc2)/tmpk; //---------------- // high-pass (s1) //---------------- tgt_a0_s1_hp = (k2)/tmpk; tgt_a1_s1_hp = (-k22)/tmpk; tgt_a2_s1_hp = (k2)/tmpk; //---------------- // prepare for s0 //---------------- fl = fc - fc*bw/4; fpi = $pi*fl; ) : ( fpi = $pi*fc; ); //--------------------------------------------- // low-band split - s0 (case: at 'fc' or 'fl') // s0 is always processed (2 band split) //--------------------------------------------- wc = 2*fpi; wc2 = wc*wc; wc22 = 2*wc2; k = wc/tan(fpi/srate); k2 = k*k; k22 = 2*k2; wck2 = 2*wc*k; tmpk = (k2+wc2+wck2); tgt_b1_s0 = (-k22+wc22)/tmpk; tgt_b2_s0 = (-wck2+k2+wc2)/tmpk; //--------------- // low-pass (s0) //--------------- tgt_a0_s0_lp = (wc2)/tmpk; tgt_a1_s0_lp = (wc22)/tmpk; tgt_a2_s0_lp = (wc2)/tmpk; //---------------- // high-pass (s0) //---------------- tgt_a0_s0_hp = (k2)/tmpk; tgt_a1_s0_hp = (-k22)/tmpk; tgt_a2_s0_hp = (k2)/tmpk; //============================================================================== @sample //============================================================================== //------------------------------------------------------------------------------ // mono //------------------------------------------------------------------------------ mono == 1 ? ( //---------------------------------- // s0, b //---------------------------------- b1_s0 += d_b1_s0; b2_s0 += d_b2_s0; //---------- // s0, lp //---------- a0_s0_lp += d_a0_s0_lp; a1_s0_lp += d_a1_s0_lp; a2_s0_lp += d_a2_s0_lp; s0_lp_l_in = (spl0+spl1)*0.5; s0_lp_l_output = a0_s0_lp*s0_lp_l_in + s0_lp_l_xm0; s0_lp_l_xm0 = a1_s0_lp*s0_lp_l_in - b1_s0*s0_lp_l_output + s0_lp_l_xm1; s0_lp_l_xm1 = a2_s0_lp*s0_lp_l_in - b2_s0*s0_lp_l_output; //---------- // s0, hp //---------- a0_s0_hp += d_a0_s0_hp; a1_s0_hp += d_a1_s0_hp; a2_s0_hp += d_a2_s0_hp; s0_hp_l_in = (spl0+spl1)*0.5; s0_hp_l_output = a0_s0_hp*s0_hp_l_in + s0_hp_l_xm0; s0_hp_l_xm0 = a1_s0_hp*s0_hp_l_in - b1_s0*s0_hp_l_output + s0_hp_l_xm1; s0_hp_l_xm1 = a2_s0_hp*s0_hp_l_in - b2_s0*s0_hp_l_output; s0_hp_l_output *= -1; //---------------------------------- // s1, b //---------------------------------- target == 0 ? ( b1_s1 += d_b1_s1; b2_s1 += d_b2_s1; //---------- // s1, lp //---------- a0_s1_lp += d_a0_s1_lp; a1_s1_lp += d_a1_s1_lp; a2_s1_lp += d_a2_s1_lp; s1_lp_l_in = s0_hp_l_output; s1_lp_l_output = a0_s1_lp*s1_lp_l_in + s1_lp_l_xm0; s1_lp_l_xm0 = a1_s1_lp*s1_lp_l_in - b1_s1*s1_lp_l_output + s1_lp_l_xm1; s1_lp_l_xm1 = a2_s1_lp*s1_lp_l_in - b2_s1*s1_lp_l_output; //---------- // s1, hp //---------- a0_s1_hp += d_a0_s1_hp; a1_s1_hp += d_a1_s1_hp; a2_s1_hp += d_a2_s1_hp; s1_hp_l_in = s0_hp_l_output; s1_hp_l_output = a0_s1_hp*s1_hp_l_in + s1_hp_l_xm0; s1_hp_l_xm0 = a1_s1_hp*s1_hp_l_in - b1_s1*s1_hp_l_output + s1_hp_l_xm1; s1_hp_l_xm1 = a2_s1_hp*s1_hp_l_in - b2_s1*s1_hp_l_output; s1_hp_l_output *= -1; //--------------------------- // set process band (cband) //--------------------------- cband_l = s1_lp_l_output; ) : ( cband_l = s0_hp_l_output; ); //--------------------------- // compressor //--------------------------- dtl = abs(cband_l); (dtl > envl) ? envl = envl + att*(dtl - envl) : envl = envl*(1 - rel); (envl > thr) ? (cgainl = 1+(rat*((envl/thr)-1)); g_reset = 0;) : (cgainl = 1; g_reset = 1); (envl < e10) ? envl = 0; //-------------------------- // update gr meter //-------------------------- g_reset == 0 ? g_meter = 1/cgainl : g_meter = 1; //----------------------- // monitor or sum bands //----------------------- monitor == 1 ? ( outl = cband_l*outgain/cgainl+cdenorm; ) : ( target == 0 ? ( sum_l = s0_lp_l_output+cband_l/cgainl+s1_hp_l_output; ) : ( sum_l = s0_lp_l_output+cband_l/cgainl; ); outl = sum_l*outgain+cdenorm; ); //check clip (outl < -1 || outl > 1) ? clip = 1; spl0 = spl1 = outl; //********** // test output // spl0 = spl1 = s1_lp_l_output; //********** //------------------------------------------------------------------------------ // stereo //------------------------------------------------------------------------------ ) : ( //---------------------------------- // s0, b //---------------------------------- b1_s0 += d_b1_s0; b2_s0 += d_b2_s0; //---------- // s0, lp //---------- a0_s0_lp += d_a0_s0_lp; a1_s0_lp += d_a1_s0_lp; a2_s0_lp += d_a2_s0_lp; s0_lp_l_in = spl0; s0_lp_l_output = a0_s0_lp*s0_lp_l_in + s0_lp_l_xm0; s0_lp_l_xm0 = a1_s0_lp*s0_lp_l_in - b1_s0*s0_lp_l_output + s0_lp_l_xm1; s0_lp_l_xm1 = a2_s0_lp*s0_lp_l_in - b2_s0*s0_lp_l_output; s0_lp_r_in = spl1; s0_lp_r_output = a0_s0_lp*s0_lp_r_in + s0_lp_r_xm0; s0_lp_r_xm0 = a1_s0_lp*s0_lp_r_in - b1_s0*s0_lp_r_output + s0_lp_r_xm1; s0_lp_r_xm1 = a2_s0_lp*s0_lp_r_in - b2_s0*s0_lp_r_output; //---------- // s0, hp //---------- a0_s0_hp += d_a0_s0_hp; a1_s0_hp += d_a1_s0_hp; a2_s0_hp += d_a2_s0_hp; s0_hp_l_in = spl0; s0_hp_l_output = a0_s0_hp*s0_hp_l_in + s0_hp_l_xm0; s0_hp_l_xm0 = a1_s0_hp*s0_hp_l_in - b1_s0*s0_hp_l_output + s0_hp_l_xm1; s0_hp_l_xm1 = a2_s0_hp*s0_hp_l_in - b2_s0*s0_hp_l_output; s0_hp_l_output *= -1; s0_hp_r_in = spl1; s0_hp_r_output = a0_s0_hp*s0_hp_r_in + s0_hp_r_xm0; s0_hp_r_xm0 = a1_s0_hp*s0_hp_r_in - b1_s0*s0_hp_r_output + s0_hp_r_xm1; s0_hp_r_xm1 = a2_s0_hp*s0_hp_r_in - b2_s0*s0_hp_r_output; s0_hp_r_output *= -1; //---------------------------------- // s1, b //---------------------------------- target == 0 ? ( b1_s1 += d_b1_s1; b2_s1 += d_b2_s1; //---------- // s1, lp //---------- a0_s1_lp += d_a0_s1_lp; a1_s1_lp += d_a1_s1_lp; a2_s1_lp += d_a2_s1_lp; s1_lp_l_in = s0_hp_l_output; s1_lp_l_output = a0_s1_lp*s1_lp_l_in + s1_lp_l_xm0; s1_lp_l_xm0 = a1_s1_lp*s1_lp_l_in - b1_s1*s1_lp_l_output + s1_lp_l_xm1; s1_lp_l_xm1 = a2_s1_lp*s1_lp_l_in - b2_s1*s1_lp_l_output; s1_lp_r_in = s0_hp_r_output; s1_lp_r_output = a0_s1_lp*s1_lp_r_in + s1_lp_r_xm0; s1_lp_r_xm0 = a1_s1_lp*s1_lp_r_in - b1_s1*s1_lp_r_output + s1_lp_r_xm1; s1_lp_r_xm1 = a2_s1_lp*s1_lp_r_in - b2_s1*s1_lp_r_output; //---------- // s1, hp //---------- a0_s1_hp += d_a0_s1_hp; a1_s1_hp += d_a1_s1_hp; a2_s1_hp += d_a2_s1_hp; s1_hp_l_in = s0_hp_l_output; s1_hp_l_output = a0_s1_hp*s1_hp_l_in + s1_hp_l_xm0; s1_hp_l_xm0 = a1_s1_hp*s1_hp_l_in - b1_s1*s1_hp_l_output + s1_hp_l_xm1; s1_hp_l_xm1 = a2_s1_hp*s1_hp_l_in - b2_s1*s1_hp_l_output; s1_hp_l_output *= -1; s1_hp_r_in = s0_hp_r_output; s1_hp_r_output = a0_s1_hp*s1_hp_r_in + s1_hp_r_xm0; s1_hp_r_xm0 = a1_s1_hp*s1_hp_r_in - b1_s1*s1_hp_r_output + s1_hp_r_xm1; s1_hp_r_xm1 = a2_s1_hp*s1_hp_r_in - b2_s1*s1_hp_r_output; s1_hp_r_output *= -1; //--------------------------- // set process band (cband) //--------------------------- cband_l = s1_lp_l_output; cband_r = s1_lp_r_output; ) : ( cband_l = s0_hp_l_output; cband_r = s0_hp_r_output; ); //--------------------------- // compressor //--------------------------- dtl = abs(cband_l); dtr = abs(cband_r); dtr > dtl ? dtl = dtr; (dtl > envl) ? envl = envl + att*(dtl - envl) : envl = envl*(1 - rel); (envl > thr) ? (cgainl = 1+(rat*((envl/thr)-1)); g_reset = 0;) : (cgainl = 1; g_reset = 1); (envl < e10) ? envl = 0; dtr = abs(cband_r); //-------------------------- // update gr meter //-------------------------- g_reset == 0 ? ( (cgainl > cgainr) ? g_meter = 1/cgainl : g_meter = 1/cgainr; ) : ( g_meter = 1; ); //----------------------- // monitor or sum bands //----------------------- monitor == 1 ? ( outl = cband_l*outgain/cgainl+cdenorm; outr = cband_r*outgain/cgainl+cdenorm; ) : ( target == 0 ? ( sum_l = s0_lp_l_output+cband_l/cgainl+s1_hp_l_output; sum_r = s0_lp_r_output+cband_r/cgainl+s1_hp_r_output; ) : ( sum_l = s0_lp_l_output+cband_l/cgainl; sum_r = s0_lp_r_output+cband_r/cgainl; ); outl = sum_l*outgain+cdenorm; outr = sum_r*outgain+cdenorm; ); //check clip (outl < -1 || outl > 1) ? clip = 1; (outr < -1 || outr > 1) ? clip = 1; spl0 = outl; spl1 = outr; ); //********** // test output // spl0 = spl1 = s1_lp_l_output; //********** //----------------------------------------- // meter decay //----------------------------------------- g_meter < gr_meter ? gr_meter=g_meter : gr_meter*=gr_meter_decay; @block //----------------------------------------- // update clip indicator //----------------------------------------- bps = srate/samplesblock; n > bps ? ( clip = 0; n = 0; ); n += 1; //============================================================================== // interpolate *all* coefficients here //============================================================================== //------------------------------------------------------------------------------ // s0 //------------------------------------------------------------------------------ //------------------- // s0 b //------------------- d_b1_s0 = (tgt_b1_s0-src_b1_s0)/samplesblock; b1_s0 = src_b1_s0; src_b1_s0 = tgt_b1_s0; d_b2_s0 = (tgt_b2_s0-src_b2_s0)/samplesblock; b2_s0 = src_b2_s0; src_b2_s0 = tgt_b2_s0; //------------------- // s0 a lp //------------------- d_a0_s0_lp = (tgt_a0_s0_lp-src_a0_s0_lp)/samplesblock; a0_s0_lp = src_a0_s0_lp; src_a0_s0_lp = tgt_a0_s0_lp; d_a1_s0_lp = (tgt_a1_s0_lp-src_a1_s0_lp)/samplesblock; a1_s0_lp = src_a1_s0_lp; src_a1_s0_lp = tgt_a1_s0_lp; d_a2_s0_lp = (tgt_a2_s0_lp-src_a2_s0_lp)/samplesblock; a2_s0_lp = src_a2_s0_lp; src_a2_s0_lp = tgt_a2_s0_lp; //------------------- // s0 a hp //------------------- d_a0_s0_hp = (tgt_a0_s0_hp-src_a0_s0_hp)/samplesblock; a0_s0_hp = src_a0_s0_hp; src_a0_s0_hp = tgt_a0_s0_hp; d_a1_s0_hp = (tgt_a1_s0_hp-src_a1_s0_hp)/samplesblock; a1_s0_hp = src_a1_s0_hp; src_a1_s0_hp = tgt_a1_s0_hp; d_a2_s0_hp = (tgt_a2_s0_hp-src_a2_s0_hp)/samplesblock; a2_s0_hp = src_a2_s0_hp; src_a2_s0_hp = tgt_a2_s0_hp; //------------------------------------------------------------------------------ // s1 //------------------------------------------------------------------------------ target == 0 ? ( //------------------- // s1 b //------------------- d_b1_s1 = (tgt_b1_s1-src_b1_s1)/samplesblock; b1_s1 = src_b1_s1; src_b1_s1 = tgt_b1_s1; d_b2_s1 = (tgt_b2_s1-src_b2_s1)/samplesblock; b2_s1 = src_b2_s1; src_b2_s1 = tgt_b2_s1; //------------------- // s1 a lp //------------------- d_a0_s1_lp = (tgt_a0_s1_lp-src_a0_s1_lp)/samplesblock; a0_s1_lp = src_a0_s1_lp; src_a0_s1_lp = tgt_a0_s1_lp; d_a1_s1_lp = (tgt_a1_s1_lp-src_a1_s1_lp)/samplesblock; a1_s1_lp = src_a1_s1_lp; src_a1_s1_lp = tgt_a1_s1_lp; d_a2_s1_lp = (tgt_a2_s1_lp-src_a2_s1_lp)/samplesblock; a2_s1_lp = src_a2_s1_lp; src_a2_s1_lp = tgt_a2_s1_lp; //------------------- // s1 a hp //------------------- d_a0_s1_hp = (tgt_a0_s1_hp-src_a0_s1_hp)/samplesblock; a0_s1_hp = src_a0_s1_hp; src_a0_s1_hp = tgt_a0_s1_hp; d_a1_s1_hp = (tgt_a1_s1_hp-src_a1_s1_hp)/samplesblock; a1_s1_hp = src_a1_s1_hp; src_a1_s1_hp = tgt_a1_s1_hp; d_a2_s1_hp = (tgt_a2_s1_hp-src_a2_s1_hp)/samplesblock; a2_s1_hp = src_a2_s1_hp; src_a2_s1_hp = tgt_a2_s1_hp; ); //============================================================================= @gfx 425 16 //============================================================================= //--------------------------------- // set gr meter //--------------------------------- gr_meter *= exp(1/30); gr_meter > 1 ? gr_meter=1; gfx_r=0.6; gfx_g=0.4; gfx_b=0.5; gfx_a=0.8; meter_bot=20; meter_h=min(gfx_h,21); xscale=gfx_w*20/meter_bot; gfx_y=0; gfx_x=gfx_w + log10(gr_meter)*xscale; gfx_rectto(gfx_w,meter_h); //--------------------------------- // draw scale //--------------------------------- gfx_r=1; gfx_b=1; gfx_g=1; gfx_a=0.6; g = s2; while( gfx_x=gfx_w + log10(g)*xscale; gfx_x >= 0 ? ( gfx_y=0; gfx_lineto(gfx_x,meter_h-1,0); gfx_y=meter_h-gfx_texth-5; gfx_x+=4; gfx_drawnumber(log10(g)*20,0); gfx_drawchar($'d'); gfx_drawchar($'B'); ); g*=s2; gfx_x >=0; ); gfx_x=0; gfx_y=meter_h; gfx_lineto(gfx_w,meter_h,0); gfx_a=0.9; gfx_x=gfx_w - 61; gfx_y=meter_h + gfx_texth - 1; //--------------------------------- // clip indicator //--------------------------------- gfx_x = gfx_w/1.1; gfx_r=1; gfx_g=0; gfx_b=0; clip == 1 ? ( gfx_a = 1; ) : ( gfx_a = 0.4; ); gfx_drawchar($'*'); jsusfx-0.4.0/scripts/liteon/farmodulator.jsfx000066400000000000000000000057651353477307700214460ustar00rootroot00000000000000// (C) 2009, Lubomir I. Ivanov // // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . // desc:F/A/R Modulator //----------------------------------------------------- slider1:0<0,1,0.0001>F0 sine (carrier) slider2:0.4<0,1,0.0001>F1 sine (mod) slider3:0<0,2,1{FM,M1,M2}>Mode slider4:0<0,1,1{Sine,Input}>Modulator slider5:0<-24,24,0.1>Carrier gain (dB) slider6:0<-24,24,0.1>Mod gain (dB) slider7:14<1,100,1>Mod Drive (*x) slider8:-6<-24,24,0.1>Out gain (dB) //----------------------------------------------------- @init pi2=6.283185307179586476925286766559; // 2*$pi ln22k=9.9987977323404529055331500634764; // log(22e+3) ln11k=9.3056505517805075961159179420182; // log(11e+3); amp=0.11552453009332421823620535357634; // 1/6/log(2) k=pi2/srate; gfx_a=1;gfx_r=0.3;gfx_g=0.4;gfx_b=0.6; //----------------------------------------------------- @slider p1t=k*(p1f=exp(slider1*ln11k)); p0t=k*(p0f=exp(slider2*ln11k)); cgt=exp((slider5)*amp); mgt=exp((slider6)*amp); amntt=slider7; og=exp((slider8-0.01)*amp); //----------------------------------------------------- @sample s0=sin(a1+=(p1+=p1d)); slider4?s1=(mg+=mgd)*(spl0+spl1)*0.5:s1=(mg+=mgd)*sin(a0+=(p0+=p0d)); slider3==0?spl0=spl1=sin((cg+=cgd)*s0+(amnt+=amntd)*sin(s1)):slider3==1?spl0=spl1=sin(s1*(amnt+=amntd)*sin(s0*(cg+=cgd))):spl0=spl1=s0*min(cg+=cgdm,1)*sin((amnt+=amntd)*s1); spl0=spl1*=og; //----------------------------------------------------- @block sbd1=1/samplesblock; p0d=(p0t-p0s)*sbd1;p0=p0s;p0s=p0t; p1d=(p1t-p1s)*sbd1;p1=p1s;p1s=p1t; cgd=(cgt-cgs)*sbd1;cg=cgs;cgs=cgt; mgd=(mgt-mgs)*sbd1;mg=mgs;mgs=mgt; amntd=(amntt-amnts)*sbd1;amnt=amnts;amnts=amntt; //----------------------------------------------------- @gfx 100 10 gfx_x=gfx_y=5; gfx_drawchar($'F'); gfx_drawchar($'0'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(p1f,2); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); gfx_x=5;gfx_y+=15; gfx_drawchar($'F'); gfx_drawchar($'1'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); slider4?gfx_drawchar($'-'):gfx_drawnumber(p0f,2); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); jsusfx-0.4.0/scripts/liteon/lo-fi.jsfx000066400000000000000000000052321353477307700177420ustar00rootroot00000000000000// (C) 2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . desc:Lo-Fi slider1:0<0,1,1{Mono,Stereo}>Mode slider2:21<0,100,1>S&&H Amount (%) slider3:10<4,16,1>Depth slider4:1<0,1,1{Off,On}>Interpolation slider5:0.95<0,1,0.01>Post-Filter slider6:0<-8,32,0.01>Pre Amp (dB) slider7:-0.1<-18,0,0.01>Limit (dB) @init pifs=$pi/srate; i=0;gfx_r=gfx_g=gfx_b=gfx_a=0.9; @slider mode=slider1; r=(exp(slider2*0.0486)-1)|0; gfxr=srate/(r+1); s=(2^(slider3-1))*.5; s5=s*.5; sd=1/s; depth=slider3; g=2^(slider6/6); lim=2^(slider7/6); int=slider4; //+++ post filter c=1/tan(pifs*f1=exp(slider5*6.90775+2.99573)); k1=(1+(c2=c*c)-(c131=c*1.31))*(k0=1/(1+c2+c131)); k2=2*(1-c2)*k0; @sample !mode?( //+++ mono s0=(spl0+spl1)*s5; s0|=0; s0*=sd*g; n1=n0; (i+=1)>r?( i=0; h0=s0; int?h0=.5*(n1+n0=s0); ); spl0=(m0l=k0*h0-k1*m2l-k2*m1l)+m1l+m1l+m2l; m2l=m1l;m1l=m0l; spl0=spl1=min(max(spl0,-lim),lim); ):( //+++ stereo s0=s*spl0;s1=s*spl1; s0|=0;s1|=0; s0*=sd*g;s1*=sd*g; n1=n0;j1=j0; (i+=1)>r?( i=0; h0=s0; h1=s1; int?h0=.5*(n1+n0=s0); int?h1=.5*(j1+j0=s1); ); spl0=(m0l=k0*h0-k1*m2l-k2*m1l)+m1l+m1l+m2l; m2l=m1l;m1l=m0l; spl1=(m0r=k0*h1-k1*m2r-k2*m1r)+m1r+m1r+m2r; m2r=m1r;m1r=m0r; spl0=min(max(spl0,-lim),lim); spl1=min(max(spl1,-lim),lim); ); @gfx 100 5 gfx_x=gfx_y=10; gfx_drawnumber(gfxr,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); gfx_x=90; gfx_drawchar($'|'); gfx_drawchar($' '); gfx_drawnumber(depth,0); gfx_drawchar($' '); gfx_drawchar($'B'); gfx_drawchar($'i'); gfx_drawchar($'t'); gfx_drawchar($'s'); gfx_x=180; gfx_drawchar($'|'); gfx_drawchar($' '); gfx_drawnumber(f1,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); jsusfx-0.4.0/scripts/liteon/lorenzattractor.jsfx000066400000000000000000000054321353477307700221730ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . //****************************************************************************** // References: // Wikipedia, Google, Cockos //****************************************************************************** desc: LorenzAttractor slider1:3000<1,10000,1>Rate (Fast/Slow)) slider2:0<0,1,1{Lines,Dots}>Plot (OSC 1+2/1) slider3:14<10,28,0.1>Prandtl Number slider4:28<14,46,0.1>Rayleigh Number slider5:0.5<0,1,0.01>Color (Mod Min/Max) slider6:0<-4,4,0.1>Tune slider7:0<-25,25,0.05>Gain (-inf/25db) @init gfx_clear = -1; gfx_mode = 1; n = j = 0; x0 = 0.1; y0 = 0; z0 = 0; itm1=itm2=otm1=otm2=0; @slider f = 440; t = slider6; axis = slider2; slider7 == -25 ? ( gain = 0; ) : ( gain = 10^(slider7/20); ); step = slider1; green = slider5; line = slider2; h = 0.01; a = slider3; b = slider4; c = 8.0 / 3.0; old_a != a || old_b != b ?( gfx_clear = 1; ); old_a = a; old_b = b; @sample //di/dt n = n+1; n > step ? ( n = 0; x1 = x0 + h * a * (y0 - x0); y1 = y0 + h * (x0 * (b - z0) - y0); z1 = z0 + h * (x0 * y0 - c * z0); x0 = x1; y0 = y1; z0 = z1; ); //osc tone1 = sin(pos1); slider2 == 0 ? ( tone2 = (1-pos2/$pi)/2.5; ) : ( tone2 = 0; ); out = (tone1+tone2)*z1/15; adj1 = 2.0*$pi*f*(2^(t))/srate; adj1_1 = x1/700*(green); adj2 = 2.0*$pi*f*(2^(t+1))/srate; adj2_1 = y1/300*(green); pos1=pos1+adj1+adj1_1; pos2=pos2+adj2+adj2_1; (pos1 >= 2.0*$pi) ? pos1 -= 2.0*$pi; (pos2 >= 2.0*$pi) ? pos2 -= 2.0*$pi; pos2 = max(pos2,-10); //limit spl0=spl1=min(max(out/16*gain,-0.98),0.98); @gfx 600 600 gfx_g=green; gfx_b=y1-1; size=z0/40; gfx_r=size; gfx_a=size+0.3; gfx_x=x2; gfx_y=y2; line == 0 ? ( gfx_lineto((x2+size*size*12),(y2+size*size*12),1); ) : ( gfx_rectto(x2+4*size*size,y2+4*size*size); ); gfx_blurto(x2+4,y2+4); x2=(x1*15+gfx_w/2); y2=(y1*15+gfx_h/2); gfx_clear = -1; jsusfx-0.4.0/scripts/liteon/moog24db.jsfx000066400000000000000000000150041353477307700203470ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . //****************************************************************************** // References: // Moog filter appromixation // by CSound source code, Stilson/Smith CCRMA paper // Distortion by Bram de Jong //****************************************************************************** desc:Moog LP/HP/BP slider1:0<0,1,1{Stereo,Mono}>Processing slider2:0<0,2,1{LP (24dB/oct),HP (6dB/oct),BP (6dB/oct)}>Filter Type slider3:100<0,100,0.05>Cutoff (Scale) slider4:0<0,0.85,0.001>Res (Min/Max) slider5:0<0,100,0.05>Drive (%) slider6:0<-25,25,0.05>Output (dB) slider7:0<0,1,1{On,Off}>Limiter slider8:0<0,1,1{Off,On}>Oversample (x2) @init cDenorm = 10^-30; mv=2^(-0.2/6); fs = srate; //fir restoration c1 = 1; c2 = -0.75; c3 = 0.17; fgain = 5; //fir bandlimit bl_c1 = 0.52; bl_c2 = 0.54; bl_c3 = -0.02; @slider os = slider8; mono = slider1; ftype = slider2; res = slider4; drive = 1+slider5/100; drvc = 1.2; outgain = 10^(slider6/20); limiter = slider7; sx = 16+slider3*1.20103; cutoff = floor(exp(sx*log(1.059))*8.17742); f = 2 * cutoff / fs; tgt_k = 3.6*f-1.6*f*f-1; tgt_p = (tgt_k+1)*0.5; scale = 2.718281828459045^((1-tgt_p)*1.386249); tgt_r = res*scale; @block d_p = (tgt_p-src_p)/samplesblock; tp = src_p; src_p = tgt_p; d_k = (tgt_k-src_k)/samplesblock; tk = src_k; src_k = tgt_k; d_r = (tgt_r-src_r)/samplesblock; tr = src_r; src_r = tgt_r; @sample tk += d_k; tp += d_p; tr += d_r; //stereo mono == 0 ? ( //distortion drive > 1 ? ( inl = spl0; inr = spl1; os == 1 ? ( //power series in ps_out1l = 0.5*(inl+ps_out2l); ps_out2l = 0.5*ps_out1l; ps_out1r = 0.5*(inr+ps_out2r); ps_out2r = 0.5*ps_out1r; //drive o_in1l = ps_out1l*(abs(ps_out1l) + drive)/(ps_out1l^2 + (drive-1)*abs(ps_out1l) + 1)*(drive/drvc); o_in2l = ps_out2l*(abs(ps_out2l) + drive)/(ps_out2l^2 + (drive-1)*abs(ps_out2l) + 1)*(drive/drvc); o_in1r = ps_out1r*(abs(ps_out1r) + drive)/(ps_out1r^2 + (drive-1)*abs(ps_out1r) + 1)*(drive/drvc); o_in2r = ps_out2r*(abs(ps_out2r) + drive)/(ps_out2r^2 + (drive-1)*abs(ps_out2r) + 1)*(drive/drvc); //--------------------------- //bandlimit bl3_l1 = bl2_l1; bl3_r1 = bl2_r1; bl3_l2 = bl2_l2; bl3_r2 = bl2_r2; bl2_l1 = bl1_l1; bl2_r1 = bl1_r1; bl2_l2 = bl1_l2; bl2_r2 = bl1_r2; bl1_l1 = o_in1l; bl1_r1 = o_in1r; bl1_l2 = o_in2l; bl1_r2 = o_in2r; bl_out1l = (bl1_l1*bl_c1 + bl2_l1*bl_c2 + bl3_l1*bl_c3); bl_out1r = (bl1_r1*bl_c1 + bl2_r1*bl_c2 + bl3_r1*bl_c3); bl_out2l = (bl1_l2*bl_c1 + bl2_l2*bl_c2 + bl3_l2*bl_c3); bl_out2r = (bl1_r2*bl_c1 + bl2_r2*bl_c2 + bl3_r2*bl_c3); //power series out o_out1l = 0.5*(bl_out1l+o_out2l); o_out2l = 0.5*(bl_out2l+o_out1l); o_out1r = 0.5*(bl_out1r+o_out2r); o_out2r = 0.5*(bl_out2r+o_out1r); //fir restoration s3l = s2l; s3r = s2r; s2l = s1l; s2r = s1r; s1l = o_out1l; s1r = o_out1r; inputl = (s1l*c1+s2l*c2+s3l*c3)*fgain; inputr = (s1r*c1+s2r*c2+s3r*c3)*fgain; ) : ( inputl = inl*(abs(inl) + drive)/(inl^2 + (drive-1)*abs(inl) + 1)*(drive/drvc); inputr = inr*(abs(inr) + drive)/(inr^2 + (drive-1)*abs(inr) + 1)*(drive/drvc); ); ) : ( inputl = spl0; inputr = spl1; ); //filter xl = inputl-tr*y4l; xr = inputr-tr*y4r; y1l=xl*tp+oldxl*tp-tk*y1l; y1r=xr*tp+oldxr*tp-tk*y1r; y2l=y1l*tp+oldy1l*tp-tk*y2l; y2r=y1r*tp+oldy1r*tp-tk*y2r; y3l=y2l*tp+oldy2l*tp-tk*y3l; y3r=y2r*tp+oldy2r*tp-tk*y3r; y4l=y3l*tp+oldy3l*tp-tk*y4l; y4r=y3r*tp+oldy3r*tp-tk*y4r; oldxl = xl; oldxr = xr; oldy1l = y1l; oldy1r = y1r; oldy2l = y2l; oldy2r = y2r; oldy3l = y3l; oldy3r = y3r; ftype == 0 ? ( outl = y4l; outr = y4r; ); ftype == 1 ? ( outl = inputl-y4l; outr = inputr-y4r; ); ftype == 2 ? ( outl = 6*(y3l-y4l); outr = 6*(y3r-y4r); ); outl = outl*outgain; outr = outr*outgain; //limiter limiter == 0 ? ( spl0 = min(max((outl+cDenorm),-mv),mv); spl1 = min(max((outr+cDenorm),-mv),mv); ) : ( spl0 = outl; spl1 = outr; ); //mono ) : ( in = (spl0+spl1)/2; //distortion drive > 1 ? ( os == 1 ? ( //power series in ps_out1l = 0.5*(in+ps_out2l); ps_out2l = 0.5*ps_out1l; //drive o_in1l = ps_out1l*(abs(ps_out1l) + drive)/(ps_out1l^2 + (drive-1)*abs(ps_out1l) + 1)*(drive/drvc); o_in2l = ps_out2l*(abs(ps_out2l) + drive)/(ps_out2l^2 + (drive-1)*abs(ps_out2l) + 1)*(drive/drvc); //--------------------------- //bandlimit bl3_1 = bl2_1; bl3_2 = bl2_2; bl2_1 = bl1_1; bl2_2 = bl1_2; bl1_1 = o_in1l; bl1_2 = o_in12; bl_out1 = (bl1_1*bl_c1 + bl2_1*bl_c2 + bl3_1*bl_c3); bl_out2 = (bl1_2*bl_c1 + bl2_2*bl_c2 + bl3_2*bl_c3); //power series out o_out1l = 0.5*(bl_out1+o_out2l); o_out2l = 0.5*(bl_out2+o_out1l); //fir restoration s3l = s2l; s2l = s1l; s1l = o_out1l; input = (s1l*c1+s2l*c2+s3l*c3)*fgain; ) : ( input = in*(abs(in) + drive)/(in^2 + (drive-1)*abs(in) + 1)*(drive/drvc); ); ) : ( input = in; ); //filter x = input-tr*y4; y1=x*tp+oldx*tp-tk*y1; y2=y1*tp+oldy1*tp-tk*y2; y3=y2*tp+oldy2*tp-tk*y3; y4=y3*tp+oldy3*tp-tk*y4; oldx = x; oldy1 = y1; oldy2 = y2; oldy3 = y3; ftype == 0 ? ( out = y4; ); ftype == 1 ? ( out = input-y4; ); ftype == 2 ? ( out = 6*(y3-y4); ); out = out*outgain; //limiter limiter == 0 ? ( spl0 = min(max((out+cDenorm),-mv),mv); spl1 = min(max((out+cDenorm),-mv),mv); ) : ( spl0 = out; spl1 = out; ); ); @gfx 100 10 gfx_x=gfx_y=5; gfx_lineto(gfx_x, gfx_y,0); gfx_r=gfx_b=0; gfx_g=gfx_a=1; gfx_drawchar($'F'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(cutoff,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); jsusfx-0.4.0/scripts/liteon/nonlinear.jsfx000066400000000000000000000125601353477307700207230ustar00rootroot00000000000000// (C) 2009, Lubomir I. Ivanov // // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . // // ***************************************************************************** // Non-linear processor, which attempts 'dynamic' modeling of fluctuations // and frequency response of basic electronic circuit. // ***************************************************************************** desc: Non-Linear Processor slider1:30<0,100,0.01> Saturation Amount (%) slider2:50<0,100,0.01> Fluctuation Amount (%) slider3:16<0,32,1>Noise Floor at (Bits) slider4:0<-24,24,0.01>Input (dB) slider5:0<-24,24,0.01>Output (dB) //============================================================================== @init //============================================================================== ext_noinit = 1; //set limits n = 100000; n2 = 2*n; n3 = 3*n; n4 = 4*n; //push ar0 i = 0; loop(n, m[i] = (rand(2)-1); i += 1; ); //push ar1 i = n; loop(n, m[i] = (rand(2)-1); i += 1; ); //push ar2 i = 2*n; loop(n, m[i] = (rand(2)-1); i += 1; ); //push ar3 i = 3*n; loop(n, m[i] = (rand(2)-1); i += 1; ); //sys vars pi = 3.1415926535897932384626433832795; sr = srate; //lp coeff lpk0 = 0.121; lpk1 = -0.56; //hp coeff // - at 30Hz hpk1 = exp(-188.49555921538759430775860299677/sr); hpk0 = 1 - hpk1; //nf coeff // - at 2000Hz nfk1 = exp(-12566.370614359172953850573533118/sr); nfk0 = 1 - nfk1; //ls coeff // - at 300Hz lsk0 = exp(-1884.9555921538759430775860299677/sr); lsk1 = 1 - lsk0; pdc_delay = 2; pdc_bot_ch = 0; pdc_top_ch = 2; //begin i = 0; //============================================================================== @slider //============================================================================== //drive drv = slider1/200+0.001; pidrv = pi*drv; sinpidrv = 1/sin(pidrv); //ranges r1 = slider2/300; r2 = 1/2^slider3; //ingain ingain = 10^(slider4/20); //outgain outgain = 10^(slider5/20); //============================================================================== @block //============================================================================== //average amplitude avs = (s0+s1)*0.5; //interpolate ar2 values tgt_min2 = avs*m[i+2*n]*r1; d_min2 = (tgt_min2-src_min2)/samplesblock; min2 = src_min2; src_min2 = tgt_min2; //interpolate ar3 values tgt_min3 = avs*m[i+3*n]*r1; d_min3 = (tgt_min3-src_min3)/samplesblock; min3 = src_min3; src_min3 = tgt_min3; //average for gfx min_av = (tgt_min2+tgt_min3)*0.5; //============================================================================== @sample //============================================================================== spl0 *= ingain; spl1 *= ingain; s0 = spl0; s1 = spl1; //seeds min0 = m[i]*r2; min1 = m[i+n]*r2; min2 += d_min2; min3 += d_min3; min2s = min2*0.05; min3s = min3*0.05; min2h = min2*0.005; min3h = min3*0.005; min2d = min2*5; min3d = min3*5; //floor reduction nfout0 = nfk0*min0 + nfk1*nfout0; nfout1 = nfk0*min1 + nfk1*nfout1; inl = spl0 + nfout0; inr = spl1 + nfout1; //check if input (s0 && s1) == 0 ? ( inl = spl0; inr = spl1; ); //waveshaper wsoutl = sin(pidrv*inl)*(sinpidrv+min2d); wsoutr = sin(pidrv*inr)*(sinpidrv+min3d); //lp fs2l = fs1l; fs1l = fs0l; fs0l = wsoutl; lpoutl = (lpk0-min2)*fs0l + (lpk1+min3)*(fs1l+fs2l); fs2r = fs1r; fs1r = fs0r; fs0r = wsoutr; lpoutr = (lpk0-min3)*fs0r + (lpk1+min2)*(fs1r+fs2r); //ls ls0l = (lsk1-min2s)*lpoutl + (lsk0+min3s)*ls0l; ls0r = (lsk1-min3s)*lpoutr + (lsk0+min2s)*ls0r; lsoutl = lpoutl + ls0l*0.25; lsoutr = lpoutr + ls0r*0.25; //hp hptmpl = (hpk0+min2h)*lsoutl + (hpk1-min3h)*hptmpl; hptmpr = (hpk0+min3h)*lsoutr + (hpk1-min2h)*hptmpr; fxoutl = lsoutl - hptmpl; fxoutr = lsoutr - hptmpr; //counter i += 1; i > n ? i = 0; //output spl0 = -fxoutl*outgain; spl1 = -fxoutr*outgain; //============================================================================== @gfx 100 10 //============================================================================== //draw color block pd = 5; gfx_x=gfx_y=pd; gfx_a=0; gfx_b=drv*2; gfx_r=0.1+r1; gfx_g=1.2-slider3/32; gfx_a=0.9+1.5*min_av; gfx_rectto(gfx_w-pd,gfx_h-pd); gfx_a = 1; gfx_r=gfx_g=gfx_b=0; //vertical lines vl = slider3; vln=0; loop(vl, gfx_y = 0; gfx_x = gfx_w/vl*vln; gfx_lineto(gfx_x,gfx_h,1); vln+=1; ); //shades gfx_a = 0.2; gfx_x=pd; gfx_y=pd; gfx_rectto(gfx_w,gfx_h/3); gfx_x=pd; gfx_y=gfx_h-pd; gfx_r=gfx_g=gfx_b=1; gfx_a = 0.2; gfx_rectto(gfx_w,gfx_h-gfx_h/3); jsusfx-0.4.0/scripts/liteon/np1136peaklimiter.jsfx000066400000000000000000000360021353477307700221120ustar00rootroot00000000000000// (C) 2009, Lubomir I. Ivanov // // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . // // ***************************************************************************** // NP1136 - Program dependent Peak Limiter. // // The effect borrows ideas / functionality from some commercial // software / hardware products. // Uses code from Paul Kellet (mda) for the compressor envelopes and from // Michale Gruhn (loser) for the GR meter - Thanks goes to them. // Also to Chritian W. Budde for his VST Plugin Analyzer. // // Use it wisely and with moderation. // ***************************************************************************** // // REDISTRIBUTION AND MODIFICATIONS PERMITED ONLY WHILE PROVIDING // FULL CREDIT TO THE ORIGINAL AUTHORS AND INCLUDING THE ABOVE LINES OF TEXT. //============================================================================= desc: NP1136 (Peak Limiter) //============================================================================= slider1:-12<-40,0,0.01>Threshold (dB) slider2:4<1,20,0.01>Ratio (20:1 - PD Mode) slider3:30<0,100,0.01>Attack (µs) slider4:45<0,100,0.01>Release (ms) slider5:0<0,100,0.01>Detector HP (Hz) slider6:-18<-40,0,0.01>GR Limit (Off / Y dB) slider7:0<0,30,0.01>Makeup Gain (dB) slider8:50<0,100,0.01>Tilt EQ Center (Hz) slider9:0<-6,6,0.01>Tilt EQ Low/High (dB) slider10:100<0,100,0.01>Wet Mix (%) slider11:0<0,1,1{Stereo,Mono}>Processing Mode slider12:1<0,1,1{Stereo,Mono}>Detector Mode slider13:0<0,1,1{Normal (Ch0 - Ch1),Sidechain (Ch2 - Ch3)}>Detector Input slider14:0<0,1,1{Off,On}>Hard Clip //============================================================================= @init //============================================================================= br = 0; clip = 0; tlt_gain = 0; amp = 6/log(2); sr3 = 3*srate; gfactor = 4; n = 0; g_reset = 1; e10 = 10^-10; cdenorm = 10^-30; mv = 2^(-0.2/6); g_meter = gr_meter = 1; gr_meter_decay = exp(1/(1*srate)); sqrt2 = sqrt(2); s2 = sqrt2/2; //============================================================================= @slider //============================================================================= //----------------------------------------- // detector hp (12db/oct) //----------------------------------------- sx = 16 + slider5*1.20103; cutoff = floor(exp(sx*log(1.059))*8.17742); cx = 2*cutoff/srate; cpi = $pi*cx; fk = 0.67*sin(cpi); c1 = 0.5*(1 - fk)/(1 + fk); c2 = (0.5 + c1)*cos(cpi); c3 = (0.5 + c1 + c2)*0.25; hpa0 = 2*c3; hpa1 = -4*c3; hpa2 = 2*c3; hpb1 = -2*c2; hpb2 = 2*c1; //----------------------------------------- // compressor //----------------------------------------- thr = pow(10, 2 * (slider1/40+1) - 2); rat = (slider2-1)/19; att = pow(10, -0.002 - 3.97772619*(slider3/100)); rel = pow(10, -3.11 - 1.8698*(slider4/100)); ascale = -301030.1 / (srate * log10(1 - att)); rscale = -301.0301 / (srate * log10(1 - rel)); //----------------------------------------- // tilt filter //----------------------------------------- tlt_gain = slider9; //conditition tlt_gain > 0 ? ( g1 = -gfactor*tlt_gain; g2 = tlt_gain; ) : ( g1 = -tlt_gain; g2 = gfactor*tlt_gain; ); //two separate gains lgain = exp(g1/amp)-1; hgain = exp(g2/amp)-1; //f0 sx = 16+slider8*1.20103; tf = floor(exp(sx*log(1.059))*8.17742); //filter tomega = 2*$pi*tf; tn = 1/(sr3 + tomega); tgt_ta0 = 2*tomega*tn; tgt_tb1 = (sr3 - tomega)*tn; //----------------------------------------- // mix //----------------------------------------- slider6 == -40 ? grlimit = 10^(-6*64/20) : grlimit = 10^((slider6-0.3)/20); outgain = 10^(slider7/20); mix = (100-slider10)/100; mono = slider11; link = slider12; sidechain = slider13; hardclip = slider14; //============================================================================= @sample //============================================================================= //----------------------------------------- // detector input - sidechain //----------------------------------------- sidechain == 0 ? ( det_inl = spl0; det_inr = spl1; ) : ( det_inl = spl2; det_inr = spl3; ); //========================================= // // detector mono // //========================================= (link == 1) ? ( det_inl = (det_inl+det_inr)/2; //----------------------------------------- // detector hp filter //----------------------------------------- cutoff > 20 ? ( inl = hpa0*det_inl + hpa1*meml1 + hpa2*meml2 - hpb1*meml3 - hpb2*meml4; meml2 = meml1; meml1 = det_inl; meml4 = meml3; meml3 = inl; dtl = abs(inl); dtr = dtl; ) : ( //----------------------------------------- // detector no filter //----------------------------------------- dtl = abs(det_inl); dtr = dtl; ); //----------------------------------------- // program dependency (british mode) //----------------------------------------- rat == 1 ? ( //interpolate envelopes pdattl += d_pdattl; pdrell += d_pdrell; pdratl += d_pdratl; ) : ( pdattl = att; pdrell = rel; pdratl = rat; ); //-------------------------- // envelope //-------------------------- (dtr > dtl) ? dtl = dtr; (dtl > envl) ? envl = envl + pdattl*(dtl - envl) : envl = envl*(1 - pdrell); (envl > thr) ? (cgainl = min(1+(pdratl*((envl/thr)-1)), 1/grlimit); g_reset = 0;) : (cgainl = 1; g_reset = 1); (envl < e10) ? envl = 0; //-------------------------- // update gr meter //-------------------------- g_reset == 0 ? g_meter = max(1/cgainl,grlimit) : g_meter = 1; cgainr = cgainl; ) : ( //========================================= // // detector stereo // //========================================= //----------------------------------------- // detector hp filter //----------------------------------------- cutoff > 20 ? ( inl = hpa0*det_inl + hpa1*meml1 + hpa2*meml2 - hpb1*meml3 - hpb2*meml4; meml2 = meml1; meml1 = det_inl; meml4 = meml3; meml3 = inl; inr = hpa0*det_inr + hpa1*memr1 + hpa2*memr2 - hpb1*memr3 - hpb2*memr4; memr2 = memr1; memr1 = det_inr; memr4 = memr3; memr3 = inr; //abs dtl = abs(inl); dtr = abs(inr); ) : ( //----------------------------------------- // detector no filter //----------------------------------------- dtl = abs(det_inl); dtr = abs(det_inr); ); //------------------------------------ // program dependency (british mode) //------------------------------------ rat == 1 ? ( //interpolate envelopes pdattl += d_pdattl; pdattr += d_pdattr; pdrell += d_pdrell; pdrelr += d_pdrelr; pdratl += d_pdratl; pdratr += d_pdratr; ) : ( pdattl = pdattr = att; pdrell = pdrelr = rel; pdratl = pdratr = rat; ); //-------------------------- // envelope //-------------------------- (dtl > envl) ? envl = envl + pdattl*(dtl - envl) : envl = envl*(1 - pdrell); (envl > thr) ? (cgainl = min(1+(pdratl*((envl/thr)-1)), 1/grlimit); g_reset = 0;) : (cgainl = 1; g_reset = 1); (envl < e10) ? envl = 0; (dtr > envr) ? envr = envr + pdattr*(dtr - envr) : envr = envr*(1 - pdrelr); (envr > thr) ? (cgainr = min(1+(pdratr*((envr/thr)-1)), 1/grlimit); g_reset = 0;) : (cgainr = 1; g_reset = 1); (envr < e10) ? envr = 0; //-------------------------- // update gr meter //-------------------------- g_reset == 0 ? ( (cgainl > cgainr) ? g_meter = max(1/cgainl, grlimit) : g_meter = max(1/cgainr, grlimit); ) : ( g_meter = 1; ); ); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end detector stage //-------------------------- // apply gains //-------------------------- coutl = spl0*outgain/cgainl; coutr = spl1*outgain/cgainr; //--------------------------------- //interpolate tilt coefficients //--------------------------------- ta0 += d_ta0; tb1 += d_tb1; mono == 1 ? ( //========================================= // // process mono out // //========================================= //--------------------------------- // tilt filter //--------------------------------- tlt_gain != 0 ? ( tinput = coutl; lp_out = ta0*tinput + tb1*lp_out; toutl = tinput + lgain*lp_out + hgain*(tinput - lp_out); ) : ( toutl = coutl; ); //--------------------------------- // mix //--------------------------------- outl = mix*spl0 + (1-mix)*toutl; //--------------------------------- // hardclip //--------------------------------- (outl < -1 || outl > 1) ? clip = 1; hardclip == 1 ? ( spl0 = min(max((outl+cdenorm),-mv),mv); spl1 = spl0; ) : ( spl0 = outl+cdenorm; spl1 = spl0; ); ) : ( //========================================= // // process stereo out // //========================================= //--------------------------------- // tilt filter //--------------------------------- tlt_gain != 0 ? ( tinput = coutl; lp_out = ta0*tinput + tb1*lp_out; toutl = tinput + lgain*lp_out + hgain*(tinput - lp_out); tinput_r = coutr; lp_out_r = ta0*tinput_r + tb1*lp_out_r; toutr = tinput_r + lgain*lp_out_r + hgain*(tinput_r - lp_out_r); ) : ( toutl = coutl; toutr = coutr; ); //--------------------------------- // mix //--------------------------------- outl = mix*spl0 + (1-mix)*toutl; outr = mix*spl1 + (1-mix)*toutr; //--------------------------------- // hardclip //--------------------------------- (outl < -1 || outl > 1) ? clip = 1; (outr < -1 || outr > 1) ? clip = 1; hardclip == 1 ? ( spl0 = min(max((outl+cdenorm),-mv),mv); spl1 = min(max((outr+cdenorm),-mv),mv); ) : ( spl0 = outl+cdenorm; spl1 = outr+cdenorm; ); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end output stage ); //*** test (scope variables) // //spl0 = spl1 = pdrell*900; //spl0 = spl1 = rel; //spl0 = spl1 = pdratl; // //*** //----------------------------------------- // meter decay //----------------------------------------- g_meter < gr_meter ? gr_meter=g_meter : gr_meter*=gr_meter_decay; //============================================================================= @block //============================================================================= //----------------------------------------- // update clip indicator //----------------------------------------- bps = srate/samplesblock; n > bps ? ( clip = 0; n = 0; ); n += 1; //----------------------------------------- // interpolate tilt filter coeffcients //----------------------------------------- tlt_gain != 0 ? ( d_ta0 = (tgt_ta0-src_ta0)/samplesblock; ta0 = src_ta0; src_ta0 = tgt_ta0; d_tb1 = (tgt_tb1-src_tb1)/samplesblock; tb1 = src_tb1; src_tb1 = tgt_tb1; ); //----------------------------------------------- // interpolate ratio, attack, release (PD mode) //----------------------------------------------- rat == 1 ? ( //att tgt_pdattl = min(att*0.95+att*dtl*7,0.995405); d_pdattl = (tgt_pdattl-src_pdattl)/samplesblock; pdattl = src_pdattl; src_pdattl = tgt_pdattl; tgt_pdattr = min(att*0.95+att*dtr*7,0.995405); d_pdattr = (tgt_pdattr-src_pdattr)/samplesblock; pdattr = src_pdattr; src_pdattr = tgt_pdattr; //rel tgt_pdrell = min(rel*0.9+rel*dtl*4,0.00077625); d_pdrell = (tgt_pdrell-src_pdrell)/samplesblock; pdrell = src_pdrell; src_pdrell = tgt_pdrell; tgt_pdrelr = min(rel*0.9+rel*dtr*4,0.00077625); d_pdrelr = (tgt_pdrelr-src_pdrelr)/samplesblock; pdrelr = src_pdrelr; src_pdrelr = tgt_pdrelr; //rat tgt_pdratl = max(rat-dtl*2,0.57); d_pdratl = (tgt_pdratl-src_pdratl)/samplesblock; pdratl = src_pdratl; src_pdratl = tgt_pdratl; tgt_pdratr = max(rat-dtr*2,0.57); d_pdratr = (tgt_pdratr-src_pdratr)/samplesblock; pdratr = src_pdratr; src_pdratr = tgt_pdratr; ) : ( tgt_pdattl = tgt_pdattr = att; tgt_pdrell = tgt_pdrelr = rel; tgt_pdratl = tgt_pdratr = rat; ); //============================================================================= @gfx 425 16 //============================================================================= //--------------------------------- // set gr meter //--------------------------------- gr_meter *= exp(1/30); gr_meter > 1 ? gr_meter=1; gfx_r=0; gfx_g=0.3; gfx_b=0.8; gfx_a=0.8; meter_bot=20; meter_h=min(gfx_h,21); xscale=gfx_w*20/meter_bot; gfx_y=0; gfx_x=gfx_w + log10(gr_meter)*xscale; gfx_rectto(gfx_w,meter_h); //--------------------------------- // draw limit //--------------------------------- gfx_r=1; gfx_b=1; gfx_g=1; gfx_a=0.7; gfx_x=gfx_w + log10(grlimit*1.025)*xscale; gfx_y=meter_h-3; gfx_rectto(gfx_x+4,meter_h); //--------------------------------- // draw scale //--------------------------------- gfx_a=0.6; g = s2; while( gfx_x=gfx_w + log10(g)*xscale; gfx_x >= 0 ? ( gfx_y=0; gfx_lineto(gfx_x,meter_h-1,0); gfx_y=meter_h-gfx_texth-5; gfx_x+=4; gfx_drawnumber(log10(g)*20,0); gfx_drawchar($'d'); gfx_drawchar($'B'); ); g*=s2; gfx_x >=0; ); gfx_x=0; gfx_y=meter_h; gfx_lineto(gfx_w,meter_h,0); gfx_a=0.9; gfx_x=gfx_w - 61; gfx_y=meter_h + gfx_texth - 1; /* //--------------------------------- // draw gr numbers in realtime //--------------------------------- gfx_drawnumber(log10(gr_meter)*20,1); gfx_drawchar($'d'); gfx_drawchar($'B'); */ //--------------------------------- // hp filter f //--------------------------------- gfx_x = 12; cutoff == 20 ? ( gfx_a = 0.3; ) : ( gfx_a = 1; ); gfx_drawchar($'D'); gfx_drawchar($'H'); gfx_drawchar($'P'); gfx_drawchar($':'); gfx_drawnumber(cutoff,0); //--------------------------------- // attack //--------------------------------- gfx_x = gfx_w/3; gfx_a=1; gfx_drawchar($'A'); gfx_drawchar($':'); gfx_drawnumber(ascale,0); //--------------------------------- // release //--------------------------------- gfx_x = gfx_w/1.9; gfx_a=1; gfx_drawchar($'R'); gfx_drawchar($':'); gfx_drawnumber(rscale,0); //--------------------------------- // tilt filter f //--------------------------------- gfx_x = gfx_w/1.25; tlt_gain != 0 ? ( gfx_a = 1; ) : ( gfx_a = 0.3; ); gfx_drawchar($'T'); gfx_drawchar($'L'); gfx_drawchar($'T'); gfx_drawchar($':'); gfx_drawnumber(tf,0); //--------------------------------- // clip indicator //--------------------------------- gfx_x = gfx_w/1.42; gfx_r=1; gfx_g=0; gfx_b=0; clip == 1 ? ( gfx_a = 1; ) : ( gfx_a = 0.4; ); gfx_drawchar($'*'); //--------------------------------- // british mode indicator //--------------------------------- gfx_x = gfx_w/3.9; gfx_r=0.8; gfx_g=0.4; gfx_b=0.4; rat == 1 ? ( gfx_a = 1; ) : ( gfx_a = 0.4; ); gfx_drawchar($'B'); jsusfx-0.4.0/scripts/liteon/pinknoisegen.jsfx000066400000000000000000000071611353477307700214300ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . // white noise trought 6pole recursive filter // works with different sample rates desc: Pink Noise Generator slider1:0<0,1,1{Mono,Stereo}> Mode slider2:-6<-25,25,0.05> Noise (dB) slider3:-6<-25,25,0.05> Dry (dB) slider4:0<-25,25,0.05> Output (dB) @init //trc - test rate coeff trc = 1; sr = srate*trc; //******* case1 sr <= 48000 ? ( case = 1; k0 = exp(-2*$pi*4752.456/sr); k1 = exp(-2*$pi*4030.961/sr); k2 = exp(-2*$pi*2784.711/sr); k3 = exp(-2*$pi*1538.461/sr); k4 = exp(-2*$pi*357.681/sr); k5 = exp(-2*$pi*70/sr); k6 = exp(-2*$pi*30/sr); ); //******* case2 sr > 48000 && sr <= 96000 ? ( case = 2; k0 = exp(-2*$pi*8227.219/sr); k1 = exp(-2*$pi*8227.219/sr); k2 = exp(-2*$pi*6388.570/sr); k3 = exp(-2*$pi*3302.754/sr); k4 = exp(-2*$pi*479.412/sr); k5 = exp(-2*$pi*151.070/sr); k6 = exp(-2*$pi*54.264/sr); ); //******* case3 sr > 96000 && sr < 192000? ( case = 3; k0 = exp(-2*$pi*9211.912/sr); k1 = exp(-2*$pi*8621.096/sr); k2 = exp(-2*$pi*8555.228/sr); k3 = exp(-2*$pi*8292.754/sr); k4 = exp(-2*$pi*518.334/sr); k5 = exp(-2*$pi*163.712/sr); k6 = exp(-2*$pi*240.241/sr); ); //******* case4 sr >= 192000? ( case = 4; k0 = exp(-2*$pi*10000/sr); k1 = exp(-2*$pi*10000/sr); k2 = exp(-2*$pi*10000/sr); k3 = exp(-2*$pi*10000/sr); k4 = exp(-2*$pi*544.948/sr); k5 = exp(-2*$pi*142.088/sr); k6 = exp(-2*$pi*211.616/sr); ); //vector v vi = 0; loop(17, v[vi] = rand(1)*0.001; vi+=1; ); vi = 0; //vector k ki = 0; loop(21, k[ki] = rand(1)*0.00001; ki+=1; ); ki = 0; @slider mode = slider1; n = 10^((slider2-28)/20); d = 10^(slider3/20); o = 10^(slider4/20); @sample mode == 0 ? ( dryl = (spl0+spl1)/2; whitel = min(rand(2)-1+v[vi]+k[ki],1); b0l = k0*whitel+k0*b0l; b1l = k1*whitel+k1*b1l; b2l = k2*whitel+k2*b2l; b3l = k3*whitel+k3*b3l; b4l = k4*whitel+k4*b4l; b5l = k5*whitel+k5*b5l; b6l = k6*whitel+k6*b6l; pinkl = (b0l+b1l+b2l+b3l+b4l+b5l+whitel-b6l); spl0 = spl1 = (pinkl*n + dryl*d)*o; vi += 1; vi == 17 ? vi = 0; ki += 1; ki == 21 ? ki = 0; ) : ( dryl = spl0; whitel = min(rand(2)-1+v[vi]+k[ki],1); b0l = k0*whitel+k0*b0l; b1l = k1*whitel+k1*b1l; b2l = k2*whitel+k2*b2l; b3l = k3*whitel+k3*b3l; b4l = k4*whitel+k4*b4l; b5l = k5*whitel+k5*b5l; b6l = k6*whitel+k6*b6l; pinkl = (b0l+b1l+b2l+b3l+b4l+b5l+whitel-b6l); spl0 = (pinkl*n+dryl*d)*o; dryr = spl1; whiter = min(rand(2)-1+v[vi]+k[ki],1); b0r = k0*whiter+k0*b0r; b1r = k1*whiter+k1*b1r; b2r = k2*whiter+k2*b2r; b3r = k3*whiter+k3*b3r; b4r = k4*whiter+k4*b4r; b5r = k5*whiter+k5*b5r; b6r = k6*whiter+k6*b6r; pinkr = (b0r+b1r+b2r+b3r+b4r+b5r+whiter-b6r); spl1 = (pinkr*n+dryr*d)*o; vi += 1; vi == 17 ? vi = 0; ki += 1; ki == 21 ? ki = 0; ); jsusfx-0.4.0/scripts/liteon/presenceeq.jsfx000066400000000000000000000063541353477307700210740ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . //****************************************************************************** // References: "filters3.txt" - modified // Presence EQ as given in // James A. Moorer // The manifold joys of conformal mapping: // applications to digital filtering in the studio // JAES, Vol. 31, No. 11, 1983 November //****************************************************************************** desc:PresenceEQ (Moorer) slider1:0<0,1,1{Stereo,Mono}>Processing slider2:7700<3100,18500,0.1>Frequency (Hz) slider3:0<-15,15,0.01>Cut/Boost (dB) slider4:0.20<0.07,0.40,0.0001>BW (Min/Max) slider5:0<-25,25,0.05>Output (dB) @init yl=x1l=x2l=y1l=y2l=yr=x1r=x2r=y1r=y2r=SPN=0; @slider mono = slider1; cf = slider2/srate; boost = slider3; bw = slider4; // removed "/srate" here and added BW in proper ranges outgain = 10^(slider5/20); ca = tan($pi*(cf-0.25)); A = 10^(boost/20); (boost < 6.0) && (boost > -6.0) ? ( F = sqrt(A); ) : ( A > 1 ? ( F = A/sqrt(2); ) : ( F = A*sqrt(2); ); ); T = tan(2*$pi*bw); as2 = ca*ca; as4 = as2*as2; d = 2*as2*T; sn = (1 + as4)*T; cs = (1 - as4); mag = sqrt(sn*sn + cs*cs); //"d /= mag" prevents adding any boost at all - replaced with d=mag; d = mag; delta = atan2(sn,cs); asnd = asin(d); theta = 0.5*($pi - asnd - delta); tmp = 0.5*(asnd-delta); tmp > 0 && tmp < theta ? ( theta = tmp; ); xfmbw = theta/(2*$pi); C = 1/tan(2*$pi*xfmbw); F2 = F*F; tmp = A*A - F2; abs(tmp) <= SPN ? ( alphad = C; ) : ( alphad = sqrt(C*C*(F2-1)/tmp); ); alphan = A*alphad; a2plus1 = 1 + as2; ma2plus1 = 1 - as2; a0 = a2plus1 + alphan*ma2plus1; a1 = 4.0*ca; a2 = a2plus1 - alphan*ma2plus1; b0 = a2plus1 + alphad*ma2plus1; b2 = a2plus1 - alphad*ma2plus1; recipb0 = 1/b0; a0 *= recipb0; a1 *= recipb0; a2 *= recipb0; b1 = a1; b2 *= recipb0; b1 = -b1; b2 = -b2; @sample //mono mono == 1 ? ( xl = (spl0+spl1)/2; yl = a0*xl + a1*x1l + a2*x2l + b1*y1l + b2*y2l; x2l = x1l; x1l = xl; y2l = y1l; y1l = yl; spl0=spl1=yl*outgain; //stereo ) : ( xl = spl0; xr = spl1; yl = a0*xl + a1*x1l + a2*x2l + b1*y1l + b2*y2l; x2l = x1l; x1l = xl; y2l = y1l; y1l = yl; yr = a0*xr + a1*x1r + a2*x2r + b1*y1r + b2*y2r; x2r = x1r; x1r = xr; y2r = y1r; y1r = yr; spl0=yl*outgain; spl1=yr*outgain; ); jsusfx-0.4.0/scripts/liteon/pseudostereo.jsfx000066400000000000000000000125341353477307700214600ustar00rootroot00000000000000/// (C) 2008-2009, Lubomir I. Ivanov // // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . // // ***************************************************************************** // Pseudo-Stereo // Based on Paul Kellet's excelent 'mdaStereo' plugin // ***************************************************************************** //======================================================= desc:Pseudo-Stereo (mda) //======================================================= slider1:0<-100,100,0.01>Fx (%) : Haas ( - ) / Comb ( + ) slider2:20<1,50,0.01>Delay (ms) slider3:0<-100,100,0.01>Balance (L/R) slider4:0<-20,20,0.01>Output (dB) //======================================================= @init //======================================================= //------------------------------------------------------- //define buffer size, srate based - 4410, 4800, 9600 etc //------------------------------------------------------- size = srate/10; bp = size; buffer = 0; //======================================================= @slider //======================================================= //------------------------------------------------------- //fx type: 'haas' or 'comb' //fxk - coeff for tweaking fx amounts //------------------------------------------------------- slider1 > 0 ? fxk = 115 : fxk = 200; fxamount = 0.5+(slider1/fxk); //------------------------------------------------------- //delay, some math here based on - x/1000*srate //------------------------------------------------------- tgt_del = sqr((srate*(22+4*slider2)-200000)/208000); //------------------------------------------------------- //outgain //------------------------------------------------------- outgain = 10^(slider4/20); //------------------------------------------------------- //balance //------------------------------------------------------- bal = slider3/100; tgt_bl = min(1-bal,1)*outgain; tgt_br = min(1+bal,1)*outgain; //------------------------------------------------------- //calculate feedback - haas or comb //------------------------------------------------------- fxamount<0.5 ? ( tgt_li = 0.25+(1.5*fxamount); tgt_ld = 0; tgt_ri = 2*fxamount; tgt_rd = 1-tgt_ri; ) : ( tgt_li = 1.5-fxamount; tgt_ld = fxamount-0.5; tgt_ri = tgt_li; tgt_rd = -tgt_ld; ); fxamnt_abs = 0.5+abs(fxamount-0.5); tgt_li *= fxamnt_abs; tgt_ld *= fxamnt_abs; tgt_ri *= fxamnt_abs; tgt_rd *= fxamnt_abs; //======================================================= @block //======================================================= //------------------------------------------------------- //interpolate params per sblock //------------------------------------------------------- d_ri = (tgt_ri-src_ri)/samplesblock; ri = src_ri; src_ri = tgt_ri; d_rd = (tgt_rd-src_rd)/samplesblock; rd = src_rd; src_rd = tgt_rd; d_li = (tgt_li-src_li)/samplesblock; li = src_li; src_li = tgt_li; d_ld = (tgt_ld-src_ld)/samplesblock; ld = src_ld; src_ld = tgt_ld; d_del = (tgt_del-src_del)/samplesblock; del = src_del; src_del = tgt_del; d_bl = (tgt_bl-src_bl)/samplesblock; bl = src_bl; src_bl = tgt_bl; d_br = (tgt_br-src_br)/samplesblock; br = src_br; src_br = tgt_br; //======================================================= @sample //======================================================= //------------------------------------------------------- //interpolate params //------------------------------------------------------- li += d_li; ld += d_ld; ri += d_ri; rd += d_rd; del += d_del; bl += d_bl; br += d_br; //------------------------------------------------------- //set inputs and sum to mono //------------------------------------------------------- chl = spl0; chr = spl1; a = (spl0+spl1)/2; //------------------------------------------------------- //write new value in buffer //------------------------------------------------------- buffer[bp] = a; //------------------------------------------------------- //apply feedback //------------------------------------------------------- tmp = (bp+del)%size; b = buffer[tmp]; chl += (a*li)-(b*ld); chr += (a*ri)-(b*rd); //------------------------------------------------------- //new buffer position or reset //------------------------------------------------------- bp = bp-1; bp < 0 ? bp = size; //------------------------------------------------------- //output //------------------------------------------------------- spl0 = chl*bl*0.7; spl1 = chr*br*0.7; jsusfx-0.4.0/scripts/liteon/rbjstereofilter12db.jsfx000066400000000000000000000206061353477307700226140ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . // ***************************************************************************** // Referances (or uses code) from: // RBJ Cookbook filters - implementation by Stillwell (info at bottom) // M-S splitter by LOSER // Distortion by Bram de Jong // ***************************************************************************** desc:RbjStereoFilter 12db - Stereo image filter slider1:100<0,100,1>S - Filter Amount (%) slider2:0<0,100,0.05>S - HP (Scale) slider3:100<0,100,0.05>S - LP (Scale) slider4:0<0,100>S - Drive 2xOS (%) slider5:100<0,200,0.05>Side (%) slider6:100<0,200,0.05>Mid (%) slider7:0<-25,25,0.05>Output M+S (dB) slider8:0<0,1,1{Off,On}>Oversample (x2) @init //fir restoration c1 = 1; c2 = -0.75; c3 = 0.17; fgain = 4.1; //fir bandlimit bl_c1 = 0.52; bl_c2 = 0.54; bl_c3 = -0.02; //hp hpf = 0; gain1 = 0; freq1=20; a1 = 1; s1 = 1; q1 = 1 / (sqrt((a1 + 1/a1)*(1/s1 - 1) + 2)); w01 = 2 * $pi * freq1/srate; cosw01 = cos(w01); sinw01 = sin(w01); alpha1 = sinw01 / (2 * q1); b01 = (1 + cosw01)/2; b11 = -(1 + cosw01); b21 = (1 + cosw01)/2; a01 = 1 + alpha1; a11 = -2 * cosw01; a21 = 1 - alpha1; b01 /= a01; b11 /= a01; b21 /= a01; a11 /= a01; a21 /= a01; //lp lpf = 0; gain3 = 0; freq3 = 20000; a3 = 10^(gain3/40); s3 = 2; q3 = 1 / (sqrt((a3 + 1/a3)*(1/s3 - 1) + 2)); w03 = 2 * $pi * freq3/srate; cosw03 = cos(w03); sinw03 = sin(w03); alpha3 = sinw03 / (2 * q3); b03 = (1 - cosw03)/2; b13 = (1 - cosw03); b23 = (1 - cosw03)/2; a03 = 1 + alpha3; a13 = -2 * cosw03; a23 = 1 - alpha3; b03 /= a03; b13 /= a03; b23 /= a03; a13 /= a03; a23 /= a03; @slider os = slider8; amount = (100-slider1)/200; drive = 1+slider4/50; drvc = 1.2; outgain = 10^(slider7/20); side = slider5/200; mid = slider6/200; sx1 = 16+slider2*1.20103; freq1 = floor(exp(sx1*log(1.059))*8.17742); sx2 = 16+slider3*1.20103; freq3 = floor(exp(sx2*log(1.059))*8.17742); slider2 == 0 ? hpf = 0 : hpf = 1; slider3 == 100 ? lpf = 0 : lpf = 1; a1 = 1; s1 = 1; q1 = 1 / (sqrt((a1 + 1/a1)*(1/s1 - 1) + 2)); w01 = 2 * $pi * freq1/srate; cosw01 = cos(w01); sinw01 = sin(w01); alpha1 = sinw01 / (2 * q1); b01 = (1 + cosw01)/2; b11 = -(1 + cosw01); b21 = (1 + cosw01)/2; a01 = 1 + alpha1; a11 = -2 * cosw01; a21 = 1 - alpha1; b01 /= a01; b11 /= a01; b21 /= a01; a11 /= a01; a21 /= a01; a3 = 1; s3 = 1; q3 = 1 / (sqrt((a3 + 1/a3)*(1/s3 - 1) + 2)); w03 = 2 * $pi * freq3/srate; cosw03 = cos(w03); sinw03 = sin(w03); alpha3 = sinw03 / (2 * q3); b03 = (1 - cosw03)/2; b13 = (1 - cosw03); b23 = (1 - cosw03)/2; a03 = 1 + alpha3; a13 = -2 * cosw03; a23 = 1 - alpha3; b03 /= a03; b13 /= a03; b23 /= a03; a13 /= a03; a23 /= a03; @sample s0 = spl0; s1 = spl1; //distortion drive > 1 ? ( inl = spl0; inr = spl1; os == 1 ? ( //ps in ps_out1l = 0.5*(inl+ps_out2l); ps_out2l = 0.5*ps_out1l; ps_out1r = 0.5*(inr+ps_out2r); ps_out2r = 0.5*ps_out1r; //drive o_in1l= (ps_out1l)*(abs((ps_out1l)) + drive)/((ps_out1l)^2 + (drive-1)*abs((ps_out1l)) + 1)*(drive/drvc); o_in2l= (ps_out2l)*(abs((ps_out2l)) + drive)/((ps_out2l)^2 + (drive-1)*abs((ps_out2l)) + 1)*(drive/drvc); o_in1r= (ps_out1r)*(abs((ps_out1r)) + drive)/((ps_out1r)^2 + (drive-1)*abs((ps_out1r)) + 1)*(drive/drvc); o_in2r= (ps_out2r)*(abs((ps_out2r)) + drive)/((ps_out2r)^2 + (drive-1)*abs((ps_out2r)) + 1)*(drive/drvc); //--------------------------- //bandlimit bl3_l1 = bl2_l1; bl3_r1 = bl2_r1; bl3_l2 = bl2_l2; bl3_r2 = bl2_r2; bl2_l1 = bl1_l1; bl2_r1 = bl1_r1; bl2_l2 = bl1_l2; bl2_r2 = bl1_r2; bl1_l1 = o_in1l; bl1_r1 = o_in1r; bl1_l2 = o_in2l; bl1_r2 = o_in2r; bl_out1l = (bl1_l1*bl_c1 + bl2_l1*bl_c2 + bl3_l1*bl_c3); bl_out1r = (bl1_r1*bl_c1 + bl2_r1*bl_c2 + bl3_r1*bl_c3); bl_out2l = (bl1_l2*bl_c1 + bl2_l2*bl_c2 + bl3_l2*bl_c3); bl_out2r = (bl1_r2*bl_c1 + bl2_r2*bl_c2 + bl3_r2*bl_c3); //ps out o_out1l = 0.5*(bl_out1l+o_out2l); o_out2l = 0.5*(bl_out2l+o_out1l); o_out1r = 0.5*(bl_out1r+o_out2r); o_out2r = 0.5*(bl_out2r+o_out1r); //restore s3l = s2l; s3r = s2r; s2l = s1l; s2r = s1r; s1l = o_out1l; s1r = o_out1r; spl0 = (s1l*c1+s2l*c2+s3l*c3)*fgain; spl1 = (s1r*c1+s2r*c2+s3r*c3)*fgain; ) : ( spl0 = (inl)*(abs((inr)) + drive)/((inl)^2 + (drive-1)*abs((inl)) + 1)*(drive/drvc); spl1 = (inr)*(abs((inr)) + drive)/((inr)^2 + (drive-1)*abs((inr)) + 1)*(drive/drvc); ); ); //filters hpf != 0 ? ( ospl0 = spl0; hpspl0 = b01 * spl0 + b11 * xl11 + b21 * xl21 - a11 * yl11 - a21 * yl21; spl0 = hpspl0; xl21 = xl11; xl11 = ospl0; yl21 = yl11; yl11 = spl0; ospl1 = spl1; hpspl1 = b01 * spl1 + b11 * xr11 + b21 * xr21 - a11 * yr11 - a21 * yr21; spl1 = hpspl1; xr21 = xr11; xr11 = ospl1; yr21 = yr11; yr11 = spl1; ); lpf != 0 ? ( ospl0 = spl0; lpspl0 = b03 * spl0 + b13 * xl13 + b23 * xl23 - a13 * yl13 - a23 * yl23; spl0 = lpspl0; xl23 = xl13; xl13 = ospl0; yl23 = yl13; yl13 = spl0; ospl1 = spl1; lpspl1 = b03 * spl1 + b13 * xr13 + b23 * xr23 - a13 * yr13 - a23 * yr23; spl1 = lpspl1; xr23 = xr13; xr13 = ospl1; yr23 = yr13; yr13 = spl1; ); s0 -= spl0; s1 -= spl1; mono = (s0 + s1)/2; stereo = (s0 - s1); s0 = (mono + stereo * amount) * max(amount,1); s1 = (mono - stereo * amount) * max(amount,1); spl0 += s0; spl1 += s1; mono = (spl0 + spl1); stereo = (spl0 - spl1); spl0 = (mono*mid + stereo*side);// / max(side,1); spl1 = (mono*mid - stereo*side);// / max(width,1); spl0 = spl0*outgain; spl1 = spl1*outgain; @gfx 100 10 gfx_x=gfx_y=5; gfx_lineto(gfx_x, gfx_y,0); gfx_r=gfx_b=0; gfx_g=gfx_a=1; gfx_drawchar($'H'); gfx_drawchar($'P'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(freq1,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); gfx_y += 15; gfx_x = 5; gfx_drawchar($'L'); gfx_drawchar($'P'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(freq3,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); //RBJ Filters Implementation // Copyright 2006, Thomas Scott Stillwell // All rights reserved. // //Redistribution and use in source and binary forms, with or without modification, are permitted //provided that the following conditions are met: // //Redistributions of source code must retain the above copyright notice, this list of conditions //and the following disclaimer. // //Redistributions in binary form must reproduce the above copyright notice, this list of conditions //and the following disclaimer in the documentation and/or other materials provided with the distribution. // //The name of Thomas Scott Stillwell may not be used to endorse or //promote products derived from this software without specific prior written permission. // //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR //IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND //FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS //BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, //STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF //THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jsusfx-0.4.0/scripts/liteon/ringmodulator.jsfx000066400000000000000000000222741353477307700216270ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . //================================================= desc:Ring Modulator //================================================= slider1:0<0,1,1{Stereo,Mono}>Processing slider2:0<0,1,1{Off,On}>Mod Input Diode (Waveshaper) slider3:40<0,100,0.01>Mod Frequency (Scale) slider4:0<0,100,0.01>Feedback (%) slider5:10<0,100,0.01>Non-Linearities (%) slider6:100<0,100,0.01>Mix (%) slider7:0<-40,40,0.01>Output (-inf/+40dB) slider8:0<0,1,1{Off,On}>Oversample (x2) //================================================= @init //================================================= //2*pi pi2 = 2*$pi; //sim resistance r = 0.85; //fir restoration filter c1 = 1; c2 = -0.75; c3 = 0.17; fgain = 4; //fir bandlimit bl_c1 = 0.52; bl_c2 = 0.54; bl_c3 = -0.02; //================================================= @slider //================================================= mono = slider1; os = slider8; sx = 16+slider3*1.20103; tgt_f = floor(exp(sx*log(1.059))*8.17742); fb = slider4/100; tgt_mix = slider6/100; diode = slider2; nl = slider5; slider7 == -40 ? outgain = 0 : outgain = 10^(slider7/20); //================================================= @block //================================================= //interpolate 'f' d_f = (tgt_f-src_f)/samplesblock; tf = src_f; src_f = tgt_f; //interpolate 'mix' d_mix = (tgt_mix-src_mix)/samplesblock; tmix = src_mix; src_mix = tgt_mix; @sample //================================================= // set mod signal //================================================= //a couple of pseudo non-linearities for 'f' and 'fb' nl > 0 ? ( nl_f = rand(4*nl)-2*nl; nl_fb = (rand(2*nl)-nl)*0.001; ) : ( nl_f = nl_fb = 0; ); //interpolate 'f' tf += d_f; //interpolate 'mix' tmix += d_mix; //mod signal gen sina = pi2*(tf-nl_f)/srate; sinout = sin(sinp); sinp = sinp+sina; sinp >= pi2 ? sinp -= pi2; //diode - positive semi-periods diode == 0 ? ( m_out = sinout; ) : ( //os - diode-ed signal? os == 0 ? ( //abs() d_sin = abs(sinout)*2-0.20260; ) : ( //power series in ps_sin_out1 = 0.5*(sinout+ps_sin_out2); ps_sin_out2 = 0.5*ps_sin_out1; //abs() ps_d_sin1 = abs(ps_sin_out1)*2-0.20260; ps_d_sin2 = abs(ps_sin_out2)*2-0.20260; //bandlimit sin_bl3_1 = sin_bl2_1; sin_bl3_2 = sin_bl2_2; sin_bl2_1 = sin_bl1_1; sin_bl2_2 = sin_bl1_2; sin_bl1_1 = ps_d_sin1; sin_bl1_2 = ps_d_sin2; sin_bl_out1 = (sin_bl1_1*bl_c1 + sin_bl2_1*bl_c2 + sin_bl3_1*bl_c3); sin_bl_out2 = (sin_bl1_2*bl_c1 + sin_bl2_2*bl_c2 + sin_bl3_2*bl_c3); //power series out o_sin_out1 = 0.5*(sin_bl_out1+o_sin_out2); o_sin_out2 = 0.5*(sin_bl_out2+o_sin_out1); //fir restoration s3 = s2; s2 = s1; s1 = o_sin_out1; d_sin = (s1*c1+s2*c2+s3*c3)*fgain; ); m_out = d_sin ); //no feedback? fb == 0 ? nl_fb = 0; //================================================= //fx mono //================================================= mono == 1 ? ( //------------------------------------------------- //input //------------------------------------------------- in_l = (spl0+spl1)/2; //------------------------------------------------- //os - no //------------------------------------------------- os == 0 ? ( //feedback ala Paul Kellet fp_l = (in_l+(fb-nl_fb)*fp_l)*sinout*r; //multiply carrier with mod s_out_l = m_out*in_l; //apply feedback s_out_l += fp_l; fx_outl = s_out_l; ) : ( //------------------------------------------------- //os - yes //------------------------------------------------- //power series in ps_fx_out1l = 0.5*(in_l+ps_fx_out2l); ps_fx_out2l = 0.5*ps_fx_out1l; //------------------------ //fx //------------------------ fp_l_os_1 = (ps_fx_out1l+(fb-nl_fb)*fp_l_os_1)*sinout*r; s_out_l_os_1 = m_out*ps_fx_out1l; s_out_l_os_1 += fp_l_os_1; fp_l_os_2 = (ps_fx_out2l+(fb-nl_fb)*fp_l_os_2)*sinout*r; s_out_l_os_2 = m_out*ps_fx_out2l; s_out_l_os_2 += fp_l_os_2; //------------------------ //bandlimit //------------------------ bl3_1 = bl2_1; bl3_2 = bl2_2; bl2_1 = bl1_1; bl2_2 = bl1_2; bl1_1 = s_out_l_os_1; bl1_2 = s_out_l_os_2; bl_out1 = (bl1_1*bl_c1 + bl2_1*bl_c2 + bl3_1*bl_c3); bl_out2 = (bl1_2*bl_c1 + bl2_2*bl_c2 + bl3_2*bl_c3); //------------------------ //power series out //------------------------ o_fx_out1l = 0.5*(bl_out1+o_fx_out2l); o_fx_out2l = 0.5*(bl_out2+o_fx_out1l); //fir restoration s3l = s2l; s2l = s1l; s1l = o_fx_out1l; fx_outl = (s1l*c1+s2l*c2+s3l*c3)*fgain; ); //------------------------ //mixer //------------------------ out_l = fx_outl*(tmix)+in_l*(1-tmix); spl1 = spl0 = out_l*r*outgain; ):( //================================================= //fx stereo //================================================= in_l = spl0; in_r = spl1; //------------------------------------------------- //os - no //------------------------------------------------- os == 0 ? ( fp_l = (in_l+(fb-nl_fb)*fp_l)*sinout*r; s_out_l = m_out*in_l; s_out_l += fp_l; out_l = s_out_l*(tmix)+in_l*(1-tmix); fx_outl = out_l*r*outgain; fp_r = (in_r+(fb-nl_fb)*fp_r)*sinout*r; s_out_r = m_out*in_r; s_out_r += fp_r; out_r = s_out_r*(tmix)+in_r*(1-tmix); fx_outr = out_r*r*outgain; ) : ( //------------------------------------------------- //os - yes //------------------------------------------------- //power series in ps_fx_out1l = 0.5*(in_l+ps_fx_out2l); ps_fx_out2l = 0.5*ps_fx_out1l; ps_fx_out1r = 0.5*(in_r+ps_fx_out2r); ps_fx_out2r = 0.5*ps_fx_out1r; //------------------------ //fx //------------------------ fp_l_os_1 = (ps_fx_out1l+(fb-nl_fb)*fp_l_os_1)*sinout*r; s_out_l_os_1 = m_out*ps_fx_out1l; s_out_l_os_1 += fp_l_os_1; fp_l_os_2 = (ps_fx_out2l+(fb-nl_fb)*fp_l_os_2)*sinout*r; s_out_l_os_2 = m_out*ps_fx_out2l; s_out_l_os_2 += fp_l_os_2; fp_r_os_1 = (ps_fx_out1r+(fb-nl_fb)*fp_r_os_1)*sinout*r; s_out_r_os_1 = m_out*ps_fx_out1r; s_out_r_os_1 += fp_r_os_1; fp_r_os_2 = (ps_fx_out2r+(fb-nl_fb)*fp_r_os_2)*sinout*r; s_out_r_os_2 = m_out*ps_fx_out2r; s_out_r_os_2 += fp_r_os_2; //------------------------ //bandlimit //------------------------ bl3_l1 = bl2_l1; bl3_r1 = bl2_r1; bl3_l2 = bl2_l2; bl3_r2 = bl2_r2; bl2_l1 = bl1_l1; bl2_r1 = bl1_r1; bl2_l2 = bl1_l2; bl2_r2 = bl1_r2; bl1_l1 = s_out_l_os_1; bl1_r1 = s_out_r_os_1; bl1_l2 = s_out_l_os_2; bl1_r2 = s_out_r_os_2; bl_out1l = (bl1_l1*bl_c1 + bl2_l1*bl_c2 + bl3_l1*bl_c3); bl_out1r = (bl1_r1*bl_c1 + bl2_r1*bl_c2 + bl3_r1*bl_c3); bl_out2l = (bl1_l2*bl_c1 + bl2_l2*bl_c2 + bl3_l2*bl_c3); bl_out2r = (bl1_r2*bl_c1 + bl2_r2*bl_c2 + bl3_r2*bl_c3); //------------------------ //power series out //------------------------ o_fx_out1l = 0.5*(bl_out1l+o_fx_out2l); o_fx_out2l = 0.5*(bl_out2l+o_fx_out1l); o_fx_out1r = 0.5*(bl_out1r+o_fx_out2r); o_fx_out2r = 0.5*(bl_out2r+o_fx_out1r); //------------------------ //fir restoration //------------------------ s3l = s2l; s2l = s1l; s1l = o_fx_out1l; fx_outl = (s1l*c1+s2l*c2+s3l*c3)*fgain; s3r = s2r; s2r = s1r; s1r = o_fx_out1r; fx_outr = (s1r*c1+s2r*c2+s3r*c3)*fgain; ); //------------------------ //mixer //------------------------ out_l = fx_outl*(tmix)+in_l*(1-tmix); out_r = fx_outr*(tmix)+in_r*(1-tmix); spl0 = out_l*r*outgain; spl1 = out_r*r*outgain; ); //================================================= @gfx 100 10 //================================================= //draw 'f' gfx_x=gfx_y=5; gfx_lineto(gfx_x, gfx_y,0); gfx_r=gfx_b=0.5; gfx_g=0.7; gfx_a=1; gfx_drawchar($'M'); gfx_drawchar($'O'); gfx_drawchar($'D'); gfx_drawchar($' '); gfx_drawchar($'F'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(tgt_f,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); //draw diode picture diode == 0 ? gfx_r=gfx_g=gfx_b=0.4; padx = 385; pady = 7; gfx_y = gfx_y+8; gfx_x = padx-50; gfx_drawchar($'M'); gfx_drawchar($'O'); gfx_drawchar($'D'); gfx_drawchar($'~'); gfx_x = padx; gfx_y = pady; gfx_lineto(padx,pady+20,0); gfx_lineto(padx+15,pady+10,0); gfx_lineto(padx,pady,0); gfx_x = padx+15; gfx_y = pady; gfx_lineto(padx+15,pady+20,0); gfx_x = padx-10; gfx_y = pady+10; gfx_lineto(padx,pady+10,0); gfx_x = padx+15; gfx_lineto(padx+30,pady+10,0); jsusfx-0.4.0/scripts/liteon/shelvingfilter.jsfx000066400000000000000000000135061353477307700217640ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . //****************************************************************************** // References: "filters3.txt" // Shelf Filters as given in // James A. Moorer // The manifold joys of conformal mappping: // applications to digital filtering in the studio // JAES, Vol. 31, No. 11, 1983 November //****************************************************************************** desc:ShelvingFilter (Moorer) slider1:0<0,1,1{Stereo,Mono}>Processing slider2:50<0,100,0.05>LowShelf (Scale) slider3:0<-24,24,0.01>Gain (dB) slider4:50<0,100,0.05>HighShelf (Scale) slider5:0<-24,24,0.01>Gain (dB) slider6:0<-24,24,0.05>Output (dB) @init SPN=0; yl_ls=x1l_ls=x2l_ls=y1l_ls=y2l_ls=yr_ls=x1r_ls=x2r_ls=y1r_ls=y2r_ls=0; yl_hs=x1l_hs=x2l_hs=y1l_hs=y2l_hs=yr_hs=x1r_hs=x2r_hs=y1r_hs=y2r_hs=0; @slider mono = slider1; outgain = 10^(slider6/20); //*** LS sx = 16+slider2*1.20103; cf = floor(exp(sx*log(1.059))*8.17742); freq1 = cf; cf /= srate; boost = slider3; sa = tan($pi*(cf-0.25)); asq = sa*sa; A = 10^(boost/20.0); (boost < 6.0) && (boost > -6.0) ? ( F = sqrt(A); ) : ( (A > 1.0) ? ( F = A/sqrt(2.0); ) : ( F = A*sqrt(2.0); ); ); F2 = F*F; tmp = A*A - F2; abs(tmp) <= SPN ? ( gammad = 1.0; ) : ( gammad = ((F2-1.0)/tmp)^(0.25); ); gamman = sqrt(A)*gammad; gamma2 = gamman*gamman; gam2p1 = 1.0 + gamma2; siggam2 = 2.0*sqrt(2.0)/2.0*gamman; ta0 = gam2p1 + siggam2; ta1 = -2.0*(1.0 - gamma2); ta2 = gam2p1 - siggam2; gamma2 = gammad*gammad; gam2p1 = 1.0 + gamma2; siggam2 = 2.0*sqrt(2.0)/2.0*gammad; tb0 = gam2p1 + siggam2; tb1 = -2.0*(1.0 - gamma2); tb2 = gam2p1 - siggam2; aa1 = sa*ta1; a0 = ta0 + aa1 + asq*ta2; a1 = 2.0*sa*(ta0+ta2)+(1.0+asq)*ta1; a2 = asq*ta0 + aa1 + ta2; ab1 = sa*tb1; b0 = tb0 + ab1 + asq*tb2; b1 = 2.0*sa*(tb0+tb2)+(1.0+asq)*tb1; b2 = asq*tb0 + ab1 + tb2; recipb0 = 1.0/b0; a0 *= recipb0; a1 *= recipb0; a2 *= recipb0; b1 *= recipb0; b2 *= recipb0; a0_ls = a0; a1_ls = a1; a2_ls = a2; b1_ls = -b1; b2_ls = -b2; //*** HS sx = 16+slider4*1.20103; cf = floor(exp(sx*log(1.059))*8.17742); freq2 = cf; cf /= srate; boost = -slider5; sa = tan($pi*(cf-0.25)); asq = sa*sa; A = 10^(boost/20.0); (boost < 6.0) && (boost > -6.0) ? ( F = sqrt(A); ) : ( (A > 1.0) ? ( F = A/sqrt(2.0); ) : ( F = A*sqrt(2.0); ); ); F2 = F*F; tmp = A*A - F2; abs(tmp) <= SPN ? ( gammad = 1.0; ) : ( gammad = ((F2-1.0)/tmp)^(0.25); ); gamman = sqrt(A)*gammad; gamma2 = gamman*gamman; gam2p1 = 1.0 + gamma2; siggam2 = 2.0*sqrt(2.0)/2.0*gamman; ta0 = gam2p1 + siggam2; ta1 = -2.0*(1.0 - gamma2); ta2 = gam2p1 - siggam2; gamma2 = gammad*gammad; gam2p1 = 1.0 + gamma2; siggam2 = 2.0*sqrt(2.0)/2.0*gammad; tb0 = gam2p1 + siggam2; tb1 = -2.0*(1.0 - gamma2); tb2 = gam2p1 - siggam2; aa1 = sa*ta1; a0 = ta0 + aa1 + asq*ta2; a1 = 2.0*sa*(ta0+ta2)+(1.0+asq)*ta1; a2 = asq*ta0 + aa1 + ta2; ab1 = sa*tb1; b0 = tb0 + ab1 + asq*tb2; b1 = 2.0*sa*(tb0+tb2)+(1.0+asq)*tb1; b2 = asq*tb0 + ab1 + tb2; recipb0 = 1.0/b0; a0 *= recipb0; a1 *= recipb0; a2 *= recipb0; b1 *= recipb0; b2 *= recipb0; gain = 10^(boost/20.0); a0_hs = a0/gain; a1_hs = a1/gain; a2_hs = a2/gain; b1_hs = -b1; b2_hs = -b2; @sample //mono mono == 1 ? ( //LS xl_ls = (spl0+spl1)/2; yl_ls = a0_ls*xl_ls + a1_ls*x1l_ls + a2_ls*x2l_ls + b1_ls*y1l_ls + b2_ls*y2l_ls; x2l_ls = x1l_ls; x1l_ls = xl_ls; y2l_ls = y1l_ls; y1l_ls = yl_ls; //HS xl_hs = yl_ls; yl_hs = a0_hs*xl_hs + a1_hs*x1l_hs + a2_hs*x2l_hs + b1_hs*y1l_hs + b2_hs*y2l_hs; x2l_hs = x1l_hs; x1l_hs = xl_hs; y2l_hs = y1l_hs; y1l_hs = yl_hs; spl0=spl1=yl_hs*outgain; //stereo ) : ( //LS xl_ls = spl0; xr_ls = spl1; yl_ls = a0_ls*xl_ls + a1_ls*x1l_ls + a2_ls*x2l_ls + b1_ls*y1l_ls + b2_ls*y2l_ls; x2l_ls = x1l_ls; x1l_ls = xl_ls; y2l_ls = y1l_ls; y1l_ls = yl_ls; yr_ls = a0_ls*xr_ls + a1_ls*x1r_ls + a2_ls*x2r_ls + b1_ls*y1r_ls + b2_ls*y2r_ls; x2r_ls = x1r_ls; x1r_ls = xr_ls; y2r_ls = y1r_ls; y1r_ls = yr_ls; //HS xl_hs = yl_ls; xr_hs = yr_ls; yl_hs = a0_hs*xl_hs + a1_hs*x1l_hs + a2_hs*x2l_hs + b1_hs*y1l_hs + b2_hs*y2l_hs; x2l_hs = x1l_hs; x1l_hs = xl_hs; y2l_hs = y1l_hs; y1l_hs = yl_hs; yr_hs = a0_hs*xr_hs + a1_hs*x1r_hs + a2_hs*x2r_hs + b1_hs*y1r_hs + b2_hs*y2r_hs; x2r_hs = x1r_hs; x1r_hs = xr_hs; y2r_hs = y1r_hs; y1r_hs = yr_hs; spl0 = yl_hs*outgain; spl1 = yr_hs*outgain; ); @gfx 100 10 gfx_x=gfx_y=5; gfx_lineto(gfx_x, gfx_y,0); gfx_r=gfx_b=0; gfx_g=gfx_a=1; gfx_drawchar($'L'); gfx_drawchar($'S'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(freq1,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); gfx_y += 15; gfx_x = 5; gfx_drawchar($'H'); gfx_drawchar($'S'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(freq2,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); jsusfx-0.4.0/scripts/liteon/simplelp6db.jsfx000066400000000000000000000047111353477307700211560ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . //================================================= desc: Simple LP, HP Filter 6db slider1:0<0,1,1{Stereo,Mono}>Processing slider2:0<0,1,1{LP,HP}>Filter Type slider3:100<0,100,0.05>Cutoff (Scale) slider4:0<-25,25,0.05>Output (dB) //================================================= @slider //mono mono = slider1; //type hp = slider2; //exp scale sx = 16+slider3*1.20103; cutoff = floor(exp(sx*log(1.059))*8.17742); //coeff cutoff = min(cutoff,20000); lp_cut = 2*$pi*cutoff; lp_n = 1/(lp_cut+ 3*srate); lp_b1 = (3*srate - lp_cut)*lp_n; lp_a0 = lp_cut*lp_n; //outgain outgain = 10^(slider4/20); //================================================= @sample //stereo mono == 0 ? ( //recursion inl = spl0; inr = spl1; lp_outl = 2*inl*lp_a0 + lp_outl*lp_b1; lp_outr = 2*inr*lp_a0 + lp_outr*lp_b1; //type hp == 0 ? ( spl0 = lp_outl*outgain; spl1 = lp_outr*outgain; ) : ( spl0 = (inl-lp_outl)*outgain; spl1 = (inr-lp_outr)*outgain; ); ) : ( //mono //recursion inl = (spl0+spl1)/2; lp_outl = 2*inl*lp_a0 + lp_outl*lp_b1; //type hp == 0 ? ( spl0=spl1=lp_outl*outgain; ) : ( spl0=spl1=(inl-lp_outl)*outgain; ); ); //================================================= @gfx 100 10 //draw freq scale numbers gfx_x=gfx_y=5; gfx_lineto(gfx_x, gfx_y,0); gfx_r=gfx_b=0; gfx_g=gfx_a=1; gfx_drawchar($'F'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(cutoff,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); jsusfx-0.4.0/scripts/liteon/sonic_enhancer.jsfx000066400000000000000000000075421353477307700217200ustar00rootroot00000000000000/* sonic enhancer thing Copyright (C) 2011 lubomir i. ivanov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ desc: Sonic Enhancer slider1:0<-12, 12, 0.1>Input slider2:0<0, 10, 0.1>Low Contour slider3:0<0, 10, 0.1>Process slider4:2<0, 10, 0.1>CV slider5:0<-12, 12, 0.1>Output slider6:1<0, 1, {Off,On})>Noise Floor @init r_6 = 1/6; nf_k = pow(2, -96 * r_6); rc0_k0 = 0.0003; rc0_k1 = 1 - rc0_k0; lp_fc = tan($pi * 0.48); lp_r1pfc = 1 / (1 + lp_fc); fc = 700; fs = srate; pi2 = 2*$pi; q = 0.23; omega = pi2 * fc / fs; sn = sin(omega); cs = cos(omega); alpha = sn / (2.0 * Q); b0_ap = 1.0 / (1.0 + alpha); b1_ap = (-2.0 * cs) * b0_ap; b2_ap = (1.0 - alpha) * b0_ap; a0_ap = b2_ap; a1_ap = b1_ap; a2_ap = 1; b0_lp = 1.0 / (1.0 + alpha); b1_lp = (-2.0 * cs) * b0_lp; b2_lp = (1.0 - alpha) * b0_lp; a1_lp = (1.0 - cs) * b0_lp; a0_lp = a1_lp * 0.5; a2_lp = a0_lp; b0_hp = 1.0 / (1.0 + alpha); b1_hp = (-2.0 * cs) * b0_hp; b2_hp = (1.0 - alpha) * b0_hp; a1_hp = -(1.0 + cs) * b0_hp; a0_hp = -a1_hp * 0.5; a2_hp = a0_hp; @slider g_in = pow(2, slider1 * r_6); g_lp = slider2*0.5; g_hp = slider3*0.5; cv_k = slider4; g_out = pow(2, slider5 * r_6); noise_floor = slider6; @sample in0 = spl0*g_in; in1 = spl1*g_in; nf0 = 0.0; nf1 = 0.0; noise_floor ? ( nf0 = (rand(2.0) - 1.0)*nf_k; nf1 = (rand(2.0) - 1.0)*nf_k; ); out_ap0 = a0_ap*in0 + a1_ap*x1_ap0 + a2_ap*x2_ap0 - b1_ap*y1_ap0 - b2_ap*y2_ap0; x2_ap0 = x1_ap0; x1_ap0 = in0; y2_ap0 = y1_ap0; y1_ap0 = out_ap0; out_ap1 = a0_ap*in1 + a1_ap*x1_ap1 + a2_ap*x2_ap1 - b1_ap*y1_ap1 - b2_ap*y2_ap1; x2_ap1 = x1_ap1; x1_ap1 = in1; y2_ap1 = y1_ap1; y1_ap1 = out_ap1; out_lp0 = a0_lp*in0 + a1_lp*x1_lp0 + a2_lp*x2_lp0 - b1_lp*y1_lp0 - b2_lp*y2_lp0; x2_lp0 = x1_lp0; x1_lp0 = in0; y2_lp0 = y1_lp0; y1_lp0 = out_lp0; out_lp1 = a0_lp*in1 + a1_lp*x1_lp1 + a2_lp*x2_lp1 - b1_lp*y1_lp1 - b2_lp*y2_lp1; x2_lp1 = x1_lp1; x1_lp1 = in1; y2_lp1 = y1_lp1; y1_lp1 = out_lp1; out_hp0 = a0_hp*in0 + a1_hp*x1_hp0 + a2_hp*x2_hp0 - b1_hp*y1_hp0 - b2_hp*y2_hp0; x2_hp0 = x1_hp0; x1_hp0 = in0; y2_hp0 = y1_hp0; y1_hp0 = out_hp0; out_hp1 = a0_hp*in1 + a1_hp*x1_hp1 + a2_hp*x2_hp1 - b1_hp*y1_hp1 - b2_hp*y2_hp1; x2_hp1 = x1_hp1; x1_hp1 = in1; y2_hp1 = y1_hp1; y1_hp1 = out_hp1; cv0 = 1 - abs(in0)*cv_k; cv1 = 1 - abs(in1)*cv_k; cv_rc0 = rc0_k0*cv0 + rc0_k1*cv_rc0; cv_rc1 = rc0_k0*cv1 + rc0_k1*cv_rc1; out_sv0 = out_ap0 + out_hp0*cv_rc0*g_hp + out_lp0*g_lp; out_sv1 = out_ap1 + out_hp1*cv_rc1*g_hp + out_lp1*g_lp; out_rc0 = rc0_k0*out_sv0 + rc0_k1*out_rc0; out_rc1 = rc0_k0*out_sv1 + rc0_k1*out_rc1; out_dc0 = out_sv0 - out_rc0; out_dc1 = out_sv1 - out_rc1; out_lp0 = (buf_lp0 + lp_fc*out_dc0) * lp_r1pfc; buf_lp0 = lp_fc*(out_dc0 - out_lp0) + out_lp0; out_lp1 = (buf_lp1 + lp_fc*out_dc1) * lp_r1pfc; buf_lp1 = lp_fc*(out_dc1 - out_lp1) + out_lp1; spl0 = out_lp0*g_out + nf0; spl1 = out_lp1*g_out + nf1; @gfx 0 10 gfx_r = 0.8; gfx_g = 0.5; gfx_b = 0; gfx_a = min(1, 0.55 + cv_rc0*0.35 + g_hp*0.1); gfx_x = 5; gfx_y = 5; gfx_rectto(gfx_w*0.5 - 3, gfx_h - 5); gfx_a = min(1, 0.55 + cv_rc1*0.35 + g_hp*0.1); gfx_x = gfx_w*0.5 + 3; gfx_y = 5; gfx_rectto(gfx_w - 5, gfx_h - 5); jsusfx-0.4.0/scripts/liteon/statevariable.jsfx000066400000000000000000000301321353477307700215570ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . // //****************************************************************************** // StateVariable (Morphing) filter // AppleFilter - butterworth filter implementation // original port from apple.com au tutorial (c++) // added coefficients for HP, BP, BR // :::NOTE: cutoff glitches when automated fast::: // :::Better interpolation or oversampling is required::: //****************************************************************************** desc: StateVariable(Morphing) Filter: Use X,Y pads slider1:0<0,1,1{Stereo,Mono}>Processing slider2:0.5<0,1,0.001>X (Morph) slider3:0.5<0,1,0.001>Y (Morph) slider4:50<0,100,0.01>Frequency (Scale) slider5:6<0,24,0.01>Res (dB) slider6:100<0,100,0.01>Filter Amount (%) //slider7:0<0,100,0.01>Flux (%) slider7:0<-26,26,0.01>Output (-inf/+26dB) @init step = 200; old_f_x = 39; old_f_y = 39; old_c_x = step+39; old_c_y = 191; @block //---interpolate filters //lp d_a0_lp = (tgt_a0_lp-src_a0_lp)/samplesblock; a0_lp = src_a0_lp; src_a0_lp = tgt_a0_lp; d_a1_lp = (tgt_a1_lp-src_a1_lp)/samplesblock; a1_lp = src_a1_lp; src_a1_lp = tgt_a1_lp; d_a2_lp = (tgt_a2_lp-src_a2_lp)/samplesblock; a2_lp = src_a2_lp; src_a2_lp = tgt_a2_lp; d_b1_lp = (tgt_b1_lp-src_b1_lp)/samplesblock; b1_lp = src_b1_lp; src_b1_lp = tgt_b1_lp; d_b2_lp = (tgt_b2_lp-src_b2_lp)/samplesblock; b2_lp = src_b2_lp; src_b2_lp = tgt_b2_lp; //hp d_a0_hp = (tgt_a0_hp-src_a0_hp)/samplesblock; a0_hp = src_a0_hp; src_a0_hp = tgt_a0_hp; d_a1_hp = (tgt_a1_hp-src_a1_hp)/samplesblock; a1_hp = src_a1_hp; src_a1_hp = tgt_a1_hp; d_a2_hp = (tgt_a2_hp-src_a2_hp)/samplesblock; a2_hp = src_a2_hp; src_a2_hp = tgt_a2_hp; d_b1_hp = (tgt_b1_hp-src_b1_hp)/samplesblock; b1_hp = src_b1_hp; src_b1_hp = tgt_b1_hp; d_b2_hp = (tgt_b2_hp-src_b2_hp)/samplesblock; b2_hp = src_b2_hp; src_b2_hp = tgt_b2_hp; //bp d_a0_bp = (tgt_a0_bp-src_a0_bp)/samplesblock; a0_bp = src_a0_bp; src_a0_bp = tgt_a0_bp; d_b1_bp = (tgt_b1_bp-src_b1_bp)/samplesblock; b1_bp = src_b1_bp; src_b1_bp = tgt_b1_bp; d_b2_bp = (tgt_b2_bp-src_b2_bp)/samplesblock; b2_bp = src_b2_bp; src_b2_bp = tgt_b2_bp; //br d_a0_br = (tgt_a0_br-src_a0_br)/samplesblock; a0_br = src_a0_br; src_a0_br = tgt_a0_br; d_a1_br = (tgt_a1_br-src_a1_br)/samplesblock; a1_br = src_a1_br; src_a1_br = tgt_a1_br; d_b1_br = (tgt_b1_br-src_b1_br)/samplesblock; b1_br = src_b1_br; src_b1_br = tgt_b1_br; d_b2_br = (tgt_b2_br-src_b2_br)/samplesblock; b2_br = src_b2_br; src_b2_br = tgt_b2_br; //----------interpolate x,y d_x = (tgt_x-src_x)/samplesblock; x = src_x; src_x = tgt_x; d_y = (tgt_y-src_y)/samplesblock; y = src_y; src_y = tgt_y; @sample //---interpolate filters //lp a0_lp += d_a0_lp; a1_lp += d_a1_lp; a2_lp += d_a2_lp; b1_lp += d_b1_lp; b2_lp += d_b2_lp; //hp a0_hp += d_a0_hp; a1_hp += d_a1_hp; a2_hp += d_a2_hp; b1_hp += d_b1_hp; b2_hp += d_b2_hp; //bp a0_bp += d_a0_bp; b1_bp += d_b1_bp; b2_bp += d_b2_bp; //br a0_br += d_a0_br; a1_br += d_a1_br; b1_br += d_b1_br; b2_br += d_b2_br; //---------interpolate x,y x += d_x; y += d_y; //----------------------------------------- //mono slider1 == 1 ? ( inl = (spl0+spl1)/2; //lp out_lp_l = a0_lp*inl+a1_lp*mem1_lp_l+a2_lp*mem2_lp_l-b1_lp*mem3_lp_l-b2_lp*mem4_lp_l; mem2_lp_l = mem1_lp_l; mem1_lp_l = inl; mem4_lp_l = mem3_lp_l; mem3_lp_l = out_lp_l; //hp out_hp_l = a0_hp*inl+a1_hp*mem1_hp_l+a2_hp*mem2_hp_l-b1_hp*mem3_hp_l-b2_hp*mem4_hp_l; mem2_hp_l = mem1_hp_l; mem1_hp_l = inl; mem4_hp_l = mem3_hp_l; mem3_hp_l = out_hp_l; //bp out_bp_l = a0_bp*inl-a0_bp*mem2_bp_l-b1_bp*mem3_bp_l-b2_bp*mem4_bp_l; mem2_bp_l = mem1_bp_l; mem1_bp_l = inl; mem4_bp_l = mem3_bp_l; mem3_bp_l = out_bp_l; //br out_br_l = a0_br*inl+a1_br*mem1_br_l+a0_br*mem2_br_l-b1_br*mem3_br_l-b2_br*mem4_br_l; mem2_br_l = mem1_br_l; mem1_br_l = inl; mem4_br_l = mem3_br_l; mem3_br_l = out_br_l; //out //hp, lp pair1_l = out_lp_l*y+out_hp_l*(1-y); //br, bp pair2_l = out_bp_l*y+out_br_l*(1-y); //out outl = pair2_l*x+pair1_l*(1-x); spl0 = spl1 = (outl*(1-amount)+inl*amount)*outgain; ) : ( //---------------------stereo //-------LEFT inl = spl0; //lp out_lp_l = a0_lp*inl+a1_lp*mem1_lp_l+a2_lp*mem2_lp_l-b1_lp*mem3_lp_l-b2_lp*mem4_lp_l; mem2_lp_l = mem1_lp_l; mem1_lp_l = inl; mem4_lp_l = mem3_lp_l; mem3_lp_l = out_lp_l; //hp out_hp_l = a0_hp*inl+a1_hp*mem1_hp_l+a2_hp*mem2_hp_l-b1_hp*mem3_hp_l-b2_hp*mem4_hp_l; mem2_hp_l = mem1_hp_l; mem1_hp_l = inl; mem4_hp_l = mem3_hp_l; mem3_hp_l = out_hp_l; //bp out_bp_l = a0_bp*inl-a0_bp*mem2_bp_l-b1_bp*mem3_bp_l-b2_bp*mem4_bp_l; mem2_bp_l = mem1_bp_l; mem1_bp_l = inl; mem4_bp_l = mem3_bp_l; mem3_bp_l = out_bp_l; //br out_br_l = a0_br*inl+a1_br*mem1_br_l+a0_br*mem2_br_l-b1_br*mem3_br_l-b2_br*mem4_br_l; mem2_br_l = mem1_br_l; mem1_br_l = inl; mem4_br_l = mem3_br_l; mem3_br_l = out_br_l; //out //hp, lp pair1_l = out_lp_l*y+out_hp_l*(1-y); //br, bp pair2_l = out_bp_l*y+out_br_l*(1-y); //out outl = pair2_l*x+pair1_l*(1-x); spl0 = (outl*(1-amount)+inl*amount)*outgain; //----------RIGHT inr = spl1; //lp out_lp_r = a0_lp*inr+a1_lp*mem1_lp_r+a2_lp*mem2_lp_r-b1_lp*mem3_lp_r-b2_lp*mem4_lp_r; mem2_lp_r = mem1_lp_r; mem1_lp_r = inr; mem4_lp_r = mem3_lp_r; mem3_lp_r = out_lp_r; //hp out_hp_r = a0_hp*inr+a1_hp*mem1_hp_r+a2_hp*mem2_hp_r-b1_hp*mem3_hp_r-b2_hp*mem4_hp_r; mem2_hp_r = mem1_hp_r; mem1_hp_r = inr; mem4_hp_r = mem3_hp_r; mem3_hp_r = out_hp_r; //bp out_bp_r = a0_bp*inr-a0_bp*mem2_bp_r-b1_bp*mem3_bp_r-b2_bp*mem4_bp_r; mem2_bp_r = mem1_bp_r; mem1_bp_r = inr; mem4_bp_r = mem3_bp_r; mem3_bp_r = out_bp_r; //br out_br_r = a0_br*inr+a1_br*mem1_br_r+a0_br*mem2_br_r-b1_br*mem3_br_r-b2_br*mem4_br_r; mem2_br_r = mem1_br_r; mem1_br_r = inr; mem4_br_r = mem3_br_r; mem3_br_r = out_br_r; //out //hp, lp pair1_r = out_lp_r*y+out_hp_r*(1-y); //br, bp pair2_r = out_bp_r*y+out_br_r*(1-y); //out outr = pair2_r*x+pair1_r*(1-x); spl1 = (outr*(1-amount)+inr*amount)*outgain; ); @gfx 100 200 gfx_r=0.5; gfx_b=0.5; gfx_g=1; gfx_a=1; //amnt gfx_x=32; gfx_y=12; gfx_drawchar($'A'); gfx_drawchar($'M'); gfx_drawchar($'N'); gfx_drawchar($'T'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(slider6,0); gfx_drawchar($' '); gfx_drawchar($'%'); //freq gfx_x=230; gfx_y=12; gfx_drawchar($'F'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(cx,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); //filter box gfx_r=1; gfx_b=1; gfx_g=1; gfx_a=1; gfx_y = 30; gfx_x = 30; gfx_rectto(200,200); gfx_r=0; gfx_b=0.6; gfx_g=0; gfx_a=1; gfx_y = 32; gfx_x = 32; gfx_rectto(198,198); //filter text gfx_r=1; gfx_b=1; gfx_g=1; gfx_a=1; gfx_x = 35; gfx_y = 35; gfx_drawchar($'H'); gfx_drawchar($'P'); gfx_x = 35; gfx_y = 187; gfx_drawchar($'L'); gfx_drawchar($'P'); gfx_x = 178; gfx_y = 35; gfx_drawchar($'B'); gfx_drawchar($'R'); gfx_x = 178; gfx_y = 187; gfx_drawchar($'B'); gfx_drawchar($'P'); //cut,res box gfx_r=1; gfx_b=1; gfx_g=1; gfx_a=1; gfx_y = 30; gfx_x = 30+step; gfx_rectto(200+step,200); gfx_r=0; gfx_b=0.6; gfx_g=0; gfx_a=1; gfx_y = 32; gfx_x = 32+step; gfx_rectto(198+step,198); //cut,res text gfx_r=1; gfx_b=1; gfx_g=1; gfx_a=1; gfx_x = 35+step; gfx_y = 35; gfx_drawchar($'R'); gfx_drawchar($'E'); gfx_drawchar($'S'); gfx_x = 170+step; gfx_y = 187; gfx_drawchar($'C'); gfx_drawchar($'U'); gfx_drawchar($'T'); //cut,res lines gfx_r=1; gfx_b=1; gfx_g=1; gfx_a=0.7; gfx_x = 40+step; gfx_y = 90; gfx_lineto(40+step,50,0.5); gfx_x = 110+step; gfx_y = 190; gfx_lineto(160+step,190,0.5); //cross lines gfx_x = 228/2; gfx_y = 30; gfx_lineto(228/2,198,1); gfx_x = 30; gfx_y = 228/2; gfx_lineto(198,228/2,1); gfx_x = step+30; gfx_y = 200; gfx_lineto(398,30,1); gfx_x = step+30; gfx_y = 200; gfx_lineto(398,30,1); //-------------get mouse mouse_cap == 1 && mouse_x < step+15 && target != 2 ? ( target = 1; //-------marker1 old_f_x = mouse_x; old_f_y = mouse_y; old_f_x = max(39,min(old_f_x,191)); old_f_y = max(39,min(old_f_y,191)); //update sliders slider2 = s2 = (old_f_x-39)/(191-39); slider3 = s3 = (old_f_y-39)/(191-39); sliderchange(slider2); sliderchange(slider3); ); mouse_cap == 1 && mouse_x > step+15 && target != 1? ( target = 2; //--------marker2 old_c_x = mouse_x; old_c_y = mouse_y; old_c_x = max(39+step,min(old_c_x,191+step)); old_c_y = max(39,min(old_c_y,191)); //update sliders slider4 = s4 = (old_c_x-39-step)/(191-39)*100; slider5 = s5 = 24-(old_c_y-39)/(191-39)*24; sliderchange(slider4); sliderchange(slider5); ); mouse_cap == 0 ? ( target = 0; //slider to gfx old_f_x = slider2*(191-39)+39; old_f_y = slider3*(191-39)+39; old_c_x = slider4*(191-39)/100+39+step; old_c_y = 191-slider5*(191-39)/24; ); //---------draw markers //----marker1 gfx_r=0; gfx_b=0.5; gfx_g=1; gfx_a=0.7; gfx_x = old_f_x-7; gfx_y = old_f_y-7; gfx_rectto(old_f_x+7,old_f_y+7); //---marker2 gfx_r=0; gfx_b=0.5; gfx_g=1; gfx_a=0.7; gfx_x = old_c_x-7; gfx_y = old_c_y-7; gfx_rectto(old_c_x+7,old_c_y+7); //--------------------------------------------------------------- //@slider code here //---------------mix amount = (100-slider6)/100; outgain = 10^(slider7/20); slider7 == -24 ? outgain = 0; // x,y scheme // // hp - br // | | // lp - bp // tgt_x = slider2; tgt_y = slider3; //-------------filters sx = 16+slider4*1.20103; cx = floor(exp(sx*log(1.059))*8.17742); cutoff = 2*cx/srate; cx < 50 ? ( res = 1; ) : ( res = 10^(0.05*(-slider5+1.5)); ); //lp k = 0.5*res*sin($pi*cutoff); c1 = 0.5*(1-k)/(1+k); c2 = (0.5+c1)*cos($pi*cutoff); c3 = (0.5+c1-c2)*0.25; tgt_a0_lp = 2*c3; tgt_a1_lp = 4*c3; tgt_a2_lp = 2*c3; tgt_b1_lp = -2*c2; tgt_b2_lp = 2*c1; //hp c3 = (0.5+c1+c2)*0.25; tgt_a0_hp = 2*c3; tgt_a1_hp = -4*c3; tgt_a2_hp = 2*c3; tgt_b1_hp = -2*c2; tgt_b2_hp = 2*c1; //bp c3 = (0.5+c1-c2)*0.25; tgt_a0_bp = k/(1+k); tgt_b1_bp = -2*c2; tgt_b2_bp = 2*c1; //br k = 2*res*sin($pi*cutoff); c1 = 0.5*(1-k)/(1+k); c2 = (0.5+c1)*cos($pi*cutoff); c3 = (0.5+c1-c2)*0.25; tgt_a0_br = 1/(1+k); tgt_a1_br = tgt_a0_br*(-2*cos($pi*cutoff)); tgt_b1_br = -2*c2; tgt_b2_br = 2*c1; @slider //---------------mix amount = (100-slider6)/100; outgain = 10^(slider7/20); slider7 == -24 ? outgain = 0; // x,y scheme // // hp - br // | | // lp - bp // tgt_x = slider2; tgt_y = slider3; //-------------filters sx = 16+slider4*1.20103; cx = floor(exp(sx*log(1.059))*8.17742); cutoff = 2*cx/srate; cx < 50 ? ( res = 1; ) : ( res = 10^(0.05*(-slider5+1.5)); ); //lp k = 0.5*res*sin($pi*cutoff); c1 = 0.5*(1-k)/(1+k); c2 = (0.5+c1)*cos($pi*cutoff); c3 = (0.5+c1-c2)*0.25; tgt_a0_lp = 2*c3; tgt_a1_lp = 4*c3; tgt_a2_lp = 2*c3; tgt_b1_lp = -2*c2; tgt_b2_lp = 2*c1; //hp c3 = (0.5+c1+c2)*0.25; tgt_a0_hp = 2*c3; tgt_a1_hp = -4*c3; tgt_a2_hp = 2*c3; tgt_b1_hp = -2*c2; tgt_b2_hp = 2*c1; //bp c3 = (0.5+c1-c2)*0.25; tgt_a0_bp = k/(1+k); tgt_b1_bp = -2*c2; tgt_b2_bp = 2*c1; //br k = 2*res*sin($pi*cutoff); c1 = 0.5*(1-k)/(1+k); c2 = (0.5+c1)*cos($pi*cutoff); c3 = (0.5+c1-c2)*0.25; tgt_a0_br = 1/(1+k); tgt_a1_br = tgt_a0_br*(-2*cos($pi*cutoff)); tgt_b1_br = -2*c2; tgt_b2_br = 2*c1; jsusfx-0.4.0/scripts/liteon/stereotilt.jsfx000066400000000000000000000041671353477307700211400ustar00rootroot00000000000000// (C) 2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . desc:StereoTilt (Mono-to-Stereo) slider1:50<0,100,0.05>Center Frequency (Scale) slider2:0<-6,6,0.05>Tilt (- / +) (dB) slider3:0<-100,100,0.05>Balance (Left / Right) (%) slider4:0<-16,16,0.05>Output Gain (dB) @init amp = 6/log(2); denorm = 10^-30; pi = $pi; sr3 = 3*srate; @slider //gain gain = slider2; lgain0 = hgain1 = exp(gain/amp)-1; hgain0 = lgain1 = exp(-gain/amp)-1; outgain = exp((slider4-sign(gain)*gain)/amp); gl = min(1,1-slider3*0.01); gr = min(1,1+slider3*0.01); //f0 sx = 16+slider1*1.20103; f0 = exp(sx*log(1.059))*8.17742|0; //filter omega = 2*pi*f0; n = 1/(sr3 + omega); a0 = 2*omega*n; b1 = (sr3 - omega)*n; @sample //process spl0=(output = spl0 + lgain0*(lp_out = a0*spl0 + b1*lp_out) + hgain0*(spl0 - lp_out))*gl*outgain+denorm; spl1=(output_r = spl1 + lgain1*(lp_out_r = a0*spl1 + b1*lp_out_r) + hgain1*(spl1 - lp_out_r))*gr*outgain+denorm; @gfx 100 10 //draw freq scale numbers gfx_x=gfx_y=5; gfx_lineto(gfx_x, gfx_y,0); gfx_r=0; gfx_b=0.8; gfx_g=0.6; gfx_a=1; gfx_drawchar($'F'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(f0,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); jsusfx-0.4.0/scripts/liteon/tilteq.jsfx000066400000000000000000000047571353477307700202510ustar00rootroot00000000000000// (C) 2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . desc:Tilt Equalizer slider1:0<0,1,1{Stereo,Mono}>Processing slider2:50<0,100,0.05>Center Frequency (Scale) slider3:0<-6,6,0.05>Tilt (Low / High) (dB) slider4:0<-25,25,0.05>Output Gain (dB) @init amp = 6/log(2); denorm = 10^-30; pi = $pi; sr3 = 3*srate; @slider mono = slider1; gain = slider3; outgain = exp(slider4/amp); //condition gfactor = 4; gain > 0 ? ( g1 = -gfactor*gain; g2 = gain; ) : ( g1 = -gain; g2 = gfactor*gain; ); //two separate gains lgain = exp(g1/amp)-1; hgain = exp(g2/amp)-1; //f0 slider2_val = max(min(slider2,100), 0); sx = 16+slider2_val*1.20103; f0 = floor(exp(sx*log(1.059))*8.17742); //filter omega = 2*pi*f0; n = 1/(sr3 + omega); a0 = 2*omega*n; b1 = (sr3 - omega)*n; @sample mono == 1 ? ( //process mono input = (spl0+spl1)/2; lp_out = a0*input + b1*lp_out; output = input + lgain*lp_out + hgain*(input - lp_out); spl0=spl1=output*outgain+denorm; ) : ( //process stereo input = spl0; lp_out = a0*input + b1*lp_out; output = input + lgain*lp_out + hgain*(input - lp_out); spl0=output*outgain+denorm; input_r = spl1; lp_out_r = a0*input_r + b1*lp_out_r; output_r = input_r + lgain*lp_out_r + hgain*(input_r - lp_out_r); spl1=output_r*outgain+denorm; ); @gfx 100 10 //draw freq scale numbers gfx_x=gfx_y=5; gfx_lineto(gfx_x, gfx_y,0); gfx_r=0; gfx_b=0.8; gfx_g=0.6; gfx_a=1; gfx_drawchar($'F'); gfx_drawchar($' '); gfx_drawchar($'='); gfx_drawchar($' '); gfx_drawnumber(f0,0); gfx_drawchar($' '); gfx_drawchar($'H'); gfx_drawchar($'z'); jsusfx-0.4.0/scripts/liteon/tubeharmonics.jsfx000066400000000000000000000112601353477307700215750ustar00rootroot00000000000000// (C) 2009, Lubomir I. Ivanov // // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . // //********************************************************** // Tube Harmonics: // Simulates the behaviour of a vacuum tube circuit stage. // Adds odd and even harmonics to the signal. // Has flux and program dependent saturation. //********************************************************** desc: Tube Harmonics slider1:0.3<0,1,0.001>Even Harmonics slider2:0.3<0,1,0.001>Odd Harmonics slider3:0.1<0,1,0.001>Fluctuation slider4:0<-12,12,0.001>TS Input (dB) slider5:0<-12,12,0.001>TS Output (dB) slider6:0<-12,12,0.001>Output Gain (dB) @init ext_noinit=1; seed0=rand(999)|0; while(seed1=rand(999)|0;seed1==seed0;); sc_y0=sc_y1=1; ka=0.97; kb=1-ka; lim=0.5; @slider tgt_drve=slider1*4; drvo=slider2*9; kr=slider3; kabs=slider3*10; ingain=2^(slider4/6); hgain=2^(slider5/6); trim=2^(slider6/6); @sample // set in gain ch0=spl0*ingain; ch1=spl1*ingain; //interpolate y0+=d_y0; y1+=d_y1; abs0+=d_abs0; abs1+=d_abs1; drve+=d_drve; //set drive values drve_rnd0=drve-abs0; drve_rnd1=drve-abs1; drvo_rnd0=drvo-abs0-y0; drvo_rnd1=drvo-abs1-y1; //apply harmonics h0=sin(ch0)/sin(ch0*2)*drve_rnd0+(ch0-tan(ch0))*drvo_rnd0; h1=sin(ch1)/sin(ch1*2)*drve_rnd1+(ch1-tan(ch1))*drvo_rnd1; //dc filter i dc00=h0-(dcf00=h0*kb+dcf00*ka); dc01=h1-(dcf01=h1*kb+dcf01*ka); //limiter lim0=min(max(dc00*hgain,-lim),lim); lim1=min(max(dc01*hgain,-lim),lim); //fir filter m01=m00;m03=m02;m05=m04; fir0=0.5*(m05+m04=0.5*(m03+m02=0.5*(m01+m00=lim0))); m11=m10;m13=m12;m15=m14; fir1=0.5*(m15+m14=0.5*(m13+m12=0.5*(m11+m10=lim1))); //dc filter ii dc10=fir0-(dcf10=fir0*kb+dcf10*ka); dc11=fir1-(dcf11=fir1*kb+dcf11*ka); //sum spl0=(spl0+dc10)*trim; spl1=(spl1+dc11)*trim; @block //*** interpolate parameters d_drve=(tgt_drve-src_drve)/samplesblock; drve=src_drve; src_drve=tgt_drve; sc_y0=sin((seed0+=1)*sc_y0); tgt_y0=sc_y0*kr; d_y0=(tgt_y0-src_y0)/samplesblock; y0=src_y0; src_y0=tgt_y0; sc_y1=sin((seed1+=1)*sc_y1); tgt_y1=sc_y1*kr; d_y1=(tgt_y1-src_y1)/samplesblock; y1=src_y1; src_y1=tgt_y1; tgt_abs0=abs(ch0)*kabs; d_abs0=(tgt_abs0-src_abs0)/samplesblock; abs0=src_abs0; src_abs0=tgt_abs0; tgt_abs1=abs(ch1)*kabs; d_abs1=(tgt_abs1-src_abs1)/samplesblock; abs1=src_abs1; src_abs1=tgt_abs1; @gfx 200 42 drva=(drve+0.1+drvo*0.2)*0.5; //draw tube i gfx_a=1; gfx_r=gfx_g=gfx_b=1; ox=10; gfx_x=ox; gfx_y=10; gfx_rectto(ox+20,50); gfx_r=gfx_g=gfx_b=0; gfx_x=ox+1; gfx_y=10+1; gfx_rectto(ox+20-1,50-1); gfx_g=0.6; gfx_r=0.4; gfx_b=0.4; gfx_x=ox; gfx_y=42; gfx_rectto(ox+20,gfx_y+5); gfx_r=gfx_g=gfx_b=1; gfx_x=ox+7; gfx_y=8; gfx_rectto(ox+13,gfx_y+2); gfx_r=gfx_g=gfx_b=0.7; gfx_x=ox+4; gfx_y=50; gfx_rectto(ox+6,gfx_y+4); gfx_x=ox+9; gfx_y=50; gfx_rectto(ox+11,gfx_y+4); gfx_x=ox+14; gfx_y=50; gfx_rectto(ox+16,gfx_y+4); gfx_r=gfx_g=1; gfx_b=0.4; gfx_a=max(min(drva,1)-abs0*0.05,0.7); gfx_x=ox+4; gfx_y=14; gfx_rectto(ox+16,gfx_y+26); //draw tube ii gfx_a=1; gfx_r=gfx_g=gfx_b=1; ox=gfx_w-30; gfx_x=ox; gfx_y=10; gfx_rectto(ox+20,50); gfx_r=gfx_g=gfx_b=0; gfx_x=ox+1; gfx_y=10+1; gfx_rectto(ox+20-1,50-1); gfx_g=0.6; gfx_r=0.4; gfx_b=0.4; gfx_x=ox; gfx_y=42; gfx_rectto(ox+20,gfx_y+5); gfx_r=gfx_g=gfx_b=1; gfx_x=ox+7; gfx_y=8; gfx_rectto(ox+13,gfx_y+2); gfx_r=gfx_g=gfx_b=0.7; gfx_x=ox+4; gfx_y=50; gfx_rectto(ox+6,gfx_y+4); gfx_x=ox+9; gfx_y=50; gfx_rectto(ox+11,gfx_y+4); gfx_x=ox+14; gfx_y=50; gfx_rectto(ox+16,gfx_y+4); gfx_r=gfx_g=1; gfx_b=0.4; gfx_a=max(min(drva,1)-abs1*0.05,0.7); gfx_x=ox+4; gfx_y=14; gfx_rectto(ox+16,gfx_y+26); //draw bkg gfx_a=1; gfx_r=0.7; gfx_g=0.35; gfx_b=0; gfx_x=40; gfx_y=10; gfx_rectto(gfx_w-40,gfx_y+45); gfx_a=0.15; gfx_r=gfx_g=gfx_b=0; gfx_x=42; gfx_y=32; gfx_rectto(gfx_w-43,gfx_y+23); jsusfx-0.4.0/scripts/liteon/tubeharmonics_amp.jsfx000066400000000000000000000112251353477307700224330ustar00rootroot00000000000000// (C) 2009, Lubomir I. Ivanov // // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . // //********************************************************** // Tube Harmonics: // Simulates the behaviour of a vacuum tube circuit stage. // Adds odd and even harmonics to the signal. // Has flux and program dependent saturation. //********************************************************** desc: Tube Harmonics ( Amp Version ) slider1:0.3<0,1,0.001>Even Harmonics slider2:0.3<0,1,0.001>Odd Harmonics slider3:0.3<0,1,0.001>Fluctuation slider4:0<-24,24,0.001>TS Input (dB) slider5:0<-24,24,0.001>TS Output (dB) slider6:0<-12,12,0.001>Output Gain (dB) @init ext_noinit=1; seed0=rand(999)|0; while(seed1=rand(999)|0;seed1==seed0;); sc_y0=sc_y1=1; ka=0.99; kb=1-ka; lim=0.4; @slider tgt_drve=slider1*2; drvo=slider2*2; kr=slider3*0.3; kabs=slider3*0.3; ingain=2^(slider4/6); hgain=2^(slider5/6); trim=2^(slider6/6); @sample // set in gain ch0=spl0*ingain; ch1=spl1*ingain; //interpolate y0+=d_y0; y1+=d_y1; abs0+=d_abs0; abs1+=d_abs1; drve+=d_drve; //set drive values drve_rnd0=drve-abs0; drve_rnd1=drve-abs1; drvo_rnd0=drvo-abs0-y0; drvo_rnd1=drvo-abs1-y1; //apply harmonics h0=sin(ch0*drve_rnd0)/sin(ch0)*drve+(tan(ch0)*drvo_rnd0)*drvo*0.3; h1=sin(ch1*drve_rnd1)/sin(ch1)*drve+(tan(ch1)*drvo_rnd1)*drvo*0.3; //dc filter i dc00=h0-(dcf00=h0*kb+dcf00*ka); dc01=h1-(dcf01=h1*kb+dcf01*ka); //limiter lim0=min(max(dc00*hgain,-lim),lim); lim1=min(max(dc01*hgain,-lim),lim); //fir filter m01=m00;m03=m02; fir0=0.5*(m03+m02=0.5*(m01+m00=lim0)); m11=m10;m13=m12; fir1=0.5*(m13+m12=0.5*(m11+m10=lim1)); //dc filter ii dc10=fir0-(dcf10=fir0*kb+dcf10*ka); dc11=fir1-(dcf11=fir1*kb+dcf11*ka); //sum spl0=(spl0+dc10)*trim; spl1=(spl1+dc11)*trim; @block //*** interpolate parameters d_drve=(tgt_drve-src_drve)/samplesblock; drve=src_drve; src_drve=tgt_drve; sc_y0=sin((seed0+=1)*sc_y0); tgt_y0=sc_y0*kr; d_y0=(tgt_y0-src_y0)/samplesblock; y0=src_y0; src_y0=tgt_y0; sc_y1=sin((seed1+=1)*sc_y1); tgt_y1=sc_y1*kr; d_y1=(tgt_y1-src_y1)/samplesblock; y1=src_y1; src_y1=tgt_y1; tgt_abs0=abs(ch0)*kabs; d_abs0=(tgt_abs0-src_abs0)/samplesblock; abs0=src_abs0; src_abs0=tgt_abs0; tgt_abs1=abs(ch1)*kabs; d_abs1=(tgt_abs1-src_abs1)/samplesblock; abs1=src_abs1; src_abs1=tgt_abs1; @gfx 200 42 drva=(drve+drvo)*0.75; //draw tube i gfx_a=1; gfx_r=gfx_g=gfx_b=1; ox=10; gfx_x=ox; gfx_y=10; gfx_rectto(ox+20,50); gfx_r=gfx_g=gfx_b=0; gfx_x=ox+1; gfx_y=10+1; gfx_rectto(ox+20-1,50-1); gfx_r=0.8; gfx_g=0; gfx_b=0; gfx_x=ox; gfx_y=42; gfx_rectto(ox+20,gfx_y+5); gfx_r=gfx_g=gfx_b=1; gfx_x=ox+7; gfx_y=8; gfx_rectto(ox+13,gfx_y+2); gfx_r=gfx_g=gfx_b=0.7; gfx_x=ox+4; gfx_y=50; gfx_rectto(ox+6,gfx_y+4); gfx_x=ox+9; gfx_y=50; gfx_rectto(ox+11,gfx_y+4); gfx_x=ox+14; gfx_y=50; gfx_rectto(ox+16,gfx_y+4); gfx_r=gfx_g=1; gfx_b=0.4; gfx_a=max(min(drva,1)-abs0,0.8); gfx_x=ox+4; gfx_y=14; gfx_rectto(ox+16,gfx_y+26); //draw tube ii gfx_a=1; gfx_r=gfx_g=gfx_b=1; ox=gfx_w-30; gfx_x=ox; gfx_y=10; gfx_rectto(ox+20,50); gfx_r=gfx_g=gfx_b=0; gfx_x=ox+1; gfx_y=10+1; gfx_rectto(ox+20-1,50-1); gfx_r=0.8; gfx_g=0; gfx_b=0; gfx_x=ox; gfx_y=42; gfx_rectto(ox+20,gfx_y+5); gfx_r=gfx_g=gfx_b=1; gfx_x=ox+7; gfx_y=8; gfx_rectto(ox+13,gfx_y+2); gfx_r=gfx_g=gfx_b=0.7; gfx_x=ox+4; gfx_y=50; gfx_rectto(ox+6,gfx_y+4); gfx_x=ox+9; gfx_y=50; gfx_rectto(ox+11,gfx_y+4); gfx_x=ox+14; gfx_y=50; gfx_rectto(ox+16,gfx_y+4); gfx_r=gfx_g=1; gfx_b=0.4; gfx_a=max(min(drva,1)-abs1,0.80); gfx_x=ox+4; gfx_y=14; gfx_rectto(ox+16,gfx_y+26); //draw bkg gfx_a=0.6; gfx_r=0.1; gfx_g=0.5; gfx_b=0.75; gfx_x=40; gfx_y=10; gfx_rectto(gfx_w-40,gfx_y+45); gfx_a=0.15; gfx_r=gfx_g=gfx_b=0; gfx_x=42; gfx_y=32; gfx_rectto(gfx_w-43,gfx_y+23); jsusfx-0.4.0/scripts/liteon/waveshapermulti.jsfx000066400000000000000000000153751353477307700221650ustar00rootroot00000000000000// (C) 2008-2009, Lubomir I. Ivanov // NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT // WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO, // ANY DIRECT OR INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING // OUT OF THE USE OR INABILITY TO USE THIS PLUG-IN, COMPUTER FAILTURE OF // MALFUNCTION INCLUDED. THE USE OF THE SOURCE CODE, EITHER PARTIALLY OR IN // TOTAL, IS ONLY GRANTED, IF USED IN THE SENSE OF THE AUTHOR'S INTENTION, AND // USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A THIRD // PARTY CONTRIBUTION, EVEN IF INCLUDED IN REAPER(TM), COCKOS INCORPORATED OR // ITS AFFILIATES HAVE NOTHING TO DO WITH IT. LAST BUT NOT LEAST, BY USING THIS // PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO // ENTRUST SOMEBODY ELSE WITH DOING SO. // // Released under GPL: // . desc: Waveshaper Multi (Various Formulas) slider1:0<0,1,1{Stereo,Mono}>Processing slider2:0<0,1,1{Type1,Type2,Type3}>Waveshaper slider3:0<0,100,0.05>Drive 2xOS (%) slider4:0<0,100,0.05>Muffle (%) slider5:0<-25,25,0.05>Output (dB) slider6:0<0,1,1{On,Off}>Limiter slider7:0<0,1,1{Off,On}>Oversample (x2) @init //fir restoration c1 = 1; c2 = -0.75; c3 = 0.17; fgain = 4.1; //fir bandlimit bl_c1 = 0.52; bl_c2 = 0.54; bl_c3 = -0.02; @slider os = slider7; //outgain outgain = 10^(slider5/20); //drive drive1 = 1+slider3/35; drvc = 1.5; drive2 = slider3/99-0.07; drv2_k = drive2/(1-drive2); pi_drv2 = $pi*drive2; sin_pi_drv2 = sin($pi*drive2); //lp slider4 > 0 ? ( muffle = 20000-(slider4*100+9000); lp_cut = 2*$pi*muffle; lp_n = 1/(lp_cut+2*srate); lp_b1 = (2*srate-lp_cut)*lp_n; lp_a0 = lp_a1=lp_cut*lp_n; ); @sample //=========================== //stereo slider1 == 0 ? ( inl = spl0; inr = spl1; slider3 > 0 ? ( //oversample ? os == 1 ? ( //--------------------------- //power series in ps_out1l = 0.5*(inl+ps_out2l); ps_out2l = 0.5*ps_out1l; ps_out1r = 0.5*(inr+ps_out2r); ps_out2r = 0.5*ps_out1r; //--------------------------- //drive slider2 == 0 ? ( o_in1l = (1+drv2_k)*ps_out1l/(1+drv2_k*abs(ps_out1l)); o_in2l = (1+drv2_k)*ps_out2l/(1+drv2_k*abs(ps_out2l)); o_in1r = (1+drv2_k)*ps_out1r/(1+drv2_k*abs(ps_out1r)); o_in2r = (1+drv2_k)*ps_out2r/(1+drv2_k*abs(ps_out2r)); ); slider2 == 1 ? ( o_in1l = sin(pi_drv2*ps_out1l)*1/sin_pi_drv2; o_in2l = sin(pi_drv2*ps_out2l)*1/sin_pi_drv2; o_in1r = sin(pi_drv2*ps_out1r)*1/sin_pi_drv2; o_in2r = sin(pi_drv2*ps_out2r)*1/sin_pi_drv2; ); slider2 == 2 ? ( o_in1l = (ps_out1l)*(abs((ps_out1l)) + drive1)/((ps_out1l)^2 + (drive1-1)*abs((ps_out1l)) + 1)*(drive1/drvc); o_in2l = (ps_out2l)*(abs((ps_out2l)) + drive1)/((ps_out2l)^2 + (drive1-1)*abs((ps_out2l)) + 1)*(drive1/drvc); o_in1r = (ps_out1r)*(abs((ps_out1r)) + drive1)/((ps_out1r)^2 + (drive1-1)*abs((ps_out1r)) + 1)*(drive1/drvc); o_in2r = (ps_out2r)*(abs((ps_out2r)) + drive1)/((ps_out2r)^2 + (drive1-1)*abs((ps_out2r)) + 1)*(drive1/drvc); ); //--------------------------- //bandlimit bl3_l1 = bl2_l1; bl3_r1 = bl2_r1; bl3_l2 = bl2_l2; bl3_r2 = bl2_r2; bl2_l1 = bl1_l1; bl2_r1 = bl1_r1; bl2_l2 = bl1_l2; bl2_r2 = bl1_r2; bl1_l1 = o_in1l; bl1_r1 = o_in1r; bl1_l2 = o_in2l; bl1_r2 = o_in2r; bl_out1l = (bl1_l1*bl_c1 + bl2_l1*bl_c2 + bl3_l1*bl_c3); bl_out1r = (bl1_r1*bl_c1 + bl2_r1*bl_c2 + bl3_r1*bl_c3); bl_out2l = (bl1_l2*bl_c1 + bl2_l2*bl_c2 + bl3_l2*bl_c3); bl_out2r = (bl1_r2*bl_c1 + bl2_r2*bl_c2 + bl3_r2*bl_c3); //--------------------------- //power series out o_out1l = 0.5*(bl_out1l+o_out2l); o_out2l = 0.5*(bl_out2l+o_out1l); o_out1r = 0.5*(bl_out1r+o_out2r); o_out2r = 0.5*(bl_out2r+o_out1r); //--------------------------- //fir restoration s3l = s2l; s3r = s2r; s2l = s1l; s2r = s1r; s1l = o_out1l; s1r = o_out1r; o_outl = (s1l*c1+s2l*c2+s3l*c3)*fgain; o_outr = (s1r*c1+s2r*c2+s3r*c3)*fgain; ) : ( //drive slider2 == 0 ? ( o_outl = (1+drv2_k)*inl/(1+drv2_k*abs(inl)); o_outr = (1+drv2_k)*inr/(1+drv2_k*abs(inr)); ); slider2 == 1 ? ( o_outl = sin(pi_drv2*inl)*1/sin_pi_drv2; o_outr = sin(pi_drv2*inr)*1/sin_pi_drv2; ); slider2 == 2 ? ( o_outl = (inl)*(abs((inl)) + drive1)/((inl)^2 + (drive1-1)*abs((inl)) + 1)*(drive1/drvc); o_outr = (inr)*(abs((inr)) + drive1)/((inr)^2 + (drive1-1)*abs((inr)) + 1)*(drive1/drvc); ); ); ) : ( o_outl = inl; o_outr = inr; ); //--------------------------- //lp slider4 > 0 ? ( lp_inl = o_outl; lp_inr = o_outr; lp_outputl = lp_inl*lp_a0+lp_inl*lp_a1+lp_outputl*lp_b1; lp_outputr = lp_inr*lp_a0+lp_inr*lp_a1+lp_outputr*lp_b1; o_outl = lp_outputl; o_outr = lp_outputr; ); //--------------------------- //limiter outl = o_outl*outgain; outr = o_outr*outgain; slider6 == 0 ? ( outl = min(max(outl,-0.98),0.98); outr = min(max(outr,-0.98),0.98); ); spl0 = outl; spl1 = outr; //=========================== //mono ) : ( in = (spl0+spl1)/2; slider3 > 0 ? ( os == 1 ? ( //--------------------------- //power series in ps_out1 = 0.5*(in+ps_out2); ps_out2 = 0.5*ps_out1; //--------------------------- //drive slider2 == 0 ? ( o_in1 = (1+drv2_k)*ps_out1/(1+drv2_k*abs(ps_out1)); o_in2 = (1+drv2_k)*ps_out2/(1+drv2_k*abs(ps_out2)); ); slider2 == 1 ? ( o_in1 = sin(pi_drv2*ps_out1)*1/sin_pi_drv2; o_in2 = sin(pi_drv2*ps_out2)*1/sin_pi_drv2; ); slider2 == 2 ? ( o_in1 = (ps_out1)*(abs((ps_out1)) + drive1)/((ps_out1)^2 + (drive1-1)*abs((ps_out1)) + 1)*(drive1/drvc); o_in2 = (ps_out2)*(abs((ps_out2)) + drive1)/((ps_out2)^2 + (drive1-1)*abs((ps_out2)) + 1)*(drive1/drvc); ); //--------------------------- //bandlimit bl3_1 = bl2_1; bl3_2 = bl2_2; bl2_1 = bl1_1; bl2_2 = bl1_2; bl1_1 = o_in1; bl1_2 = o_in2; bl_out1 = (bl1_1*bl_c1 + bl2_1*bl_c2 + bl3_1*bl_c3); bl_out2 = (bl1_2*bl_c1 + bl2_2*bl_c2 + bl3_2*bl_c3); //--------------------------- //power series out o_out1 = 0.5*(bl_out1+o_out2); o_out2 = 0.5*(bl_out2+o_out1); //--------------------------- //fir restoration s3l = s2l; s2l = s1l; s1l = o_out1; o_out = (s1l*c1+s2l*c2+s3l*c3)*fgain; ) : ( //drive slider2 == 0 ? ( o_out = (1+drv2_k)*in/(1+drv2_k*abs(in)); ); slider2 == 1 ? ( o_out = sin(pi_drv2*in)*1/sin_pi_drv2; ); slider2 == 2 ? ( o_out = (in)*(abs((in)) + drive1)/((in)^2 + (drive1-1)*abs((in)) + 1)*(drive1/drvc); ); ); ) : ( o_out = in; ); //--------------------------- //lp slider4 > 0 ? ( lp_in = o_out; lp_output = lp_in*lp_a0+lp_in*lp_a1+lp_output*lp_b1; o_out = lp_output; ); //--------------------------- //limiter out = o_out*outgain; slider6 == 0 ? ( out = min(max(out,-0.98),0.98); ); spl0=spl1=out; ); jsusfx-0.4.0/src/000077500000000000000000000000001353477307700136445ustar00rootroot00000000000000jsusfx-0.4.0/src/CMakeLists.txt000066400000000000000000000030331353477307700164030ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.6) project(jsusfx) # -- JSUSFX library -- set(sources jsusfx.cpp jsusfx_file.cpp jsusfx_gfx.cpp jsusfx_serialize.cpp riff.cpp WDL/eel2/nseel-compiler.c WDL/eel2/nseel-eval.c WDL/eel2/nseel-ram.c WDL/eel2/nseel-yylex.c WDL/eel2/nseel-cfunc.c WDL/fft.c) file(GLOB_RECURSE headers *.h) source_group("sources" FILES ${sources}) source_group("headers" FILES ${headers}) if (UNIX AND NOT APPLE) if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") add_definitions(-mfpu=vfp -march=armv6t2 -marm) add_library(jsusfx ${sources} ${headers}) else() # Linux x64 if (CMAKE_SIZEOF_VOID_P EQUAL 8) add_custom_command( OUTPUT ${PROJECT_SOURCE_DIR}/WDL/eel2/asm-nseel-x64.o COMMAND php a2x64.php elf64 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/WDL/eel2 ) add_library(jsusfx ${sources} ${headers} ${PROJECT_SOURCE_DIR}/WDL/eel2/asm-nseel-x64.o) else() # Linux i686 add_library(jsusfx ${sources} ${headers}) endif() endif() else() if (WIN32) add_library(jsusfx ${sources} ${headers}) else() # MacOS, 64-bit always add_custom_command( OUTPUT ${PROJECT_SOURCE_DIR}/WDL/eel2/asm-nseel-x64-macho.o COMMAND php a2x64.php macho64x DEPENDS ${PROJECT_SOURCE_DIR}/WDL/eel2/asm-nseel-x86-gcc.c WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/WDL/eel2 ) add_library(jsusfx ${sources} ${headers} ${PROJECT_SOURCE_DIR}/WDL/eel2/asm-nseel-x64-macho.o) endif() endif() target_compile_definitions(jsusfx PUBLIC WDL_FFT_REALSIZE=8) target_include_directories(jsusfx PUBLIC "${PROJECT_SOURCE_DIR}") jsusfx-0.4.0/src/WDL/000077500000000000000000000000001353477307700142725ustar00rootroot00000000000000jsusfx-0.4.0/src/WDL/assocarray.h000066400000000000000000000261241353477307700166170ustar00rootroot00000000000000#ifndef _WDL_ASSOCARRAY_H_ #define _WDL_ASSOCARRAY_H_ #include "heapbuf.h" // on all of these, if valdispose is set, the array will dispose of values as needed. // if keydup/keydispose are set, copies of (any) key data will be made/destroyed as necessary // WDL_AssocArrayImpl can be used on its own, and can contain structs for keys or values template class WDL_AssocArrayImpl { WDL_AssocArrayImpl(const WDL_AssocArrayImpl &cp) { CopyContents(cp); } WDL_AssocArrayImpl &operator=(const WDL_AssocArrayImpl &cp) { CopyContents(cp); return *this; } public: explicit WDL_AssocArrayImpl(int (*keycmp)(KEY *k1, KEY *k2), KEY (*keydup)(KEY)=0, void (*keydispose)(KEY)=0, void (*valdispose)(VAL)=0) { m_keycmp = keycmp; m_keydup = keydup; m_keydispose = keydispose; m_valdispose = valdispose; } ~WDL_AssocArrayImpl() { DeleteAll(); } VAL* GetPtr(KEY key, KEY *keyPtrOut=NULL) const { bool ismatch = false; int i = LowerBound(key, &ismatch); if (ismatch) { KeyVal* kv = m_data.Get()+i; if (keyPtrOut) *keyPtrOut = kv->key; return &(kv->val); } return 0; } bool Exists(KEY key) const { bool ismatch = false; LowerBound(key, &ismatch); return ismatch; } int Insert(KEY key, VAL val) { bool ismatch = false; int i = LowerBound(key, &ismatch); if (ismatch) { KeyVal* kv = m_data.Get()+i; if (m_valdispose) m_valdispose(kv->val); kv->val = val; } else { KeyVal* kv = m_data.Resize(m_data.GetSize()+1)+i; memmove(kv+1, kv, (m_data.GetSize()-i-1)*(unsigned int)sizeof(KeyVal)); if (m_keydup) key = m_keydup(key); kv->key = key; kv->val = val; } return i; } void Delete(KEY key) { bool ismatch = false; int i = LowerBound(key, &ismatch); if (ismatch) { KeyVal* kv = m_data.Get()+i; if (m_keydispose) m_keydispose(kv->key); if (m_valdispose) m_valdispose(kv->val); m_data.Delete(i); } } void DeleteByIndex(int idx) { if (idx >= 0 && idx < m_data.GetSize()) { KeyVal* kv = m_data.Get()+idx; if (m_keydispose) m_keydispose(kv->key); if (m_valdispose) m_valdispose(kv->val); m_data.Delete(idx); } } void DeleteAll(bool resizedown=false) { if (m_keydispose || m_valdispose) { int i; for (i = 0; i < m_data.GetSize(); ++i) { KeyVal* kv = m_data.Get()+i; if (m_keydispose) m_keydispose(kv->key); if (m_valdispose) m_valdispose(kv->val); } } m_data.Resize(0, resizedown); } int GetSize() const { return m_data.GetSize(); } VAL* EnumeratePtr(int i, KEY* key=0) const { if (i >= 0 && i < m_data.GetSize()) { KeyVal* kv = m_data.Get()+i; if (key) *key = kv->key; return &(kv->val); } return 0; } KEY* ReverseLookupPtr(VAL val) const { int i; for (i = 0; i < m_data.GetSize(); ++i) { KeyVal* kv = m_data.Get()+i; if (kv->val == val) return &kv->key; } return 0; } void ChangeKey(KEY oldkey, KEY newkey) { bool ismatch=false; int i = LowerBound(oldkey, &ismatch); if (ismatch) { KeyVal* kv = m_data.Get()+i; if (m_keydispose) m_keydispose(kv->key); if (m_keydup) newkey = m_keydup(newkey); kv->key = newkey; Resort(); } } void ChangeKeyByIndex(int idx, KEY newkey, bool needsort) { if (idx >= 0 && idx < m_data.GetSize()) { KeyVal* kv = m_data.Get()+idx; if (m_keydispose) m_keydispose(kv->key); if (m_keydup) newkey = m_keydup(newkey); kv->key = newkey; if (needsort) Resort(); } } // fast add-block mode void AddUnsorted(KEY key, VAL val) { int i=m_data.GetSize(); KeyVal* kv = m_data.Resize(i+1)+i; if (m_keydup) key = m_keydup(key); kv->key = key; kv->val = val; } void Resort() { if (m_data.GetSize() > 1 && m_keycmp) { qsort(m_data.Get(),m_data.GetSize(),sizeof(KeyVal),(int(*)(const void *,const void *))m_keycmp); // AddUnsorted can add duplicate keys // unfortunately qsort is not guaranteed to preserve order, // ideally this filter would always preserve the last-added key int i; for (i=0; i < m_data.GetSize()-1; ++i) { KeyVal* kv=m_data.Get()+i; KeyVal* nv=kv+1; if (!m_keycmp(&kv->key, &nv->key)) { DeleteByIndex(i--); } } } } int LowerBound(KEY key, bool* ismatch) const { int a = 0; int c = m_data.GetSize(); while (a != c) { int b = (a+c)/2; KeyVal* kv=m_data.Get()+b; int cmp = m_keycmp(&key, &kv->key); if (cmp > 0) a = b+1; else if (cmp < 0) c = b; else { *ismatch = true; return b; } } *ismatch = false; return a; } int GetIdx(KEY key) const { bool ismatch=false; int i = LowerBound(key, &ismatch); if (ismatch) return i; return -1; } void SetGranul(int gran) { m_data.SetGranul(gran); } void CopyContents(const WDL_AssocArrayImpl &cp) { m_data=cp.m_data; m_keycmp = cp.m_keycmp; m_keydup = cp.m_keydup; m_keydispose = m_keydup ? cp.m_keydispose : NULL; m_valdispose = NULL; // avoid disposing of values twice, since we don't have a valdup, we can't have a fully valid copy if (m_keydup) { int x; const int n=m_data.GetSize(); for (x=0;xkey) kv->key = m_keydup(kv->key); } } } void CopyContentsAsReference(const WDL_AssocArrayImpl &cp) { DeleteAll(true); m_keydup = NULL; // this no longer can own any data m_keydispose = NULL; m_valdispose = NULL; m_data=cp.m_data; } protected: struct KeyVal { KEY key; VAL val; }; WDL_TypedBuf m_data; int (*m_keycmp)(KEY *k1, KEY *k2); KEY (*m_keydup)(KEY); void (*m_keydispose)(KEY); void (*m_valdispose)(VAL); }; // WDL_AssocArray adds useful functions but cannot contain structs for keys or values template class WDL_AssocArray : public WDL_AssocArrayImpl { public: explicit WDL_AssocArray(int (*keycmp)(KEY *k1, KEY *k2), KEY (*keydup)(KEY)=0, void (*keydispose)(KEY)=0, void (*valdispose)(VAL)=0) : WDL_AssocArrayImpl(keycmp, keydup, keydispose, valdispose) { } VAL Get(KEY key, VAL notfound=0) const { VAL* p = this->GetPtr(key); if (p) return *p; return notfound; } VAL Enumerate(int i, KEY* key=0, VAL notfound=0) const { VAL* p = this->EnumeratePtr(i, key); if (p) return *p; return notfound; } KEY ReverseLookup(VAL val, KEY notfound=0) const { KEY* p=this->ReverseLookupPtr(val); if (p) return *p; return notfound; } }; template class WDL_IntKeyedArray : public WDL_AssocArray { public: explicit WDL_IntKeyedArray(void (*valdispose)(VAL)=0) : WDL_AssocArray(cmpint, NULL, NULL, valdispose) {} ~WDL_IntKeyedArray() {} private: static int cmpint(int *i1, int *i2) { return *i1-*i2; } }; template class WDL_StringKeyedArray : public WDL_AssocArray { public: explicit WDL_StringKeyedArray(bool caseSensitive=true, void (*valdispose)(VAL)=0) : WDL_AssocArray(caseSensitive?cmpstr:cmpistr, dupstr, freestr, valdispose) {} ~WDL_StringKeyedArray() { } static const char *dupstr(const char *s) { return strdup(s); } // these might not be necessary but depending on the libc maybe... static int cmpstr(const char **s1, const char **s2) { return strcmp(*s1, *s2); } static int cmpistr(const char **a, const char **b) { return stricmp(*a,*b); } static void freestr(const char* s) { free((void*)s); } static void freecharptr(char *p) { free(p); } }; template class WDL_StringKeyedArray2 : public WDL_AssocArrayImpl { public: explicit WDL_StringKeyedArray2(bool caseSensitive=true, void (*valdispose)(VAL)=0) : WDL_AssocArrayImpl(caseSensitive?cmpstr:cmpistr, dupstr, freestr, valdispose) {} ~WDL_StringKeyedArray2() { } static const char *dupstr(const char *s) { return strdup(s); } // these might not be necessary but depending on the libc maybe... static int cmpstr(const char **s1, const char **s2) { return strcmp(*s1, *s2); } static int cmpistr(const char **a, const char **b) { return stricmp(*a,*b); } static void freestr(const char* s) { free((void*)s); } static void freecharptr(char *p) { free(p); } }; // sorts text as text, sorts anything that looks like a number as a number template class WDL_LogicalSortStringKeyedArray : public WDL_StringKeyedArray { public: explicit WDL_LogicalSortStringKeyedArray(bool caseSensitive=true, void (*valdispose)(VAL)=0) : WDL_StringKeyedArray(caseSensitive, valdispose) { WDL_StringKeyedArray::m_keycmp = caseSensitive?cmpstr:cmpistr; // override } ~WDL_LogicalSortStringKeyedArray() { } private: static int cmpstr(const char **a, const char **b) { return _cmpstr(*a, *b, true); } static int cmpistr(const char **a, const char **b) { return _cmpstr(*a, *b, false); } static int _cmpstr(const char *s1, const char *s2, bool case_sensitive) { // this also exists as WDL_strcmp_logical in wdlcstring.h char lastNonZeroChar=0; // last matching character, updated if not 0. this allows us to track whether // we are inside of a number with the same leading digits for (;;) { char c1=*s1++, c2=*s2++; if (!c1) return c1-c2; if (c1!=c2) { if (c1 >= '0' && c1 <= '9' && c2 >= '0' && c2 <= '9') { int lzdiff=0, cnt=0; if (lastNonZeroChar < '1' || lastNonZeroChar > '9') { while (c1 == '0') { c1=*s1++; lzdiff--; } while (c2 == '0') { c2=*s2++; lzdiff++; } // lzdiff = lz2-lz1, more leading 0s = earlier in list } for (;;) { if (c1 >= '0' && c1 <= '9') { if (c2 < '0' || c2 > '9') return 1; c1=s1[cnt]; c2=s2[cnt++]; } else { if (c2 >= '0' && c2 <= '9') return -1; break; } } s1--; s2--; while (cnt--) { const int d = *s1++ - *s2++; if (d) return d; } if (lzdiff) return lzdiff; } else { if (!case_sensitive) { if (c1>='a' && c1<='z') c1+='A'-'a'; if (c2>='a' && c2<='z') c2+='A'-'a'; } if (c1 != c2) return c1-c2; } } else if (c1 != '0') lastNonZeroChar=c1; } } }; template class WDL_PtrKeyedArray : public WDL_AssocArray { public: explicit WDL_PtrKeyedArray(void (*valdispose)(VAL)=0) : WDL_AssocArray(cmpptr, 0, 0, valdispose) {} ~WDL_PtrKeyedArray() {} private: static int cmpptr(INT_PTR* a, INT_PTR* b) { const INT_PTR d = *a - *b; return d<0?-1:(d!=0); } }; #endif jsusfx-0.4.0/src/WDL/denormal.h000066400000000000000000000124151353477307700162470ustar00rootroot00000000000000#ifndef _WDL_DENORMAL_H_ #define _WDL_DENORMAL_H_ typedef struct { #ifdef __ppc__ // todo: other big endian platforms... unsigned int hw; unsigned int lw; #else unsigned int lw; unsigned int hw; #endif } WDL_DenormalTwoInts; typedef union { double fl; WDL_DenormalTwoInts w; } WDL_DenormalDoubleAccess; typedef union { float fl; unsigned int w; } WDL_DenormalFloatAccess; // note: the _aggressive versions filter out anything less than around 1.0e-16 or so (approximately) to 0.0, including -0.0 (becomes 0.0) // note: new! the _aggressive versions also filter inf and NaN to 0.0 #ifdef __cplusplus #define WDL_DENORMAL_INLINE inline #elif defined(_MSC_VER) #define WDL_DENORMAL_INLINE __inline #else #define WDL_DENORMAL_INLINE #endif #define WDL_DENORMAL_DOUBLE_HW(a) (((const WDL_DenormalDoubleAccess*)(a))->w.hw) #define WDL_DENORMAL_DOUBLE_LW(a) (((const WDL_DenormalDoubleAccess*)(a))->w.lw) #define WDL_DENORMAL_FLOAT_W(a) (((const WDL_DenormalFloatAccess*)(a))->w) #define WDL_DENORMAL_DOUBLE_HW_NC(a) (((WDL_DenormalDoubleAccess*)(a))->w.hw) #define WDL_DENORMAL_DOUBLE_LW_NC(a) (((WDL_DenormalDoubleAccess*)(a))->w.lw) #define WDL_DENORMAL_FLOAT_W_NC(a) (((WDL_DenormalFloatAccess*)(a))->w) #define WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF 0x3cA00000 // 0x3B8000000 maybe instead? that's 10^-5 smaller or so #define WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF 0x25000000 static double WDL_DENORMAL_INLINE denormal_filter_double(double a) { return (WDL_DENORMAL_DOUBLE_HW(&a)&0x7ff00000) ? a : 0.0; } static double WDL_DENORMAL_INLINE denormal_filter_double2(double a) { return ((WDL_DENORMAL_DOUBLE_HW(&a)+0x100000)&0x7ff00000) > 0x100000 ? a : 0.0; } static double WDL_DENORMAL_INLINE denormal_filter_double_aggressive(double a) { return ((WDL_DENORMAL_DOUBLE_HW(&a)+0x100000)&0x7ff00000) >= WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF ? a : 0.0; } static float WDL_DENORMAL_INLINE denormal_filter_float(float a) { return (WDL_DENORMAL_FLOAT_W(&a)&0x7f800000) ? a : 0.0f; } static float WDL_DENORMAL_INLINE denormal_filter_float2(float a) { return ((WDL_DENORMAL_FLOAT_W(&a)+0x800000)&0x7f800000) > 0x800000 ? a : 0.0f; } static float WDL_DENORMAL_INLINE denormal_filter_float_aggressive(float a) { return ((WDL_DENORMAL_FLOAT_W(&a)+0x800000)&0x7f800000) >= WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF ? a : 0.0f; } static void WDL_DENORMAL_INLINE denormal_fix_double(double *a) { if (!(WDL_DENORMAL_DOUBLE_HW(a)&0x7ff00000)) *a=0.0; } static void WDL_DENORMAL_INLINE denormal_fix_double_aggressive(double *a) { if (((WDL_DENORMAL_DOUBLE_HW(a)+0x100000)&0x7ff00000) < WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF) *a=0.0; } static void WDL_DENORMAL_INLINE denormal_fix_float(float *a) { if (!(WDL_DENORMAL_FLOAT_W(a)&0x7f800000)) *a=0.0f; } static void WDL_DENORMAL_INLINE denormal_fix_float_aggressive(float *a) { if (((WDL_DENORMAL_FLOAT_W(a)+0x800000)&0x7f800000) < WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF) *a=0.0f; } #ifdef __cplusplus // automatic typed versions (though one should probably use the explicit versions... static double WDL_DENORMAL_INLINE denormal_filter(double a) { return (WDL_DENORMAL_DOUBLE_HW(&a)&0x7ff00000) ? a : 0.0; } static double WDL_DENORMAL_INLINE denormal_filter_aggressive(double a) { return ((WDL_DENORMAL_DOUBLE_HW(&a)+0x100000)&0x7ff00000) >= WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF ? a : 0.0; } static float WDL_DENORMAL_INLINE denormal_filter(float a) { return (WDL_DENORMAL_FLOAT_W(&a)&0x7f800000) ? a : 0.0f; } static float WDL_DENORMAL_INLINE denormal_filter_aggressive(float a) { return ((WDL_DENORMAL_FLOAT_W(&a)+0x800000)&0x7f800000) >= WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF ? a : 0.0f; } static void WDL_DENORMAL_INLINE denormal_fix(double *a) { if (!(WDL_DENORMAL_DOUBLE_HW(a)&0x7ff00000)) *a=0.0; } static void WDL_DENORMAL_INLINE denormal_fix_aggressive(double *a) { if (((WDL_DENORMAL_DOUBLE_HW(a)+0x100000)&0x7ff00000) < WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF) *a=0.0; } static void WDL_DENORMAL_INLINE denormal_fix(float *a) { if (!(WDL_DENORMAL_FLOAT_W(a)&0x7f800000)) *a=0.0f; } static void WDL_DENORMAL_INLINE denormal_fix_aggressive(float *a) { if (((WDL_DENORMAL_FLOAT_W(a)+0x800000)&0x7f800000) < WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF) *a=0.0f; } #endif // cplusplus versions //////////////////// // this isnt a denormal function but it is similar, so we'll put it here as a bonus static void WDL_DENORMAL_INLINE GetDoubleMaxAbsValue(double *out, const double *in) // note: the value pointed to by "out" must be >=0.0, __NOT__ <= -0.0 { unsigned int hw = WDL_DENORMAL_DOUBLE_HW(in)&0x7fffffff; if (hw >= WDL_DENORMAL_DOUBLE_HW(out) && (hw>WDL_DENORMAL_DOUBLE_HW(out) || WDL_DENORMAL_DOUBLE_LW(in) > WDL_DENORMAL_DOUBLE_LW(out))) { WDL_DENORMAL_DOUBLE_LW_NC(out) = WDL_DENORMAL_DOUBLE_LW(in); WDL_DENORMAL_DOUBLE_HW_NC(out) = hw; } } static void WDL_DENORMAL_INLINE GetFloatMaxAbsValue(float *out, const float *in) // note: the value pointed to by "out" must be >=0.0, __NOT__ <= -0.0 { unsigned int hw = WDL_DENORMAL_FLOAT_W(in)&0x7fffffff; if (hw > WDL_DENORMAL_FLOAT_W(out)) WDL_DENORMAL_FLOAT_W_NC(out)=hw; } #ifdef __cplusplus static void WDL_DENORMAL_INLINE GetFloatMaxAbsValue(double *out, const double *in) // note: the value pointed to by "out" must be >=0.0, __NOT__ <= -0.0 { GetDoubleMaxAbsValue(out,in); } #endif #endif jsusfx-0.4.0/src/WDL/eel2/000077500000000000000000000000001353477307700151215ustar00rootroot00000000000000jsusfx-0.4.0/src/WDL/eel2/.gitignore000066400000000000000000000001571353477307700171140ustar00rootroot00000000000000/*.obj /asm-nseel-x64-macho.asm /asm-nseel-x64.asm /loose_eel.exe !/asm-nseel-x64-macho.o !/asm-nseel-x64.obj jsusfx-0.4.0/src/WDL/eel2/Makefile000066400000000000000000000052721353477307700165670ustar00rootroot00000000000000CC=gcc CFLAGS=-g -DWDL_FFT_REALSIZE=8 -Wall -Wno-unused-function -Wno-multichar -Wno-unused-result -Wshadow LFLAGS= CXX=g++ ifdef DEBUG CFLAGS += -D_DEBUG -O0 else CFLAGS += -DNDEBUG -O endif OBJS=nseel-caltab.o nseel-compiler.o nseel-eval.o nseel-lextab.o nseel-ram.o nseel-yylex.o nseel-cfunc.o fft.o OBJS2= UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) ifdef ARCH CFLAGS += -arch $(ARCH) else ARCH = i686 CFLAGS += -arch i386 endif else ARCH := $(shell uname -m) endif ifneq ($(filter arm%,$(ARCH)),) CFLAGS += -fsigned-char -mfpu=vfp -march=armv6t2 -marm endif ifndef ALLOW_WARNINGS ifneq ($(UNAME_S),Darwin) CFLAGS += -Werror endif endif ifndef DEPRECATED_WARNINGS CFLAGS += -Wno-deprecated-declarations endif default: loose_eel nseel-compiler.o: glue*.h ns-eel*.h nseel-cfunc.o: asm*.c ns-eel*.h loose_eel.o: eel*.h ns-eel*.h nseel-*.o: ns-eel*.h vpath %.cpp ../lice ../swell vpath %.mm ../swell vpath %.c ../ ifdef MAXLOOP CFLAGS += -DNSEEL_LOOPFUNC_SUPPORT_MAXLEN=$(MAXLOOP) else CFLAGS += -DNSEEL_LOOPFUNC_SUPPORT_MAXLEN=0 endif ifndef NO_GFX OBJS += lice.o lice_image.o lice_line.o lice_ico.o lice_bmp.o lice_textnew.o lice_text.o lice_arc.o CFLAGS += -DEEL_LICE_WANT_STANDALONE ifeq ($(UNAME_S),Darwin) CFLAGS += -mmacosx-version-min=10.5 OBJS += swell-wnd.o swell-gdi.o swell.o swell-misc.o swell-dlg.o swell-menu.o swell-kb.o LFLAGS += -lobjc -framework Cocoa -framework Carbon else CFLAGS += -DSWELL_LICE_GDI ifdef GDK2 CFLAGS += -DSWELL_TARGET_GDK=2 $(shell pkg-config --cflags gdk-2.0) LFLAGS += $(shell pkg-config --libs gdk-2.0) -lX11 -lXi else CFLAGS += -DSWELL_TARGET_GDK=3 $(shell pkg-config --cflags gdk-3.0) LFLAGS += $(shell pkg-config --libs gdk-3.0) -lX11 -lXi endif ifndef NOFREETYPE CFLAGS += -DSWELL_FREETYPE $(shell freetype-config --cflags) LFLAGS += $(shell freetype-config --libs) endif OBJS += swell-wnd-generic.o swell-gdi-lice.o swell.o swell-misc-generic.o \ swell-dlg-generic.o swell-menu-generic.o swell-kb-generic.o \ swell-gdi-generic.o swell-ini.o swell-generic-gdk.o LFLAGS += -ldl endif endif asm-nseel-x64.o: a2x64.php asm-nseel-x86-gcc.c php a2x64.php elf64 ifdef PORTABLE CFLAGS += -DEEL_TARGET_PORTABLE else ifeq ($(UNAME_S),Darwin) ifeq ($(ARCH),x86_64) OBJS2 += asm-nseel-x64-macho.o endif endif ifeq ($(UNAME_S),Linux) ifeq ($(ARCH),x86_64) OBJS2 += asm-nseel-x64.o endif endif endif CXXFLAGS=$(CFLAGS) %.o : %.mm $(CXX) $(CXXFLAGS) -c -o $@ $^ loose_eel: loose_eel.o $(OBJS) $(OBJS2) g++ -o $@ $^ $(CXXFLAGS) $(LFLAGS) clean: -rm loose_eel loose_eel.o $(OBJS) jsusfx-0.4.0/src/WDL/eel2/a2i.php000066400000000000000000000164171353477307700163160ustar00rootroot000000000000001) $end_restore = substr($line,1-strlen($lastchunk)); else $end_restore=""; $sline = substr($sline,1,strlen($sline)-1-strlen($lastchunk)); // get rid of chars we can ignore $sline=preg_replace("/%\d+/","__TEMP_REPLACE__", $sline); $sline=str_replace("\\n","", $sline); $sline=str_replace("\"","", $sline); $sline=str_replace("$","", $sline); $sline=str_replace("%","", $sline); // get rid of excess whitespace, especially around commas $sline=str_replace(" "," ", $sline); $sline=str_replace(" "," ", $sline); $sline=str_replace(" "," ", $sline); $sline=str_replace(", ",",", $sline); $sline=str_replace(" ,",",", $sline); $sline=preg_replace("/st\\(([0-9]+)\\)/","FPREG_$1",$sline); if (preg_match("/^([0-9]+):/",trim($sline))) { $d = (int) $sline; $a = strstr($sline,":"); if ($a) $sline = substr($a,1); if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d]; else $thislbl = "label_" . $labelcnt++; $btfut[$d]=""; $bthist[$d] = $thislbl; fputs($out,$thislbl . ":\n"); } $sploded = explode(" ",trim($sline)); if ($sline != "" && count($sploded)>0) { $inst = trim($sploded[0]); $suffix = ""; $instline = strstr($sline,$inst); $beg_restore .= substr($sline,0,-strlen($instline)); $parms = trim(substr($instline,strlen($inst))); if ($inst=="j") $inst="jmp"; //if ($inst == "fdiv" && $parms == "") $inst="fdivr"; if ($inst != "call" && substr($inst,-2) == "ll") $suffix = "ll"; else if ($inst != "call" && $inst != "fmul" && substr($inst,-1) == "l") $suffix = "l"; else if (substr($inst,0,1)=="f" && $inst != "fcos" && $inst != "fsincos" && $inst != "fabs" && $inst != "fchs" && substr($inst,-1) == "s") $suffix = "s"; if ($suffix != "" && $inst != "jl") $inst = substr($inst,0,-strlen($suffix)); $parms = preg_replace("/\\((.{2,3}),(.{2,3})\\)/","($1+$2)",$parms); $parms=preg_replace("/EEL_F_SUFFIX (-?[0-9]+)\\((.*)\\)/","EEL_ASM_TYPE [$2+$1]",$parms); $parms=preg_replace("/EEL_F_SUFFIX \\((.*)\\)/","EEL_ASM_TYPE [$1]",$parms); if ($inst == "sh" && $suffix == "ll") { $suffix="l"; $inst="shl"; } if ($suffix == "ll" || ($suffix == "l" && substr($inst,0,1) == "f" && substr($inst,0,2) != "fi")) $suffixstr = "qword ptr "; else if ($suffix == "l") $suffixstr = "dword ptr "; else if ($suffix == "s") $suffixstr = "dword ptr "; else $suffixstr = ""; $parms=preg_replace("/(-?[0-9]+)\\((.*)\\)/",$suffixstr . "[$2+$1]",$parms); $parms=preg_replace("/\\((.*)\\)/",$suffixstr . "[$1]",$parms); $parms=str_replace("EEL_F_SUFFIX","EEL_ASM_TYPE", $parms); $parms=str_replace("EEL_F_SSTR","EEL_F_SIZE", $parms); $plist = explode(",",$parms); if (count($plist) > 2) echo "Warning: too many parameters $parms!\n"; else if (count($plist)==2) { $parms = trim($plist[1]) . ", " . trim($plist[0]); } else { } if ($inst=="fsts") $inst="fstsw"; if ($inst=="call" && substr($parms,0,1) == "*") $parms=substr($parms,1); if (substr($inst,0,1) == "j") { if (substr($parms,-1) == "f") { $d = (int) substr($parms,0,-1); if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d]; else $btfut[$d] = $thislbl = "label_" . $labelcnt++; $parms = $thislbl; } else if (substr($parms,-1) == "b") { $d = (int) substr($parms,0,-1); if ($bthist[$d]=="") echo "Error resolving label $parms\n"; $parms = $bthist[$d]; } } if (stristr($parms,"[0xfefefefe]")) { if ($inst == "fmul" || $inst=="fadd" || $inst == "fcomp") { if ($inst=="fmul") $hdr="0x0D"; if ($inst=="fadd") $hdr="0x05"; if ($inst=="fcomp") $hdr="0x1D"; fputs($out,"#if EEL_F_SIZE == 8\n"); fputs($out,"_emit 0xDC; // $inst qword ptr [0xfefefefe]\n"); fputs($out,"_emit $hdr;\n"); fputs($out,"_emit 0xFE;\n"); fputs($out,"_emit 0xFE;\n"); fputs($out,"_emit 0xFE;\n"); fputs($out,"_emit 0xFE;\n"); fputs($out,"#else\n"); fputs($out,"_emit 0xD8; // $inst dword ptr [0xfefefefe]\n"); fputs($out,"_emit $hdr;\n"); fputs($out,"_emit 0xFE;\n"); fputs($out,"_emit 0xFE;\n"); fputs($out,"_emit 0xFE;\n"); fputs($out,"_emit 0xFE;\n"); fputs($out,"#endif\n"); $nowrite=1; } } $sline = $inst; if ($parms !="") $sline .= " " . $parms; $sline .= ";"; } $sline=preg_replace("/FPREG_([0-9]+)/","st($1)",$sline); $line = $beg_restore . $sline . $end_restore; } } } if (!$nowrite) { if (strstr($line,"__TEMP_REPLACE__")) { $a = strstr($line,"//REPLACE="); if ($a === false) die ("__TEMP_REPLACE__ found, no REPLACE=\n"); $line=str_replace("__TEMP_REPLACE__",substr($a,10),$line); } fputs($out,$line . "\n"); } } if ($inblock) echo "Error (ended in __asm__ block???)\n"; fclose($in); fclose($out); }; process_file("asm-nseel-x86-gcc.c" , "asm-nseel-x86-msvc.c"); // process_file("asm-miscfunc-x86-gcc.c" , "asm-miscfunc-x86-msvc.c"); //process_file("asm-megabuf-x86-gcc.c" , "asm-megabuf-x86-msvc.c"); ?> jsusfx-0.4.0/src/WDL/eel2/a2x64.php000066400000000000000000000220061353477307700164760ustar00rootroot000000000000001) $end_restore = substr($line,1-strlen($lastchunk)); else $end_restore=""; $sline = substr($sline,1,strlen($sline)-1-strlen($lastchunk)); $sline=preg_replace("/%\d+/","__TEMP_REPLACE__", $sline); // get rid of chars we can ignore $sline=str_replace("\\n","", $sline); $sline=str_replace("\"","", $sline); $sline=str_replace("$","", $sline); $sline=str_replace("%","", $sline); // get rid of excess whitespace, especially around commas $sline=str_replace(" "," ", $sline); $sline=str_replace(" "," ", $sline); $sline=str_replace(" "," ", $sline); $sline=str_replace(", ",",", $sline); $sline=str_replace(" ,",",", $sline); $sline=preg_replace("/st\\(([0-9]+)\\)/","FPREG_$1",$sline); if (preg_match("/^([0-9]+):/",trim($sline))) { $d = (int) $sline; $a = strstr($sline,":"); if ($a) $sline = substr($a,1); if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d]; else $thislbl = "label_" . $labelcnt++; $btfut[$d]=""; $bthist[$d] = $thislbl; fputs($out,$thislbl . ":\n"); } $sploded = explode(" ",trim($sline)); if ($sline != "" && count($sploded)>0) { $inst = trim($sploded[0]); $suffix = ""; $instline = strstr($sline,$inst); $beg_restore .= substr($sline,0,-strlen($instline)); $parms = trim(substr($instline,strlen($inst))); if ($inst=="j") $inst="jmp"; // if ($inst == "fdiv" && $parms == "") $inst="fdivr"; if ($inst != "call" && substr($inst,-2) == "ll") $suffix = "ll"; else if ($inst != "call" && $inst != "fmul" && substr($inst,-1) == "l") $suffix = "l"; else if (substr($inst,0,1)=="f" && $inst != "fcos" && $inst != "fsincos" && $inst != "fchs" && $inst != "fabs" && substr($inst,-1) == "s") $suffix = "s"; if ($suffix != "" && $inst != "jl") $inst = substr($inst,0,-strlen($suffix)); $parms = preg_replace("/\\((.{2,3}),(.{2,3})\\)/","($1+$2)",$parms); $parms=preg_replace("/EEL_F_SUFFIX (-?[0-9]+)\\((.*)\\)/","qword [$2+$1]",$parms); $parms=preg_replace("/EEL_F_SUFFIX \\((.*)\\)/","qword [$1]",$parms); if ($inst == "sh" && $suffix == "ll") { $suffix="l"; $inst="shl"; } if ($suffix == "ll" || ($suffix == "l" && substr($inst,0,1) == "f" && substr($inst,0,2) != "fi")) $suffixstr = "qword "; else if ($suffix == "l") $suffixstr = "dword "; else if ($suffix == "s") $suffixstr = "dword "; else $suffixstr = ""; $parms=preg_replace("/(-?[0-9]+)\\((.*)\\)/",$suffixstr . "[$2+$1]",$parms); $parms=preg_replace("/\\((.*)\\)/",$suffixstr . "[$1]",$parms); $parms=str_replace("EEL_F_SUFFIX","qword", $parms); $parms=str_replace("EEL_F_SSTR","8", $parms); $plist = explode(",",$parms); if (count($plist) > 2) echo "Warning: too many parameters $parms!\n"; else if (count($plist)==2) { if ($suffixstr != "dword " || strstr($plist[0],"[")) makeregs64($plist[0]); if ($suffixstr != "dword " || stristr($plist[0],"ffffffff") || strstr($plist[1],"[")) makeregs64($plist[1]); if (!stristr($plist[0],"[") && !stristr($plist[1],"[")) { makeregs64($plist[1]); makeregs64($plist[0]); } $parms = trim($plist[1]) . ", " . trim($plist[0]); } else { // if ($suffixstr != "dword ") makeregs64($parms); } if ($inst=="fsts") $inst="fstsw"; if ($inst=="fistp") $inst="fisttp"; if ($inst=="call" && substr($parms,0,1) == "*") $parms=substr($parms,1); if (substr($inst,0,1) == "j") { if (substr($parms,-1) == "f") { $d = (int) substr($parms,0,-1); if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d]; else $btfut[$d] = $thislbl = "label_" . $labelcnt++; $parms = $thislbl; } else if (substr($parms,-1) == "b") { $d = (int) substr($parms,0,-1); if ($bthist[$d]=="") echo "Error resolving label $parms\n"; $parms = $bthist[$d]; } } $parms = preg_replace("/0x[fe,FE]{8}/","qword 0xFEFEFEFEFEFEFEFE",$parms); $sline = $inst; if ($parms !="") $sline .= " " . $parms; } $sline=preg_replace("/FPREG_([0-9]+)/","st$1",$sline); $line = $beg_restore . $sline . $end_restore; } } } if ($inblock) { if (strstr($line,"__TEMP_REPLACE__")) { $a = strstr($line,"; REPLACE="); if ($a === false) die ("__TEMP_REPLACE__ found, no REPLACE=\n"); $line=str_replace("__TEMP_REPLACE__",substr($a,10),$line); } fputs($out,$line . "\n"); } } if ($inblock) echo "Error (ended in __asm__ block???)\n"; fclose($in); fclose($out); }; $nasm="nasm"; $want_funclead=""; $fmt = "win64"; if (isset($argv[1]) && $argv[1] != "") $fmt = $argv[1]; $fnout = "asm-nseel-x64.asm"; if ($fmt == "macho64") { $fnout="asm-nseel-x64-macho.asm"; $nasm = "nasm64"; $want_funclead = "_"; } if ($fmt == "macho64x") { $fnout="asm-nseel-x64-macho.asm"; /* The version of NASM which ships with XCode (0.98.40) is vastly outdated and doesn't support macho64 output. Sadly when building from XCode it sets to path so it finds the old version first. We try to locate a more recent version of NASM and call it instead. */ $nasm_usr = "/usr/local/bin/nasm"; // this is where brew installs NASM by default. if (file_exists($nasm_usr)) $nasm = $nasm_usr; else $nasm = "nasm"; $want_funclead = "_"; $fmt="macho64"; } if ($fmt == "win64x") { $nasm="nasm64"; $fmt = "win64"; } process_file("asm-nseel-x86-gcc.c" , $fnout, $fmt != "win64" ? "%define AMD64ABI\n" : ""); system("$nasm -f $fmt $fnout"); ?> jsusfx-0.4.0/src/WDL/eel2/asm-nseel-arm-gcc.c000066400000000000000000000742001353477307700204630ustar00rootroot00000000000000#define FUNCTION_MARKER "mov r0, r0\n" \ "mov r1, r1\n" \ "mov r2, r2\n" #if EEL_F_SIZE == 8 __attribute__((naked)) void nseel_asm_1pdd(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "str lr, [sp, #-8]!\n" "blx r3\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_1pdd_end(void){} __attribute__((naked)) void nseel_asm_2pdd(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "fcpyd d1, d0\n" "fldd d0, [r1]\n" "str lr, [sp, #-8]!\n" "blx r3\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); }; __attribute__((naked)) void nseel_asm_2pdd_end(void){} __attribute__((naked)) void nseel_asm_2pdds(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "push {r1, lr}\n" "fcpyd d1, d0\n" "fldd d0, [r1]\n" "blx r3\n" "pop {r0, lr}\n" "fstd d0, [r0]\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_2pdds_end(void){} #else // 32 bit floating point calls #error no 32 bit float support #endif //--------------------------------------------------------------------------------------------------------------- // do nothing, eh __attribute__((naked)) void nseel_asm_exec2(void) { __asm__ __volatile__( FUNCTION_MARKER FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_exec2_end(void) { } __attribute__((naked)) void nseel_asm_invsqrt(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r0, 0x59df\n" "movt r0, 0x5f37\n" "fcvtsd s2, d0\n" "fldd d3, [r6, #32]\n" "fmrs r1, s2\n" "fmuld d0, d0, d3\n" "mov r1, r1, asr #1\n" "sub r0, r0, r1\n" "fmsr s4, r0\n" "fcvtds d1, s4\n" "fldd d2, [r6, #40]\n" "fmuld d0, d0, d1\n" "fmuld d0, d0, d1\n" "faddd d0, d0, d2\n" "fmuld d0, d0, d1\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_invsqrt_end(void) {} __attribute__((naked)) void nseel_asm_dbg_getstackptr(void) { __asm__ __volatile__( FUNCTION_MARKER "fmsr s0, sp\n" "fsitod d0, s0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_dbg_getstackptr_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_sqr(void) { __asm__ __volatile__( FUNCTION_MARKER "fmuld d0, d0, d0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_sqr_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_abs(void) { __asm__ __volatile__( FUNCTION_MARKER "fabsd d0, d0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_abs_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_assign(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d0, [r0]\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_assign_end(void) {} // //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_assign_fromfp(void) { __asm__ __volatile__( FUNCTION_MARKER "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_assign_fromfp_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_assign_fast(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d0, [r0]\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_assign_fast_end(void) {} // //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_assign_fast_fromfp(void) { __asm__ __volatile__( FUNCTION_MARKER "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_assign_fast_fromfp_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_add(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "faddd d0, d1, d0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_add_end(void) {} __attribute__((naked)) void nseel_asm_add_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "faddd d0, d1, d0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_add_op_end(void) {} __attribute__((naked)) void nseel_asm_add_op_fast(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "faddd d0, d1, d0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_add_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_sub(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fsubd d0, d1, d0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_sub_end(void) {} __attribute__((naked)) void nseel_asm_sub_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fsubd d0, d1, d0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_sub_op_end(void) {} __attribute__((naked)) void nseel_asm_sub_op_fast(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fsubd d0, d1, d0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_sub_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_mul(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fmuld d0, d0, d1\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_mul_end(void) {} __attribute__((naked)) void nseel_asm_mul_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fmuld d0, d0, d1\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_mul_op_end(void) {} __attribute__((naked)) void nseel_asm_mul_op_fast(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fmuld d0, d0, d1\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_mul_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_div(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fdivd d0, d1, d0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_div_end(void) {} __attribute__((naked)) void nseel_asm_div_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fdivd d0, d1, d0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_div_op_end(void) {} __attribute__((naked)) void nseel_asm_div_op_fast(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fdivd d0, d1, d0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_div_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_mod(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftouizd s0, d0\n" // round to unsigned integers "fmrs r3, s0\n" "fuitod d0, s0\n" // divisor "ftouizd s2, d1\n" "cmp r3, #0\n" "beq 0f\n" "fuitod d1, s2\n" // value "fdivd d2, d1, d0\n" "ftouizd s4, d2\n" "fuitod d2, s4\n" "fmuld d2, d2, d0\n" "fsubd d0, d1, d2\n" "0:\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_mod_end(void) {} __attribute__((naked)) void nseel_asm_shl(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "mov r3, r2, asl r3\n" "fmsr s0, r3\n" "fsitod d0, s0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_shl_end(void) {} __attribute__((naked)) void nseel_asm_shr(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "mov r3, r2, asr r3\n" "fmsr s0, r3\n" "fsitod d0, s0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_shr_end(void) {} __attribute__((naked)) void nseel_asm_mod_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftouizd s0, d0\n" // round to unsigned integers "fmrs r3, s0\n" "fuitod d0, s0\n" // divisor "ftouizd s2, d1\n" "cmp r3, #0\n" "beq 0f\n" "fuitod d1, s2\n" // value "fdivd d2, d1, d0\n" "ftouizd s4, d2\n" "fuitod d2, s4\n" "fmuld d2, d2, d0\n" "fsubd d0, d1, d2\n" "0:\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_mod_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_or(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "orr r3, r3, r2\n" "fmsr s0, r3\n" "fsitod d0, s0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_or_end(void) {} __attribute__((naked)) void nseel_asm_or0(void) { __asm__ __volatile__( FUNCTION_MARKER "ftosizd s0, d0\n" "fsitod d0, s0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_or0_end(void) {} __attribute__((naked)) void nseel_asm_or_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "orr r3, r3, r2\n" "fmsr s0, r3\n" "fsitod d0, s0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_or_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_xor(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "eor r3, r3, r2\n" "fmsr s0, r3\n" "fsitod d0, s0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_xor_end(void) {} __attribute__((naked)) void nseel_asm_xor_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "eor r3, r3, r2\n" "fmsr s0, r3\n" "fsitod d0, s0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_xor_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_and(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "and r3, r3, r2\n" "fmsr s0, r3\n" "fsitod d0, s0\n" FUNCTION_MARKER );} __attribute__((naked)) void nseel_asm_and_end(void) {} __attribute__((naked)) void nseel_asm_and_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "and r3, r3, r2\n" "fmsr s0, r3\n" "fsitod d0, s0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_and_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_uplus(void) // this is the same as doing nothing, it seems { __asm__ __volatile__( FUNCTION_MARKER FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_uplus_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_uminus(void) { __asm__ __volatile__( FUNCTION_MARKER "fnegd d0, d0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_uminus_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_sign(void) { __asm__ __volatile__( FUNCTION_MARKER "fcmpzd d0\n" "fmstat\n" "flddgt d0, [r6, #16]\n" "flddlt d0, [r6, #24]\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_sign_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_bnot(void) { __asm__ __volatile__( FUNCTION_MARKER "cmp r0, #0\n" "movne r0, #0\n" "moveq r0, #1\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_bnot_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_if(void) { __asm__ __volatile__( FUNCTION_MARKER "str lr, [sp, #-8]!\n" "movw r1, 0xdead\n" "movt r1, 0xbeef\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "cmp r0, #0\n" "moveq r1, r2\n" "blx r1\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_if_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_repeat(void) { #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 __asm__ __volatile__( FUNCTION_MARKER "ftosizd s0, d0\n" "fmrs r3, s0\n" "cmp r3, #0\n" "ble 0f\n" "movw r2, %0\n" "movt r2, %1\n" "cmp r3, r2\n" "movgt r3, r2\n" "push {r10,lr}\n" "movw r10, 0xdead\n" "movt r10, 0xbeef\n" "1:\n" "push {r3,r5}\n" // save counter + worktable "blx r10\n" "pop {r3,r5}\n" "sub r3, r3, #1\n" "cmp r3, #0\n" "bgt 1b\n" "pop {r10,lr}\n" "0:\n" FUNCTION_MARKER ::"g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN&65535), "g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN>>16) ); #else __asm__ __volatile__( FUNCTION_MARKER "ftosizd s0, d0\n" "fmrs r3, s0\n" "cmp r3, #0\n" "ble 0f\n" "push {r10,lr}\n" "movw r10, 0xdead\n" "movt r10, 0xbeef\n" "1:\n" "push {r3,r5}\n" // save counter + worktable "blx r10\n" "pop {r3,r5}\n" "sub r3, r3, #1\n" "cmp r3, #0\n" "bgt 1b\n" "pop {r10,lr}\n" "0:\n" FUNCTION_MARKER ); #endif } __attribute__((naked)) void nseel_asm_repeat_end(void) {} __attribute__((naked)) void nseel_asm_repeatwhile(void) { #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 __asm__ __volatile__( FUNCTION_MARKER "movw r3, %0\n" "movt r3, %1\n" "push {r10,lr}\n" "movw r10, 0xdead\n" "movt r10, 0xbeef\n" "0:\n" "push {r3,r5}\n" // save counter + worktable "blx r10\n" "pop {r3,r5}\n" "sub r3, r3, #1\n" "cmp r0, #0\n" "cmpne r3, #0\n" "bne 0b\n" "pop {r10,lr}\n" FUNCTION_MARKER ::"g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN&65535), "g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN>>16) ); #else __asm__ __volatile__( FUNCTION_MARKER "push {r10,lr}\n" "movw r10, 0xdead\n" "movt r10, 0xbeef\n" "0:\n" "push {r3,r5}\n" // save worktable (r3 just for alignment) "blx r10\n" "pop {r3,r5}\n" "cmp r0, #0\n" "bne 0b\n" "pop {r10,lr}\n" "0:\n" FUNCTION_MARKER ); #endif } __attribute__((naked)) void nseel_asm_repeatwhile_end(void) {} __attribute__((naked)) void nseel_asm_band(void) { __asm__ __volatile__( FUNCTION_MARKER "cmp r0, #0\n" "beq 0f\n" "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "push {r3, lr}\n" "blx r3\n" "pop {r3, lr}\n" "0:\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_band_end(void) {} __attribute__((naked)) void nseel_asm_bor(void) { __asm__ __volatile__( FUNCTION_MARKER "cmp r0, #0\n" "bne 0f\n" "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "push {r3, lr}\n" "blx r3\n" "pop {r3, lr}\n" "0:\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_bor_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_equal(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fldd d2, [r6]\n" "fsubd d0, d0, d1\n" "fabsd d0, d0\n" "fcmpd d2, d0\n" "fmstat\n" "movlt r0, #0\n" "movge r0, #1\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_equal_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_equal_exact(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fcmpd d0, d1\n" "fmstat\n" "movne r0, #0\n" "moveq r0, #1\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_equal_exact_end(void) {} // //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_notequal_exact(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fcmpd d0, d1\n" "fmstat\n" "moveq r0, #0\n" "movne r0, #1\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_notequal_exact_end(void) {} // // // //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_notequal(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fldd d2, [r6]\n" "fsubd d0, d0, d1\n" "fabsd d0, d0\n" "fcmpd d2, d0\n" "fmstat\n" "movlt r0, #1\n" "movge r0, #0\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_notequal_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_below(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fcmpd d1, d0\n" "fmstat\n" "movlt r0, #1\n" "movge r0, #0\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_below_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_beloweq(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fcmpd d1, d0\n" "fmstat\n" "movle r0, #1\n" "movgt r0, #0\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_beloweq_end(void) {} //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_above(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fcmpd d1, d0\n" "fmstat\n" "movgt r0, #1\n" "movle r0, #0\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_above_end(void) {} __attribute__((naked)) void nseel_asm_aboveeq(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fcmpd d1, d0\n" "fmstat\n" "movge r0, #1\n" "movlt r0, #0\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_aboveeq_end(void) {} __attribute__((naked)) void nseel_asm_min(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d0, [r0]\n" "fldd d1, [r1]\n" "fcmpd d1, d0\n" "fmstat\n" "movlt r0, r1\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_min_end(void) {} __attribute__((naked)) void nseel_asm_max(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d0, [r0]\n" "fldd d1, [r1]\n" "fcmpd d1, d0\n" "fmstat\n" "movge r0, r1\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_max_end(void) {} __attribute__((naked)) void nseel_asm_min_fp(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fcmpd d1, d0\n" "fmstat\n" "fcpydlt d0, d1\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_min_fp_end(void) {} __attribute__((naked)) void nseel_asm_max_fp(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fcmpd d1, d0\n" "fmstat\n" "fcpydge d0, d1\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_max_fp_end(void) {} __attribute__((naked)) void _asm_generic3parm(void) { __asm__ __volatile__( FUNCTION_MARKER "push {r4, lr}\n" // input: r0 last, r1=second to last, r2=third to last // output: r0=context, r1=r2, r2=r1, r3=r0 "mov r3, r0\n" // r0 (last parameter) -> r3 "mov r4, r1\n" // r1 (second to last parameter) r1->r4->r2 "movw r0, 0xdead\n" // r0 is first parm (context) "movt r0, 0xbeef\n" "mov r1, r2\n" // r2->r1 "mov r2, r4\n" // r1->r2 "movw r4, 0xdead\n" "movt r4, 0xbeef\n" "blx r4\n" "pop {r4, lr}\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_generic3parm_end(void) {} __attribute__((naked)) void _asm_generic3parm_retd(void) { __asm__ __volatile__( FUNCTION_MARKER "push {r4, lr}\n" // input: r0 last, r1=second to last, r2=third to last // output: r0=context, r1=r2, r2=r1, r3=r0 "mov r3, r0\n" // r0 (last parameter) -> r3 "mov r4, r1\n" // r1 (second to last parameter) r1->r4->r2 "movw r0, 0xdead\n" // r0 is first parm (context) "movt r0, 0xbeef\n" "mov r1, r2\n" // r2->r1 "mov r2, r4\n" // r1->r2 "movw r4, 0xdead\n" "movt r4, 0xbeef\n" "blx r4\n" "pop {r4, lr}\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_generic3parm_retd_end(void) {} __attribute__((naked)) void _asm_generic2parm(void) { __asm__ __volatile__( FUNCTION_MARKER "str lr, [sp, #-8]!\n" "mov r2, r0\n" // r0 -> r2, r1-r1, "movw r0, 0xdead\n" // r0 is first parm "movt r0, 0xbeef\n" "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "blx r3\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_generic2parm_end(void) {} __attribute__((naked)) void _asm_generic2parm_retd(void) { __asm__ __volatile__( FUNCTION_MARKER "str lr, [sp, #-8]!\n" "mov r2, r0\n" // r0 -> r2, r1-r1, "movw r0, 0xdead\n" // r0 is first parm "movt r0, 0xbeef\n" "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "blx r3\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_generic2parm_retd_end(void) {} __attribute__((naked)) void _asm_generic1parm(void) { __asm__ __volatile__( FUNCTION_MARKER "str lr, [sp, #-8]!\n" "mov r1, r0\n" // r0 -> r1 "movw r0, 0xdead\n" // r0 is first parm "movt r0, 0xbeef\n" "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "blx r3\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_generic1parm_end(void) {} __attribute__((naked)) void _asm_generic1parm_retd(void) { __asm__ __volatile__( FUNCTION_MARKER "str lr, [sp, #-8]!\n" "mov r1, r0\n" // r0 -> r1 "movw r0, 0xdead\n" // r0 is first parm "movt r0, 0xbeef\n" "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "blx r3\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_generic1parm_retd_end(void) {} __attribute__((naked)) void _asm_megabuf(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r7, #-8]\n" "faddd d0, d0, d1\n" "ftouizd s0, d0\n" "fmrs r3, s0\n" // r3 is slot index "mov r2, r3, asr %0\n" "bic r2, r2, #7\n" // r2 is page index*8 "cmp r2, %1\n" "bge 0f\n" "add r2, r2, r7\n" "ldr r2, [r2]\n" "cmp r2, #0\n" "beq 0f\n" "movw r0, %2\n" "and r3, r3, r0\n" // r3 mask item in slot "add r0, r2, r3, asl #3\n" // set result "b 1f\n" "0:\n" // failed, call stub function "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "str lr, [sp, #-8]!\n" "mov r0, r7\n" // first parameter: blocks "mov r1, r3\n" // second parameter: slot index "blx r2\n" "ldr lr, [sp], #8\n" "1:\n" FUNCTION_MARKER :: "i" (NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 3/*log2(sizeof(EEL_F))*/), "i" (NSEEL_RAM_BLOCKS*8), "i" (NSEEL_RAM_ITEMSPERBLOCK-1) ); } __attribute__((naked)) void _asm_megabuf_end(void) {} __attribute__((naked)) void _asm_gmegabuf(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r0, 0xdead\n" "movt r0, 0xbeef\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "fldd d1, [r7, #-8]\n" "faddd d0, d0, d1\n" "ftouizd s0, d0\n" "fmrs r1, s0\n" // r1 is slot index "push {r4, lr}\n" "blx r2\n" "pop {r4, lr}\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_gmegabuf_end(void) {} __attribute__((naked)) void nseel_asm_fcall(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r0, 0xdead\n" "movt r0, 0xbeef\n" "push {r4, lr}\n" "blx r0\n" "pop {r4, lr}\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_fcall_end(void) {} __attribute__((naked)) void nseel_asm_stack_push(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d0, [r0]\n" "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "ldr r0, [r3]\n" "add r0, r0, #8\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "and r0, r0, r2\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "orr r0, r0, r2\n" "str r0, [r3]\n" "fstd d0, [r0]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_push_end(void) {} __attribute__((naked)) void nseel_asm_stack_pop(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "ldr r1, [r3]\n" "fldd d0, [r1]\n" "sub r1, r1, #8\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "fstd d0, [r0]\n" "and r1, r1, r2\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "orr r1, r1, r2\n" "str r1, [r3]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_pop_end(void) {} __attribute__((naked)) void nseel_asm_stack_pop_fast(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "ldr r1, [r3]\n" "mov r0, r1\n" "sub r1, r1, #8\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "and r1, r1, r2\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "orr r1, r1, r2\n" "str r1, [r3]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_pop_fast_end(void) {} __attribute__((naked)) void nseel_asm_stack_peek(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "ftosizd s0, d0\n" "fmrs r2, s0\n" // r2 is index in stack "ldr r1, [r3]\n" "sub r1, r1, r2, asl #3\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "and r1, r1, r2\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "orr r0, r1, r2\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_peek_end(void) {} __attribute__((naked)) void nseel_asm_stack_peek_top(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "ldr r0, [r3]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_peek_top_end(void) {} __attribute__((naked)) void nseel_asm_stack_peek_int(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "movw r2, 0xdead\n" // r3 is stack "movt r2, 0xbeef\n" "ldr r1, [r3]\n" "sub r1, r1, r2\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "and r1, r1, r2\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "orr r0, r1, r2\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_peek_int_end(void) {} __attribute__((naked)) void nseel_asm_stack_exch(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "ldr r1, [r3]\n" "fldd d0, [r0]\n" "fldd d1, [r1]\n" "fstd d0, [r1]\n" "fstd d1, [r0]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_exch_end(void) {} __attribute__((naked)) void nseel_asm_booltofp(void) { __asm__ __volatile__( FUNCTION_MARKER "cmp r0, #0\n" "flddne d0, [r6, #16]\n" "flddeq d0, [r6, #8]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_booltofp_end(void){ } __attribute__((naked)) void nseel_asm_fptobool(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r6]\n" "fabsd d0, d0\n" "fcmpd d0, d1\n" "fmstat\n" "movgt r0, #1\n" "movlt r0, #0\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_fptobool_end(void){ } __attribute__((naked)) void nseel_asm_fptobool_rev(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r6]\n" "fabsd d0, d0\n" "fcmpd d0, d1\n" "fmstat\n" "movgt r0, #0\n" "movlt r0, #1\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_fptobool_rev_end(void){ } jsusfx-0.4.0/src/WDL/eel2/asm-nseel-ppc-gcc.c000066400000000000000000000741441353477307700204750ustar00rootroot00000000000000#define FUNCTION_MARKER "mr r0, r0\n" \ "mr r1, r1\n" \ "mr r2, r2\n" #if EEL_F_SIZE == 8 void nseel_asm_1pdd(void) { __asm__( FUNCTION_MARKER "addis r5, 0, 0xdead\n" "ori r5, r5, 0xbeef\n" "mtctr r5\n" "subi r1, r1, 64\n" "bctrl\n" "addi r1, r1, 64\n" FUNCTION_MARKER :: ); } void nseel_asm_1pdd_end(void){} void nseel_asm_2pdd(void) { __asm__( FUNCTION_MARKER "addis r7, 0, 0xdead\n" "ori r7, r7, 0xbeef\n" "fmr f2, f1\n" "lfd f1, 0(r14)\n" "mtctr r7\n" "subi r1, r1, 64\n" "bctrl\n" "addi r1, r1, 64\n" FUNCTION_MARKER :: ); }; void nseel_asm_2pdd_end(void){} void nseel_asm_2pdds(void) { __asm__( FUNCTION_MARKER "addis r5, 0, 0xdead\n" "ori r5, r5, 0xbeef\n" "fmr f2, f1\n" "lfd f1, 0(r14)\n" "mtctr r5\n" "subi r1, r1, 64\n" "bctrl\n" "addi r1, r1, 64\n" "stfd f1, 0(r14)\n" "mr r3, r14\n" FUNCTION_MARKER :: ); } void nseel_asm_2pdds_end(void){} #else // 32 bit floating point calls #error no 32 bit float support #endif //--------------------------------------------------------------------------------------------------------------- // do nothing, eh void nseel_asm_exec2(void) { __asm__( FUNCTION_MARKER FUNCTION_MARKER ); } void nseel_asm_exec2_end(void) { } void nseel_asm_invsqrt(void) { __asm__( FUNCTION_MARKER "frsqrte f1, f1\n" // less accurate than our x86 equivilent, but invsqrt() is inherently inaccurate anyway FUNCTION_MARKER ); } void nseel_asm_invsqrt_end(void) {} void nseel_asm_dbg_getstackptr(void) { __asm__( FUNCTION_MARKER "addis r11, 0, 0x4330\n" "xoris r10, r1, 0x8000\n" "stw r11, -8(r1)\n" // 0x43300000 "stw r10, -4(r1)\n" // our integer sign flipped "lfd f1, -8(r1)\n" "fsub f1, f1, f30\n" FUNCTION_MARKER ); } void nseel_asm_dbg_getstackptr_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_sqr(void) { __asm__( FUNCTION_MARKER "fmul f1, f1, f1\n" FUNCTION_MARKER ); } void nseel_asm_sqr_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_abs(void) { __asm__( FUNCTION_MARKER "fabs f1, f1\n" FUNCTION_MARKER ); } void nseel_asm_abs_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_assign(void) { __asm__( FUNCTION_MARKER "lfd f1, 0(r3)\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_assign_end(void) {} // //--------------------------------------------------------------------------------------------------------------- void nseel_asm_assign_fromfp(void) { __asm__( FUNCTION_MARKER "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_assign_fromfp_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_assign_fast(void) { __asm__( FUNCTION_MARKER "lfd f1, 0(r3)\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_assign_fast_end(void) {} // //--------------------------------------------------------------------------------------------------------------- void nseel_asm_assign_fast_fromfp(void) { __asm__( FUNCTION_MARKER "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_assign_fast_fromfp_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_add(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fadd f1, f1, f2\n" FUNCTION_MARKER ); } void nseel_asm_add_end(void) {} void nseel_asm_add_op(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fadd f1, f1, f2\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_add_op_end(void) {} void nseel_asm_add_op_fast(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fadd f1, f1, f2\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_add_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_sub(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fsub f1, f2, f1\n" FUNCTION_MARKER ); } void nseel_asm_sub_end(void) {} void nseel_asm_sub_op(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fsub f1, f2, f1\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_sub_op_end(void) {} void nseel_asm_sub_op_fast(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fsub f1, f2, f1\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_sub_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_mul(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fmul f1, f2, f1\n" FUNCTION_MARKER ); } void nseel_asm_mul_end(void) {} void nseel_asm_mul_op(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fmul f1, f2, f1\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_mul_op_end(void) {} void nseel_asm_mul_op_fast(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fmul f1, f2, f1\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_mul_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_div(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fdiv f1, f2, f1\n" FUNCTION_MARKER ); } void nseel_asm_div_end(void) {} void nseel_asm_div_op(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fdiv f1, f2, f1\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_div_op_end(void) {} void nseel_asm_div_op_fast(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fdiv f1, f2, f1\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_div_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_mod(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fabs f1, f1\n" "fabs f2, f2\n" "fctiwz f1, f1\n" "fctiwz f2, f2\n" "stfd f1, -8(r1)\n" "stfd f2, -16(r1)\n" "lwz r10, -4(r1)\n" "lwz r11, -12(r1)\n" //r11 and r12 have the integers "divw r12, r11, r10\n" "mullw r12, r12, r10\n" "subf r10, r12, r11\n" "addis r11, 0, 0x4330\n" "xoris r10, r10, 0x8000\n" "stw r11, -8(r1)\n" // 0x43300000 "stw r10, -4(r1)\n" // our integer sign flipped "lfd f1, -8(r1)\n" "fsub f1, f1, f30\n" FUNCTION_MARKER ); } void nseel_asm_mod_end(void) {} void nseel_asm_shl(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fctiwz f1, f1\n" "fctiwz f2, f2\n" "stfd f1, -8(r1)\n" "stfd f2, -16(r1)\n" "lwz r10, -4(r1)\n" "lwz r11, -12(r1)\n" //r11 and r12 have the integers "slw r10, r11, r10\n" // r10 has the result "addis r11, 0, 0x4330\n" "xoris r10, r10, 0x8000\n" "stw r11, -8(r1)\n" // 0x43300000 "stw r10, -4(r1)\n" // our integer sign flipped "lfd f1, -8(r1)\n" "fsub f1, f1, f30\n" FUNCTION_MARKER ); } void nseel_asm_shl_end(void) {} void nseel_asm_shr(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fctiwz f1, f1\n" "fctiwz f2, f2\n" "stfd f1, -8(r1)\n" "stfd f2, -16(r1)\n" "lwz r10, -4(r1)\n" "lwz r11, -12(r1)\n" //r11 and r12 have the integers "sraw r10, r11, r10\n" // r10 has the result "addis r11, 0, 0x4330\n" "xoris r10, r10, 0x8000\n" "stw r11, -8(r1)\n" // 0x43300000 "stw r10, -4(r1)\n" // our integer sign flipped "lfd f1, -8(r1)\n" "fsub f1, f1, f30\n" FUNCTION_MARKER ); } void nseel_asm_shr_end(void) {} void nseel_asm_mod_op(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fabs f1, f1\n" "fabs f2, f2\n" "fctiwz f1, f1\n" "fctiwz f2, f2\n" "stfd f1, -8(r1)\n" "stfd f2, -16(r1)\n" "lwz r10, -4(r1)\n" "lwz r11, -12(r1)\n" //r11 and r12 have the integers "divw r12, r11, r10\n" "mullw r12, r12, r10\n" "subf r10, r12, r11\n" "addis r11, 0, 0x4330\n" "xoris r10, r10, 0x8000\n" "stw r11, -8(r1)\n" // 0x43300000 "stw r10, -4(r1)\n" // our integer sign flipped "lfd f1, -8(r1)\n" "fsub f1, f1, f30\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_mod_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_or(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fctiwz f1, f1\n" "fctiwz f2, f2\n" "stfd f1, -8(r1)\n" "stfd f2, -16(r1)\n" "lwz r10, -4(r1)\n" "lwz r11, -12(r1)\n" //r11 and r12 have the integers "or r10, r10, r11\n" // r10 has the result "addis r11, 0, 0x4330\n" "xoris r10, r10, 0x8000\n" "stw r11, -8(r1)\n" // 0x43300000 "stw r10, -4(r1)\n" // our integer sign flipped "lfd f1, -8(r1)\n" "fsub f1, f1, f30\n" FUNCTION_MARKER ); } void nseel_asm_or_end(void) {} void nseel_asm_or0(void) { __asm__( FUNCTION_MARKER "fctiwz f1, f1\n" "addis r11, 0, 0x4330\n" "stfd f1, -8(r1)\n" "lwz r10, -4(r1)\n" "xoris r10, r10, 0x8000\n" "stw r11, -8(r1)\n" // 0x43300000 "stw r10, -4(r1)\n" // our integer sign flipped "lfd f1, -8(r1)\n" "fsub f1, f1, f30\n" FUNCTION_MARKER ); } void nseel_asm_or0_end(void) {} void nseel_asm_or_op(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fctiwz f1, f1\n" "fctiwz f2, f2\n" "stfd f1, -8(r1)\n" "stfd f2, -16(r1)\n" "lwz r10, -4(r1)\n" "lwz r11, -12(r1)\n" //r11 and r12 have the integers "or r10, r10, r11\n" // r10 has the result "addis r11, 0, 0x4330\n" "xoris r10, r10, 0x8000\n" "stw r11, -8(r1)\n" // 0x43300000 "stw r10, -4(r1)\n" // our integer sign flipped "lfd f1, -8(r1)\n" "fsub f1, f1, f30\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_or_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_xor(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fctiwz f1, f1\n" "fctiwz f2, f2\n" "stfd f1, -8(r1)\n" "stfd f2, -16(r1)\n" "lwz r10, -4(r1)\n" "lwz r11, -12(r1)\n" //r11 and r12 have the integers "xor r10, r10, r11\n" // r10 has the result "addis r11, 0, 0x4330\n" "xoris r10, r10, 0x8000\n" "stw r11, -8(r1)\n" // 0x43300000 "stw r10, -4(r1)\n" // our integer sign flipped "lfd f1, -8(r1)\n" "fsub f1, f1, f30\n" FUNCTION_MARKER ); } void nseel_asm_xor_end(void) {} void nseel_asm_xor_op(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fctiwz f1, f1\n" "fctiwz f2, f2\n" "stfd f1, -8(r1)\n" "stfd f2, -16(r1)\n" "lwz r10, -4(r1)\n" "lwz r11, -12(r1)\n" //r11 and r12 have the integers "xor r10, r10, r11\n" // r10 has the result "addis r11, 0, 0x4330\n" "xoris r10, r10, 0x8000\n" "stw r11, -8(r1)\n" // 0x43300000 "stw r10, -4(r1)\n" // our integer sign flipped "lfd f1, -8(r1)\n" "fsub f1, f1, f30\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_xor_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_and(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fctiwz f1, f1\n" "fctiwz f2, f2\n" "stfd f1, -8(r1)\n" "stfd f2, -16(r1)\n" "lwz r10, -4(r1)\n" "lwz r11, -12(r1)\n" //r11 and r12 have the integers "and r10, r10, r11\n" // r10 has the result "addis r11, 0, 0x4330\n" "xoris r10, r10, 0x8000\n" "stw r11, -8(r1)\n" // 0x43300000 "stw r10, -4(r1)\n" // our integer sign flipped "lfd f1, -8(r1)\n" "fsub f1, f1, f30\n" FUNCTION_MARKER );} void nseel_asm_and_end(void) {} void nseel_asm_and_op(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fctiwz f1, f1\n" "fctiwz f2, f2\n" "stfd f1, -8(r1)\n" "stfd f2, -16(r1)\n" "lwz r10, -4(r1)\n" "lwz r11, -12(r1)\n" //r11 and r12 have the integers "and r10, r10, r11\n" // r10 has the result "addis r11, 0, 0x4330\n" "xoris r10, r10, 0x8000\n" "stw r11, -8(r1)\n" // 0x43300000 "stw r10, -4(r1)\n" // our integer sign flipped "lfd f1, -8(r1)\n" "fsub f1, f1, f30\n" "mr r3, r14\n" "stfd f1, 0(r14)\n" FUNCTION_MARKER ); } void nseel_asm_and_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_uplus(void) // this is the same as doing nothing, it seems { __asm__( FUNCTION_MARKER FUNCTION_MARKER ); } void nseel_asm_uplus_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_uminus(void) { __asm__( FUNCTION_MARKER "fneg f1, f1\n" FUNCTION_MARKER ); } void nseel_asm_uminus_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_sign(void) { __asm__( FUNCTION_MARKER "li r9, 0\n" "stw r9, -4(r1)\n" "lis r9, 0xbf80\n" // -1 in float "lfs f2, -4(r1)\n" "fcmpu cr7, f1, f2\n" "blt- cr7, 0f\n" "ble- cr7, 1f\n" " lis r9, 0x3f80\n" // 1 in float "0:\n" " stw r9, -4(r1)\n" " lfs f1, -4(r1)\n" "1:\n" FUNCTION_MARKER :: ); } void nseel_asm_sign_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_bnot(void) { __asm__( FUNCTION_MARKER "cmpwi cr0, r3, 0\n" "addis r3, 0, 0\n" "bne cr0, 0f\n" "addis r3, 0, 1\n" "0:\n" FUNCTION_MARKER ); } void nseel_asm_bnot_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_if(void) { __asm__( FUNCTION_MARKER "cmpwi cr0, r3, 0\n" "beq cr0, 0f\n" " addis r6, 0, 0xdead\n" " ori r6, r6, 0xbeef\n" " mtctr r6\n" " bctrl\n" "b 1f\n" "0:\n" " addis r6, 0, 0xdead\n" " ori r6, r6, 0xbeef\n" " mtctr r6\n" " bctrl\n" "1:\n" FUNCTION_MARKER :: ); } void nseel_asm_if_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_repeat(void) { #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 __asm__( FUNCTION_MARKER "fctiwz f1, f1\n" "stfd f1, -8(r1)\n" "lwz r5, -4(r1)\n" // r5 has count now "cmpwi cr0, r5, 0\n" "ble cr0, 1f\n" // skip the loop "addis r7, 0, ha16(%0)\n" "addi r7, r7, lo16(%0)\n" "stwu r16, -16(r1)\n" // set up the stack for the loop, save r16 "cmpw cr0, r7, r5\n" "bge cr0, 0f\n" "mr r5, r7\n" // set r5 to max if we have to "0:\n" "addis r6, 0, 0xdead\n" "ori r6, r6, 0xbeef\n" "addi r5, r5, -1\n" "stw r5, 4(r1)\n" "mtctr r6\n" "bctrl\n" "lwz r16, 0(r1)\n" "lwz r5, 4(r1)\n" "cmpwi cr0, r5, 0\n" "bgt cr0, 0b\n" "addi r1, r1, 16\n" // restore old stack "1:\n" FUNCTION_MARKER ::"g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN) ); #else __asm__( FUNCTION_MARKER "fctiwz f1, f1\n" "stfd f1, -8(r1)\n" "lwz r5, -4(r1)\n" // r5 has count now "cmpwi cr0, r5, 0\n" "ble cr0, 1f\n" // skip the loop "stwu r16, -16(r1)\n" // set up the stack for the loop, save r16 "0:\n" "addis r6, 0, 0xdead\n" "ori r6, r6, 0xbeef\n" "addi r5, r5, -1\n" "stw r5, 4(r1)\n" "mtctr r6\n" "bctrl\n" "lwz r16, 0(r1)\n" "lwz r5, 4(r1)\n" "cmpwi cr0, r5, 0\n" "bgt cr0, 0b\n" "addi r1, r1, 16\n" // restore old stack "1:\n" FUNCTION_MARKER :: ); #endif } void nseel_asm_repeat_end(void) {} void nseel_asm_repeatwhile(void) { #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 __asm__( FUNCTION_MARKER "stwu r16, -16(r1)\n" // save r16 to stack, update stack "addis r5, 0, ha16(%0)\n" "addi r5, r5, lo16(%0)\n" "0:\n" "addis r6, 0, 0xdead\n" "ori r6, r6, 0xbeef\n" "stw r5, 4(r1)\n" // save maxcnt "mtctr r6\n" "bctrl\n" "lwz r16, 0(r1)\n" // restore r16 "lwz r5, 4(r1)\n" // restore, check maxcnt "cmpwi cr7, r3, 0\n" // check return value "addi r5, r5, -1\n" "beq cr7, 1f\n" "cmpwi cr0, r5, 0\n" "bgt cr0, 0b\n" "1:\n" "addi r1, r1, 16\n" // restore stack FUNCTION_MARKER ::"g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN) ); #else __asm__( FUNCTION_MARKER "stwu r16, -16(r1)\n" // save r16 to stack, update stack "0:\n" "addis r6, 0, 0xdead\n" "ori r6, r6, 0xbeef\n" "mtctr r6\n" "bctrl\n" "lwz r16, 0(r1)\n" // restore r16 "cmpwi cr7, r3, 0\n" // check return value "bne cr7, 0b\n" "addi r1, r1, 16\n" // restore stack FUNCTION_MARKER :: ); #endif } void nseel_asm_repeatwhile_end(void) {} void nseel_asm_band(void) { __asm__( FUNCTION_MARKER "cmpwi cr7, r3, 0\n" "beq cr7, 0f\n" " addis r6, 0, 0xdead\n" " ori r6, r6, 0xbeef\n" " mtctr r6\n" " bctrl\n" "0:\n" FUNCTION_MARKER :: ); } void nseel_asm_band_end(void) {} void nseel_asm_bor(void) { __asm__( FUNCTION_MARKER "cmpwi cr7, r3, 0\n" "bne cr7, 0f\n" " addis r6, 0, 0xdead\n" " ori r6, r6, 0xbeef\n" " mtctr r6\n" " bctrl\n" "0:\n" FUNCTION_MARKER :: ); } void nseel_asm_bor_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_equal(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fsub f1, f1, f2\n" "fabs f1, f1\n" "fcmpu cr7, f1, f31\n" "addis r3, 0, 0\n" "bge cr7, 0f\n" "addis r3, 0, 1\n" "0:\n" FUNCTION_MARKER :: ); } void nseel_asm_equal_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_equal_exact(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fcmpu cr7, f1, f2\n" "addis r3, 0, 0\n" "bne cr7, 0f\n" "addis r3, 0, 1\n" "0:\n" FUNCTION_MARKER :: ); } void nseel_asm_equal_exact_end(void) {} // //--------------------------------------------------------------------------------------------------------------- void nseel_asm_notequal_exact(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fcmpu cr7, f1, f2\n" "addis r3, 0, 0\n" "beq cr7, 0f\n" "addis r3, 0, 1\n" "0:\n" FUNCTION_MARKER :: ); } void nseel_asm_notequal_exact_end(void) {} // // // //--------------------------------------------------------------------------------------------------------------- void nseel_asm_notequal(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fsub f1, f1, f2\n" "fabs f1, f1\n" "fcmpu cr7, f1, f31\n" "addis r3, 0, 0\n" "blt cr7, 0f\n" " addis r3, 0, 1\n" "0:\n" FUNCTION_MARKER :: ); } void nseel_asm_notequal_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_below(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fcmpu cr7, f1, f2\n" "addis r3, 0, 0\n" "ble cr7, 0f\n" "addis r3, 0, 1\n" "0:\n" FUNCTION_MARKER :: ); } void nseel_asm_below_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_beloweq(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fcmpu cr7, f1, f2\n" "addis r3, 0, 0\n" "blt cr7, 0f\n" " addis r3, 0, 1\n" "0:\n" FUNCTION_MARKER :: ); } void nseel_asm_beloweq_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_above(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fcmpu cr7, f1, f2\n" "addis r3, 0, 0\n" "bge cr7, 0f\n" "addis r3, 0, 1\n" "0:\n" FUNCTION_MARKER :: ); } void nseel_asm_above_end(void) {} void nseel_asm_aboveeq(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fcmpu cr7, f1, f2\n" "addis r3, 0, 0\n" "bgt cr7, 0f\n" "addis r3, 0, 1\n" "0:\n" FUNCTION_MARKER :: ); } void nseel_asm_aboveeq_end(void) {} void nseel_asm_min(void) { __asm__( FUNCTION_MARKER "lfd f1, 0(r3)\n" "lfd f2, 0(r14)\n" "fcmpu cr7, f2, f1\n" "bgt cr7, 0f\n" "mr r3, r14\n" "0:\n" FUNCTION_MARKER ); } void nseel_asm_min_end(void) {} void nseel_asm_max(void) { __asm__( FUNCTION_MARKER "lfd f1, 0(r3)\n" "lfd f2, 0(r14)\n" "fcmpu cr7, f2, f1\n" "blt cr7, 0f\n" "mr r3, r14\n" "0:\n" FUNCTION_MARKER ); } void nseel_asm_max_end(void) {} void nseel_asm_min_fp(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fcmpu cr7, f2, f1\n" "bgt cr7, 0f\n" "fmr f1, f2\n" "0:\n" FUNCTION_MARKER ); } void nseel_asm_min_fp_end(void) {} void nseel_asm_max_fp(void) { __asm__( FUNCTION_MARKER "lfd f2, 0(r14)\n" "fcmpu cr7, f2, f1\n" "blt cr7, 0f\n" "fmr f1, f2\n" "0:\n" FUNCTION_MARKER ); } void nseel_asm_max_fp_end(void) {} void _asm_generic3parm(void) { __asm__( FUNCTION_MARKER "mr r6, r3\n" "addis r3, 0, 0xdead\n" "ori r3, r3, 0xbeef\n" "addis r7, 0, 0xdead\n" "ori r7, r7, 0xbeef\n" "mr r4, r15\n" "mr r5, r14\n" "mtctr r7\n" "subi r1, r1, 64\n" "bctrl\n" "addi r1, r1, 64\n" FUNCTION_MARKER :: ); } void _asm_generic3parm_end(void) {} void _asm_generic3parm_retd(void) { __asm__( FUNCTION_MARKER "mr r6, r3\n" "addis r3, 0, 0xdead\n" "ori r3, r3, 0xbeef\n" "addis r7, 0, 0xdead\n" "ori r7, r7, 0xbeef\n" "mr r4, r15\n" "mr r5, r14\n" "mtctr r7\n" "subi r1, r1, 64\n" "bctrl\n" "addi r1, r1, 64\n" FUNCTION_MARKER :: ); } void _asm_generic3parm_retd_end(void) {} void _asm_generic2parm(void) // this prob neds to be fixed for ppc { __asm__( FUNCTION_MARKER "mr r5, r3\n" "addis r3, 0, 0xdead\n" "ori r3, r3, 0xbeef\n" "addis r7, 0, 0xdead\n" "ori r7, r7, 0xbeef\n" "mr r4, r14\n" "mtctr r7\n" "subi r1, r1, 64\n" "bctrl\n" "addi r1, r1, 64\n" FUNCTION_MARKER :: ); } void _asm_generic2parm_end(void) {} void _asm_generic2parm_retd(void) { __asm__( FUNCTION_MARKER "mr r5, r3\n" "addis r3, 0, 0xdead\n" "ori r3, r3, 0xbeef\n" "addis r7, 0, 0xdead\n" "ori r7, r7, 0xbeef\n" "mr r4, r14\n" "mtctr r7\n" "subi r1, r1, 64\n" "bctrl\n" "addi r1, r1, 64\n" FUNCTION_MARKER :: ); } void _asm_generic2parm_retd_end(void) {} void _asm_generic1parm(void) // this prob neds to be fixed for ppc { __asm__( FUNCTION_MARKER "mr r4, r3\n" "addis r3, 0, 0xdead\n" "ori r3, r3, 0xbeef\n" "addis r7, 0, 0xdead\n" "ori r7, r7, 0xbeef\n" "mtctr r7\n" "subi r1, r1, 64\n" "bctrl\n" "addi r1, r1, 64\n" FUNCTION_MARKER :: ); } void _asm_generic1parm_end(void) {} void _asm_generic1parm_retd(void) { __asm__( FUNCTION_MARKER "mr r4, r3\n" "addis r3, 0, 0xdead\n" "ori r3, r3, 0xbeef\n" "addis r7, 0, 0xdead\n" "ori r7, r7, 0xbeef\n" "mtctr r7\n" "subi r1, r1, 64\n" "bctrl\n" "addi r1, r1, 64\n" FUNCTION_MARKER :: ); } void _asm_generic1parm_retd_end(void) {} void _asm_megabuf(void) { __asm__( FUNCTION_MARKER "lfd f2, -8(r13)\n" "mr r3, r13\n" "fadd f1, f2, f1\n" // f1 has (float) index of array, r3 has EEL_F ** "fctiwz f1, f1\n" "stfd f1, -8(r1)\n" "lwz r4, -4(r1)\n" // r4 is index of array "andis. r15, r4, %0\n" // check to see if it has any bits in 0xFF800000, which is 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) "bne cr0, 0f\n" // out of range, jump to error // shr 14 (16 for NSEEL_RAM_ITEMSPERBLOCK, minus two for pointer size), which is rotate 18 // mask 7 bits (NSEEL_RAM_BLOCKS), but leave two empty bits (pointer size) "rlwinm r15, r4, %1, %2, 29\n" "lwzx r15, r3, r15\n" // r15 = (r3+r15) "cmpi cr0, r15, 0\n" "bne cr0, 1f\n" // if nonzero, jump to final calculation "0:\n" // set up function call "addis r7, 0, 0xdead\n" "ori r7, r7, 0xbeef\n" "mtctr r7\n" "subi r1, r1, 64\n" "bctrl\n" "addi r1, r1, 64\n" "b 2f\n" "1:\n" // good news: we can do a direct addr return // bad news: more rlwinm ugliness! // shift left by 3 (sizeof(EEL_F)), mask off lower 3 bits, only allow 16 bits (NSEEL_RAM_ITEMSPERBLOCK) through "rlwinm r3, r4, 3, %3, 28\n" // add offset of loaded block "add r3, r3, r15\n" "2:\n" FUNCTION_MARKER :: "i" ((0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1))>>16), "i" (32 - NSEEL_RAM_ITEMSPERBLOCK_LOG2 + 2), "i" (30 - NSEEL_RAM_BLOCKS_LOG2), "i" (28 - NSEEL_RAM_ITEMSPERBLOCK_LOG2 + 1) ); } void _asm_megabuf_end(void) {} void _asm_gmegabuf(void) { __asm__( FUNCTION_MARKER "fadd f1, f31, f1\n" "addis r3, 0, 0xdead\n" // set up context pointer "ori r3, r3, 0xbeef\n" "fctiwz f1, f1\n" "subi r1, r1, 64\n" "addis r7, 0, 0xdead\n" "ori r7, r7, 0xbeef\n" "stfd f1, 8(r1)\n" "mtctr r7\n" "lwz r4, 12(r1)\n" "bctrl\n" "addi r1, r1, 64\n" FUNCTION_MARKER :: ); } void _asm_gmegabuf_end(void) {} void nseel_asm_fcall(void) { __asm__( FUNCTION_MARKER "addis r6, 0, 0xdead\n" "ori r6, r6, 0xbeef\n" "mtctr r6\n" "bctrl\n" FUNCTION_MARKER ); } void nseel_asm_fcall_end(void) {} void nseel_asm_stack_push(void) { __asm__( FUNCTION_MARKER "addis r6, 0, 0xdead\n" "ori r6, r6, 0xbeef\n" // r6 is stack "lfd f1, 0(r3)\n" // f1 is value to copy to stack "lwz r3, 0(r6)\n" "addis r14, 0, 0xdead\n" "ori r14, r14, 0xbeef\n" "addi r3, r3, 0x8\n" "and r3, r3, r14\n" "addis r14, 0, 0xdead\n" "ori r14, r14, 0xbeef\n" "or r3, r3, r14\n" "stfd f1, 0(r3)\n" // copy parameter to stack "stw r3, 0(r6)\n" // update stack state FUNCTION_MARKER ); } void nseel_asm_stack_push_end(void) {} void nseel_asm_stack_pop(void) { __asm__( FUNCTION_MARKER "addis r6, 0, 0xdead\n" "ori r6, r6, 0xbeef\n" // r6 is stack "lwz r15, 0(r6)\n" // return the old stack pointer "lfd f1, 0(r15)\n" "subi r15, r15, 0x8\n" "addis r14, 0, 0xdead\n" "ori r14, r14, 0xbeef\n" "and r15, r15, r14\n" "addis r14, 0, 0xdead\n" "ori r14, r14, 0xbeef\n" "or r15, r15, r14\n" "stw r15, 0(r6)\n" "stfd f1, 0(r3)\n" FUNCTION_MARKER ); } void nseel_asm_stack_pop_end(void) {} void nseel_asm_stack_pop_fast(void) { __asm__( FUNCTION_MARKER "addis r6, 0, 0xdead\n" "ori r6, r6, 0xbeef\n" // r6 is stack "lwz r3, 0(r6)\n" // return the old stack pointer "mr r15, r3\n" // update stack pointer "subi r15, r15, 0x8\n" "addis r14, 0, 0xdead\n" "ori r14, r14, 0xbeef\n" "and r15, r15, r14\n" "addis r14, 0, 0xdead\n" "ori r14, r14, 0xbeef\n" "or r15, r15, r14\n" "stw r15, 0(r6)\n" FUNCTION_MARKER ); } void nseel_asm_stack_pop_fast_end(void) {} void nseel_asm_stack_peek(void) { __asm__( FUNCTION_MARKER "fctiwz f1, f1\n" "stfd f1, -8(r1)\n" "addis r6, 0, 0xdead\n" "ori r6, r6, 0xbeef\n" // r6 is stack "lwz r14, -4(r1)\n" "rlwinm r14, r14, 3, 0, 28\n" // slwi r14, r14, 3 -- 3 is log2(sizeof(EEL_F)) -- 28 represents 31-3 "lwz r3, 0(r6)\n" // return the old stack pointer "sub r3, r3, r14\n" "addis r14, 0, 0xdead\n" "ori r14, r14, 0xbeef\n" "and r3, r3, r14\n" "addis r14, 0, 0xdead\n" "ori r14, r14, 0xbeef\n" "or r3, r3, r14\n" FUNCTION_MARKER ); } void nseel_asm_stack_peek_end(void) {} void nseel_asm_stack_peek_top(void) { __asm__( FUNCTION_MARKER "addis r6, 0, 0xdead\n" "ori r6, r6, 0xbeef\n" // r6 is stack "lwz r3, 0(r6)\n" // return the old stack pointer FUNCTION_MARKER ); } void nseel_asm_stack_peek_top_end(void) {} void nseel_asm_stack_peek_int(void) { __asm__( FUNCTION_MARKER "addis r6, 0, 0xdead\n" "ori r6, r6, 0xbeef\n" // r6 is stack "lwz r3, 0(r6)\n" // return the old stack pointer "addis r14, 0, 0xdead\n" // add manual offset "ori r14, r14, 0xbeef\n" "sub r3, r3, r14\n" "addis r14, 0, 0xdead\n" "ori r14, r14, 0xbeef\n" "and r3, r3, r14\n" "addis r14, 0, 0xdead\n" "ori r14, r14, 0xbeef\n" "or r3, r3, r14\n" FUNCTION_MARKER ); } void nseel_asm_stack_peek_int_end(void) {} void nseel_asm_stack_exch(void) { __asm__( FUNCTION_MARKER "addis r6, 0, 0xdead\n" "ori r6, r6, 0xbeef\n" // r6 is stack "lfd f1, 0(r3)\n" "lwz r14, 0(r6)\n" "lfd f2, 0(r14)\n" "stfd f1, 0(r14)\n" "stfd f2, 0(r3)\n" FUNCTION_MARKER ); } void nseel_asm_stack_exch_end(void) {} void nseel_asm_booltofp(void) { __asm__( FUNCTION_MARKER "cmpwi cr7, r3, 0\n" "li r14, 0\n" "beq cr7, 0f\n" "addis r14, 0, 0x3f80\n" "0:\n" "stw r14, -8(r1)\n" "lfs f1, -8(r1)\n" FUNCTION_MARKER ); } void nseel_asm_booltofp_end(void){ } void nseel_asm_fptobool(void) { __asm__( FUNCTION_MARKER "fabs f1, f1\n" "fcmpu cr7, f1, f31\n" "addis r3, 0, 1\n" "bge cr7, 0f\n" " addis r3, 0, 0\n" "0:\n" FUNCTION_MARKER :: ); } void nseel_asm_fptobool_end(void){ } void nseel_asm_fptobool_rev(void) { __asm__( FUNCTION_MARKER "fabs f1, f1\n" "fcmpu cr7, f1, f31\n" "addis r3, 0, 0\n" "bge cr7, 0f\n" " addis r3, 0, 1\n" "0:\n" FUNCTION_MARKER :: ); } void nseel_asm_fptobool_rev_end(void){ } jsusfx-0.4.0/src/WDL/eel2/asm-nseel-x86-gcc.c000066400000000000000000001247011353477307700203330ustar00rootroot00000000000000/* note: only EEL_F_SIZE=8 is now supported (no float EEL_F's) */ #ifndef AMD64ABI #define X64_EXTRA_STACK_SPACE 32 // win32 requires allocating space for 4 parameters at 8 bytes each, even though we pass via register #endif void nseel_asm_1pdd(void) { __asm__( FUNCTION_MARKER "movl $0xfefefefe, %edi\n" #ifdef TARGET_X64 "fstpl (%rsi)\n" "movq (%rsi), %xmm0\n" #ifdef AMD64ABI "movl %rsi, %r15\n" "call *%edi\n" "movl %r15, %rsi\n" #else "subl X64_EXTRA_STACK_SPACE, %rsp\n" "call *%edi\n" "addl X64_EXTRA_STACK_SPACE, %rsp\n" #endif "movq xmm0, (%rsi)\n" "fldl (%rsi)\n" #else "subl $16, %esp\n" "fstpl (%esp)\n" "call *%edi\n" "addl $16, %esp\n" #endif FUNCTION_MARKER ); } void nseel_asm_1pdd_end(void){} void nseel_asm_2pdd(void) { __asm__( FUNCTION_MARKER "movl $0xfefefefe, %edi\n" #ifdef TARGET_X64 "fstpl 8(%rsi)\n" "fstpl (%rsi)\n" "movq 8(%rsi), %xmm1\n" "movq (%rsi), %xmm0\n" #ifdef AMD64ABI "movl %rsi, %r15\n" "call *%edi\n" "movl %r15, %rsi\n" #else "subl X64_EXTRA_STACK_SPACE, %rsp\n" "call *%edi\n" "addl X64_EXTRA_STACK_SPACE, %rsp\n" #endif "movq xmm0, (%rsi)\n" "fldl (%rsi)\n" #else "subl $16, %esp\n" "fstpl 8(%esp)\n" "fstpl (%esp)\n" "call *%edi\n" "addl $16, %esp\n" #endif FUNCTION_MARKER ); } void nseel_asm_2pdd_end(void){} void nseel_asm_2pdds(void) { __asm__( FUNCTION_MARKER "movl $0xfefefefe, %eax\n" #ifdef TARGET_X64 "fstpl (%rsi)\n" "movq (%rdi), %xmm0\n" "movq (%rsi), %xmm1\n" #ifdef AMD64ABI "movl %rsi, %r15\n" "movl %rdi, %r14\n" "call *%eax\n" "movl %r14, %rdi\n" /* restore thrashed rdi */ "movl %r15, %rsi\n" "movl %r14, %rax\n" /* set return value */ "movq xmm0, (%r14)\n" #else "subl X64_EXTRA_STACK_SPACE, %rsp\n" "call *%eax\n" "movq xmm0, (%edi)\n" "movl %edi, %eax\n" /* set return value */ "addl X64_EXTRA_STACK_SPACE, %rsp\n" #endif #else "subl $8, %esp\n" "fstpl (%esp)\n" "pushl 4(%edi)\n" /* push parameter */ "pushl (%edi)\n" /* push the rest of the parameter */ "call *%eax\n" "addl $16, %esp\n" "fstpl (%edi)\n" /* store result */ "movl %edi, %eax\n" /* set return value */ #endif // denormal-fix result (this is only currently used for pow_op, so we want this!) "movl 4(%edi), %edx\n" "addl $0x00100000, %edx\n" "andl $0x7FF00000, %edx\n" "cmpl $0x00100000, %edx\n" "jg 0f\n" "subl %edx, %edx\n" #ifdef TARGET_X64 "movll %rdx, (%rdi)\n" #else "movl %edx, (%edi)\n" "movl %edx, 4(%edi)\n" #endif "0:\n" FUNCTION_MARKER ); } void nseel_asm_2pdds_end(void){} //--------------------------------------------------------------------------------------------------------------- // do nothing, eh void nseel_asm_exec2(void) { __asm__( FUNCTION_MARKER "" FUNCTION_MARKER ); } void nseel_asm_exec2_end(void) { } void nseel_asm_invsqrt(void) { __asm__( FUNCTION_MARKER "movl $0x5f3759df, %edx\n" "fsts (%esi)\n" #ifdef TARGET_X64 "movl 0xfefefefe, %rax\n" "fmul" EEL_F_SUFFIX " (%rax)\n" "movsxl (%esi), %rcx\n" #else "fmul" EEL_F_SUFFIX " (0xfefefefe)\n" "movl (%esi), %ecx\n" #endif "sarl $1, %ecx\n" "subl %ecx, %edx\n" "movl %edx, (%esi)\n" "fmuls (%esi)\n" "fmuls (%esi)\n" #ifdef TARGET_X64 "movl 0xfefefefe, %rax\n" "fadd" EEL_F_SUFFIX " (%rax)\n" #else "fadd" EEL_F_SUFFIX " (0xfefefefe)\n" #endif "fmuls (%esi)\n" FUNCTION_MARKER ); } void nseel_asm_invsqrt_end(void) {} void nseel_asm_dbg_getstackptr(void) { __asm__( FUNCTION_MARKER #ifdef __clang__ "ffree %st(0)\n" #else "fstpl %st(0)\n" #endif "movl %esp, (%esi)\n" "fildl (%esi)\n" FUNCTION_MARKER ); } void nseel_asm_dbg_getstackptr_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_sin(void) { __asm__( FUNCTION_MARKER "fsin\n" FUNCTION_MARKER ); } void nseel_asm_sin_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_cos(void) { __asm__( FUNCTION_MARKER "fcos\n" FUNCTION_MARKER ); } void nseel_asm_cos_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_tan(void) { __asm__( FUNCTION_MARKER "fptan\n" "fstp %st(0)\n" FUNCTION_MARKER ); } void nseel_asm_tan_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_sqr(void) { __asm__( FUNCTION_MARKER "fmul %st(0), %st(0)\n" FUNCTION_MARKER ); } void nseel_asm_sqr_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_sqrt(void) { __asm__( FUNCTION_MARKER "fabs\n" "fsqrt\n" FUNCTION_MARKER ); } void nseel_asm_sqrt_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_log(void) { __asm__( FUNCTION_MARKER "fldln2\n" "fxch\n" "fyl2x\n" FUNCTION_MARKER ); } void nseel_asm_log_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_log10(void) { __asm__( FUNCTION_MARKER "fldlg2\n" "fxch\n" "fyl2x\n" FUNCTION_MARKER ); } void nseel_asm_log10_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_abs(void) { __asm__( FUNCTION_MARKER "fabs\n" FUNCTION_MARKER ); } void nseel_asm_abs_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_assign(void) { #ifdef TARGET_X64 __asm__( FUNCTION_MARKER "movll (%rax), %rdx\n" "movll %rdx, %rcx\n" "shrl $32, %rdx\n" "addl $0x00100000, %edx\n" "andl $0x7FF00000, %edx\n" "cmpl $0x00100000, %edx\n" "movll %rdi, %rax\n" "jg 0f\n" "subl %ecx, %ecx\n" "0:\n" "movll %rcx, (%edi)\n" FUNCTION_MARKER ); #else __asm__( FUNCTION_MARKER "movl (%eax), %ecx\n" "movl 4(%eax), %edx\n" "movl %edx, %eax\n" "addl $0x00100000, %eax\n" // if exponent is zero, make exponent 0x7ff, if 7ff, make 7fe "andl $0x7ff00000, %eax\n" "cmpl $0x00100000, %eax\n" "jg 0f\n" "subl %ecx, %ecx\n" "subl %edx, %edx\n" "0:\n" "movl %edi, %eax\n" "movl %ecx, (%edi)\n" "movl %edx, 4(%edi)\n" FUNCTION_MARKER ); #endif } void nseel_asm_assign_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_assign_fromfp(void) { __asm__( FUNCTION_MARKER "fstpl (%edi)\n" "movl 4(%edi), %edx\n" "addl $0x00100000, %edx\n" "andl $0x7FF00000, %edx\n" "cmpl $0x00100000, %edx\n" "movl %edi, %eax\n" "jg 0f\n" "subl %edx, %edx\n" #ifdef TARGET_X64 "movll %rdx, (%rdi)\n" #else "movl %edx, (%edi)\n" "movl %edx, 4(%edi)\n" #endif "0:\n" FUNCTION_MARKER ); } void nseel_asm_assign_fromfp_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_assign_fast_fromfp(void) { __asm__( FUNCTION_MARKER "movl %edi, %eax\n" "fstpl (%edi)\n" FUNCTION_MARKER ); } void nseel_asm_assign_fast_fromfp_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_assign_fast(void) { #ifdef TARGET_X64 __asm__( FUNCTION_MARKER "movll (%rax), %rdx\n" "movll %rdx, (%edi)\n" "movll %rdi, %rax\n" FUNCTION_MARKER ); #else __asm__( FUNCTION_MARKER "movl (%eax), %ecx\n" "movl %ecx, (%edi)\n" "movl 4(%eax), %ecx\n" "movl %edi, %eax\n" "movl %ecx, 4(%edi)\n" FUNCTION_MARKER ); #endif } void nseel_asm_assign_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_add(void) { __asm__( FUNCTION_MARKER #ifdef __clang__ "faddp %st(1)\n" #else "fadd\n" #endif FUNCTION_MARKER ); } void nseel_asm_add_end(void) {} void nseel_asm_add_op(void) { __asm__( FUNCTION_MARKER "fadd" EEL_F_SUFFIX " (%edi)\n" "movl %edi, %eax\n" "fstp" EEL_F_SUFFIX " (%edi)\n" "movl 4(%edi), %edx\n" "addl $0x00100000, %edx\n" "andl $0x7FF00000, %edx\n" "cmpl $0x00100000, %edx\n" "jg 0f\n" "subl %edx, %edx\n" #ifdef TARGET_X64 "movll %rdx, (%rdi)\n" #else "movl %edx, (%edi)\n" "movl %edx, 4(%edi)\n" #endif "0:\n" FUNCTION_MARKER ); } void nseel_asm_add_op_end(void) {} void nseel_asm_add_op_fast(void) { __asm__( FUNCTION_MARKER "fadd" EEL_F_SUFFIX " (%edi)\n" "movl %edi, %eax\n" "fstp" EEL_F_SUFFIX " (%edi)\n" FUNCTION_MARKER ); } void nseel_asm_add_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_sub(void) { __asm__( FUNCTION_MARKER #ifdef __clang__ "fsubrp %st(0), %st(1)\n" #else #ifdef __GNUC__ #ifdef __INTEL_COMPILER "fsub\n" #else "fsubr\n" // gnuc has fsub/fsubr backwards, ack #endif #else "fsub\n" #endif #endif FUNCTION_MARKER ); } void nseel_asm_sub_end(void) {} void nseel_asm_sub_op(void) { __asm__( FUNCTION_MARKER "fsubr" EEL_F_SUFFIX " (%edi)\n" "movl %edi, %eax\n" "fstp" EEL_F_SUFFIX " (%edi)\n" "movl 4(%edi), %edx\n" "addl $0x00100000, %edx\n" "andl $0x7FF00000, %edx\n" "cmpl $0x00100000, %edx\n" "jg 0f\n" "subl %edx, %edx\n" #ifdef TARGET_X64 "movll %rdx, (%rdi)\n" #else "movl %edx, (%edi)\n" "movl %edx, 4(%edi)\n" #endif "0:\n" FUNCTION_MARKER ); } void nseel_asm_sub_op_end(void) {} void nseel_asm_sub_op_fast(void) { __asm__( FUNCTION_MARKER "fsubr" EEL_F_SUFFIX " (%edi)\n" "movl %edi, %eax\n" "fstp" EEL_F_SUFFIX " (%edi)\n" FUNCTION_MARKER ); } void nseel_asm_sub_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_mul(void) { __asm__( FUNCTION_MARKER #ifdef __clang__ "fmulp %st(0), %st(1)\n" #else "fmul\n" #endif FUNCTION_MARKER ); } void nseel_asm_mul_end(void) {} void nseel_asm_mul_op(void) { __asm__( FUNCTION_MARKER "fmul" EEL_F_SUFFIX " (%edi)\n" "movl %edi, %eax\n" "fstp" EEL_F_SUFFIX " (%edi)\n" "movl 4(%edi), %edx\n" "addl $0x00100000, %edx\n" "andl $0x7FF00000, %edx\n" "cmpl $0x00100000, %edx\n" "jg 0f\n" "subl %edx, %edx\n" #ifdef TARGET_X64 "movll %rdx, (%rdi)\n" #else "movl %edx, (%edi)\n" "movl %edx, 4(%edi)\n" #endif "0:\n" FUNCTION_MARKER ); } void nseel_asm_mul_op_end(void) {} void nseel_asm_mul_op_fast(void) { __asm__( FUNCTION_MARKER "fmul" EEL_F_SUFFIX " (%edi)\n" "movl %edi, %eax\n" "fstp" EEL_F_SUFFIX " (%edi)\n" FUNCTION_MARKER ); } void nseel_asm_mul_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_div(void) { __asm__( FUNCTION_MARKER #ifdef __clang__ "fdivrp %st(1)\n" #else #ifdef __GNUC__ #ifdef __INTEL_COMPILER "fdiv\n" #else "fdivr\n" // gcc inline asm seems to have fdiv/fdivr backwards #endif #else "fdiv\n" #endif #endif FUNCTION_MARKER ); } void nseel_asm_div_end(void) {} void nseel_asm_div_op(void) { __asm__( FUNCTION_MARKER "fld" EEL_F_SUFFIX " (%edi)\n" #ifdef __clang__ "fdivp %st(1)\n" #else #ifndef __GNUC__ "fdivr\n" #else #ifdef __INTEL_COMPILER "fdivp %st(1)\n" #else "fdiv\n" #endif #endif #endif "movl %edi, %eax\n" "fstp" EEL_F_SUFFIX " (%edi)\n" "movl 4(%edi), %edx\n" "addl $0x00100000, %edx\n" "andl $0x7FF00000, %edx\n" "cmpl $0x00100000, %edx\n" "jg 0f\n" "subl %edx, %edx\n" #ifdef TARGET_X64 "movll %rdx, (%rdi)\n" #else "movl %edx, (%edi)\n" "movl %edx, 4(%edi)\n" #endif "0:\n" FUNCTION_MARKER ); } void nseel_asm_div_op_end(void) {} void nseel_asm_div_op_fast(void) { __asm__( FUNCTION_MARKER "fld" EEL_F_SUFFIX " (%edi)\n" #ifdef __clang__ "fdivp %st(1)\n" #else #ifndef __GNUC__ "fdivr\n" #else #ifdef __INTEL_COMPILER "fdivp %st(1)\n" #else "fdiv\n" #endif #endif #endif "movl %edi, %eax\n" "fstp" EEL_F_SUFFIX " (%edi)\n" FUNCTION_MARKER ); } void nseel_asm_div_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_mod(void) { __asm__( FUNCTION_MARKER "fabs\n" "fistpl (%esi)\n" "fabs\n" "fistpl 4(%esi)\n" "xorl %edx, %edx\n" "cmpl $0, (%esi)\n" "je 0f\n" // skip devide, set return to 0 "movl 4(%esi), %eax\n" "divl (%esi)\n" "0:\n" "movl %edx, (%esi)\n" "fildl (%esi)\n" FUNCTION_MARKER ); } void nseel_asm_mod_end(void) {} void nseel_asm_shl(void) { __asm__( FUNCTION_MARKER "fistpl (%esi)\n" "fistpl 4(%esi)\n" "movl (%esi), %ecx\n" "movl 4(%esi), %eax\n" "shll %cl, %eax\n" "movl %eax, (%esi)\n" "fildl (%esi)\n" FUNCTION_MARKER ); } void nseel_asm_shl_end(void) {} void nseel_asm_shr(void) { __asm__( FUNCTION_MARKER "fistpl (%esi)\n" "fistpl 4(%esi)\n" "movl (%esi), %ecx\n" "movl 4(%esi), %eax\n" "sarl %cl, %eax\n" "movl %eax, (%esi)\n" "fildl (%esi)\n" FUNCTION_MARKER ); } void nseel_asm_shr_end(void) {} void nseel_asm_mod_op(void) { __asm__( FUNCTION_MARKER "fld" EEL_F_SUFFIX " (%edi)\n" "fxch\n" "fabs\n" "fistpl (%edi)\n" "fabs\n" "fistpl (%esi)\n" "xorl %edx, %edx\n" "cmpl $0, (%edi)\n" "je 0f\n" // skip devide, set return to 0 "movl (%esi), %eax\n" "divl (%edi)\n" "0:\n" "movl %edx, (%edi)\n" "fildl (%edi)\n" "movl %edi, %eax\n" "fstp" EEL_F_SUFFIX " (%edi)\n" FUNCTION_MARKER ); } void nseel_asm_mod_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_or(void) { __asm__( FUNCTION_MARKER "fistpll (%esi)\n" "fistpll 8(%esi)\n" #ifdef TARGET_X64 "movll 8(%rsi), %rdi\n" "orll %rdi, (%rsi)\n" #else "movl 8(%esi), %edi\n" "movl 12(%esi), %ecx\n" "orl %edi, (%esi)\n" "orl %ecx, 4(%esi)\n" #endif "fildll (%esi)\n" FUNCTION_MARKER ); } void nseel_asm_or_end(void) {} void nseel_asm_or0(void) { __asm__( FUNCTION_MARKER "fistpll (%esi)\n" "fildll (%esi)\n" FUNCTION_MARKER ); } void nseel_asm_or0_end(void) {} void nseel_asm_or_op(void) { __asm__( FUNCTION_MARKER "fld" EEL_F_SUFFIX " (%edi)\n" "fxch\n" "fistpll (%edi)\n" "fistpll (%esi)\n" #ifdef TARGET_X64 "movll (%rsi), %rax\n" "orll %rax, (%rdi)\n" #else "movl (%esi), %eax\n" "movl 4(%esi), %ecx\n" "orl %eax, (%edi)\n" "orl %ecx, 4(%edi)\n" #endif "fildll (%edi)\n" "movl %edi, %eax\n" "fstp" EEL_F_SUFFIX " (%edi)\n" FUNCTION_MARKER ); } void nseel_asm_or_op_end(void) {} void nseel_asm_xor(void) { __asm__( FUNCTION_MARKER "fistpll (%esi)\n" "fistpll 8(%esi)\n" #ifdef TARGET_X64 "movll 8(%rsi), %rdi\n" "xorll %rdi, (%rsi)\n" #else "movl 8(%esi), %edi\n" "movl 12(%esi), %ecx\n" "xorl %edi, (%esi)\n" "xorl %ecx, 4(%esi)\n" #endif "fildll (%esi)\n" FUNCTION_MARKER ); } void nseel_asm_xor_end(void) {} void nseel_asm_xor_op(void) { __asm__( FUNCTION_MARKER "fld" EEL_F_SUFFIX " (%edi)\n" "fxch\n" "fistpll (%edi)\n" "fistpll (%esi)\n" #ifdef TARGET_X64 "movll (%rsi), %rax\n" "xorll %rax, (%rdi)\n" #else "movl (%esi), %eax\n" "movl 4(%esi), %ecx\n" "xorl %eax, (%edi)\n" "xorl %ecx, 4(%edi)\n" #endif "fildll (%edi)\n" "movl %edi, %eax\n" "fstp" EEL_F_SUFFIX " (%edi)\n" FUNCTION_MARKER ); } void nseel_asm_xor_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_and(void) { __asm__( FUNCTION_MARKER "fistpll (%esi)\n" "fistpll 8(%esi)\n" #ifdef TARGET_X64 "movll 8(%rsi), %rdi\n" "andll %rdi, (%rsi)\n" #else "movl 8(%esi), %edi\n" "movl 12(%esi), %ecx\n" "andl %edi, (%esi)\n" "andl %ecx, 4(%esi)\n" #endif "fildll (%esi)\n" FUNCTION_MARKER ); } void nseel_asm_and_end(void) {} void nseel_asm_and_op(void) { __asm__( FUNCTION_MARKER "fld" EEL_F_SUFFIX " (%edi)\n" "fxch\n" "fistpll (%edi)\n" "fistpll (%esi)\n" #ifdef TARGET_X64 "movll (%rsi), %rax\n" "andll %rax, (%rdi)\n" #else "movl (%esi), %eax\n" "movl 4(%esi), %ecx\n" "andl %eax, (%edi)\n" "andl %ecx, 4(%edi)\n" #endif "fildll (%edi)\n" "movl %edi, %eax\n" "fstp" EEL_F_SUFFIX " (%edi)\n" FUNCTION_MARKER ); } void nseel_asm_and_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_uplus(void) // this is the same as doing nothing, it seems { __asm__( FUNCTION_MARKER "" FUNCTION_MARKER ); } void nseel_asm_uplus_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_uminus(void) { __asm__( FUNCTION_MARKER "fchs\n" FUNCTION_MARKER ); } void nseel_asm_uminus_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_sign(void) { __asm__( FUNCTION_MARKER #ifdef TARGET_X64 "fst" EEL_F_SUFFIX " (%rsi)\n" "mov" EEL_F_SUFFIX " (%rsi), %rdx\n" "movll $0x7FFFFFFFFFFFFFFF, %rcx\n" "testll %rcx, %rdx\n" "jz 0f\n" // zero zero, return the value passed directly // calculate sign "incll %rcx\n" // rcx becomes 0x80000... "fstp %st(0)\n" "fld1\n" "testl %rcx, %rdx\n" "jz 0f\n" "fchs\n" "0:\n" #else "fsts (%esi)\n" "movl (%esi), %ecx\n" "movl $0x7FFFFFFF, %edx\n" "testl %edx, %ecx\n" "jz 0f\n" // zero zero, return the value passed directly // calculate sign "incl %edx\n" // edx becomes 0x8000... "fstp %st(0)\n" "fld1\n" "testl %edx, %ecx\n" "jz 0f\n" "fchs\n" "0:\n" #endif FUNCTION_MARKER ); } void nseel_asm_sign_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_bnot(void) { __asm__( FUNCTION_MARKER "testl %eax, %eax\n" "setz %al\n" "andl $0xff, %eax\n" FUNCTION_MARKER ); } void nseel_asm_bnot_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_fcall(void) { __asm__( FUNCTION_MARKER "movl $0xfefefefe, %edx\n" #ifdef TARGET_X64 "subl $8, %esp\n" "call *%edx\n" "addl $8, %esp\n" #else "subl $12, %esp\n" /* keep stack 16 byte aligned, 4 bytes for return address */ "call *%edx\n" "addl $12, %esp\n" #endif FUNCTION_MARKER ); } void nseel_asm_fcall_end(void) {} void nseel_asm_band(void) { __asm__( FUNCTION_MARKER "testl %eax, %eax\n" "jz 0f\n" "movl $0xfefefefe, %ecx\n" #ifdef TARGET_X64 "subl $8, %rsp\n" #else "subl $12, %esp\n" #endif "call *%ecx\n" #ifdef TARGET_X64 "addl $8, %rsp\n" #else "addl $12, %esp\n" #endif "0:\n" FUNCTION_MARKER ); } void nseel_asm_band_end(void) {} void nseel_asm_bor(void) { __asm__( FUNCTION_MARKER "testl %eax, %eax\n" "jnz 0f\n" "movl $0xfefefefe, %ecx\n" #ifdef TARGET_X64 "subl $8, %rsp\n" #else "subl $12, %esp\n" #endif "call *%ecx\n" #ifdef TARGET_X64 "addl $8, %rsp\n" #else "addl $12, %esp\n" #endif "0:\n" FUNCTION_MARKER ); } void nseel_asm_bor_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_equal(void) { __asm__( FUNCTION_MARKER #ifdef __clang__ "fsubp %st(1)\n" #else "fsub\n" #endif "fabs\n" #ifdef TARGET_X64 "fcomp" EEL_F_SUFFIX " -8(%r12)\n" //[g_closefact] #else "fcomp" EEL_F_SUFFIX " -8(%ebx)\n" //[g_closefact] #endif "fstsw %ax\n" "andl $256, %eax\n" // old behavior: if 256 set, true (NaN means true) FUNCTION_MARKER ); } void nseel_asm_equal_end(void) {} // //--------------------------------------------------------------------------------------------------------------- void nseel_asm_equal_exact(void) { __asm__( FUNCTION_MARKER "fcompp\n" "fstsw %ax\n" // for equal 256 and 1024 should be clear, 16384 should be set "andl $17664, %eax\n" // mask C4/C3/C1, bits 8/10/14, 16384|256|1024 -- if equals 16384, then equality "cmp $16384, %eax\n" "je 0f\n" "subl %eax, %eax\n" "0:\n" FUNCTION_MARKER ); } void nseel_asm_equal_exact_end(void) {} void nseel_asm_notequal_exact(void) { __asm__( FUNCTION_MARKER "fcompp\n" "fstsw %ax\n" // for equal 256 and 1024 should be clear, 16384 should be set "andl $17664, %eax\n" // mask C4/C3/C1, bits 8/10/14, 16384|256|1024 -- if equals 16384, then equality "cmp $16384, %eax\n" "je 0f\n" "subl %eax, %eax\n" "0:\n" "xorl $16384, %eax\n" // flip the result FUNCTION_MARKER ); } void nseel_asm_notequal_exact_end(void) {} // //--------------------------------------------------------------------------------------------------------------- void nseel_asm_notequal(void) { __asm__( FUNCTION_MARKER #ifdef __clang__ "fsubp %st(1)\n" #else "fsub\n" #endif "fabs\n" #ifdef TARGET_X64 "fcomp" EEL_F_SUFFIX " -8(%r12)\n" //[g_closefact] #else "fcomp" EEL_F_SUFFIX " -8(%ebx)\n" //[g_closefact] #endif "fstsw %ax\n" "andl $256, %eax\n" "xorl $256, %eax\n" // old behavior: if 256 set, FALSE (NaN makes for false) FUNCTION_MARKER ); } void nseel_asm_notequal_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_above(void) { __asm__( FUNCTION_MARKER "fcompp\n" "fstsw %ax\n" "andl $1280, %eax\n" // (1024+256) old behavior: NaN would mean 1, preserve that FUNCTION_MARKER ); } void nseel_asm_above_end(void) {} //--------------------------------------------------------------------------------------------------------------- void nseel_asm_beloweq(void) { __asm__( FUNCTION_MARKER "fcompp\n" "fstsw %ax\n" "andl $256, %eax\n" // old behavior: NaN would be 0 (ugh) "xorl $256, %eax\n" FUNCTION_MARKER ); } void nseel_asm_beloweq_end(void) {} void nseel_asm_booltofp(void) { __asm__( FUNCTION_MARKER "testl %eax, %eax\n" "jz 0f\n" "fld1\n" "jmp 1f\n" "0:\n" "fldz\n" "1:\n" FUNCTION_MARKER ); } void nseel_asm_booltofp_end(void) {} void nseel_asm_fptobool(void) { __asm__( FUNCTION_MARKER "fabs\n" #ifdef TARGET_X64 "fcomp" EEL_F_SUFFIX " -8(%r12)\n" //[g_closefact] #else "fcomp" EEL_F_SUFFIX " -8(%ebx)\n" //[g_closefact] #endif "fstsw %ax\n" "andl $256, %eax\n" "xorl $256, %eax\n" FUNCTION_MARKER ); } void nseel_asm_fptobool_end(void) {} void nseel_asm_fptobool_rev(void) { __asm__( FUNCTION_MARKER "fabs\n" #ifdef TARGET_X64 "fcomp" EEL_F_SUFFIX " -8(%r12)\n" //[g_closefact] #else "fcomp" EEL_F_SUFFIX " -8(%ebx)\n" //[g_closefact] #endif "fstsw %ax\n" "andl $256, %eax\n" FUNCTION_MARKER ); } void nseel_asm_fptobool_rev_end(void) {} void nseel_asm_min(void) { __asm__( FUNCTION_MARKER "fld" EEL_F_SUFFIX " (%edi)\n" "fcomp" EEL_F_SUFFIX " (%eax)\n" "movl %eax, %ecx\n" "fstsw %ax\n" "testl $256, %eax\n" "movl %ecx, %eax\n" "jz 0f\n" "movl %edi, %eax\n" "0:\n" FUNCTION_MARKER ); } void nseel_asm_min_end(void) {} void nseel_asm_max(void) { __asm__( FUNCTION_MARKER "fld" EEL_F_SUFFIX " (%edi)\n" "fcomp" EEL_F_SUFFIX " (%eax)\n" "movl %eax, %ecx\n" "fstsw %ax\n" "testl $256, %eax\n" "movl %ecx, %eax\n" "jnz 0f\n" "movl %edi, %eax\n" "0:\n" FUNCTION_MARKER ); } void nseel_asm_max_end(void) {} void nseel_asm_min_fp(void) { __asm__( FUNCTION_MARKER "fcom\n" "fstsw %ax\n" "testl $256, %eax\n" "jz 0f\n" "fxch\n" "0:\n" "fstp %st(0)\n" FUNCTION_MARKER ); } void nseel_asm_min_fp_end(void) {} void nseel_asm_max_fp(void) { __asm__( FUNCTION_MARKER "fcom\n" "fstsw %ax\n" "testl $256, %eax\n" "jnz 0f\n" "fxch\n" "0:\n" "fstp %st(0)\n" FUNCTION_MARKER ); } void nseel_asm_max_fp_end(void) {} // just generic functions left, yay void _asm_generic3parm(void) { __asm__( FUNCTION_MARKER #ifdef TARGET_X64 #ifdef AMD64ABI "movl %rsi, %r15\n" "movl %rdi, %rdx\n" // third parameter = parm "movl $0xfefefefe, %rdi\n" // first parameter= context "movl %ecx, %rsi\n" // second parameter = parm "movl %rax, %rcx\n" // fourth parameter = parm "movl $0xfefefefe, %rax\n" // call function "call *%rax\n" "movl %r15, %rsi\n" #else "movl %ecx, %edx\n" // second parameter = parm "movl $0xfefefefe, %ecx\n" // first parameter= context "movl %rdi, %r8\n" // third parameter = parm "movl %rax, %r9\n" // fourth parameter = parm "movl $0xfefefefe, %edi\n" // call function "subl X64_EXTRA_STACK_SPACE, %rsp\n" "call *%edi\n" "addl X64_EXTRA_STACK_SPACE, %rsp\n" #endif #else "movl $0xfefefefe, %edx\n" "pushl %eax\n" // push parameter "pushl %edi\n" // push parameter "movl $0xfefefefe, %edi\n" "pushl %ecx\n" // push parameter "pushl %edx\n" // push context pointer "call *%edi\n" "addl $16, %esp\n" #endif FUNCTION_MARKER ); } void _asm_generic3parm_end(void) {} void _asm_generic3parm_retd(void) { __asm__( FUNCTION_MARKER #ifdef TARGET_X64 #ifdef AMD64ABI "movl %rsi, %r15\n" "movl %rdi, %rdx\n" // third parameter = parm "movl $0xfefefefe, %rdi\n" // first parameter= context "movl %ecx, %rsi\n" // second parameter = parm "movl %rax, %rcx\n" // fourth parameter = parm "movl $0xfefefefe, %rax\n" // call function "call *%rax\n" "movl %r15, %rsi\n" "movq xmm0, (%r15)\n" "fldl (%r15)\n" #else "movl %ecx, %edx\n" // second parameter = parm "movl $0xfefefefe, %ecx\n" // first parameter= context "movl %rdi, %r8\n" // third parameter = parm "movl %rax, %r9\n" // fourth parameter = parm "movl $0xfefefefe, %edi\n" // call function "subl X64_EXTRA_STACK_SPACE, %rsp\n" "call *%edi\n" "addl X64_EXTRA_STACK_SPACE, %rsp\n" "movq xmm0, (%rsi)\n" "fldl (%rsi)\n" #endif #else "subl $16, %esp\n" "movl $0xfefefefe, %edx\n" "movl %edi, 8(%esp)\n" "movl $0xfefefefe, %edi\n" "movl %eax, 12(%esp)\n" "movl %ecx, 4(%esp)\n" "movl %edx, (%esp)\n" "call *%edi\n" "addl $16, %esp\n" #endif FUNCTION_MARKER ); } void _asm_generic3parm_retd_end(void) {} void _asm_generic2parm(void) // this prob neds to be fixed for ppc { __asm__( FUNCTION_MARKER #ifdef TARGET_X64 #ifdef AMD64ABI "movl %rsi, %r15\n" "movl %edi, %esi\n" // second parameter = parm "movl $0xfefefefe, %edi\n" // first parameter= context "movl %rax, %rdx\n" // third parameter = parm "movl $0xfefefefe, %rcx\n" // call function "call *%rcx\n" "movl %r15, %rsi\n" #else "movl $0xfefefefe, %ecx\n" // first parameter= context "movl %edi, %edx\n" // second parameter = parm "movl %rax, %r8\n" // third parameter = parm "movl $0xfefefefe, %edi\n" // call function "subl X64_EXTRA_STACK_SPACE, %rsp\n" "call *%edi\n" "addl X64_EXTRA_STACK_SPACE, %rsp\n" #endif #else "movl $0xfefefefe, %edx\n" "movl $0xfefefefe, %ecx\n" "subl $4, %esp\n" // keep stack aligned "pushl %eax\n" // push parameter "pushl %edi\n" // push parameter "pushl %edx\n" // push context pointer "call *%ecx\n" "addl $16, %esp\n" #endif FUNCTION_MARKER ); } void _asm_generic2parm_end(void) {} void _asm_generic2parm_retd(void) { __asm__( FUNCTION_MARKER #ifdef TARGET_X64 #ifdef AMD64ABI "movl %rsi, %r15\n" "movl %rdi, %rsi\n" // second parameter = parm "movl $0xfefefefe, %rdi\n" // first parameter= context "movl $0xfefefefe, %rcx\n" // call function "movl %rax, %rdx\n" // third parameter = parm "call *%rcx\n" "movl %r15, %rsi\n" "movq xmm0, (%r15)\n" "fldl (%r15)\n" #else "movl %rdi, %rdx\n" // second parameter = parm "movl $0xfefefefe, %rcx\n" // first parameter= context "movl $0xfefefefe, %rdi\n" // call function "movl %rax, %r8\n" // third parameter = parm "subl X64_EXTRA_STACK_SPACE, %rsp\n" "call *%edi\n" "addl X64_EXTRA_STACK_SPACE, %rsp\n" "movq xmm0, (%rsi)\n" "fldl (%rsi)\n" #endif #else "subl $16, %esp\n" "movl $0xfefefefe, %edx\n" "movl $0xfefefefe, %ecx\n" "movl %edx, (%esp)\n" "movl %edi, 4(%esp)\n" "movl %eax, 8(%esp)\n" "call *%ecx\n" "addl $16, %esp\n" #endif FUNCTION_MARKER ); } void _asm_generic2parm_retd_end(void) {} void _asm_generic1parm(void) { __asm__( FUNCTION_MARKER #ifdef TARGET_X64 #ifdef AMD64ABI "movl $0xfefefefe, %rdi\n" // first parameter= context "movl %rsi, %r15\n" "movl %eax, %rsi\n" // second parameter = parm "movl $0xfefefefe, %rcx\n" // call function "call *%rcx\n" "movl %r15, %rsi\n" #else "movl $0xfefefefe, %ecx\n" // first parameter= context "movl %eax, %edx\n" // second parameter = parm "movl $0xfefefefe, %edi\n" // call function "subl X64_EXTRA_STACK_SPACE, %rsp\n" "call *%edi\n" "addl X64_EXTRA_STACK_SPACE, %rsp\n" #endif #else "movl $0xfefefefe, %edx\n" "subl $8, %esp\n" // keep stack aligned "movl $0xfefefefe, %ecx\n" "pushl %eax\n" // push parameter "pushl %edx\n" // push context pointer "call *%ecx\n" "addl $16, %esp\n" #endif FUNCTION_MARKER ); } void _asm_generic1parm_end(void) {} void _asm_generic1parm_retd(void) // 1 parameter returning double { __asm__( FUNCTION_MARKER #ifdef TARGET_X64 #ifdef AMD64ABI "movl $0xfefefefe, %rdi\n" // first parameter = context pointer "movl $0xfefefefe, %rcx\n" // function address "movl %rsi, %r15\n" // save rsi "movl %rax, %rsi\n" // second parameter = parameter "call *%rcx\n" "movl %r15, %rsi\n" "movq xmm0, (%r15)\n" "fldl (%r15)\n" #else "movl $0xfefefefe, %ecx\n" // first parameter= context "movl $0xfefefefe, %edi\n" // call function "movl %rax, %rdx\n" // second parameter = parm "subl X64_EXTRA_STACK_SPACE, %rsp\n" "call *%edi\n" "addl X64_EXTRA_STACK_SPACE, %rsp\n" "movq xmm0, (%rsi)\n" "fldl (%rsi)\n" #endif #else "movl $0xfefefefe, %edx\n" // context pointer "movl $0xfefefefe, %ecx\n" // func-addr "subl $16, %esp\n" "movl %eax, 4(%esp)\n" // push parameter "movl %edx, (%esp)\n" // push context pointer "call *%ecx\n" "addl $16, %esp\n" #endif FUNCTION_MARKER ); } void _asm_generic1parm_retd_end(void) {} // this gets its own stub because it's pretty crucial for performance :/ void _asm_megabuf(void) { __asm__( FUNCTION_MARKER #ifdef TARGET_X64 #ifdef AMD64ABI "fadd" EEL_F_SUFFIX " -8(%r12)\n" "fistpl (%rsi)\n" // check if (%rsi) is in range, and buffer available, otherwise call function "movl (%rsi), %edx\n" "cmpl %1, %rdx\n" //REPLACE=((NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK)) "jae 0f\n" "movll %rdx, %rax\n" "shrll %2, %rax\n" //REPLACE=(NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 3/*log2(sizeof(void *))*/ ) "andll %3, %rax\n" //REPLACE=((NSEEL_RAM_BLOCKS-1)*8 /*sizeof(void*)*/ ) "movll (%r12, %rax), %rax\n" "testl %rax, %rax\n" "jnz 1f\n" "0:\n" "movl $0xfefefefe, %rax\n" "movl %r12, %rdi\n" // set first parm to ctx "movl %rsi, %r15\n" // save rsi "movl %rdx, %esi\n" // esi becomes second parameter (edi is first, context pointer) "call *%rax\n" "movl %r15, %rsi\n" // restore rsi "jmp 2f\n" "1:\n" "andll %4, %rdx\n" //REPLACE=(NSEEL_RAM_ITEMSPERBLOCK-1) "shlll $3, %rdx\n" // 3 is log2(sizeof(EEL_F)) "addll %rdx, %rax\n" "2:\n" #else "fadd" EEL_F_SUFFIX " -8(%r12)\n" "fistpl (%rsi)\n" // check if (%rsi) is in range... "movl (%rsi), %edi\n" "cmpl %1, %edi\n" //REPLACE=((NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK)) "jae 0f\n" "movll %rdi, %rax\n" "shrll %2, %rax\n" //REPLACE=(NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 3/*log2(sizeof(void *))*/ ) "andll %3, %rax\n" //REPLACE=((NSEEL_RAM_BLOCKS-1)*8 /*sizeof(void*)*/ ) "movll (%r12, %rax), %rax\n" "testl %rax, %rax\n" "jnz 1f\n" "0:\n" "movl $0xfefefefe, %rax\n" // function ptr "movl %r12, %rcx\n" // set first parm to ctx "movl %rdi, %rdx\n" // rdx is second parameter (rcx is first) "subl X64_EXTRA_STACK_SPACE, %rsp\n" "call *%rax\n" "addl X64_EXTRA_STACK_SPACE, %rsp\n" "jmp 2f\n" "1:\n" "andll %4, %rdi\n" //REPLACE=(NSEEL_RAM_ITEMSPERBLOCK-1) "shlll $3, %rdi\n" // 3 is log2(sizeof(EEL_F)) "addll %rdi, %rax\n" "2:\n" #endif FUNCTION_MARKER #else "fadd" EEL_F_SUFFIX " -8(%%ebx)\n" "fistpl (%%esi)\n" // check if (%esi) is in range, and buffer available, otherwise call function "movl (%%esi), %%edi\n" "cmpl %0, %%edi\n" //REPLACE=((NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK)) "jae 0f\n" "movl %%edi, %%eax\n" "shrl %1, %%eax\n" //REPLACE=(NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 2/*log2(sizeof(void *))*/ ) "andl %2, %%eax\n" //REPLACE=((NSEEL_RAM_BLOCKS-1)*4 /*sizeof(void*)*/ ) "movl (%%ebx, %%eax), %%eax\n" "testl %%eax, %%eax\n" "jnz 1f\n" "0:\n" "subl $8, %%esp\n" // keep stack aligned "movl $0xfefefefe, %%ecx\n" "pushl %%edi\n" // parameter "pushl %%ebx\n" // push context pointer "call *%%ecx\n" "addl $16, %%esp\n" "jmp 2f\n" "1:\n" "andl %3, %%edi\n" //REPLACE=(NSEEL_RAM_ITEMSPERBLOCK-1) "shll $3, %%edi\n" // 3 is log2(sizeof(EEL_F)) "addl %%edi, %%eax\n" "2:" FUNCTION_MARKER #ifndef _MSC_VER :: "i" (((NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK))), "i" ((NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 2/*log2(sizeof(void *))*/ )), "i" (((NSEEL_RAM_BLOCKS-1)*4 /*sizeof(void*)*/ )), "i" ((NSEEL_RAM_ITEMSPERBLOCK-1 )) #endif #endif ); } void _asm_megabuf_end(void) {} void _asm_gmegabuf(void) { __asm__( FUNCTION_MARKER #ifdef TARGET_X64 #ifdef AMD64ABI "movl %rsi, %r15\n" "fadd" EEL_F_SUFFIX " -8(%r12)\n" "movl $0xfefefefe, %rdi\n" // first parameter = context pointer "fistpl (%rsi)\n" "movl $0xfefefefe, %edx\n" "movl (%rsi), %esi\n" "call *%rdx\n" "movl %r15, %rsi\n" #else "fadd" EEL_F_SUFFIX " -8(%r12)\n" "movl $0xfefefefe, %rcx\n" // first parameter = context pointer "fistpl (%rsi)\n" "movl $0xfefefefe, %rdi\n" "movl (%rsi), %edx\n" "subl X64_EXTRA_STACK_SPACE, %rsp\n" "call *%rdi\n" "addl X64_EXTRA_STACK_SPACE, %rsp\n" #endif #else "subl $16, %esp\n" // keep stack aligned "movl $0xfefefefe, (%esp)\n" "fadd" EEL_F_SUFFIX " -8(%ebx)\n" "movl $0xfefefefe, %edi\n" "fistpl 4(%esp)\n" "call *%edi\n" "addl $16, %esp\n" #endif FUNCTION_MARKER ); } void _asm_gmegabuf_end(void) {} void nseel_asm_stack_push(void) { #ifdef TARGET_X64 __asm__( FUNCTION_MARKER "movl $0xfefefefe, %rdi\n" "movll (%rax), %rcx\n" "movll (%rdi), %rax\n" "addll $8, %rax\n" "movl $0xFEFEFEFE, %rdx\n" "andll %rdx, %rax\n" "movl $0xFEFEFEFE, %rdx\n" "orll %rdx, %rax\n" "movll %rcx, (%rax)\n" "movll %rax, (%rdi)\n" FUNCTION_MARKER ); #else __asm__( FUNCTION_MARKER "movl $0xfefefefe, %edi\n" "movl (%eax), %ecx\n" "movl 4(%eax), %edx\n" "movl (%edi), %eax\n" "addl $8, %eax\n" "andl $0xfefefefe, %eax\n" "orl $0xfefefefe, %eax\n" "movl %ecx, (%eax)\n" "movl %edx, 4(%eax)\n" "movl %eax, (%edi)\n" FUNCTION_MARKER ); #endif } void nseel_asm_stack_push_end(void) {} void nseel_asm_stack_pop(void) { #ifdef TARGET_X64 __asm__( FUNCTION_MARKER "movl $0xfefefefe, %rdi\n" "movll (%rdi), %rcx\n" "movq (%rcx), %xmm0\n" "subll $8, %rcx\n" "movl $0xFEFEFEFE, %rdx\n" "andll %rdx, %rcx\n" "movl $0xFEFEFEFE, %rdx\n" "orll %rdx, %rcx\n" "movll %rcx, (%rdi)\n" "movq %xmm0, (%eax)\n" FUNCTION_MARKER ); #else __asm__( FUNCTION_MARKER "movl $0xfefefefe, %edi\n" "movl (%edi), %ecx\n" "fld" EEL_F_SUFFIX " (%ecx)\n" "subl $8, %ecx\n" "andl $0xfefefefe, %ecx\n" "orl $0xfefefefe, %ecx\n" "movl %ecx, (%edi)\n" "fstp" EEL_F_SUFFIX " (%eax)\n" FUNCTION_MARKER ); #endif } void nseel_asm_stack_pop_end(void) {} void nseel_asm_stack_pop_fast(void) { #ifdef TARGET_X64 __asm__( FUNCTION_MARKER "movl $0xfefefefe, %rdi\n" "movll (%rdi), %rcx\n" "movll %rcx, %rax\n" "subll $8, %rcx\n" "movl $0xFEFEFEFE, %rdx\n" "andll %rdx, %rcx\n" "movl $0xFEFEFEFE, %rdx\n" "orll %rdx, %rcx\n" "movll %rcx, (%rdi)\n" FUNCTION_MARKER ); #else __asm__( FUNCTION_MARKER "movl $0xfefefefe, %edi\n" "movl (%edi), %ecx\n" "movl %ecx, %eax\n" "subl $8, %ecx\n" "andl $0xfefefefe, %ecx\n" "orl $0xfefefefe, %ecx\n" "movl %ecx, (%edi)\n" FUNCTION_MARKER ); #endif } void nseel_asm_stack_pop_fast_end(void) {} void nseel_asm_stack_peek_int(void) { #ifdef TARGET_X64 __asm__( FUNCTION_MARKER "movll $0xfefefefe, %rdi\n" "movll (%rdi), %rax\n" "movl $0xfefefefe, %rdx\n" "subll %rdx, %rax\n" "movl $0xFEFEFEFE, %rdx\n" "andll %rdx, %rax\n" "movl $0xFEFEFEFE, %rdx\n" "orll %rdx, %rax\n" FUNCTION_MARKER ); #else __asm__( FUNCTION_MARKER "movl $0xfefefefe, %edi\n" "movl (%edi), %eax\n" "movl $0xfefefefe, %edx\n" "subl %edx, %eax\n" "andl $0xfefefefe, %eax\n" "orl $0xfefefefe, %eax\n" FUNCTION_MARKER ); #endif } void nseel_asm_stack_peek_int_end(void) {} void nseel_asm_stack_peek(void) { #ifdef TARGET_X64 __asm__( FUNCTION_MARKER "movll $0xfefefefe, %rdi\n" "fistpl (%rsi)\n" "movll (%rdi), %rax\n" "movll (%rsi), %rdx\n" "shll $3, %rdx\n" // log2(sizeof(EEL_F)) "subl %rdx, %rax\n" "movl $0xFEFEFEFE, %rdx\n" "andll %rdx, %rax\n" "movl $0xFEFEFEFE, %rdx\n" "orll %rdx, %rax\n" FUNCTION_MARKER ); #else __asm__( FUNCTION_MARKER "movl $0xfefefefe, %edi\n" "fistpl (%esi)\n" "movl (%edi), %eax\n" "movl (%esi), %edx\n" "shll $3, %edx\n" // log2(sizeof(EEL_F)) "subl %edx, %eax\n" "andl $0xfefefefe, %eax\n" "orl $0xfefefefe, %eax\n" FUNCTION_MARKER ); #endif } void nseel_asm_stack_peek_end(void) {} void nseel_asm_stack_peek_top(void) { #ifdef TARGET_X64 __asm__( FUNCTION_MARKER "movll $0xfefefefe, %rdi\n" "movll (%rdi), %rax\n" FUNCTION_MARKER ); #else __asm__( FUNCTION_MARKER "movl $0xfefefefe, %edi\n" "movl (%edi), %eax\n" FUNCTION_MARKER ); #endif } void nseel_asm_stack_peek_top_end(void) {} void nseel_asm_stack_exch(void) { #ifdef TARGET_X64 __asm__( FUNCTION_MARKER "movll $0xfefefefe, %rdi\n" "movll (%rdi), %rcx\n" "movq (%rcx), %xmm0\n" "movq (%rax), %xmm1\n" "movq %xmm0, (%rax)\n" "movq %xmm1, (%rcx)\n" FUNCTION_MARKER ); #else __asm__( FUNCTION_MARKER "movl $0xfefefefe, %edi\n" "movl (%edi), %ecx\n" "fld" EEL_F_SUFFIX " (%ecx)\n" "fld" EEL_F_SUFFIX " (%eax)\n" "fstp" EEL_F_SUFFIX " (%ecx)\n" "fstp" EEL_F_SUFFIX " (%eax)\n" FUNCTION_MARKER ); #endif } void nseel_asm_stack_exch_end(void) {} #ifdef TARGET_X64 void eel_callcode64() { __asm__( #ifndef EEL_X64_NO_CHANGE_FPFLAGS "subl $16, %rsp\n" "fnstcw (%rsp)\n" "mov (%rsp), %ax\n" "or $0xE3F, %ax\n" // 53 or 64 bit precision, trunc, and masking all exceptions "mov %ax, 4(%rsp)\n" "fldcw 4(%rsp)\n" #endif "push %rbx\n" "push %rbp\n" "push %r12\n" "push %r13\n" "push %r14\n" "push %r15\n" #ifdef AMD64ABI "movll %rsi, %r12\n" // second parameter is ram-blocks pointer "call %rdi\n" #else "push %rdi\n" "push %rsi\n" "movll %rdx, %r12\n" // second parameter is ram-blocks pointer "call %rcx\n" "pop %rsi\n" "pop %rdi\n" #endif "fclex\n" "pop %r15\n" "pop %r14\n" "pop %r13\n" "pop %r12\n" "pop %rbp\n" "pop %rbx\n" #ifndef EEL_X64_NO_CHANGE_FPFLAGS "fldcw (%rsp)\n" "addl $16, %rsp\n" #endif "ret\n" ); } void eel_setfp_round() { __asm__( #ifndef EEL_X64_NO_CHANGE_FPFLAGS "subl $16, %rsp\n" "fnstcw (%rsp)\n" "mov (%rsp), %ax\n" "and $0xF3FF, %ax\n" // set round to nearest "mov %ax, 4(%rsp)\n" "fldcw 4(%rsp)\n" "addl $16, %rsp\n" #endif "ret\n" ); } void eel_setfp_trunc() { __asm__( #ifndef EEL_X64_NO_CHANGE_FPFLAGS "subl $16, %rsp\n" "fnstcw (%rsp)\n" "mov (%rsp), %ax\n" "or $0xC00, %ax\n" // set to truncate "mov %ax, 4(%rsp)\n" "fldcw 4(%rsp)\n" "addl $16, %rsp\n" #endif "ret\n" ); } #endif jsusfx-0.4.0/src/WDL/eel2/asm-nseel-x86-msvc.c000066400000000000000000002003621353477307700205450ustar00rootroot00000000000000// THIS FILE AUTOGENERATED FROM asm-nseel-x86-gcc.c by a2i.php #if EEL_F_SIZE == 8 #define EEL_ASM_TYPE qword ptr #else #define EEL_ASM_TYPE dword ptr #endif /* note: only EEL_F_SIZE=8 is now supported (no float EEL_F's) */ #ifndef AMD64ABI #define X64_EXTRA_STACK_SPACE 32 // win32 requires allocating space for 4 parameters at 8 bytes each, even though we pass via register #endif __declspec(naked) void nseel_asm_1pdd(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov edi, 0xfefefefe; #ifdef TARGET_X64 fstp qword ptr [rsi]; movq xmm0, [rsi]; #ifdef AMD64ABI mov r15, rsi; call edi; mov rsi, r15; #else sub rsp, X64_EXTRA_STACK_SPACE; call edi; add rsp, X64_EXTRA_STACK_SPACE; #endif movq [rsi], xmm0; fld qword ptr [rsi]; #else sub esp, 16; fstp qword ptr [esp]; call edi; add esp, 16; #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_1pdd_end(void){} __declspec(naked) void nseel_asm_2pdd(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov edi, 0xfefefefe; #ifdef TARGET_X64 fstp qword ptr [rsi+8]; fstp qword ptr [rsi]; movq xmm1, [rsi+8]; movq xmm0, [rsi]; #ifdef AMD64ABI mov r15, rsi; call edi; mov rsi, r15; #else sub rsp, X64_EXTRA_STACK_SPACE; call edi; add rsp, X64_EXTRA_STACK_SPACE; #endif movq [rsi], xmm0; fld qword ptr [rsi]; #else sub esp, 16; fstp qword ptr [esp+8]; fstp qword ptr [esp]; call edi; add esp, 16; #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_2pdd_end(void){} __declspec(naked) void nseel_asm_2pdds(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov eax, 0xfefefefe; #ifdef TARGET_X64 fstp qword ptr [rsi]; movq xmm0, [rdi]; movq xmm1, [rsi]; #ifdef AMD64ABI mov r15, rsi; mov r14, rdi; call eax; mov rsi, r15; movq [r14], xmm0; mov rax, r14; /* set return value */ #else sub rsp, X64_EXTRA_STACK_SPACE; call eax; movq [edi], xmm0; mov eax, edi; /* set return value */ add rsp, X64_EXTRA_STACK_SPACE; #endif #else sub esp, 8; fstp qword ptr [esp]; push dword ptr [edi+4]; /* push parameter */ push dword ptr [edi]; /* push the rest of the parameter */ call eax; add esp, 16; fstp qword ptr [edi]; /* store result */ mov eax, edi; /* set return value */ #endif // denormal-fix result (this is only currently used for pow_op, so we want this!) mov edx, dword ptr [edi+4]; add edx, 0x00100000; and edx, 0x7FF00000; cmp edx, 0x00100000; jg label_0; sub edx, edx; #ifdef TARGET_X64 mov qword ptr [rdi], rdx; #else mov dword ptr [edi], edx; mov dword ptr [edi+4], edx; #endif label_0: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_2pdds_end(void){} //--------------------------------------------------------------------------------------------------------------- // do nothing, eh __declspec(naked) void nseel_asm_exec2(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_exec2_end(void) { } __declspec(naked) void nseel_asm_invsqrt(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov edx, 0x5f3759df; fst dword ptr [esi]; #ifdef TARGET_X64 mov rax, 0xfefefefe; fmul EEL_ASM_TYPE [rax]; movsx rcx, dword ptr [esi]; #else #if EEL_F_SIZE == 8 _emit 0xDC; // fmul qword ptr [0xfefefefe] _emit 0x0D; _emit 0xFE; _emit 0xFE; _emit 0xFE; _emit 0xFE; #else _emit 0xD8; // fmul dword ptr [0xfefefefe] _emit 0x0D; _emit 0xFE; _emit 0xFE; _emit 0xFE; _emit 0xFE; #endif mov ecx, dword ptr [esi]; #endif sar ecx, 1; sub edx, ecx; mov dword ptr [esi], edx; fmul dword ptr [esi]; fmul dword ptr [esi]; #ifdef TARGET_X64 mov rax, 0xfefefefe; fadd EEL_ASM_TYPE [rax]; #else #if EEL_F_SIZE == 8 _emit 0xDC; // fadd qword ptr [0xfefefefe] _emit 0x05; _emit 0xFE; _emit 0xFE; _emit 0xFE; _emit 0xFE; #else _emit 0xD8; // fadd dword ptr [0xfefefefe] _emit 0x05; _emit 0xFE; _emit 0xFE; _emit 0xFE; _emit 0xFE; #endif #endif fmul dword ptr [esi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_invsqrt_end(void) {} __declspec(naked) void nseel_asm_dbg_getstackptr(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef __clang__ ffree st(0); #else fstp st(0); #endif mov dword ptr [esi], esp; fild dword ptr [esi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_dbg_getstackptr_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_sin(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fsin; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_sin_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_cos(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fcos; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_cos_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_tan(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fptan; fstp st(0); _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_tan_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_sqr(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fmul st(0), st(0); _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_sqr_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_sqrt(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fabs; fsqrt; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_sqrt_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_log(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fldln2; fxch; fyl2x; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_log_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_log10(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fldlg2; fxch; fyl2x; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_log10_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_abs(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fabs; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_abs_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_assign(void) { #ifdef TARGET_X64 __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov rdx, qword ptr [rax]; mov rcx, rdx; shr rdx, 32; add edx, 0x00100000; and edx, 0x7FF00000; cmp edx, 0x00100000; mov rax, rdi; jg label_1; sub ecx, ecx; label_1: mov qword ptr [edi], rcx; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #else __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov ecx, dword ptr [eax]; mov edx, dword ptr [eax+4]; mov eax, edx; add eax, 0x00100000; // if exponent is zero, make exponent 0x7ff, if 7ff, make 7fe and eax, 0x7ff00000; cmp eax, 0x00100000; jg label_2; sub ecx, ecx; sub edx, edx; label_2: mov eax, edi; mov dword ptr [edi], ecx; mov dword ptr [edi+4], edx; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #endif } __declspec(naked) void nseel_asm_assign_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_assign_fromfp(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fstp qword ptr [edi]; mov edx, dword ptr [edi+4]; add edx, 0x00100000; and edx, 0x7FF00000; cmp edx, 0x00100000; mov eax, edi; jg label_3; sub edx, edx; #ifdef TARGET_X64 mov qword ptr [rdi], rdx; #else mov dword ptr [edi], edx; mov dword ptr [edi+4], edx; #endif label_3: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_assign_fromfp_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_assign_fast_fromfp(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov eax, edi; fstp qword ptr [edi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_assign_fast_fromfp_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_assign_fast(void) { #ifdef TARGET_X64 __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov rdx, qword ptr [rax]; mov qword ptr [edi], rdx; mov rax, rdi; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #else __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov ecx, dword ptr [eax]; mov dword ptr [edi], ecx; mov ecx, dword ptr [eax+4]; mov eax, edi; mov dword ptr [edi+4], ecx; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #endif } __declspec(naked) void nseel_asm_assign_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_add(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef __clang__ faddp st(1); #else fadd; #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_add_end(void) {} __declspec(naked) void nseel_asm_add_op(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fadd EEL_ASM_TYPE [edi]; mov eax, edi; fstp EEL_ASM_TYPE [edi]; mov edx, dword ptr [edi+4]; add edx, 0x00100000; and edx, 0x7FF00000; cmp edx, 0x00100000; jg label_4; sub edx, edx; #ifdef TARGET_X64 mov qword ptr [rdi], rdx; #else mov dword ptr [edi], edx; mov dword ptr [edi+4], edx; #endif label_4: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_add_op_end(void) {} __declspec(naked) void nseel_asm_add_op_fast(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fadd EEL_ASM_TYPE [edi]; mov eax, edi; fstp EEL_ASM_TYPE [edi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_add_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_sub(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef __clang__ fsubrp st(1), st(0); #else #ifdef __GNUC__ #ifdef __INTEL_COMPILER fsub; #else fsubr; // gnuc has fsub/fsubr backwards, ack #endif #else fsub; #endif #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_sub_end(void) {} __declspec(naked) void nseel_asm_sub_op(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fsubr EEL_ASM_TYPE [edi]; mov eax, edi; fstp EEL_ASM_TYPE [edi]; mov edx, dword ptr [edi+4]; add edx, 0x00100000; and edx, 0x7FF00000; cmp edx, 0x00100000; jg label_5; sub edx, edx; #ifdef TARGET_X64 mov qword ptr [rdi], rdx; #else mov dword ptr [edi], edx; mov dword ptr [edi+4], edx; #endif label_5: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_sub_op_end(void) {} __declspec(naked) void nseel_asm_sub_op_fast(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fsubr EEL_ASM_TYPE [edi]; mov eax, edi; fstp EEL_ASM_TYPE [edi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_sub_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_mul(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef __clang__ fmulp st(1), st(0); #else fmul; #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_mul_end(void) {} __declspec(naked) void nseel_asm_mul_op(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fmul EEL_ASM_TYPE [edi]; mov eax, edi; fstp EEL_ASM_TYPE [edi]; mov edx, dword ptr [edi+4]; add edx, 0x00100000; and edx, 0x7FF00000; cmp edx, 0x00100000; jg label_6; sub edx, edx; #ifdef TARGET_X64 mov qword ptr [rdi], rdx; #else mov dword ptr [edi], edx; mov dword ptr [edi+4], edx; #endif label_6: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_mul_op_end(void) {} __declspec(naked) void nseel_asm_mul_op_fast(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fmul EEL_ASM_TYPE [edi]; mov eax, edi; fstp EEL_ASM_TYPE [edi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_mul_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_div(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef __clang__ fdivrp st(1); #else #ifdef __GNUC__ #ifdef __INTEL_COMPILER fdiv; #else fdivr; // gcc inline asm seems to have fdiv/fdivr backwards #endif #else fdiv; #endif #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_div_end(void) {} __declspec(naked) void nseel_asm_div_op(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fld EEL_ASM_TYPE [edi]; #ifdef __clang__ fdivp st(1); #else #ifndef __GNUC__ fdivr; #else #ifdef __INTEL_COMPILER fdivp st(1); #else fdiv; #endif #endif #endif mov eax, edi; fstp EEL_ASM_TYPE [edi]; mov edx, dword ptr [edi+4]; add edx, 0x00100000; and edx, 0x7FF00000; cmp edx, 0x00100000; jg label_7; sub edx, edx; #ifdef TARGET_X64 mov qword ptr [rdi], rdx; #else mov dword ptr [edi], edx; mov dword ptr [edi+4], edx; #endif label_7: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_div_op_end(void) {} __declspec(naked) void nseel_asm_div_op_fast(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fld EEL_ASM_TYPE [edi]; #ifdef __clang__ fdivp st(1); #else #ifndef __GNUC__ fdivr; #else #ifdef __INTEL_COMPILER fdivp st(1); #else fdiv; #endif #endif #endif mov eax, edi; fstp EEL_ASM_TYPE [edi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_div_op_fast_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_mod(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fabs; fistp dword ptr [esi]; fabs; fistp dword ptr [esi+4]; xor edx, edx; cmp dword ptr [esi], 0; je label_8; // skip devide, set return to 0 mov eax, dword ptr [esi+4]; div dword ptr [esi]; label_8: mov dword ptr [esi], edx; fild dword ptr [esi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_mod_end(void) {} __declspec(naked) void nseel_asm_shl(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fistp dword ptr [esi]; fistp dword ptr [esi+4]; mov ecx, dword ptr [esi]; mov eax, dword ptr [esi+4]; shl eax, cl; mov dword ptr [esi], eax; fild dword ptr [esi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_shl_end(void) {} __declspec(naked) void nseel_asm_shr(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fistp dword ptr [esi]; fistp dword ptr [esi+4]; mov ecx, dword ptr [esi]; mov eax, dword ptr [esi+4]; sar eax, cl; mov dword ptr [esi], eax; fild dword ptr [esi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_shr_end(void) {} __declspec(naked) void nseel_asm_mod_op(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fld EEL_ASM_TYPE [edi]; fxch; fabs; fistp dword ptr [edi]; fabs; fistp dword ptr [esi]; xor edx, edx; cmp dword ptr [edi], 0; je label_9; // skip devide, set return to 0 mov eax, dword ptr [esi]; div dword ptr [edi]; label_9: mov dword ptr [edi], edx; fild dword ptr [edi]; mov eax, edi; fstp EEL_ASM_TYPE [edi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_mod_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_or(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fistp qword ptr [esi]; fistp qword ptr [esi+8]; #ifdef TARGET_X64 mov rdi, qword ptr [rsi+8]; or qword ptr [rsi], rdi; #else mov edi, dword ptr [esi+8]; mov ecx, dword ptr [esi+12]; or dword ptr [esi], edi; or dword ptr [esi+4], ecx; #endif fild qword ptr [esi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_or_end(void) {} __declspec(naked) void nseel_asm_or0(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fistp qword ptr [esi]; fild qword ptr [esi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_or0_end(void) {} __declspec(naked) void nseel_asm_or_op(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fld EEL_ASM_TYPE [edi]; fxch; fistp qword ptr [edi]; fistp qword ptr [esi]; #ifdef TARGET_X64 mov rax, qword ptr [rsi]; or qword ptr [rdi], rax; #else mov eax, dword ptr [esi]; mov ecx, dword ptr [esi+4]; or dword ptr [edi], eax; or dword ptr [edi+4], ecx; #endif fild qword ptr [edi]; mov eax, edi; fstp EEL_ASM_TYPE [edi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_or_op_end(void) {} __declspec(naked) void nseel_asm_xor(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fistp qword ptr [esi]; fistp qword ptr [esi+8]; #ifdef TARGET_X64 mov rdi, qword ptr [rsi+8]; xor qword ptr [rsi], rdi; #else mov edi, dword ptr [esi+8]; mov ecx, dword ptr [esi+12]; xor dword ptr [esi], edi; xor dword ptr [esi+4], ecx; #endif fild qword ptr [esi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_xor_end(void) {} __declspec(naked) void nseel_asm_xor_op(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fld EEL_ASM_TYPE [edi]; fxch; fistp qword ptr [edi]; fistp qword ptr [esi]; #ifdef TARGET_X64 mov rax, qword ptr [rsi]; xor qword ptr [rdi], rax; #else mov eax, dword ptr [esi]; mov ecx, dword ptr [esi+4]; xor dword ptr [edi], eax; xor dword ptr [edi+4], ecx; #endif fild qword ptr [edi]; mov eax, edi; fstp EEL_ASM_TYPE [edi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_xor_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_and(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fistp qword ptr [esi]; fistp qword ptr [esi+8]; #ifdef TARGET_X64 mov rdi, qword ptr [rsi+8]; and qword ptr [rsi], rdi; #else mov edi, dword ptr [esi+8]; mov ecx, dword ptr [esi+12]; and dword ptr [esi], edi; and dword ptr [esi+4], ecx; #endif fild qword ptr [esi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_and_end(void) {} __declspec(naked) void nseel_asm_and_op(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fld EEL_ASM_TYPE [edi]; fxch; fistp qword ptr [edi]; fistp qword ptr [esi]; #ifdef TARGET_X64 mov rax, qword ptr [rsi]; and qword ptr [rdi], rax; #else mov eax, dword ptr [esi]; mov ecx, dword ptr [esi+4]; and dword ptr [edi], eax; and dword ptr [edi+4], ecx; #endif fild qword ptr [edi]; mov eax, edi; fstp EEL_ASM_TYPE [edi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_and_op_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_uplus(void) // this is the same as doing nothing, it seems { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_uplus_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_uminus(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fchs; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_uminus_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_sign(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef TARGET_X64 fst EEL_ASM_TYPE [rsi]; mov rdx, EEL_ASM_TYPE [rsi]; mov rcx, 0x7FFFFFFFFFFFFFFF; test rdx, rcx; jz label_10; // zero zero, return the value passed directly // calculate sign inc rcx; // rcx becomes 0x80000... fstp st(0); fld1; test rdx, rcx; jz label_10; fchs; label_10: #else fst dword ptr [esi]; mov ecx, dword ptr [esi]; mov edx, 0x7FFFFFFF; test ecx, edx; jz label_11; // zero zero, return the value passed directly // calculate sign inc edx; // edx becomes 0x8000... fstp st(0); fld1; test ecx, edx; jz label_11; fchs; label_11: #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_sign_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_bnot(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; test eax, eax; setz al; and eax, 0xff; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_bnot_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_fcall(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov edx, 0xfefefefe; #ifdef TARGET_X64 sub esp, 8; call edx; add esp, 8; #else sub esp, 12; /* keep stack 16 byte aligned, 4 bytes for return address */ call edx; add esp, 12; #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_fcall_end(void) {} __declspec(naked) void nseel_asm_band(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; test eax, eax; jz label_12; mov ecx, 0xfefefefe; #ifdef TARGET_X64 sub rsp, 8; #else sub esp, 12; #endif call ecx; #ifdef TARGET_X64 add rsp, 8; #else add esp, 12; #endif label_12: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_band_end(void) {} __declspec(naked) void nseel_asm_bor(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; test eax, eax; jnz label_13; mov ecx, 0xfefefefe; #ifdef TARGET_X64 sub rsp, 8; #else sub esp, 12; #endif call ecx; #ifdef TARGET_X64 add rsp, 8; #else add esp, 12; #endif label_13: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_bor_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_equal(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef __clang__ fsubp st(1); #else fsub; #endif fabs; #ifdef TARGET_X64 fcomp EEL_ASM_TYPE [r12+-8]; //[g_closefact] #else fcomp EEL_ASM_TYPE [ebx+-8]; //[g_closefact] #endif fstsw ax; and eax, 256; // old behavior: if 256 set, true (NaN means true) _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_equal_end(void) {} // //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_equal_exact(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fcompp; fstsw ax; // for equal 256 and 1024 should be clear, 16384 should be set and eax, 17664; // mask C4/C3/C1, bits 8/10/14, 16384|256|1024 -- if equals 16384, then equality cmp eax, 16384; je label_14; sub eax, eax; label_14: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_equal_exact_end(void) {} __declspec(naked) void nseel_asm_notequal_exact(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fcompp; fstsw ax; // for equal 256 and 1024 should be clear, 16384 should be set and eax, 17664; // mask C4/C3/C1, bits 8/10/14, 16384|256|1024 -- if equals 16384, then equality cmp eax, 16384; je label_15; sub eax, eax; label_15: xor eax, 16384; // flip the result _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_notequal_exact_end(void) {} // //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_notequal(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef __clang__ fsubp st(1); #else fsub; #endif fabs; #ifdef TARGET_X64 fcomp EEL_ASM_TYPE [r12+-8]; //[g_closefact] #else fcomp EEL_ASM_TYPE [ebx+-8]; //[g_closefact] #endif fstsw ax; and eax, 256; xor eax, 256; // old behavior: if 256 set, FALSE (NaN makes for false) _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_notequal_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_above(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fcompp; fstsw ax; and eax, 1280; // (1024+256) old behavior: NaN would mean 1, preserve that _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_above_end(void) {} //--------------------------------------------------------------------------------------------------------------- __declspec(naked) void nseel_asm_beloweq(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fcompp; fstsw ax; and eax, 256; // old behavior: NaN would be 0 (ugh) xor eax, 256; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_beloweq_end(void) {} __declspec(naked) void nseel_asm_booltofp(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; test eax, eax; jz label_16; fld1; jmp label_17; label_16: fldz; label_17: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_booltofp_end(void) {} __declspec(naked) void nseel_asm_fptobool(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fabs; #ifdef TARGET_X64 fcomp EEL_ASM_TYPE [r12+-8]; //[g_closefact] #else fcomp EEL_ASM_TYPE [ebx+-8]; //[g_closefact] #endif fstsw ax; and eax, 256; xor eax, 256; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_fptobool_end(void) {} __declspec(naked) void nseel_asm_fptobool_rev(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fabs; #ifdef TARGET_X64 fcomp EEL_ASM_TYPE [r12+-8]; //[g_closefact] #else fcomp EEL_ASM_TYPE [ebx+-8]; //[g_closefact] #endif fstsw ax; and eax, 256; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_fptobool_rev_end(void) {} __declspec(naked) void nseel_asm_min(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fld EEL_ASM_TYPE [edi]; fcomp EEL_ASM_TYPE [eax]; mov ecx, eax; fstsw ax; test eax, 256; mov eax, ecx; jz label_18; mov eax, edi; label_18: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_min_end(void) {} __declspec(naked) void nseel_asm_max(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fld EEL_ASM_TYPE [edi]; fcomp EEL_ASM_TYPE [eax]; mov ecx, eax; fstsw ax; test eax, 256; mov eax, ecx; jnz label_19; mov eax, edi; label_19: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_max_end(void) {} __declspec(naked) void nseel_asm_min_fp(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fcom; fstsw ax; test eax, 256; jz label_20; fxch; label_20: fstp st(0); _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_min_fp_end(void) {} __declspec(naked) void nseel_asm_max_fp(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; fcom; fstsw ax; test eax, 256; jnz label_21; fxch; label_21: fstp st(0); _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void nseel_asm_max_fp_end(void) {} // just generic functions left, yay __declspec(naked) void _asm_generic3parm(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef TARGET_X64 #ifdef AMD64ABI mov r15, rsi; mov rdx, rdi; // third parameter = parm mov rdi, 0xfefefefe; // first parameter= context mov rsi, ecx; // second parameter = parm mov rcx, rax; // fourth parameter = parm mov rax, 0xfefefefe; // call function call rax; mov rsi, r15; #else mov edx, ecx; // second parameter = parm mov ecx, 0xfefefefe; // first parameter= context mov r8, rdi; // third parameter = parm mov r9, rax; // fourth parameter = parm mov edi, 0xfefefefe; // call function sub rsp, X64_EXTRA_STACK_SPACE; call edi; add rsp, X64_EXTRA_STACK_SPACE; #endif #else mov edx, 0xfefefefe; push eax; // push parameter push edi; // push parameter mov edi, 0xfefefefe; push ecx; // push parameter push edx; // push context pointer call edi; add esp, 16; #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void _asm_generic3parm_end(void) {} __declspec(naked) void _asm_generic3parm_retd(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef TARGET_X64 #ifdef AMD64ABI mov r15, rsi; mov rdx, rdi; // third parameter = parm mov rdi, 0xfefefefe; // first parameter= context mov rsi, ecx; // second parameter = parm mov rcx, rax; // fourth parameter = parm mov rax, 0xfefefefe; // call function call rax; mov rsi, r15; movq [r15], xmm0; fld qword ptr [r15]; #else mov edx, ecx; // second parameter = parm mov ecx, 0xfefefefe; // first parameter= context mov r8, rdi; // third parameter = parm mov r9, rax; // fourth parameter = parm mov edi, 0xfefefefe; // call function sub rsp, X64_EXTRA_STACK_SPACE; call edi; add rsp, X64_EXTRA_STACK_SPACE; movq [rsi], xmm0; fld qword ptr [rsi]; #endif #else sub esp, 16; mov edx, 0xfefefefe; mov dword ptr [esp+8], edi; mov edi, 0xfefefefe; mov dword ptr [esp+12], eax; mov dword ptr [esp+4], ecx; mov dword ptr [esp], edx; call edi; add esp, 16; #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void _asm_generic3parm_retd_end(void) {} __declspec(naked) void _asm_generic2parm(void) // this prob neds to be fixed for ppc { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef TARGET_X64 #ifdef AMD64ABI mov r15, rsi; mov esi, edi; // second parameter = parm mov edi, 0xfefefefe; // first parameter= context mov rdx, rax; // third parameter = parm mov rcx, 0xfefefefe; // call function call rcx; mov rsi, r15; #else mov ecx, 0xfefefefe; // first parameter= context mov edx, edi; // second parameter = parm mov r8, rax; // third parameter = parm mov edi, 0xfefefefe; // call function sub rsp, X64_EXTRA_STACK_SPACE; call edi; add rsp, X64_EXTRA_STACK_SPACE; #endif #else mov edx, 0xfefefefe; mov ecx, 0xfefefefe; sub esp, 4; // keep stack aligned push eax; // push parameter push edi; // push parameter push edx; // push context pointer call ecx; add esp, 16; #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void _asm_generic2parm_end(void) {} __declspec(naked) void _asm_generic2parm_retd(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef TARGET_X64 #ifdef AMD64ABI mov r15, rsi; mov rsi, rdi; // second parameter = parm mov rdi, 0xfefefefe; // first parameter= context mov rcx, 0xfefefefe; // call function mov rdx, rax; // third parameter = parm call rcx; mov rsi, r15; movq [r15], xmm0; fld qword ptr [r15]; #else mov rdx, rdi; // second parameter = parm mov rcx, 0xfefefefe; // first parameter= context mov rdi, 0xfefefefe; // call function mov r8, rax; // third parameter = parm sub rsp, X64_EXTRA_STACK_SPACE; call edi; add rsp, X64_EXTRA_STACK_SPACE; movq [rsi], xmm0; fld qword ptr [rsi]; #endif #else sub esp, 16; mov edx, 0xfefefefe; mov ecx, 0xfefefefe; mov dword ptr [esp], edx; mov dword ptr [esp+4], edi; mov dword ptr [esp+8], eax; call ecx; add esp, 16; #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void _asm_generic2parm_retd_end(void) {} __declspec(naked) void _asm_generic1parm(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef TARGET_X64 #ifdef AMD64ABI mov rdi, 0xfefefefe; // first parameter= context mov r15, rsi; mov rsi, eax; // second parameter = parm mov rcx, 0xfefefefe; // call function call rcx; mov rsi, r15; #else mov ecx, 0xfefefefe; // first parameter= context mov edx, eax; // second parameter = parm mov edi, 0xfefefefe; // call function sub rsp, X64_EXTRA_STACK_SPACE; call edi; add rsp, X64_EXTRA_STACK_SPACE; #endif #else mov edx, 0xfefefefe; sub esp, 8; // keep stack aligned mov ecx, 0xfefefefe; push eax; // push parameter push edx; // push context pointer call ecx; add esp, 16; #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void _asm_generic1parm_end(void) {} __declspec(naked) void _asm_generic1parm_retd(void) // 1 parameter returning double { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef TARGET_X64 #ifdef AMD64ABI mov rdi, 0xfefefefe; // first parameter = context pointer mov rcx, 0xfefefefe; // function address mov r15, rsi; // save rsi mov rsi, rax; // second parameter = parameter call rcx; mov rsi, r15; movq [r15], xmm0; fld qword ptr [r15]; #else mov ecx, 0xfefefefe; // first parameter= context mov edi, 0xfefefefe; // call function mov rdx, rax; // second parameter = parm sub rsp, X64_EXTRA_STACK_SPACE; call edi; add rsp, X64_EXTRA_STACK_SPACE; movq [rsi], xmm0; fld qword ptr [rsi]; #endif #else mov edx, 0xfefefefe; // context pointer mov ecx, 0xfefefefe; // func-addr sub esp, 16; mov dword ptr [esp+4], eax; // push parameter mov dword ptr [esp], edx; // push context pointer call ecx; add esp, 16; #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void _asm_generic1parm_retd_end(void) {} // this gets its own stub because it's pretty crucial for performance :/ __declspec(naked) void _asm_megabuf(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef TARGET_X64 #ifdef AMD64ABI fadd EEL_ASM_TYPE [r12+-8]; fistp dword ptr [rsi]; // check if (%rsi) is in range, and buffer available, otherwise call function mov edx, dword ptr [rsi]; cmp rdx, ((NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK)); //REPLACE=((NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK)) jae label_22; mov rax, rdx; shr rax, (NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 3/*log2(sizeof(void *))*/ ); //REPLACE=(NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 3/*log2(sizeof(void *))*/ ) and rax, ((NSEEL_RAM_BLOCKS-1)*8 /*sizeof(void*)*/ ); //REPLACE=((NSEEL_RAM_BLOCKS-1)*8 /*sizeof(void*)*/ ) mov rax, qword ptr [r12+rax]; test rax, rax; jnz label_23; label_22: mov rax, 0xfefefefe; mov rdi, r12; // set first parm to ctx mov r15, rsi; // save rsi mov esi, rdx; // esi becomes second parameter (edi is first, context pointer) call rax; mov rsi, r15; // restore rsi jmp label_24; label_23: and rdx, (NSEEL_RAM_ITEMSPERBLOCK-1); //REPLACE=(NSEEL_RAM_ITEMSPERBLOCK-1) shl rdx, 3; // 3 is log2(sizeof(EEL_F)) add rax, rdx; label_24: #else fadd EEL_ASM_TYPE [r12+-8]; fistp dword ptr [rsi]; // check if (%rsi) is in range... mov edi, dword ptr [rsi]; cmp edi, ((NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK)); //REPLACE=((NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK)) jae label_25; mov rax, rdi; shr rax, (NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 3/*log2(sizeof(void *))*/ ); //REPLACE=(NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 3/*log2(sizeof(void *))*/ ) and rax, ((NSEEL_RAM_BLOCKS-1)*8 /*sizeof(void*)*/ ); //REPLACE=((NSEEL_RAM_BLOCKS-1)*8 /*sizeof(void*)*/ ) mov rax, qword ptr [r12+rax]; test rax, rax; jnz label_26; label_25: mov rax, 0xfefefefe; // function ptr mov rcx, r12; // set first parm to ctx mov rdx, rdi; // rdx is second parameter (rcx is first) sub rsp, X64_EXTRA_STACK_SPACE; call rax; add rsp, X64_EXTRA_STACK_SPACE; jmp label_27; label_26: and rdi, (NSEEL_RAM_ITEMSPERBLOCK-1); //REPLACE=(NSEEL_RAM_ITEMSPERBLOCK-1) shl rdi, 3; // 3 is log2(sizeof(EEL_F)) add rax, rdi; label_27: #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #else fadd EEL_ASM_TYPE [ebx+-8]; fistp dword ptr [esi]; // check if (%esi) is in range, and buffer available, otherwise call function mov edi, dword ptr [esi]; cmp edi, ((NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK)); //REPLACE=((NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK)) jae label_28; mov eax, edi; shr eax, (NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 2/*log2(sizeof(void *))*/ ); //REPLACE=(NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 2/*log2(sizeof(void *))*/ ) and eax, ((NSEEL_RAM_BLOCKS-1)*4 /*sizeof(void*)*/ ); //REPLACE=((NSEEL_RAM_BLOCKS-1)*4 /*sizeof(void*)*/ ) mov eax, dword ptr [ebx+eax]; test eax, eax; jnz label_29; label_28: sub esp, 8; // keep stack aligned mov ecx, 0xfefefefe; push edi; // parameter push ebx; // push context pointer call ecx; add esp, 16; jmp label_30; label_29: and edi, (NSEEL_RAM_ITEMSPERBLOCK-1); //REPLACE=(NSEEL_RAM_ITEMSPERBLOCK-1) shl edi, 3; // 3 is log2(sizeof(EEL_F)) add eax, edi; label_30: _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifndef _MSC_VER :: i; (((NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK))), i; ((NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 2/*log2(sizeof(void *))*/ )), i; (((NSEEL_RAM_BLOCKS-1)*4 /*sizeof(void*)*/ )), i; ((NSEEL_RAM_ITEMSPERBLOCK-1 )) #endif #endif } } __declspec(naked) void _asm_megabuf_end(void) {} __declspec(naked) void _asm_gmegabuf(void) { __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; #ifdef TARGET_X64 #ifdef AMD64ABI mov r15, rsi; fadd EEL_ASM_TYPE [r12+-8]; mov rdi, 0xfefefefe; // first parameter = context pointer fistp dword ptr [rsi]; mov edx, 0xfefefefe; mov esi, dword ptr [rsi]; call rdx; mov rsi, r15; #else fadd EEL_ASM_TYPE [r12+-8]; mov rcx, 0xfefefefe; // first parameter = context pointer fistp dword ptr [rsi]; mov rdi, 0xfefefefe; mov edx, dword ptr [rsi]; sub rsp, X64_EXTRA_STACK_SPACE; call rdi; add rsp, X64_EXTRA_STACK_SPACE; #endif #else sub esp, 16; // keep stack aligned mov dword ptr [esp], 0xfefefefe; fadd EEL_ASM_TYPE [ebx+-8]; mov edi, 0xfefefefe; fistp dword ptr [esp+4]; call edi; add esp, 16; #endif _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } } __declspec(naked) void _asm_gmegabuf_end(void) {} __declspec(naked) void nseel_asm_stack_push(void) { #ifdef TARGET_X64 __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov rdi, 0xfefefefe; mov rcx, qword ptr [rax]; mov rax, qword ptr [rdi]; add rax, 8; mov rdx, 0xFEFEFEFE; and rax, rdx; mov rdx, 0xFEFEFEFE; or rax, rdx; mov qword ptr [rax], rcx; mov qword ptr [rdi], rax; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #else __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov edi, 0xfefefefe; mov ecx, dword ptr [eax]; mov edx, dword ptr [eax+4]; mov eax, dword ptr [edi]; add eax, 8; and eax, 0xfefefefe; or eax, 0xfefefefe; mov dword ptr [eax], ecx; mov dword ptr [eax+4], edx; mov dword ptr [edi], eax; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #endif } __declspec(naked) void nseel_asm_stack_push_end(void) {} __declspec(naked) void nseel_asm_stack_pop(void) { #ifdef TARGET_X64 __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov rdi, 0xfefefefe; mov rcx, qword ptr [rdi]; movq xmm0, [rcx]; sub rcx, 8; mov rdx, 0xFEFEFEFE; and rcx, rdx; mov rdx, 0xFEFEFEFE; or rcx, rdx; mov qword ptr [rdi], rcx; movq [eax], xmm0; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #else __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov edi, 0xfefefefe; mov ecx, dword ptr [edi]; fld EEL_ASM_TYPE [ecx]; sub ecx, 8; and ecx, 0xfefefefe; or ecx, 0xfefefefe; mov dword ptr [edi], ecx; fstp EEL_ASM_TYPE [eax]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #endif } __declspec(naked) void nseel_asm_stack_pop_end(void) {} __declspec(naked) void nseel_asm_stack_pop_fast(void) { #ifdef TARGET_X64 __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov rdi, 0xfefefefe; mov rcx, qword ptr [rdi]; mov rax, rcx; sub rcx, 8; mov rdx, 0xFEFEFEFE; and rcx, rdx; mov rdx, 0xFEFEFEFE; or rcx, rdx; mov qword ptr [rdi], rcx; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #else __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov edi, 0xfefefefe; mov ecx, dword ptr [edi]; mov eax, ecx; sub ecx, 8; and ecx, 0xfefefefe; or ecx, 0xfefefefe; mov dword ptr [edi], ecx; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #endif } __declspec(naked) void nseel_asm_stack_pop_fast_end(void) {} __declspec(naked) void nseel_asm_stack_peek_int(void) { #ifdef TARGET_X64 __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov rdi, 0xfefefefe; mov rax, qword ptr [rdi]; mov rdx, 0xfefefefe; sub rax, rdx; mov rdx, 0xFEFEFEFE; and rax, rdx; mov rdx, 0xFEFEFEFE; or rax, rdx; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #else __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov edi, 0xfefefefe; mov eax, dword ptr [edi]; mov edx, 0xfefefefe; sub eax, edx; and eax, 0xfefefefe; or eax, 0xfefefefe; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #endif } __declspec(naked) void nseel_asm_stack_peek_int_end(void) {} __declspec(naked) void nseel_asm_stack_peek(void) { #ifdef TARGET_X64 __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov rdi, 0xfefefefe; fistp dword ptr [rsi]; mov rax, qword ptr [rdi]; mov rdx, qword ptr [rsi]; shl rdx, 3; // log2(sizeof(EEL_F)) sub rax, rdx; mov rdx, 0xFEFEFEFE; and rax, rdx; mov rdx, 0xFEFEFEFE; or rax, rdx; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #else __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov edi, 0xfefefefe; fistp dword ptr [esi]; mov eax, dword ptr [edi]; mov edx, dword ptr [esi]; shl edx, 3; // log2(sizeof(EEL_F)) sub eax, edx; and eax, 0xfefefefe; or eax, 0xfefefefe; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #endif } __declspec(naked) void nseel_asm_stack_peek_end(void) {} __declspec(naked) void nseel_asm_stack_peek_top(void) { #ifdef TARGET_X64 __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov rdi, 0xfefefefe; mov rax, qword ptr [rdi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #else __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov edi, 0xfefefefe; mov eax, dword ptr [edi]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #endif } __declspec(naked) void nseel_asm_stack_peek_top_end(void) {} __declspec(naked) void nseel_asm_stack_exch(void) { #ifdef TARGET_X64 __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov rdi, 0xfefefefe; mov rcx, qword ptr [rdi]; movq xmm0, [rcx]; movq xmm1, [rax]; movq [rax], xmm0; movq [rcx], xmm1; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #else __asm { _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; mov edi, 0xfefefefe; mov ecx, dword ptr [edi]; fld EEL_ASM_TYPE [ecx]; fld EEL_ASM_TYPE [eax]; fstp EEL_ASM_TYPE [ecx]; fstp EEL_ASM_TYPE [eax]; _emit 0x89; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; _emit 0x90; } #endif } __declspec(naked) void nseel_asm_stack_exch_end(void) {} #ifdef TARGET_X64 __declspec(naked) void eel_callcode64() { __asm { #ifndef EEL_X64_NO_CHANGE_FPFLAGS sub rsp, 16; fnstcw [rsp]; mov ax, [rsp]; or ax, 0xE3F; // 53 or 64 bit precision, trunc, and masking all exceptions mov [rsp+4], ax; fldcw [rsp+4]; #endif push rbx; push rbp; push r12; push r13; push r14; push r15; #ifdef AMD64ABI mov r12, rsi; // second parameter is ram-blocks pointer call rdi; #else push rdi; push rsi; mov r12, rdx; // second parameter is ram-blocks pointer call rcx; pop rsi; pop rdi; #endif fclex; pop r15; pop r14; pop r13; pop r12; pop rbp; pop rbx; #ifndef EEL_X64_NO_CHANGE_FPFLAGS fldcw [rsp]; add rsp, 16; #endif ret; } } __declspec(naked) void eel_setfp_round() { __asm { #ifndef EEL_X64_NO_CHANGE_FPFLAGS sub rsp, 16; fnstcw [rsp]; mov ax, [rsp]; and ax, 0xF3FF; // set round to nearest mov [rsp+4], ax; fldcw [rsp+4]; add rsp, 16; #endif ret; } } __declspec(naked) void eel_setfp_trunc() { __asm { #ifndef EEL_X64_NO_CHANGE_FPFLAGS sub rsp, 16; fnstcw [rsp]; mov ax, [rsp]; or ax, 0xC00; // set to truncate mov [rsp+4], ax; fldcw [rsp+4]; add rsp, 16; #endif ret; } } #endif jsusfx-0.4.0/src/WDL/eel2/eel2.l000066400000000000000000000061551353477307700161340ustar00rootroot00000000000000%option reentrant %option prefix="nseel" %option bison-bridge %option bison-locations %option noyywrap %option never-interactive %option batch %option nounput %{ #include #include #define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_FATAL_ERROR(msg) { ((struct yyguts_t*)yyscanner)->yyextra_r->errVar=1; } #define YY_INPUT(buf,result,max_size) { (result) = nseel_gets(yyextra,(buf),max_size); } #define YY_EXTRA_TYPE compileContext * #undef YY_BUF_SIZE #define YY_BUF_SIZE (NSEEL_MAX_VARIABLE_NAMELEN*2) #undef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE (NSEEL_MAX_VARIABLE_NAMELEN) #include "y.tab.h" #ifdef _WIN32 #define YY_NO_UNISTD_H #endif #include "ns-eel-int.h" int nseel_gets(compileContext *ctx, char *buf, size_t sz); #define PARSENUM *yylval = nseel_translate(yyextra,yytext, 0); return VALUE; #define EEL_ACTION(x) return x; #ifdef stdin #undef stdin #endif #define stdin (0) #ifdef stdout #undef stdout #endif #define stdout (0) static int g_fake_errno; #ifdef errno #undef errno #endif #define errno g_fake_errno static void comment(yyscan_t yyscanner); %} %% [0-9]+\.?[0-9]* PARSENUM; \.[0-9]+ PARSENUM; 0[xX][0-9a-fA-F]* PARSENUM; \$[xX][0-9a-fA-F]* PARSENUM; \$\~[0-9]* PARSENUM; \$[Ee] PARSENUM; \$[Pp][Ii] PARSENUM; \$[Pp][Hh][Ii] PARSENUM; \$\'.\' PARSENUM; \#[a-zA-Z0-9\._]* *yylval = nseel_translate(yyextra,yytext, 0); return STRING_IDENTIFIER; \<\< return TOKEN_SHL; \>\> return TOKEN_SHR; \<= return TOKEN_LTE; \>= return TOKEN_GTE; == return TOKEN_EQ; === return TOKEN_EQ_EXACT; \!= return TOKEN_NE; \!== return TOKEN_NE_EXACT; \&\& return TOKEN_LOGICAL_AND; \|\| return TOKEN_LOGICAL_OR; \+= return TOKEN_ADD_OP; -= return TOKEN_SUB_OP; %= return TOKEN_MOD_OP; \|= return TOKEN_OR_OP; \&= return TOKEN_AND_OP; \~= return TOKEN_XOR_OP; \/= return TOKEN_DIV_OP; \*= return TOKEN_MUL_OP; \^= return TOKEN_POW_OP; [a-zA-Z_][a-zA-Z0-9\._]* &yylval = nseel_createCompiledValuePtr((compileContext *)yyextra, NULL, yytext); return IDENTIFIER; [ \t\r\n]+ /* whitespace */ \/\/.*$ /* comment */ "/*" { comment(yyscanner); } . return (int)yytext[0]; %% static void comment(yyscan_t yyscanner) { int c,lc=0; while (0 != (c = input(yyscanner))) { if (c == '/' && lc == '*') return; lc = c; } // end of file, ignore for now } jsusfx-0.4.0/src/WDL/eel2/eel2.vim000066400000000000000000000462521353477307700164760ustar00rootroot00000000000000" Vim syntax file " This needs a lot of C-specific stuff removed, please help if you care =) " Language: EEL2, based on: " " " Language: C - Maintainer: Bram Moolenaar - Last Change: 2009 Nov 17 " Quit when a (custom) syntax file was already loaded if exists("b:current_syntax") finish endif " A bunch of useful C keywords syn keyword cStatement function globals global local instance syn keyword cRepeat while loop syn keyword cRepeat sin cos tan sqrt log log10 asin acos atan atan2 exp abs sqr min max sign rand floor ceil invsqrt freembuf memcpy memset stack_psuh stack_pop stack_peek stack_exch syn keyword cRepeat atomic_setifequal atomic_exch atomic_add atomic_set atomic_get convolve_c fft ifft fft_permute fft_ipermute fopen fread fgets fgetc fwrite fprintf fseek ftell feof fflush fclose syn keyword cRepeat gfx_lineto gfx_lineto gfx_rectto gfx_rect gfx_line gfx_gradrect gfx_muladdrect gfx_deltablit gfx_transformblit gfx_blurto gfx_drawnumber gfx_drawchar gfx_drawstr gfx_measurestr gfx_printf gfx_setpixel gfx_getpixel gfx_getimgdim gfx_setimgdim gfx_loadimg gfx_blit gfx_blitext gfx_blit gfx_setfont gfx_getfont gfx_init gfx_quit gfx_getchar syn keyword cRepeat mdct imdct sleep time time_precise tcp_listen tcp_listen_end tcp_connect tcp_send tcp_recv tcp_set_block tcp_close strlen syn keyword cRepeat strcat strcpy strcmp stricmp strncat strncpy strncmp strnicmp str_setlen strcpy_from strcpy_substr strcpy_substr str_getchar str_setchar str_getchar str_setchar str_insert str_delsub sprintf printf match matchi syn keyword cTodo contained TODO FIXME XXX " It's easy to accidentally add a space after a backslash that was intended " for line continuation. Some compilers allow it, which makes it " unpredicatable and should be avoided. syn match cBadContinuation contained "\\\s\+$" " cCommentGroup allows adding matches for special things in comments syn cluster cCommentGroup contains=cTodo,cBadContinuation " String and Character constants " Highlight special characters (those which have a backslash) differently syn match cSpecial display contained "\\\(x\x\+\|\o\{1,3}\|.\|$\)" if !exists("c_no_utf") syn match cSpecial display contained "\\\(u\x\{4}\|U\x\{8}\)" endif if exists("c_no_cformat") syn region cString start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial,@Spell " cCppString: same as cString, but ends at end of line syn region cCppString start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=cSpecial,@Spell else if !exists("c_no_c99") " ISO C99 syn match cFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlLjzt]\|ll\|hh\)\=\([aAbdiuoxXDOUfFeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained else syn match cFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlL]\|ll\)\=\([bdiuoxXDOUfeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained endif syn match cFormat display "%%" contained syn region cString start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial,cFormat,@Spell " cCppString: same as cString, but ends at end of line syn region cCppString start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=cSpecial,cFormat,@Spell endif syn match cCharacter "L\='[^\\]'" syn match cCharacter "L'[^']*'" contains=cSpecial syn match cCharacter "'[^']*'" contains=cSpecial if exists("c_gnu") syn match cSpecialError "L\='\\[^'\"?\\abefnrtv]'" syn match cSpecialCharacter "L\='\\['\"?\\abefnrtv]'" else syn match cSpecialError "L\='\\[^'\"?\\abfnrtv]'" syn match cSpecialCharacter "L\='\\['\"?\\abfnrtv]'" endif syn match cSpecialCharacter display "L\='\\\o\{1,3}'" syn match cSpecialCharacter display "'\\x\x\{1,2}'" syn match cSpecialCharacter display "L'\\x\x\+'" "when wanted, highlight trailing white space if exists("c_space_errors") if !exists("c_no_trail_space_error") syn match cSpaceError display excludenl "\s\+$" endif if !exists("c_no_tab_space_error") syn match cSpaceError display " \+\t"me=e-1 endif endif " This should be before cErrInParen to avoid problems with #define ({ xxx }) if exists("c_curly_error") syntax match cCurlyError "}" syntax region cBlock start="{" end="}" contains=ALLBUT,cCurlyError,@cParenGroup,cErrInParen,cCppParen,cErrInBracket,cCppBracket,cCppString,@Spell fold else syntax region cBlock start="{" end="}" transparent fold endif "catch errors caused by wrong parenthesis and brackets " also accept <% for {, %> for }, <: for [ and :> for ] (C99) " But avoid matching <::. syn cluster cParenGroup contains=cParenError,cIncluded,cSpecial,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUserCont,cUserLabel,cOctalZero,cCppOut,cCppOut2,cCppSkip,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom if exists("c_no_curly_error") syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cCppString,@Spell " cCppParen: same as cParen but ends at end-of-line; used in cDefine syn region cCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cParen,cString,@Spell syn match cParenError display ")" syn match cErrInParen display contained "^[{}]\|^<%\|^%>" elseif exists("c_no_bracket_error") syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cCppString,@Spell " cCppParen: same as cParen but ends at end-of-line; used in cDefine syn region cCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cParen,cString,@Spell syn match cParenError display ")" syn match cErrInParen display contained "[{}]\|<%\|%>" else syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cErrInBracket,cCppBracket,cCppString,@Spell " cCppParen: same as cParen but ends at end-of-line; used in cDefine syn region cCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cErrInBracket,cParen,cBracket,cString,@Spell syn match cParenError display "[\])]" syn match cErrInParen display contained "[\]{}]\|<%\|%>" syn region cBracket transparent start='\[\|<::\@!' end=']\|:>' contains=ALLBUT,@cParenGroup,cErrInParen,cCppParen,cCppBracket,cCppString,@Spell " cCppBracket: same as cParen but ends at end-of-line; used in cDefine syn region cCppBracket transparent start='\[\|<::\@!' skip='\\$' excludenl end=']\|:>' end='$' contained contains=ALLBUT,@cParenGroup,cErrInParen,cParen,cBracket,cString,@Spell syn match cErrInBracket display contained "[){}]\|<%\|%>" endif "integer number, or floating point number without a dot and with "f". syn case ignore syn match cNumbers display transparent "\<\d\|\.\d" contains=cNumber,cFloat,cOctalError,cOctal " Same, but without octal error (for comments) syn match cNumbersCom display contained transparent "\<\d\|\.\d" contains=cNumber,cFloat,cOctal syn match cNumber display contained "\d\+\(u\=l\{0,2}\|ll\=u\)\>" "hex number syn match cNumber display contained "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>" " Flag the first zero of an octal number as something special syn match cOctal display contained "0\o\+\(u\=l\{0,2}\|ll\=u\)\>" contains=cOctalZero syn match cOctalZero display contained "\<0" syn match cFloat display contained "\d\+f" "floating point number, with dot, optional exponent syn match cFloat display contained "\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=" "floating point number, starting with a dot, optional exponent syn match cFloat display contained "\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>" "floating point number, without dot, with exponent syn match cFloat display contained "\d\+e[-+]\=\d\+[fl]\=\>" if !exists("c_no_c99") "hexadecimal floating point number, optional leading digits, with dot, with exponent syn match cFloat display contained "0x\x*\.\x\+p[-+]\=\d\+[fl]\=\>" "hexadecimal floating point number, with leading digits, optional dot, with exponent syn match cFloat display contained "0x\x\+\.\=p[-+]\=\d\+[fl]\=\>" endif " flag an octal number with wrong digits syn match cOctalError display contained "0\o*[89]\d*" syn case match if exists("c_comment_strings") " A comment can contain cString, cCharacter and cNumber. " But a "*/" inside a cString in a cComment DOES end the comment! So we " need to use a special type of cString: cCommentString, which also ends on " "*/", and sees a "*" at the start of the line as comment again. " Unfortunately this doesn't very well work for // type of comments :-( syntax match cCommentSkip contained "^\s*\*\($\|\s\+\)" syntax region cCommentString contained start=+L\=\\\@" skip="\\$" end="$" keepend contains=cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError syn match cPreCondit display "^\s*\(%:\|#\)\s*\(else\|endif\)\>" if !exists("c_no_if0") if !exists("c_no_if0_fold") syn region cCppOut start="^\s*\(%:\|#\)\s*if\s\+0\+\>" end=".\@=\|$" contains=cCppOut2 fold else syn region cCppOut start="^\s*\(%:\|#\)\s*if\s\+0\+\>" end=".\@=\|$" contains=cCppOut2 endif syn region cCppOut2 contained start="0" end="^\s*\(%:\|#\)\s*\(endif\>\|else\>\|elif\>\)" contains=cSpaceError,cCppSkip syn region cCppSkip contained start="^\s*\(%:\|#\)\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\(%:\|#\)\s*endif\>" contains=cSpaceError,cCppSkip endif syn region cIncluded display contained start=+"+ skip=+\\\\\|\\"+ end=+"+ syn match cIncluded display contained "<[^>]*>" syn match cInclude display "^\s*\(%:\|#\)\s*include\>\s*["<]" contains=cIncluded "syn match cLineSkip "\\$" syn cluster cPreProcGroup contains=cPreCondit,cIncluded,cInclude,cDefine,cErrInParen,cErrInBracket,cUserLabel,cSpecial,cOctalZero,cCppOut,cCppOut2,cCppSkip,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom,cString,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cParen,cBracket,cMulti syn region cDefine start="^\s*\(%:\|#\)\s*\(define\|undef\)\>" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell syn region cPreProc start="^\s*\(%:\|#\)\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell " Highlight User Labels syn cluster cMultiGroup contains=cIncluded,cSpecial,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUserCont,cUserLabel,cOctalZero,cCppOut,cCppOut2,cCppSkip,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom,cCppParen,cCppBracket,cCppString syn region cMulti transparent start='?' skip='::' end=':' end=')' end=';' contains=ALLBUT,@cMultiGroup,@Spell " Avoid matching foo::bar() in C++ by requiring that the next char is not ':' syn match cUserLabel display "\I\i*" contained if exists("c_minlines") let b:c_minlines = c_minlines else if !exists("c_no_if0") let b:c_minlines = 50 " #if 0 constructs can be long else let b:c_minlines = 15 " mostly for () constructs endif endif if exists("c_curly_error") syn sync fromstart else exec "syn sync ccomment cComment minlines=" . b:c_minlines endif " Define the default highlighting. " Only used when an item doesn't have highlighting yet hi def link cFormat cSpecial hi def link cCppString cString hi def link cCommentL cComment hi def link cCommentStart cComment hi def link cUserLabel Label hi def link cRepeat Repeat hi def link cCharacter Character hi def link cSpecialCharacter cSpecial hi def link cNumber Number hi def link cOctal Number hi def link cOctalZero PreProc " link this to Error if you want hi def link cFloat Float hi def link cOctalError cError hi def link cParenError cError hi def link cErrInParen cError hi def link cErrInBracket cError hi def link cCommentError cError hi def link cCommentStartError cError hi def link cSpaceError cError hi def link cSpecialError cError hi def link cCurlyError cError hi def link cOperator Operator hi def link cStructure Structure hi def link cStorageClass StorageClass hi def link cInclude Include hi def link cPreProc PreProc hi def link cDefine Macro hi def link cIncluded cString hi def link cError Error hi def link cStatement Statement hi def link cPreCondit PreCondit hi def link cType Type hi def link cConstant Constant hi def link cCommentString cString hi def link cComment2String cString hi def link cCommentSkip cComment hi def link cString String hi def link cComment Comment hi def link cSpecial SpecialChar hi def link cTodo Todo hi def link cBadContinuation Error hi def link cCppSkip cCppOut hi def link cCppOut2 cCppOut hi def link cCppOut Comment let b:current_syntax = "eel2" " vim: ts=8 jsusfx-0.4.0/src/WDL/eel2/eel2.y000066400000000000000000000230321353477307700161420ustar00rootroot00000000000000%pure-parser %name-prefix="nseel" %parse-param { compileContext* context } %lex-param { void* scanner } /* this will prevent y.tab.c from ever calling yydestruct(), since we do not use it and it is a waste */ %destructor { #define yydestruct(a,b,c,d,e) } VALUE %{ #ifdef _WIN32 #include #endif #include #include #include #include #include "y.tab.h" #include "ns-eel-int.h" #define scanner context->scanner #define YY_(x) ("") %} %token VALUE IDENTIFIER TOKEN_SHL TOKEN_SHR %token TOKEN_LTE TOKEN_GTE TOKEN_EQ TOKEN_EQ_EXACT TOKEN_NE TOKEN_NE_EXACT TOKEN_LOGICAL_AND TOKEN_LOGICAL_OR %token TOKEN_ADD_OP TOKEN_SUB_OP TOKEN_MOD_OP TOKEN_OR_OP TOKEN_AND_OP TOKEN_XOR_OP TOKEN_DIV_OP TOKEN_MUL_OP TOKEN_POW_OP %token STRING_LITERAL STRING_IDENTIFIER %expect 75 %start program %% more_params: expression | expression ',' more_params { $$ = nseel_createMoreParametersOpcode(context,$1,$3); } ; string: STRING_LITERAL | STRING_LITERAL string { ((struct eelStringSegmentRec *)$1)->_next = (struct eelStringSegmentRec *)$2; $$ = $1; } ; assignable_value: IDENTIFIER { if (!($$ = nseel_resolve_named_symbol(context, $1, -1, NULL))) /* convert from purely named to namespace-relative, etc */ { yyerror(&yyloc, context, ""); YYERROR; } } /* we used to have VALUE in here rather than rvalue, to allow 1=1 1+=2 etc, but silly to, though this breaks Vmorph, which does 1=1 for a nop, and Jonas DrumReaplacer, which does x = 0 = y = 0 */ | '(' expression ')' { $$ = $2; } | IDENTIFIER '(' expression ')' '(' expression ')' { int err; if (!($$ = nseel_setCompiledFunctionCallParameters(context,$1, $3, 0, 0, $6, &err))) { if (err == -1) yyerror(&yylsp[-2], context, ""); else if (err == 0) yyerror(&yylsp[-6], context, ""); else yyerror(&yylsp[-3], context, ""); // parameter count wrong YYERROR; } } | IDENTIFIER '(' expression ')' { int err; if (!($$ = nseel_setCompiledFunctionCallParameters(context,$1, $3, 0, 0, 0, &err))) { if (err == 0) yyerror(&yylsp[-3], context, ""); else yyerror(&yylsp[0], context, ""); // parameter count wrong YYERROR; } } | IDENTIFIER '(' ')' { int err; if (!($$ = nseel_setCompiledFunctionCallParameters(context,$1, nseel_createCompiledValue(context,0.0), 0, 0, 0,&err))) { if (err == 0) yyerror(&yylsp[-2], context, ""); // function not found else yyerror(&yylsp[0], context, ""); // parameter count wrong YYERROR; } } | IDENTIFIER '(' expression ',' expression ')' { int err; if (!($$ = nseel_setCompiledFunctionCallParameters(context,$1, $3, $5, 0, 0,&err))) { if (err == 0) yyerror(&yylsp[-5], context, ""); else if (err == 2) yyerror(&yylsp[0], context, ""); // needs more than 2 parameters else yyerror(&yylsp[-2], context, ""); // less than 2 YYERROR; } } | IDENTIFIER '(' expression ',' expression ',' more_params ')' { int err; if (!($$ = nseel_setCompiledFunctionCallParameters(context,$1, $3, $5, $7, 0, &err))) { if (err == 0) yyerror(&yylsp[-7], context, ""); else if (err==2) yyerror(&yylsp[0], context, ""); // needs more parameters else if (err==4) yyerror(&yylsp[-4], context, ""); // needs single parameter else yyerror(&yylsp[-2], context, ""); // less parm YYERROR; } } | rvalue '[' ']' { $$ = nseel_createMemoryAccess(context,$1,0); } | rvalue '[' expression ']' { $$ = nseel_createMemoryAccess(context,$1,$3); } ; rvalue: VALUE | STRING_IDENTIFIER | string { $$ = nseel_eelMakeOpcodeFromStringSegments(context,(struct eelStringSegmentRec *)$1); } | assignable_value ; assignment: rvalue | assignable_value '=' if_else_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_ASSIGN,2,$1,$3); } | assignable_value TOKEN_ADD_OP if_else_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_ADD_OP,2,$1,$3); } | assignable_value TOKEN_SUB_OP if_else_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_SUB_OP,2,$1,$3); } | assignable_value TOKEN_MOD_OP if_else_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_MOD_OP,2,$1,$3); } | assignable_value TOKEN_OR_OP if_else_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_OR_OP,2,$1,$3); } | assignable_value TOKEN_AND_OP if_else_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_AND_OP,2,$1,$3); } | assignable_value TOKEN_XOR_OP if_else_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_XOR_OP,2,$1,$3); } | assignable_value TOKEN_DIV_OP if_else_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_DIV_OP,2,$1,$3); } | assignable_value TOKEN_MUL_OP if_else_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_MUL_OP,2,$1,$3); } | assignable_value TOKEN_POW_OP if_else_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_POW_OP,2,$1,$3); } | STRING_IDENTIFIER '=' if_else_expr { $$ = nseel_createFunctionByName(context,"strcpy",2,$1,$3,NULL); } | STRING_IDENTIFIER TOKEN_ADD_OP if_else_expr { $$ = nseel_createFunctionByName(context,"strcat",2,$1,$3,NULL); } ; unary_expr: assignment | '+' unary_expr { $$ = $2; } | '-' unary_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_UMINUS,1,$2,0); } | '!' unary_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_NOT,1,$2,0); } ; pow_expr: unary_expr | pow_expr '^' unary_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_POW,2,$1,$3); } ; mod_expr: pow_expr | mod_expr '%' pow_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_MOD,2,$1,$3); } | mod_expr TOKEN_SHL pow_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_SHL,2,$1,$3); } | mod_expr TOKEN_SHR pow_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_SHR,2,$1,$3); } ; div_expr: mod_expr | div_expr '/' mod_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_DIVIDE,2,$1,$3); } ; mul_expr: div_expr | mul_expr '*' div_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_MULTIPLY,2,$1,$3); } ; sub_expr: mul_expr | sub_expr '-' mul_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_SUB,2,$1,$3); } ; add_expr: sub_expr | add_expr '+' sub_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_ADD,2,$1,$3); } ; andor_expr: add_expr | andor_expr '&' add_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_AND,2,$1,$3); } | andor_expr '|' add_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_OR,2,$1,$3); } | andor_expr '~' add_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_XOR,2,$1,$3); } ; cmp_expr: andor_expr | cmp_expr '<' andor_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_LT,2,$1,$3); } | cmp_expr '>' andor_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_GT,2,$1,$3); } | cmp_expr TOKEN_LTE andor_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_LTE,2,$1,$3); } | cmp_expr TOKEN_GTE andor_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_GTE,2,$1,$3); } | cmp_expr TOKEN_EQ andor_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_EQ,2,$1,$3); } | cmp_expr TOKEN_EQ_EXACT andor_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_EQ_EXACT,2,$1,$3); } | cmp_expr TOKEN_NE andor_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_NE,2,$1,$3); } | cmp_expr TOKEN_NE_EXACT andor_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_NE_EXACT,2,$1,$3); } ; logical_and_or_expr: cmp_expr | logical_and_or_expr TOKEN_LOGICAL_AND cmp_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_LOGICAL_AND,2,$1,$3); } | logical_and_or_expr TOKEN_LOGICAL_OR cmp_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_LOGICAL_OR,2,$1,$3); } ; if_else_expr: logical_and_or_expr | logical_and_or_expr '?' if_else_expr ':' if_else_expr { $$ = nseel_createIfElse(context, $1, $3, $5); } | logical_and_or_expr '?' ':' if_else_expr { $$ = nseel_createIfElse(context, $1, 0, $4); } | logical_and_or_expr '?' if_else_expr { $$ = nseel_createIfElse(context, $1, $3, 0); } ; expression: if_else_expr | expression ';' if_else_expr { $$ = nseel_createSimpleCompiledFunction(context,FN_JOIN_STATEMENTS,2,$1,$3); } | expression ';' { $$ = $1; } ; program: expression { if (@1.first_line) { } context->result = $1; } ; %% jsusfx-0.4.0/src/WDL/eel2/eel_atomic.h000066400000000000000000000033311353477307700173730ustar00rootroot00000000000000#ifndef __EEL_ATOMIC_H__ #define __EEL_ATOMIC_H__ // requires these to be defined //#define EEL_ATOMIC_SET_SCOPE(opaque) WDL_Mutex *mutex = (opaque?&((effectProcessor *)opaque)->m_atomic_mutex:&atomic_mutex); //#define EEL_ATOMIC_ENTER mutex->Enter() //#define EEL_ATOMIC_LEAVE mutex->Leave() static EEL_F NSEEL_CGEN_CALL atomic_setifeq(void *opaque, EEL_F *a, EEL_F *cmp, EEL_F *nd) { EEL_F ret; EEL_ATOMIC_SET_SCOPE(opaque) EEL_ATOMIC_ENTER; ret = *a; if (fabs(ret - *cmp) < NSEEL_CLOSEFACTOR) *a = *nd; EEL_ATOMIC_LEAVE; return ret; } static EEL_F NSEEL_CGEN_CALL atomic_exch(void *opaque, EEL_F *a, EEL_F *b) { EEL_F tmp; EEL_ATOMIC_SET_SCOPE(opaque) EEL_ATOMIC_ENTER; tmp = *b; *b = *a; *a = tmp; EEL_ATOMIC_LEAVE; return tmp; } static EEL_F NSEEL_CGEN_CALL atomic_add(void *opaque, EEL_F *a, EEL_F *b) { EEL_F tmp; EEL_ATOMIC_SET_SCOPE(opaque) EEL_ATOMIC_ENTER; tmp = (*a += *b); EEL_ATOMIC_LEAVE; return tmp; } static EEL_F NSEEL_CGEN_CALL atomic_set(void *opaque, EEL_F *a, EEL_F *b) { EEL_F tmp; EEL_ATOMIC_SET_SCOPE(opaque) EEL_ATOMIC_ENTER; tmp = *a = *b; EEL_ATOMIC_LEAVE; return tmp; } static EEL_F NSEEL_CGEN_CALL atomic_get(void *opaque, EEL_F *a) { EEL_F tmp; EEL_ATOMIC_SET_SCOPE(opaque) EEL_ATOMIC_ENTER; tmp = *a; EEL_ATOMIC_LEAVE; return tmp; } static void EEL_atomic_register() { NSEEL_addfunc_retval("atomic_setifequal",3, NSEEL_PProc_THIS, &atomic_setifeq); NSEEL_addfunc_retval("atomic_exch",2, NSEEL_PProc_THIS, &atomic_exch); NSEEL_addfunc_retval("atomic_add",2, NSEEL_PProc_THIS, &atomic_add); NSEEL_addfunc_retval("atomic_set",2, NSEEL_PProc_THIS, &atomic_set); NSEEL_addfunc_retval("atomic_get",1, NSEEL_PProc_THIS, &atomic_get); } #endif jsusfx-0.4.0/src/WDL/eel2/eel_eval.h000066400000000000000000000026001353477307700170440ustar00rootroot00000000000000#ifndef _EEL_EVAL_H_ #define _EEL_EVAL_H_ #ifndef EEL_EVAL_GET_CACHED #define EEL_EVAL_GET_CACHED(str, ch) (NULL) #endif #ifndef EEL_EVAL_SET_CACHED #define EEL_EVAL_SET_CACHED(sv, ch) { NSEEL_code_free(ch); free(sv); } #endif static EEL_F NSEEL_CGEN_CALL _eel_eval(void *opaque, EEL_F *s) { NSEEL_VMCTX r = EEL_EVAL_GET_VMCTX(opaque); NSEEL_CODEHANDLE ch = NULL; char *sv=NULL; if (r) { EEL_STRING_MUTEXLOCK_SCOPE const char *str=EEL_STRING_GET_FOR_INDEX(*s,NULL); #ifdef EEL_STRING_DEBUGOUT if (!str) { EEL_STRING_DEBUGOUT("eval() passed invalid string handle %f",*s); } #endif if (str && *str) { sv=EEL_EVAL_GET_CACHED(str,ch); if (!sv) sv=strdup(str); } } if (sv) { if (!ch) ch = NSEEL_code_compile(r,sv,0); if (ch) { NSEEL_code_execute(ch); EEL_EVAL_SET_CACHED(sv,ch); return 1.0; } else { #ifdef EEL_STRING_DEBUGOUT const char *err=NSEEL_code_getcodeerror(r); if (err) EEL_STRING_DEBUGOUT("eval() error: %s",err); #endif } free(sv); } return 0.0; } void EEL_eval_register() { NSEEL_addfunc_retval("eval",1,NSEEL_PProc_THIS,&_eel_eval); } #ifdef EEL_WANT_DOCUMENTATION static const char *eel_eval_function_reference = "eval\t\"code\"\tExecutes code passed in. Code can use functions, but functions created in code can't be used elsewhere.\0" ; #endif #endif jsusfx-0.4.0/src/WDL/eel2/eel_fft.h000066400000000000000000000267011353477307700167040ustar00rootroot00000000000000#ifndef __EEL_FFT_H_ #define __EEL_FFT_H_ #include "../fft.h" #if WDL_FFT_REALSIZE != EEL_F_SIZE #error WDL_FFT_REALSIZE -- EEL_F_SIZE size mismatch #endif #ifndef EEL_FFT_MINBITLEN #define EEL_FFT_MINBITLEN 4 #endif #ifndef EEL_FFT_MAXBITLEN #define EEL_FFT_MAXBITLEN 15 #endif #ifndef EEL_FFT_MINBITLEN_REORDER #define EEL_FFT_MINBITLEN_REORDER (EEL_FFT_MINBITLEN-1) #endif //#define EEL_SUPER_FAST_FFT_REORDERING // quite a bit faster (50-100%) than "normal", but uses a 256kb lookup //#define EEL_SLOW_FFT_REORDERING // 20%-80% slower than normal, alloca() use, no reason to ever use this #ifdef EEL_SUPER_FAST_FFT_REORDERING static int *fft_reorder_table_for_bitsize(int bitsz) { static int s_tab[ (2 << EEL_FFT_MAXBITLEN) + 24*(EEL_FFT_MAXBITLEN-EEL_FFT_MINBITLEN_REORDER+1) ]; // big 256kb table, ugh if (bitsz<=EEL_FFT_MINBITLEN_REORDER) return s_tab; return s_tab + (1<= 4 && dir < 8) { if (dir == 4 || dir == 5) { //timingEnter(0); #if defined(EEL_SUPER_FAST_FFT_REORDERING) || !defined(EEL_SLOW_FFT_REORDERING) fft_reorder_buffer(sizebits,(WDL_FFT_COMPLEX*)data,dir==4); #else // old blech const int flen=1<= 0 && dir < 2) { WDL_fft((WDL_FFT_COMPLEX*)data,1<= 2 && dir < 4) { WDL_real_fft((WDL_FFT_REAL*)data,1<1 && bitl < EEL_FFT_MAXBITLEN) { bitl++; l>>=1; } if (bitl < ((dir&4) ? EEL_FFT_MINBITLEN_REORDER : EEL_FFT_MINBITLEN)) // smallest FFT is 16 item, smallest reorder is 8 item { return start; } ilen=1< NSEEL_RAM_ITEMSPERBLOCK || dest_offs < 0 || src_offs < 0 || dest_offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK || src_offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) return dest; if ((dest_offs&(NSEEL_RAM_ITEMSPERBLOCK-1)) + len > NSEEL_RAM_ITEMSPERBLOCK) return dest; if ((src_offs&(NSEEL_RAM_ITEMSPERBLOCK-1)) + len > NSEEL_RAM_ITEMSPERBLOCK) return dest; srcptr = __NSEEL_RAMAlloc(blocks,src_offs); if (!srcptr || srcptr==&nseel_ramalloc_onfail) return dest; destptr = __NSEEL_RAMAlloc(blocks,dest_offs); if (!destptr || destptr==&nseel_ramalloc_onfail) return dest; WDL_fft_complexmul((WDL_FFT_COMPLEX*)destptr,(WDL_FFT_COMPLEX*)srcptr,(len/2)&~1); return dest; } void EEL_fft_register() { WDL_fft_init(); #if defined(EEL_SUPER_FAST_FFT_REORDERING) if (!fft_reorder_table_for_bitsize(EEL_FFT_MINBITLEN_REORDER)[0]) { int x; for (x=EEL_FFT_MINBITLEN_REORDER;x<=EEL_FFT_MAXBITLEN;x++) fft_make_reorder_table(x,fft_reorder_table_for_bitsize(x)); } #endif NSEEL_addfunc_retptr("convolve_c",3,NSEEL_PProc_RAM,&eel_convolve_c); NSEEL_addfunc_retptr("fft",2,NSEEL_PProc_RAM,&eel_fft); NSEEL_addfunc_retptr("ifft",2,NSEEL_PProc_RAM,&eel_ifft); NSEEL_addfunc_retptr("fft_real",2,NSEEL_PProc_RAM,&eel_fft_real); NSEEL_addfunc_retptr("ifft_real",2,NSEEL_PProc_RAM,&eel_ifft_real); NSEEL_addfunc_retptr("fft_permute",2,NSEEL_PProc_RAM,&eel_fft_permute); NSEEL_addfunc_retptr("fft_ipermute",2,NSEEL_PProc_RAM,&eel_ifft_permute); } #ifdef EEL_WANT_DOCUMENTATION static const char *eel_fft_function_reference = "convolve_c\tdest,src,size\tMultiplies each of size complex pairs in dest by the complex pairs in src. Often used for convolution.\0" "fft\tbuffer,size\tPerforms a FFT on the data in the local memory buffer at the offset specified by the first parameter. The size of the FFT is specified " "by the second parameter, which must be 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, or 32768. The outputs are permuted, so if " "you plan to use them in-order, call fft_permute(buffer, size) before and fft_ipermute(buffer,size) after your in-order use. Your inputs or " "outputs will need to be scaled down by 1/size, if used.\n" "Note that fft()/ifft() require real / imaginary input pairs, so a 256 point FFT actually works with 512 items.\n" "Note that fft()/ifft() must NOT cross a 65,536 item boundary, so be sure to specify the offset accordingly.\0" "ifft\tbuffer,size\tPerform an inverse FFT. For more information see fft().\0" "fft_real\tbuffer,size\tPerforms an FFT, but takes size input samples and produces size/2 complex output pairs. Usually used along with fft_permute(size/2). Inputs/outputs will need to be scaled by 0.5/size.\0" "ifft_real\tbuffer,size\tPerforms an inverse FFT, but takes size/2 complex input pairs and produces size real output values. Usually used along with fft_ipermute(size/2).\0" "fft_permute\tbuffer,size\tPermute the output of fft() to have bands in-order. See fft() for more information.\0" "fft_ipermute\tbuffer,size\tPermute the input for ifft(), taking bands from in-order to the order ifft() requires. See fft() for more information.\0" ; #endif #endif jsusfx-0.4.0/src/WDL/eel2/eel_files.h000066400000000000000000000177111353477307700172300ustar00rootroot00000000000000#ifndef __EEL_FILES_H__ #define __EEL_FILES_H__ // should include eel_strings.h before this, probably //#define EEL_FILE_OPEN(fn,mode) ((instance)opaque)->OpenFile(fn,mode) //#define EEL_FILE_GETFP(fp) ((instance)opaque)->GetFileFP(fp) //#define EEL_FILE_CLOSE(fpindex) ((instance)opaque)->CloseFile(fpindex) static EEL_F NSEEL_CGEN_CALL _eel_fopen(void *opaque, EEL_F *fn_index, EEL_F *mode_index) { EEL_STRING_MUTEXLOCK_SCOPE const char *fn = EEL_STRING_GET_FOR_INDEX(*fn_index,NULL); const char *mode = EEL_STRING_GET_FOR_INDEX(*mode_index,NULL); if (!fn || !mode) return 0; return (EEL_F) EEL_FILE_OPEN(fn,mode); } static EEL_F NSEEL_CGEN_CALL _eel_fclose(void *opaque, EEL_F *fpp) { EEL_F ret=EEL_FILE_CLOSE((int)*fpp); #ifdef EEL_STRING_DEBUGOUT if (ret < 0) EEL_STRING_DEBUGOUT("fclose(): file handle %f not valid",*fpp); #endif return ret; } static EEL_F NSEEL_CGEN_CALL _eel_fgetc(void *opaque, EEL_F *fpp) { EEL_STRING_MUTEXLOCK_SCOPE FILE *fp = EEL_FILE_GETFP((int)*fpp); if (fp) return (EEL_F)fgetc(fp); #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fgetc(): file handle %f not valid",*fpp); #endif return -1.0; } static EEL_F NSEEL_CGEN_CALL _eel_ftell(void *opaque, EEL_F *fpp) { EEL_STRING_MUTEXLOCK_SCOPE FILE *fp = EEL_FILE_GETFP((int)*fpp); if (fp) return (EEL_F)ftell(fp); #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("ftell(): file handle %f not valid",*fpp); #endif return -1.0; } static EEL_F NSEEL_CGEN_CALL _eel_fflush(void *opaque, EEL_F *fpp) { EEL_STRING_MUTEXLOCK_SCOPE FILE *fp = EEL_FILE_GETFP((int)*fpp); if (fp) { fflush(fp); return 0.0; } #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fflush(): file handle %f not valid",*fpp); #endif return -1.0; } static EEL_F NSEEL_CGEN_CALL _eel_feof(void *opaque, EEL_F *fpp) { EEL_STRING_MUTEXLOCK_SCOPE FILE *fp = EEL_FILE_GETFP((int)*fpp); if (fp) return feof(fp) ? 1.0 : 0.0; #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("feof(): file handle %f not valid",*fpp); #endif return -1.0; } static EEL_F NSEEL_CGEN_CALL _eel_fseek(void *opaque, EEL_F *fpp, EEL_F *offset, EEL_F *wh) { EEL_STRING_MUTEXLOCK_SCOPE FILE *fp = EEL_FILE_GETFP((int)*fpp); if (fp) return fseek(fp, (int) *offset, *wh<0 ? SEEK_SET : *wh > 0 ? SEEK_END : SEEK_CUR); #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fseek(): file handle %f not valid",*fpp); #endif return -1.0; } static EEL_F NSEEL_CGEN_CALL _eel_fgets(void *opaque, EEL_F *fpp, EEL_F *strOut) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL; EEL_STRING_GET_FOR_WRITE(*strOut, &wr); FILE *fp = EEL_FILE_GETFP((int)*fpp); if (!fp) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fgets(): file handle %f not valid",*fpp); #endif if (wr) wr->Set(""); return 0.0; } char buf[16384]; buf[0]=0; fgets(buf,sizeof(buf),fp); if (wr) { wr->Set(buf); return (EEL_F)wr->GetLength(); } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fgets: bad destination specifier passed %f, throwing away %d bytes",*strOut, (int)strlen(buf)); #endif return (int)strlen(buf); } } static EEL_F NSEEL_CGEN_CALL _eel_fread(void *opaque, EEL_F *fpp, EEL_F *strOut, EEL_F *flen) { int use_len = (int) *flen; if (use_len < 1) return 0.0; EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL; EEL_STRING_GET_FOR_WRITE(*strOut, &wr); if (!wr) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fread: bad destination specifier passed %f, not reading %d bytes",*strOut, use_len); #endif return -1; } FILE *fp = EEL_FILE_GETFP((int)*fpp); if (!fp) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fread(): file handle %f not valid",*fpp); #endif if (wr) wr->Set(""); return 0.0; } wr->SetLen(use_len); if (wr->GetLength() != use_len) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fread: error allocating storage for read of %d bytes", use_len); #endif return -1.0; } use_len = (int)fread((char *)wr->Get(),1,use_len,fp); wr->SetLen(use_len > 0 ? use_len : 0, true); return (EEL_F) use_len; } static EEL_F NSEEL_CGEN_CALL _eel_fwrite(void *opaque, EEL_F *fpp, EEL_F *strOut, EEL_F *flen) { EEL_STRING_MUTEXLOCK_SCOPE int use_len = (int) *flen; EEL_STRING_STORAGECLASS *wr=NULL; const char *str=EEL_STRING_GET_FOR_INDEX(*strOut, &wr); if (!wr && !str) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fwrite: bad source specifier passed %f, not writing %d bytes",*strOut, use_len); #endif return -1.0; } if (!wr) { const int ssl = (int)strlen(str); if (use_len < 1 || use_len > ssl) use_len = ssl; } else { if (use_len < 1 || use_len > wr->GetLength()) use_len = wr->GetLength(); } if (use_len < 1) return 0.0; FILE *fp = EEL_FILE_GETFP((int)*fpp); if (!fp) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fwrite(): file handle %f not valid",*fpp); #endif return 0.0; } return (EEL_F) fwrite(str,1,use_len,fp); } static EEL_F NSEEL_CGEN_CALL _eel_fprintf(void *opaque, INT_PTR nparam, EEL_F **parm) { if (opaque && nparam > 1) { EEL_STRING_MUTEXLOCK_SCOPE FILE *fp = EEL_FILE_GETFP((int)*(parm[0])); if (!fp) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fprintf(): file handle %f not valid",parm[0][0]); #endif return 0.0; } EEL_STRING_STORAGECLASS *wr_src=NULL; const char *fmt = EEL_STRING_GET_FOR_INDEX(*(parm[1]),&wr_src); if (fmt) { char buf[16384]; const int len = eel_format_strings(opaque,fmt,wr_src?(fmt+wr_src->GetLength()) : NULL, buf,(int)sizeof(buf),(int)nparam-2,parm+2); if (len >= 0) { return (EEL_F) fwrite(buf,1,len,fp); } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fprintf: bad format string %s",fmt); #endif } } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("fprintf: bad format specifier passed %f",*(parm[1])); #endif } } return 0.0; } void EEL_file_register() { NSEEL_addfunc_retval("fopen",2,NSEEL_PProc_THIS,&_eel_fopen); NSEEL_addfunc_retval("fread",3,NSEEL_PProc_THIS,&_eel_fread); NSEEL_addfunc_retval("fgets",2,NSEEL_PProc_THIS,&_eel_fgets); NSEEL_addfunc_retval("fgetc",1,NSEEL_PProc_THIS,&_eel_fgetc); NSEEL_addfunc_retval("fwrite",3,NSEEL_PProc_THIS,&_eel_fwrite); NSEEL_addfunc_varparm("fprintf",2,NSEEL_PProc_THIS,&_eel_fprintf); NSEEL_addfunc_retval("fseek",3,NSEEL_PProc_THIS,&_eel_fseek); NSEEL_addfunc_retval("ftell",1,NSEEL_PProc_THIS,&_eel_ftell); NSEEL_addfunc_retval("feof",1,NSEEL_PProc_THIS,&_eel_feof); NSEEL_addfunc_retval("fflush",1,NSEEL_PProc_THIS,&_eel_fflush); NSEEL_addfunc_retval("fclose",1,NSEEL_PProc_THIS,&_eel_fclose); } #ifdef EEL_WANT_DOCUMENTATION static const char *eel_file_function_reference = "fopen\t\"fn\",\"mode\"\tOpens a file \"fn\" with mode \"mode\". For read, use \"r\" or \"rb\", write \"w\" or \"wb\". Returns a positive integer on success.\0" "fclose\tfp\tCloses a file previously opened with fopen().\0" "fread\tfp,#str,length\tReads from file fp into #str, up to length bytes. Returns actual length read, or negative if error.\0" "fgets\tfp,#str\tReads a line from file fp into #str. Returns length of #str read.\0" "fgetc\tfp\tReads a character from file fp, returns -1 if EOF.\0" "fwrite\tfp,#str,len\tWrites up to len characters of #str to file fp. If len is less than 1, the full contents of #str will be written. Returns the number of bytes written to file.\0" "fprintf\tfp,\"format\"[,...]\tFormats a string and writes it to file fp. For more information on format specifiers, see sprintf(). Returns bytes written to file.\0" "fseek\tfp,offset,whence\tSeeks file fp, offset bytes from whence reference. Whence negative specifies start of file, positive whence specifies end of file, and zero whence specifies current file position.\0" "ftell\tfp\tRetunrs the current file position.\0" "feof\tfp\tReturns nonzero if the file fp is at the end of file.\0" "fflush\tfp\tIf file fp is open for writing, flushes out any buffered data to disk.\0" ; #endif #endif jsusfx-0.4.0/src/WDL/eel2/eel_lice.h000066400000000000000000002715441353477307700170500ustar00rootroot00000000000000#ifndef _EEL_LICE_H_ #define _EEL_LICE_H_ // #define EEL_LICE_GET_FILENAME_FOR_STRING(idx, fs, p) (((sInst*)opaque)->GetFilenameForParameter(idx,fs,p)) // #define EEL_LICE_GET_CONTEXT(opaque) (((opaque) ? (((sInst *)opaque)->m_gfx_state) : NULL) void eel_lice_register(); #ifdef DYNAMIC_LICE #define LICE_IBitmap LICE_IBitmap_disabledAPI #include "../lice/lice.h" #undef LICE_IBitmap typedef void LICE_IBitmap; // prevent us from using LICE api directly, in case it ever changes class LICE_IFont; #ifdef EEL_LICE_API_ONLY #define EEL_LICE_FUNCDEF extern #else #define EEL_LICE_FUNCDEF #endif #define LICE_FUNCTION_VALID(x) (x) EEL_LICE_FUNCDEF LICE_IBitmap *(*__LICE_CreateBitmap)(int, int, int); EEL_LICE_FUNCDEF void (*__LICE_Clear)(LICE_IBitmap *dest, LICE_pixel color); EEL_LICE_FUNCDEF void (*__LICE_Line)(LICE_IBitmap *dest, int x1, int y1, int x2, int y2, LICE_pixel color, float alpha, int mode, bool aa); EEL_LICE_FUNCDEF bool (*__LICE_ClipLine)(int* pX1, int* pY1, int* pX2, int* pY2, int xLo, int yLo, int xHi, int yHi); EEL_LICE_FUNCDEF void (*__LICE_DrawText)(LICE_IBitmap *bm, int x, int y, const char *string, LICE_pixel color, float alpha, int mode); EEL_LICE_FUNCDEF void (*__LICE_DrawChar)(LICE_IBitmap *bm, int x, int y, char c, LICE_pixel color, float alpha, int mode); EEL_LICE_FUNCDEF void (*__LICE_MeasureText)(const char *string, int *w, int *h); EEL_LICE_FUNCDEF void (*__LICE_PutPixel)(LICE_IBitmap *bm, int x, int y, LICE_pixel color, float alpha, int mode); EEL_LICE_FUNCDEF LICE_pixel (*__LICE_GetPixel)(LICE_IBitmap *bm, int x, int y); EEL_LICE_FUNCDEF void (*__LICE_FillRect)(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel color, float alpha, int mode); EEL_LICE_FUNCDEF void (*__LICE_DrawRect)(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel color, float alpha, int mode); EEL_LICE_FUNCDEF LICE_IBitmap *(*__LICE_LoadImage)(const char* filename, LICE_IBitmap* bmp, bool tryIgnoreExtension); EEL_LICE_FUNCDEF void (*__LICE_Blur)(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int srcx, int srcy, int srcw, int srch); // src and dest can overlap, however it may look fudgy if they do EEL_LICE_FUNCDEF void (*__LICE_ScaledBlit)(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int dstw, int dsth, float srcx, float srcy, float srcw, float srch, float alpha, int mode); EEL_LICE_FUNCDEF void (*__LICE_Circle)(LICE_IBitmap* dest, float cx, float cy, float r, LICE_pixel color, float alpha, int mode, bool aa); EEL_LICE_FUNCDEF void (*__LICE_FillCircle)(LICE_IBitmap* dest, float cx, float cy, float r, LICE_pixel color, float alpha, int mode, bool aa); EEL_LICE_FUNCDEF void (*__LICE_FillTriangle)(LICE_IBitmap* dest, int x1, int y1, int x2, int y2, int x3, int y3, LICE_pixel color, float alpha, int mode); EEL_LICE_FUNCDEF void (*__LICE_FillConvexPolygon)(LICE_IBitmap* dest, const int* x, const int* y, int npoints, LICE_pixel color, float alpha, int mode); EEL_LICE_FUNCDEF void (*__LICE_RoundRect)(LICE_IBitmap *drawbm, float xpos, float ypos, float w, float h, int cornerradius, LICE_pixel col, float alpha, int mode, bool aa); EEL_LICE_FUNCDEF void (*__LICE_Arc)(LICE_IBitmap* dest, float cx, float cy, float r, float minAngle, float maxAngle, LICE_pixel color, float alpha, int mode, bool aa); // if cliptosourcerect is false, then areas outside the source rect can get in (otherwise they are not drawn) EEL_LICE_FUNCDEF void (*__LICE_RotatedBlit)(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int dstw, int dsth, float srcx, float srcy, float srcw, float srch, float angle, bool cliptosourcerect, float alpha, int mode, float rotxcent, float rotycent); // these coordinates are offset from the center of the image, in source pixel coordinates EEL_LICE_FUNCDEF void (*__LICE_MultiplyAddRect)(LICE_IBitmap *dest, int x, int y, int w, int h, float rsc, float gsc, float bsc, float asc, // 0-1, or -100 .. +100 if you really are insane float radd, float gadd, float badd, float aadd); // 0-255 is the normal range on these.. of course its clamped EEL_LICE_FUNCDEF void (*__LICE_GradRect)(LICE_IBitmap *dest, int dstx, int dsty, int dstw, int dsth, float ir, float ig, float ib, float ia, float drdx, float dgdx, float dbdx, float dadx, float drdy, float dgdy, float dbdy, float dady, int mode); EEL_LICE_FUNCDEF void (*__LICE_TransformBlit2)(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int dstw, int dsth, double *srcpoints, int div_w, int div_h, // srcpoints coords should be div_w*div_h*2 long, and be in source image coordinates float alpha, int mode); EEL_LICE_FUNCDEF void (*__LICE_DeltaBlit)(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int dstw, int dsth, float srcx, float srcy, float srcw, float srch, double dsdx, double dtdx, double dsdy, double dtdy, double dsdxdy, double dtdxdy, bool cliptosourcerect, float alpha, int mode); #define LICE_Blur __LICE_Blur #define LICE_Clear __LICE_Clear #define LICE_Line __LICE_Line #define LICE_ClipLine __LICE_ClipLine #define LICE_FillRect __LICE_FillRect #define LICE_DrawRect __LICE_DrawRect #define LICE_PutPixel __LICE_PutPixel #define LICE_GetPixel __LICE_GetPixel #define LICE_DrawText __LICE_DrawText #define LICE_DrawChar __LICE_DrawChar #define LICE_MeasureText __LICE_MeasureText #define LICE_LoadImage __LICE_LoadImage #define LICE_RotatedBlit __LICE_RotatedBlit #define LICE_ScaledBlit __LICE_ScaledBlit #define LICE_MultiplyAddRect __LICE_MultiplyAddRect #define LICE_GradRect __LICE_GradRect #define LICE_TransformBlit2 __LICE_TransformBlit2 #define LICE_DeltaBlit __LICE_DeltaBlit #define LICE_Circle __LICE_Circle #define LICE_FillCircle __LICE_FillCircle #define LICE_FillTriangle __LICE_FillTriangle #define LICE_FillConvexPolygon __LICE_FillConvexPolygon #define LICE_RoundRect __LICE_RoundRect #define LICE_Arc __LICE_Arc EEL_LICE_FUNCDEF HDC (*LICE__GetDC)(LICE_IBitmap *bm); EEL_LICE_FUNCDEF int (*LICE__GetWidth)(LICE_IBitmap *bm); EEL_LICE_FUNCDEF int (*LICE__GetHeight)(LICE_IBitmap *bm); EEL_LICE_FUNCDEF void (*LICE__Destroy)(LICE_IBitmap *bm); EEL_LICE_FUNCDEF bool (*LICE__resize)(LICE_IBitmap *bm, int w, int h); EEL_LICE_FUNCDEF void (*LICE__DestroyFont)(LICE_IFont* font); EEL_LICE_FUNCDEF LICE_IFont *(*LICE_CreateFont)(); EEL_LICE_FUNCDEF void (*LICE__SetFromHFont)(LICE_IFont* ifont, HFONT font, int flags); EEL_LICE_FUNCDEF LICE_pixel (*LICE__SetTextColor)(LICE_IFont* ifont, LICE_pixel color); EEL_LICE_FUNCDEF LICE_pixel (*LICE__SetBkColor)(LICE_IFont* ifont, LICE_pixel color); EEL_LICE_FUNCDEF void (*LICE__SetTextCombineMode)(LICE_IFont* ifont, int mode, float alpha); EEL_LICE_FUNCDEF int (*LICE__DrawText)(LICE_IFont* ifont, LICE_IBitmap *bm, const char *str, int strcnt, RECT *rect, UINT dtFlags); #else #include "../lice/lice.h" #include "../lice/lice_text.h" #define LICE_FUNCTION_VALID(x) (sizeof(int) > 0) static HDC LICE__GetDC(LICE_IBitmap *bm) { return bm->getDC(); } static int LICE__GetWidth(LICE_IBitmap *bm) { return bm->getWidth(); } static int LICE__GetHeight(LICE_IBitmap *bm) { return bm->getHeight(); } static void LICE__Destroy(LICE_IBitmap *bm) { delete bm; } static void LICE__SetFromHFont(LICE_IFont * ifont, HFONT font, int flags) { if (ifont) ifont->SetFromHFont(font,flags); } static LICE_pixel LICE__SetTextColor(LICE_IFont* ifont, LICE_pixel color) { if (ifont) return ifont->SetTextColor(color); return 0; } static LICE_pixel LICE__SetBkColor(LICE_IFont* ifont, LICE_pixel color) { if (ifont) return ifont->SetBkColor(color); return 0; } static void LICE__SetTextCombineMode(LICE_IFont* ifont, int mode, float alpha) { if (ifont) ifont->SetCombineMode(mode, alpha); } static int LICE__DrawText(LICE_IFont* ifont, LICE_IBitmap *bm, const char *str, int strcnt, RECT *rect, UINT dtFlags) { if (ifont) return ifont->DrawText(bm, str, strcnt, rect, dtFlags); return 0; } static LICE_IFont *LICE_CreateFont() { return new LICE_CachedFont(); } static void LICE__DestroyFont(LICE_IFont *bm) { delete bm; } static bool LICE__resize(LICE_IBitmap *bm, int w, int h) { return bm->resize(w,h); } static LICE_IBitmap *__LICE_CreateBitmap(int mode, int w, int h) { if (mode==1) return new LICE_SysBitmap(w,h); return new LICE_MemBitmap(w,h); } #endif #include "../wdlutf8.h" class eel_lice_state { public: eel_lice_state(NSEEL_VMCTX vm, void *ctx, int image_slots, int font_slots); ~eel_lice_state(); void resetVarsToStock() { if (m_gfx_a&&m_gfx_r&&m_gfx_g&&m_gfx_b) *m_gfx_r=*m_gfx_g=*m_gfx_b=*m_gfx_a=1.0; if (m_gfx_dest) *m_gfx_dest=-1.0; if (m_mouse_wheel) *m_mouse_wheel=0.0; if (m_mouse_hwheel) *m_mouse_hwheel=0.0; // todo: reset others? } LICE_IBitmap *m_framebuffer, *m_framebuffer_extra; int m_framebuffer_dirty; WDL_TypedBuf m_gfx_images; struct gfxFontStruct { LICE_IFont *font; char last_fontname[128]; char actual_fontname[128]; int last_fontsize; int last_fontflag; int use_fonth; }; WDL_TypedBuf m_gfx_fonts; int m_gfx_font_active; // -1 for default, otherwise index into gfx_fonts (NOTE: this differs from the exposed API, which defines 0 as default, 1-n) LICE_IFont *GetActiveFont() { return m_gfx_font_active>=0&&m_gfx_font_active-2.0) { if (idx < 0.0) return m_framebuffer; const int a = (int)idx; if (a >= 0 && a < m_gfx_images.GetSize()) return m_gfx_images.Get()[a]; } return NULL; }; void SetImageDirty(LICE_IBitmap *bm) { if (bm == m_framebuffer && !m_framebuffer_dirty) { if (m_gfx_clear && *m_gfx_clear > -1.0) { const int a=(int)*m_gfx_clear; if (LICE_FUNCTION_VALID(LICE_Clear)) LICE_Clear(m_framebuffer,LICE_RGBA((a&0xff),((a>>8)&0xff),((a>>16)&0xff),0)); } m_framebuffer_dirty=1; } } // R, G, B, A, w, h, x, y, mode(1=add,0=copy) EEL_F *m_gfx_r, *m_gfx_g, *m_gfx_b, *m_gfx_w, *m_gfx_h, *m_gfx_a, *m_gfx_x, *m_gfx_y, *m_gfx_mode, *m_gfx_clear, *m_gfx_texth,*m_gfx_dest; EEL_F *m_mouse_x, *m_mouse_y, *m_mouse_cap, *m_mouse_wheel, *m_mouse_hwheel; EEL_F *m_gfx_ext_retina; NSEEL_VMCTX m_vmref; void *m_user_ctx; int setup_frame(HWND hwnd, RECT r, int _mouse_x=0, int _mouse_y=0); // mouse_x/y used only if hwnd is NULL void gfx_lineto(EEL_F xpos, EEL_F ypos, EEL_F aaflag); void gfx_rectto(EEL_F xpos, EEL_F ypos); void gfx_line(int np, EEL_F **parms); void gfx_rect(int np, EEL_F **parms); void gfx_roundrect(int np, EEL_F **parms); void gfx_arc(int np, EEL_F **parms); void gfx_set(int np, EEL_F **parms); void gfx_grad_or_muladd_rect(int mode, int np, EEL_F **parms); void gfx_setpixel(EEL_F r, EEL_F g, EEL_F b); void gfx_getpixel(EEL_F *r, EEL_F *g, EEL_F *b); void gfx_drawnumber(EEL_F n, EEL_F ndigits); void gfx_drawchar(EEL_F ch); void gfx_getimgdim(EEL_F img, EEL_F *w, EEL_F *h); EEL_F gfx_setimgdim(int img, EEL_F *w, EEL_F *h); void gfx_blurto(EEL_F x, EEL_F y); void gfx_blit(EEL_F img, EEL_F scale, EEL_F rotate); void gfx_blitext(EEL_F img, EEL_F *coords, EEL_F angle); void gfx_blitext2(int np, EEL_F **parms, int mode); // 0=blit, 1=deltablit void gfx_transformblit(EEL_F **parms, int div_w, int div_h, EEL_F *tab); // parms[0]=src, 1-4=x,y,w,h void gfx_circle(float x, float y, float r, bool fill, bool aaflag); void gfx_triangle(EEL_F** parms, int nparms); void gfx_drawstr(void *opaque, EEL_F **parms, int nparms, int formatmode); // formatmode=1 for format, 2 for purely measure no format, 3 for measure char EEL_F gfx_loadimg(void *opaque, int img, EEL_F loadFrom); EEL_F gfx_setfont(void *opaque, int np, EEL_F **parms); EEL_F gfx_getfont(void *opaque, int np, EEL_F **parms); LICE_pixel getCurColor(); int getCurMode(); int getCurModeForBlit(bool isFBsrc); #ifdef EEL_LICE_WANT_STANDALONE HWND create_wnd(HWND par, int isChild); HWND hwnd_standalone; int hwnd_standalone_kb_state[32]; // pressed keys, if any // these have to be **parms because of the hack for getting string from parm index EEL_F gfx_showmenu(void* opaque, EEL_F** parms, int nparms); EEL_F gfx_setcursor(void* opaque, EEL_F** parms, int nparms); int m_kb_queue[64]; unsigned char m_kb_queue_valid; unsigned char m_kb_queue_pos; int m_cursor_resid; #ifdef EEL_LICE_LOADTHEMECURSOR char m_cursor_name[128]; #endif #ifndef EEL_LICE_STANDALONE_NOINITQUIT RECT m_last_undocked_r; #endif #endif int m_has_cap; // high 16 bits are current capture state, low 16 bits are temporary flags from mousedown bool m_has_had_getch; // set on first gfx_getchar(), makes mouse_cap updated with modifiers even when no mouse click is down }; #ifndef EEL_LICE_API_ONLY eel_lice_state::eel_lice_state(NSEEL_VMCTX vm, void *ctx, int image_slots, int font_slots) { #ifdef EEL_LICE_WANT_STANDALONE hwnd_standalone=NULL; memset(hwnd_standalone_kb_state,0,sizeof(hwnd_standalone_kb_state)); m_kb_queue_valid=0; m_cursor_resid=0; #ifndef EEL_LICE_STANDALONE_NOINITQUIT memset(&m_last_undocked_r,0,sizeof(m_last_undocked_r)); #endif #ifdef EEL_LICE_LOADTHEMECURSOR m_cursor_name[0]=0; #endif #endif m_user_ctx=ctx; m_vmref= vm; m_gfx_font_active=-1; m_gfx_fonts.Resize(font_slots); memset(m_gfx_fonts.Get(),0,m_gfx_fonts.GetSize()*sizeof(m_gfx_fonts.Get()[0])); m_gfx_images.Resize(image_slots); memset(m_gfx_images.Get(),0,m_gfx_images.GetSize()*sizeof(m_gfx_images.Get()[0])); m_framebuffer=m_framebuffer_extra=0; m_framebuffer_dirty=0; m_gfx_r = NSEEL_VM_regvar(vm,"gfx_r"); m_gfx_g = NSEEL_VM_regvar(vm,"gfx_g"); m_gfx_b = NSEEL_VM_regvar(vm,"gfx_b"); m_gfx_a = NSEEL_VM_regvar(vm,"gfx_a"); m_gfx_w = NSEEL_VM_regvar(vm,"gfx_w"); m_gfx_h = NSEEL_VM_regvar(vm,"gfx_h"); m_gfx_x = NSEEL_VM_regvar(vm,"gfx_x"); m_gfx_y = NSEEL_VM_regvar(vm,"gfx_y"); m_gfx_mode = NSEEL_VM_regvar(vm,"gfx_mode"); m_gfx_clear = NSEEL_VM_regvar(vm,"gfx_clear"); m_gfx_texth = NSEEL_VM_regvar(vm,"gfx_texth"); m_gfx_dest = NSEEL_VM_regvar(vm,"gfx_dest"); m_gfx_ext_retina = NSEEL_VM_regvar(vm,"gfx_ext_retina"); m_mouse_x = NSEEL_VM_regvar(vm,"mouse_x"); m_mouse_y = NSEEL_VM_regvar(vm,"mouse_y"); m_mouse_cap = NSEEL_VM_regvar(vm,"mouse_cap"); m_mouse_wheel=NSEEL_VM_regvar(vm,"mouse_wheel"); m_mouse_hwheel=NSEEL_VM_regvar(vm,"mouse_hwheel"); if (m_gfx_texth) *m_gfx_texth=8; m_has_cap=0; m_has_had_getch=false; } eel_lice_state::~eel_lice_state() { #ifdef EEL_LICE_WANT_STANDALONE if (hwnd_standalone) DestroyWindow(hwnd_standalone); #endif if (LICE_FUNCTION_VALID(LICE__Destroy)) { LICE__Destroy(m_framebuffer_extra); LICE__Destroy(m_framebuffer); int x; for (x=0;x>4)&0xf; if (sm > LICE_BLIT_MODE_COPY && sm <= LICE_BLIT_MODE_HSVADJ) return sm; return (gmode&1) ? LICE_BLIT_MODE_ADD : LICE_BLIT_MODE_COPY; } int eel_lice_state::getCurModeForBlit(bool isFBsrc) { const int gmode = (int) (*m_gfx_mode); const int sm=(gmode>>4)&0xf; int mode; if (sm > LICE_BLIT_MODE_COPY && sm <= LICE_BLIT_MODE_HSVADJ) mode=sm; else mode=((gmode&1) ? LICE_BLIT_MODE_ADD : LICE_BLIT_MODE_COPY); if (!isFBsrc && !(gmode&2)) mode|=LICE_BLIT_USE_ALPHA; if (!(gmode&4)) mode|=LICE_BLIT_FILTER_BILINEAR; return mode; } LICE_pixel eel_lice_state::getCurColor() { int red=(int) (*m_gfx_r*255.0); int green=(int) (*m_gfx_g*255.0); int blue=(int) (*m_gfx_b*255.0); if (red<0) red=0;else if (red>255)red=255; if (green<0) green=0;else if (green>255)green=255; if (blue<0) blue=0; else if (blue>255) blue=255; return LICE_RGBA(red,green,blue,255); } static EEL_F * NSEEL_CGEN_CALL _gfx_lineto(void *opaque, EEL_F *xpos, EEL_F *ypos, EEL_F *useaa) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_lineto(*xpos, *ypos, *useaa); return xpos; } static EEL_F * NSEEL_CGEN_CALL _gfx_lineto2(void *opaque, EEL_F *xpos, EEL_F *ypos) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_lineto(*xpos, *ypos, 1.0f); return xpos; } static EEL_F * NSEEL_CGEN_CALL _gfx_rectto(void *opaque, EEL_F *xpos, EEL_F *ypos) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_rectto(*xpos, *ypos); return xpos; } static EEL_F NSEEL_CGEN_CALL _gfx_line(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_line((int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_rect(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_rect((int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_roundrect(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_roundrect((int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_arc(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_arc((int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_set(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_set((int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_gradrect(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_grad_or_muladd_rect(0,(int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_muladdrect(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_grad_or_muladd_rect(1,(int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_deltablit(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_blitext2((int)np,parms,1); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_transformblit(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) { #ifndef EEL_LICE_NO_RAM const int divw = (int) (parms[5][0]+0.5); const int divh = (int) (parms[6][0]+0.5); if (divw < 1 || divh < 1) return 0.0; const int sz = divw*divh*2; #ifdef EEL_LICE_RAMFUNC EEL_F *d = EEL_LICE_RAMFUNC(opaque,7,sz); if (!d) return 0.0; #else EEL_F **blocks = ctx->m_vmref ? ((compileContext*)ctx->m_vmref)->ram_state.blocks : 0; if (!blocks || np < 8) return 0.0; const int addr1= (int) (parms[7][0]+0.5); EEL_F *d=__NSEEL_RAMAlloc(blocks,addr1); if (sz>NSEEL_RAM_ITEMSPERBLOCK) { int x; for(x=NSEEL_RAM_ITEMSPERBLOCK;xgfx_transformblit(parms,divw,divh,d); #endif } return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_circle(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); bool aa = true, fill = false; if (np>3) fill = parms[3][0] > 0.5; if (np>4) aa = parms[4][0] > 0.5; if (ctx) ctx->gfx_circle((float)parms[0][0], (float)parms[1][0], (float)parms[2][0], fill, aa); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_triangle(void* opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_triangle(parms, (int)np); return 0.0; } static EEL_F * NSEEL_CGEN_CALL _gfx_drawnumber(void *opaque, EEL_F *n, EEL_F *nd) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_drawnumber(*n, *nd); return n; } static EEL_F * NSEEL_CGEN_CALL _gfx_drawchar(void *opaque, EEL_F *n) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_drawchar(*n); return n; } static EEL_F * NSEEL_CGEN_CALL _gfx_measurestr(void *opaque, EEL_F *str, EEL_F *xOut, EEL_F *yOut) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) { EEL_F *p[3]={str,xOut,yOut}; ctx->gfx_drawstr(opaque,p,3,2); } return str; } static EEL_F * NSEEL_CGEN_CALL _gfx_measurechar(void *opaque, EEL_F *str, EEL_F *xOut, EEL_F *yOut) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) { EEL_F *p[3]={str,xOut,yOut}; ctx->gfx_drawstr(opaque,p,3,3); } return str; } static EEL_F NSEEL_CGEN_CALL _gfx_drawstr(void *opaque, INT_PTR nparms, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_drawstr(opaque,parms,(int)nparms,0); return parms[0][0]; } static EEL_F NSEEL_CGEN_CALL _gfx_printf(void *opaque, INT_PTR nparms, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx && nparms>0) { EEL_F v= **parms; ctx->gfx_drawstr(opaque,parms,(int)nparms,1); return v; } return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_showmenu(void* opaque, INT_PTR nparms, EEL_F **parms) { eel_lice_state* ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) return ctx->gfx_showmenu(opaque, parms, (int)nparms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_setcursor(void* opaque, INT_PTR nparms, EEL_F **parms) { eel_lice_state* ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) return ctx->gfx_setcursor(opaque, parms, (int)nparms); return 0.0; } static EEL_F * NSEEL_CGEN_CALL _gfx_setpixel(void *opaque, EEL_F *r, EEL_F *g, EEL_F *b) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_setpixel(*r, *g, *b); return r; } static EEL_F * NSEEL_CGEN_CALL _gfx_getpixel(void *opaque, EEL_F *r, EEL_F *g, EEL_F *b) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_getpixel(r, g, b); return r; } static EEL_F * NSEEL_CGEN_CALL _gfx_blit(void *opaque, EEL_F *img, EEL_F *scale, EEL_F *rotate) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_blit(*img,*scale,*rotate); return img; } static EEL_F NSEEL_CGEN_CALL _gfx_setfont(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) return ctx->gfx_setfont(opaque,(int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_getfont(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) { const int idx=ctx->m_gfx_font_active; if (idx>=0 && idx < ctx->m_gfx_fonts.GetSize()) { eel_lice_state::gfxFontStruct* f=ctx->m_gfx_fonts.Get()+idx; EEL_STRING_MUTEXLOCK_SCOPE #ifdef NOT_EEL_STRING_UPDATE_STRING NOT_EEL_STRING_UPDATE_STRING(parms[0][0],f->actual_fontname); #else WDL_FastString *fs=NULL; EEL_STRING_GET_FOR_WRITE(parms[0][0],&fs); if (fs) fs->Set(f->actual_fontname); #endif } return idx; } return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_blit2(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx && np>=3) { ctx->gfx_blitext2((int)np,parms,0); return *(parms[0]); } return 0.0; } static EEL_F * NSEEL_CGEN_CALL _gfx_blitext(void *opaque, EEL_F *img, EEL_F *coordidx, EEL_F *rotate) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) { #ifndef EEL_LICE_NO_RAM #ifdef EEL_LICE_RAMFUNC EEL_F *buf = EEL_LICE_RAMFUNC(opaque,1,10); if (!buf) return img; #else EEL_F fc = *coordidx; if (fc < -0.5 || fc >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) return img; int a=(int)fc; if (a<0) return img; EEL_F buf[10]; int x; EEL_F **blocks = ctx->m_vmref ? ((compileContext*)ctx->m_vmref)->ram_state.blocks : 0; if (!blocks) return img; for (x = 0;x < 10; x ++) { EEL_F *d=__NSEEL_RAMAlloc(blocks,a++); if (!d || d==&nseel_ramalloc_onfail) return img; buf[x]=*d; } #endif // read megabuf ctx->gfx_blitext(*img,buf,*rotate); #endif } return img; } static EEL_F * NSEEL_CGEN_CALL _gfx_blurto(void *opaque, EEL_F *x, EEL_F *y) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_blurto(*x,*y); return x; } static EEL_F * NSEEL_CGEN_CALL _gfx_getimgdim(void *opaque, EEL_F *img, EEL_F *w, EEL_F *h) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) ctx->gfx_getimgdim(*img,w,h); return img; } static EEL_F NSEEL_CGEN_CALL _gfx_loadimg(void *opaque, EEL_F *img, EEL_F *fr) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) return ctx->gfx_loadimg(opaque,(int)*img,*fr); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_setimgdim(void *opaque, EEL_F *img, EEL_F *w, EEL_F *h) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) return ctx->gfx_setimgdim((int)*img,w,h); return 0.0; } void eel_lice_state::gfx_lineto(EEL_F xpos, EEL_F ypos, EEL_F aaflag) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_lineto"); if (!dest) return; int x1=(int)floor(xpos),y1=(int)floor(ypos),x2=(int)floor(*m_gfx_x), y2=(int)floor(*m_gfx_y); if (LICE_FUNCTION_VALID(LICE__GetWidth) && LICE_FUNCTION_VALID(LICE__GetHeight) && LICE_FUNCTION_VALID(LICE_Line) && LICE_FUNCTION_VALID(LICE_ClipLine) && LICE_ClipLine(&x1,&y1,&x2,&y2,0,0,LICE__GetWidth(dest),LICE__GetHeight(dest))) { SetImageDirty(dest); LICE_Line(dest,x1,y1,x2,y2,getCurColor(),(float) *m_gfx_a,getCurMode(),aaflag > 0.5); } *m_gfx_x = xpos; *m_gfx_y = ypos; } void eel_lice_state::gfx_circle(float x, float y, float r, bool fill, bool aaflag) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_circle"); if (!dest) return; if (LICE_FUNCTION_VALID(LICE_Circle) && LICE_FUNCTION_VALID(LICE_FillCircle)) { SetImageDirty(dest); if(fill) LICE_FillCircle(dest, x, y, r, getCurColor(), (float) *m_gfx_a, getCurMode(), aaflag); else LICE_Circle(dest, x, y, r, getCurColor(), (float) *m_gfx_a, getCurMode(), aaflag); } } void eel_lice_state::gfx_triangle(EEL_F** parms, int np) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest, "gfx_triangle"); if (np >= 6) { np &= ~1; SetImageDirty(dest); if (np == 6) { if (!LICE_FUNCTION_VALID(LICE_FillTriangle)) return; LICE_FillTriangle(dest, (int)parms[0][0], (int)parms[1][0], (int)parms[2][0], (int)parms[3][0], (int)parms[4][0], (int)parms[5][0], getCurColor(), (float)*m_gfx_a, getCurMode()); } else { if (!LICE_FUNCTION_VALID(LICE_FillConvexPolygon)) return; const int maxpt = 512; const int n = wdl_min(np/2, maxpt); int i, rdi=0; int x[maxpt], y[maxpt]; for (i=0; i < n; i++) { x[i]=(int)parms[rdi++][0]; y[i]=(int)parms[rdi++][0]; } LICE_FillConvexPolygon(dest, x, y, n, getCurColor(), (float)*m_gfx_a, getCurMode()); } } } void eel_lice_state::gfx_rectto(EEL_F xpos, EEL_F ypos) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_rectto"); if (!dest) return; EEL_F x1=xpos,y1=ypos,x2=*m_gfx_x, y2=*m_gfx_y; if (x2 0.5 && y2-y1 > 0.5) { SetImageDirty(dest); LICE_FillRect(dest,(int)x1,(int)y1,(int)(x2-x1),(int)(y2-y1),getCurColor(),(float)*m_gfx_a,getCurMode()); } *m_gfx_x = xpos; *m_gfx_y = ypos; } void eel_lice_state::gfx_line(int np, EEL_F **parms) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_line"); if (!dest) return; int x1=(int)floor(parms[0][0]),y1=(int)floor(parms[1][0]),x2=(int)floor(parms[2][0]), y2=(int)floor(parms[3][0]); if (LICE_FUNCTION_VALID(LICE__GetWidth) && LICE_FUNCTION_VALID(LICE__GetHeight) && LICE_FUNCTION_VALID(LICE_Line) && LICE_FUNCTION_VALID(LICE_ClipLine) && LICE_ClipLine(&x1,&y1,&x2,&y2,0,0,LICE__GetWidth(dest),LICE__GetHeight(dest))) { SetImageDirty(dest); LICE_Line(dest,x1,y1,x2,y2,getCurColor(),(float)*m_gfx_a,getCurMode(),np< 5 || parms[4][0] > 0.5); } } void eel_lice_state::gfx_rect(int np, EEL_F **parms) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_rect"); if (!dest) return; int x1=(int)floor(parms[0][0]),y1=(int)floor(parms[1][0]),w=(int)floor(parms[2][0]),h=(int)floor(parms[3][0]); int filled=(np < 5 || parms[4][0] > 0.5); if (LICE_FUNCTION_VALID(LICE_FillRect) && LICE_FUNCTION_VALID(LICE_DrawRect) && w>0 && h>0) { SetImageDirty(dest); if (filled) LICE_FillRect(dest,x1,y1,w,h,getCurColor(),(float)*m_gfx_a,getCurMode()); else LICE_DrawRect(dest, x1, y1, w-1, h-1, getCurColor(), (float)*m_gfx_a, getCurMode()); } } void eel_lice_state::gfx_roundrect(int np, EEL_F **parms) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_roundrect"); if (!dest) return; const bool aa = np <= 5 || parms[5][0]>0.5; if (LICE_FUNCTION_VALID(LICE_RoundRect) && parms[2][0]>0 && parms[3][0]>0) { SetImageDirty(dest); LICE_RoundRect(dest, (float)parms[0][0], (float)parms[1][0], (float)parms[2][0], (float)parms[3][0], (int)parms[4][0], getCurColor(), (float)*m_gfx_a, getCurMode(), aa); } } void eel_lice_state::gfx_arc(int np, EEL_F **parms) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_arc"); if (!dest) return; const bool aa = np <= 5 || parms[5][0]>0.5; if (LICE_FUNCTION_VALID(LICE_Arc)) { SetImageDirty(dest); LICE_Arc(dest, (float)parms[0][0], (float)parms[1][0], (float)parms[2][0], (float)parms[3][0], (float)parms[4][0], getCurColor(), (float)*m_gfx_a, getCurMode(), aa); } } void eel_lice_state::gfx_grad_or_muladd_rect(int whichmode, int np, EEL_F **parms) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,whichmode==0?"gfx_gradrect":"gfx_muladdrect"); if (!dest) return; const int x1=(int)floor(parms[0][0]),y1=(int)floor(parms[1][0]),w=(int)floor(parms[2][0]), h=(int)floor(parms[3][0]); if (w>0 && h>0) { SetImageDirty(dest); if (whichmode==0 && LICE_FUNCTION_VALID(LICE_GradRect) && np > 7) { LICE_GradRect(dest,x1,y1,w,h,(float)parms[4][0],(float)parms[5][0],(float)parms[6][0],(float)parms[7][0], np > 8 ? (float)parms[8][0]:0.0f, np > 9 ? (float)parms[9][0]:0.0f, np > 10 ? (float)parms[10][0]:0.0f, np > 11 ? (float)parms[11][0]:0.0f, np > 12 ? (float)parms[12][0]:0.0f, np > 13 ? (float)parms[13][0]:0.0f, np > 14 ? (float)parms[14][0]:0.0f, np > 15 ? (float)parms[15][0]:0.0f, getCurMode()); } else if (whichmode==1 && LICE_FUNCTION_VALID(LICE_MultiplyAddRect) && np > 6) { const double sc = 255.0; LICE_MultiplyAddRect(dest,x1,y1,w,h,(float)parms[4][0],(float)parms[5][0],(float)parms[6][0],np>7 ? (float)parms[7][0]:1.0f, (float)(np > 8 ? sc*parms[8][0]:0.0), (float)(np > 9 ? sc*parms[9][0]:0.0), (float)(np > 10 ? sc*parms[10][0]:0.0), (float)(np > 11 ? sc*parms[11][0]:0.0)); } } } void eel_lice_state::gfx_setpixel(EEL_F r, EEL_F g, EEL_F b) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_setpixel"); if (!dest) return; int red=(int) (r*255.0); int green=(int) (g*255.0); int blue=(int) (b*255.0); if (red<0) red=0;else if (red>255)red=255; if (green<0) green=0;else if (green>255)green=255; if (blue<0) blue=0; else if (blue>255) blue=255; if (LICE_FUNCTION_VALID(LICE_PutPixel)) { SetImageDirty(dest); LICE_PutPixel(dest,(int)*m_gfx_x, (int)*m_gfx_y,LICE_RGBA(red,green,blue,255), (float)*m_gfx_a,getCurMode()); } } void eel_lice_state::gfx_getimgdim(EEL_F img, EEL_F *w, EEL_F *h) { *w=*h=0; #ifdef DYNAMIC_LICE if (!LICE__GetWidth || !LICE__GetHeight) return; #endif LICE_IBitmap *bm=GetImageForIndex(img,"gfx_getimgdim"); if (bm) { *w=LICE__GetWidth(bm); *h=LICE__GetHeight(bm); } } EEL_F eel_lice_state::gfx_loadimg(void *opaque, int img, EEL_F loadFrom) { #ifdef DYNAMIC_LICE if (!__LICE_LoadImage || !LICE__Destroy) return 0.0; #endif if (img >= 0 && img < m_gfx_images.GetSize()) { WDL_FastString fs; bool ok = EEL_LICE_GET_FILENAME_FOR_STRING(loadFrom,&fs,0); if (ok && fs.GetLength()) { LICE_IBitmap *bm = LICE_LoadImage(fs.Get(),NULL,false); if (bm) { LICE__Destroy(m_gfx_images.Get()[img]); m_gfx_images.Get()[img]=bm; return img; } } } return -1.0; } EEL_F eel_lice_state::gfx_setimgdim(int img, EEL_F *w, EEL_F *h) { int rv=0; #ifdef DYNAMIC_LICE if (!LICE__resize ||!LICE__GetWidth || !LICE__GetHeight||!__LICE_CreateBitmap) return 0.0; #endif int use_w = (int)*w; int use_h = (int)*h; if (use_w<1 || use_h < 1) use_w=use_h=0; if (use_w > 2048) use_w=2048; if (use_h > 2048) use_h=2048; LICE_IBitmap *bm=NULL; if (img >= 0 && img < m_gfx_images.GetSize()) { bm=m_gfx_images.Get()[img]; if (!bm) { m_gfx_images.Get()[img] = bm = __LICE_CreateBitmap(1,use_w,use_h); rv=!!bm; } else { rv=LICE__resize(bm,use_w,use_h); } } return rv?1.0:0.0; } void eel_lice_state::gfx_blurto(EEL_F x, EEL_F y) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_blurto"); if (!dest #ifdef DYNAMIC_LICE ||!LICE_Blur #endif ) return; SetImageDirty(dest); int srcx = (int)x; int srcy = (int)y; int srcw=(int) (*m_gfx_x-x); int srch=(int) (*m_gfx_y-y); if (srch < 0) { srch=-srch; srcy = (int)*m_gfx_y; } if (srcw < 0) { srcw=-srcw; srcx = (int)*m_gfx_x; } LICE_Blur(dest,dest,srcx,srcy,srcx,srcy,srcw,srch); *m_gfx_x = x; *m_gfx_y = y; } static bool CoordsSrcDestOverlap(EEL_F *coords) { if (coords[0]+coords[2] < coords[4]) return false; if (coords[0] > coords[4] + coords[6]) return false; if (coords[1]+coords[3] < coords[5]) return false; if (coords[1] > coords[5] + coords[7]) return false; return true; } void eel_lice_state::gfx_transformblit(EEL_F **parms, int div_w, int div_h, EEL_F *tab) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_transformblit"); if (!dest #ifdef DYNAMIC_LICE ||!LICE_ScaledBlit || !LICE_TransformBlit2 ||!LICE__GetWidth||!LICE__GetHeight #endif ) return; LICE_IBitmap *bm=GetImageForIndex(parms[0][0],"gfx_transformblit:src"); if (!bm) return; const int bmw=LICE__GetWidth(bm); const int bmh=LICE__GetHeight(bm); const bool isFromFB = bm==m_framebuffer; SetImageDirty(dest); if (bm == dest) { if (!m_framebuffer_extra && LICE_FUNCTION_VALID(__LICE_CreateBitmap)) m_framebuffer_extra=__LICE_CreateBitmap(0,bmw,bmh); if (m_framebuffer_extra) { LICE__resize(bm=m_framebuffer_extra,bmw,bmh); LICE_ScaledBlit(bm,dest, // copy the entire image 0,0,bmw,bmh, 0.0f,0.0f,(float)bmw,(float)bmh, 1.0f,LICE_BLIT_MODE_COPY); } } LICE_TransformBlit2(dest,bm,(int)floor(parms[1][0]),(int)floor(parms[2][0]),(int)floor(parms[3][0]),(int)floor(parms[4][0]),tab,div_w,div_h, (float)*m_gfx_a,getCurModeForBlit(isFromFB)); } EEL_F eel_lice_state::gfx_setfont(void *opaque, int np, EEL_F **parms) { int a = np>0 ? ((int)floor(parms[0][0]))-1 : -1; if (a>=0 && a < m_gfx_fonts.GetSize()) { gfxFontStruct *s = m_gfx_fonts.Get()+a; if (np>1 && LICE_FUNCTION_VALID(LICE_CreateFont) && LICE_FUNCTION_VALID(LICE__SetFromHFont)) { const int sz=np>2 ? (int)parms[2][0] : 10; bool doCreate=false; int fontflag=0; if (!s->font) s->actual_fontname[0]=0; { EEL_STRING_MUTEXLOCK_SCOPE const char *face=EEL_STRING_GET_FOR_INDEX(parms[1][0],NULL); #ifdef EEL_STRING_DEBUGOUT if (!face) EEL_STRING_DEBUGOUT("gfx_setfont: invalid string identifier %f",parms[1][0]); #endif if (!face || !*face) face="Arial"; { unsigned int c = np > 3 ? (unsigned int) parms[3][0] : 0; while (c) { if (toupper(c&0xff)=='B') fontflag|=1; else if (toupper(c&0xff)=='I') fontflag|=2; else if (toupper(c&0xff)=='U') fontflag|=4; else if (toupper(c&0xff)=='R') fontflag|=16; //LICE_FONT_FLAG_FX_BLUR else if (toupper(c&0xff)=='V') fontflag|=32;//LICE_FONT_FLAG_FX_INVERT else if (toupper(c&0xff)=='M') fontflag|=64;//LICE_FONT_FLAG_FX_MONO else if (toupper(c&0xff)=='S') fontflag|=128; //LICE_FONT_FLAG_FX_SHADOW else if (toupper(c&0xff)=='O') fontflag|=256; //LICE_FONT_FLAG_FX_OUTLINE c>>=8; } } if (fontflag != s->last_fontflag || sz!=s->last_fontsize || strncmp(s->last_fontname,face,sizeof(s->last_fontname)-1)) { lstrcpyn_safe(s->last_fontname,face,sizeof(s->last_fontname)); s->last_fontsize=sz; s->last_fontflag=fontflag; doCreate=1; } } if (doCreate) { s->actual_fontname[0]=0; if (!s->font) s->font=LICE_CreateFont(); if (s->font) { HFONT hf=CreateFont(sz,0,0,0,(fontflag&1) ? FW_BOLD : FW_NORMAL,!!(fontflag&2),!!(fontflag&4),FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,s->last_fontname); if (!hf) { s->use_fonth=0; // disable this font } else { TEXTMETRIC tm; tm.tmHeight = sz; if (!m_framebuffer && LICE_FUNCTION_VALID(__LICE_CreateBitmap)) m_framebuffer=__LICE_CreateBitmap(1,64,64); if (m_framebuffer && LICE_FUNCTION_VALID(LICE__GetDC)) { HGDIOBJ oldFont = 0; HDC hdc=LICE__GetDC(m_framebuffer); if (hdc) { oldFont = SelectObject(hdc,hf); GetTextMetrics(hdc,&tm); GetTextFace(hdc, sizeof(s->actual_fontname), s->actual_fontname); SelectObject(hdc,oldFont); } } s->use_fonth=wdl_max(tm.tmHeight,1); LICE__SetFromHFont(s->font,hf,512 | (fontflag&(511-15)));//LICE_FONT_FLAG_OWNS_HFONT); } } } } if (s->font && s->use_fonth) { m_gfx_font_active=a; if (m_gfx_texth) *m_gfx_texth=s->use_fonth; return 1.0; } // try to init this font } #ifdef EEL_STRING_DEBUGOUT if (a >= m_gfx_fonts.GetSize()) EEL_STRING_DEBUGOUT("gfx_setfont: invalid font %d specified",a); #endif if (a<0||a>=m_gfx_fonts.GetSize()||!m_gfx_fonts.Get()[a].font) { m_gfx_font_active=-1; if (m_gfx_texth) *m_gfx_texth=8; return 1.0; } return 0.0; } void eel_lice_state::gfx_blitext2(int np, EEL_F **parms, int blitmode) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_blitext2"); if (!dest #ifdef DYNAMIC_LICE ||!LICE_ScaledBlit || !LICE_RotatedBlit||!LICE__GetWidth||!LICE__GetHeight #endif ) return; LICE_IBitmap *bm=GetImageForIndex(parms[0][0],"gfx_blitext2:src"); if (!bm) return; const int bmw=LICE__GetWidth(bm); const int bmh=LICE__GetHeight(bm); // 0=img, 1=scale, 2=rotate double coords[8]; const double sc = blitmode==0 ? parms[1][0] : 1.0, angle = blitmode==0 ? parms[2][0] : 0.0; if (blitmode==0) { parms+=2; np -= 2; } coords[0]=np > 1 ? parms[1][0] : 0.0f; coords[1]=np > 2 ? parms[2][0] : 0.0f; coords[2]=np > 3 ? parms[3][0] : bmw; coords[3]=np > 4 ? parms[4][0] : bmh; coords[4]=np > 5 ? parms[5][0] : *m_gfx_x; coords[5]=np > 6 ? parms[6][0] : *m_gfx_y; coords[6]=np > 7 ? parms[7][0] : coords[2]*sc; coords[7]=np > 8 ? parms[8][0] : coords[3]*sc; const bool isFromFB = bm == m_framebuffer; SetImageDirty(dest); if (bm == dest && CoordsSrcDestOverlap(coords)) { if (!m_framebuffer_extra && LICE_FUNCTION_VALID(__LICE_CreateBitmap)) m_framebuffer_extra=__LICE_CreateBitmap(0,bmw,bmh); if (m_framebuffer_extra) { LICE__resize(bm=m_framebuffer_extra,bmw,bmh); LICE_ScaledBlit(bm,dest, // copy the source portion (int)coords[0],(int)coords[1],(int)coords[2],(int)coords[3], (float)coords[0],(float)coords[1],(float)coords[2],(float)coords[3], 1.0f,LICE_BLIT_MODE_COPY); } } if (blitmode==1) { if (LICE_FUNCTION_VALID(LICE_DeltaBlit)) LICE_DeltaBlit(dest,bm,(int)coords[4],(int)coords[5],(int)coords[6],(int)coords[7], (float)coords[0],(float)coords[1],(float)coords[2],(float)coords[3], np > 9 ? (float)parms[9][0]:1.0f, // dsdx np > 10 ? (float)parms[10][0]:0.0f, // dtdx np > 11 ? (float)parms[11][0]:0.0f, // dsdy np > 12 ? (float)parms[12][0]:1.0f, // dtdy np > 13 ? (float)parms[13][0]:0.0f, // dsdxdy np > 14 ? (float)parms[14][0]:0.0f, // dtdxdy true, (float)*m_gfx_a,getCurModeForBlit(isFromFB)); } else if (fabs(angle)>0.000000001) { LICE_RotatedBlit(dest,bm,(int)coords[4],(int)coords[5],(int)coords[6],(int)coords[7], (float)coords[0],(float)coords[1],(float)coords[2],(float)coords[3], (float)angle,true, (float)*m_gfx_a,getCurModeForBlit(isFromFB), np > 9 ? (float)parms[9][0] : 0.0f, np > 10 ? (float)parms[10][0] : 0.0f); } else { LICE_ScaledBlit(dest,bm,(int)coords[4],(int)coords[5],(int)coords[6],(int)coords[7], (float)coords[0],(float)coords[1],(float)coords[2],(float)coords[3], (float)*m_gfx_a,getCurModeForBlit(isFromFB)); } } void eel_lice_state::gfx_blitext(EEL_F img, EEL_F *coords, EEL_F angle) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_blitext"); if (!dest #ifdef DYNAMIC_LICE ||!LICE_ScaledBlit || !LICE_RotatedBlit||!LICE__GetWidth||!LICE__GetHeight #endif ) return; LICE_IBitmap *bm=GetImageForIndex(img,"gfx_blitext:src"); if (!bm) return; SetImageDirty(dest); const bool isFromFB = bm == m_framebuffer; int bmw=LICE__GetWidth(bm); int bmh=LICE__GetHeight(bm); if (bm == dest && CoordsSrcDestOverlap(coords)) { if (!m_framebuffer_extra && LICE_FUNCTION_VALID(__LICE_CreateBitmap)) m_framebuffer_extra=__LICE_CreateBitmap(0,bmw,bmh); if ( m_framebuffer_extra) { LICE__resize(bm=m_framebuffer_extra,bmw,bmh); LICE_ScaledBlit(bm,dest, // copy the source portion (int)coords[0],(int)coords[1],(int)coords[2],(int)coords[3], (float)coords[0],(float)coords[1],(float)coords[2],(float)coords[3], 1.0f,LICE_BLIT_MODE_COPY); } } if (fabs(angle)>0.000000001) { LICE_RotatedBlit(dest,bm,(int)coords[4],(int)coords[5],(int)coords[6],(int)coords[7], (float)coords[0],(float)coords[1],(float)coords[2],(float)coords[3],(float)angle, true, (float)*m_gfx_a,getCurModeForBlit(isFromFB), (float)coords[8],(float)coords[9]); } else { LICE_ScaledBlit(dest,bm,(int)coords[4],(int)coords[5],(int)coords[6],(int)coords[7], (float)coords[0],(float)coords[1],(float)coords[2],(float)coords[3], (float)*m_gfx_a,getCurModeForBlit(isFromFB)); } } void eel_lice_state::gfx_blit(EEL_F img, EEL_F scale, EEL_F rotate) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_blit"); if (!dest #ifdef DYNAMIC_LICE ||!LICE_ScaledBlit || !LICE_RotatedBlit||!LICE__GetWidth||!LICE__GetHeight #endif ) return; LICE_IBitmap *bm=GetImageForIndex(img,"gfx_blit:src"); if (!bm) return; SetImageDirty(dest); const bool isFromFB = bm == m_framebuffer; int bmw=LICE__GetWidth(bm); int bmh=LICE__GetHeight(bm); if (fabs(rotate)>0.000000001) { LICE_RotatedBlit(dest,bm,(int)*m_gfx_x,(int)*m_gfx_y,(int) (bmw*scale),(int) (bmh*scale),0.0f,0.0f,(float)bmw,(float)bmh,(float)rotate,true, (float)*m_gfx_a,getCurModeForBlit(isFromFB), 0.0f,0.0f); } else { LICE_ScaledBlit(dest,bm,(int)*m_gfx_x,(int)*m_gfx_y,(int) (bmw*scale),(int) (bmh*scale),0.0f,0.0f,(float)bmw,(float)bmh, (float)*m_gfx_a,getCurModeForBlit(isFromFB)); } } void eel_lice_state::gfx_set(int np, EEL_F **parms) { if (np < 1) return; if (m_gfx_r) *m_gfx_r = parms[0][0]; if (m_gfx_g) *m_gfx_g = np > 1 ? parms[1][0] : parms[0][0]; if (m_gfx_b) *m_gfx_b = np > 2 ? parms[2][0] : parms[0][0]; if (m_gfx_a) *m_gfx_a = np > 3 ? parms[3][0] : 1.0; if (m_gfx_mode) *m_gfx_mode = np > 4 ? parms[4][0] : 0; if (np > 5 && m_gfx_dest) *m_gfx_dest = parms[5][0]; } void eel_lice_state::gfx_getpixel(EEL_F *r, EEL_F *g, EEL_F *b) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_getpixel"); if (!dest) return; int ret=LICE_FUNCTION_VALID(LICE_GetPixel)?LICE_GetPixel(dest,(int)*m_gfx_x, (int)*m_gfx_y):0; *r=LICE_GETR(ret)/255.0; *g=LICE_GETG(ret)/255.0; *b=LICE_GETB(ret)/255.0; } static int __drawTextWithFont(LICE_IBitmap *dest, const RECT *rect, LICE_IFont *font, const char *buf, int buflen, int fg, int mode, float alpha, int flags, EEL_F *wantYoutput, EEL_F **measureOnly) { if (font && LICE_FUNCTION_VALID(LICE__DrawText)) { RECT tr=*rect; LICE__SetTextColor(font,fg); LICE__SetTextCombineMode(font,mode,alpha); int maxx=0; RECT r={0,0,tr.left,0}; while (buflen>0) { int thislen = 0; while (thislen < buflen && buf[thislen] != '\n') thislen++; memset(&r,0,sizeof(r)); int lineh = LICE__DrawText(font,dest,buf,thislen?thislen:1,&r,DT_SINGLELINE|DT_NOPREFIX|DT_CALCRECT); if (!measureOnly) { r.right += tr.left; lineh = LICE__DrawText(font,dest,buf,thislen?thislen:1,&tr,DT_SINGLELINE|DT_NOPREFIX|flags); if (wantYoutput) *wantYoutput = tr.top; } else { if (r.right > maxx) maxx=r.right; } tr.top += lineh; buflen -= thislen+1; buf += thislen+1; } if (measureOnly) { measureOnly[0][0] = maxx; measureOnly[1][0] = tr.top; } return r.right; } else { int xpos=rect->left, ypos=rect->top; int x; const int sxpos = xpos; int maxx=0,maxy=0; LICE_SubBitmap sbm( #ifdef DYNAMIC_LICE (LICE_IBitmap_disabledAPI*) #endif dest,rect->left,rect->top,rect->right-rect->left,rect->bottom-rect->top); if (!measureOnly) { if (!(flags & DT_NOCLIP)) { if (rect->right <= rect->left || rect->bottom <= rect->top) return 0; // invalid clip rect hm xpos = ypos = 0; dest = &sbm; } if (flags & (DT_RIGHT|DT_BOTTOM|DT_CENTER|DT_VCENTER)) { EEL_F w=0.0,h=0.0; EEL_F *mo[2] = { &w,&h}; __drawTextWithFont(dest,rect,NULL,buf,buflen,0,0,0.0f,0,NULL,mo); if (flags & DT_RIGHT) xpos += (rect->right-rect->left) - (int)floor(w); else if (flags & DT_CENTER) xpos += (rect->right-rect->left)/2 - (int)floor(w*.5); if (flags & DT_BOTTOM) ypos += (rect->bottom-rect->top) - (int)floor(h); else if (flags & DT_VCENTER) ypos += (rect->bottom-rect->top)/2 - (int)floor(h*.5); } } if (LICE_FUNCTION_VALID(LICE_DrawChar)) for(x=0;x maxx) maxx=xpos; maxy = ypos + 8; break; } } if (measureOnly) { measureOnly[0][0]=maxx; measureOnly[1][0]=maxy; } else { if (wantYoutput) *wantYoutput=ypos; } return xpos; } } static HMENU PopulateMenuFromStr(const char** str, int* startid) { HMENU hm=CreatePopupMenu(); int pos=0; int id=*startid; char buf[1024]; const char* p=*str; const char* sep=strchr(p, '|'); while (sep || *p) { int len = (int)(sep ? sep-p : strlen(p)); int destlen=wdl_min(len, (int)sizeof(buf)-1); lstrcpyn(buf, p, destlen+1); p += len; if (sep) sep=strchr(++p, '|'); const char* q=buf; HMENU subm=NULL; bool done=false; int flags=MF_BYPOSITION|MF_STRING; while (strspn(q, ">#!<")) { if (*q == '>' && !subm) { subm=PopulateMenuFromStr(&p, &id); sep=strchr(p, '|'); } if (*q == '#') flags |= MF_GRAYED; if (*q == '!') flags |= MF_CHECKED; if (*q == '<') done=true; ++q; } if (subm) flags |= MF_POPUP; if (*q) InsertMenu(hm, pos++, flags, (subm ? (INT_PTR)subm : (INT_PTR)id++), q); else if (!done) InsertMenu(hm, pos++, MF_BYPOSITION|MF_SEPARATOR, 0, NULL); if (done) break; } *str=p; *startid=id; if (!pos) { DestroyMenu(hm); return NULL; } return hm; } EEL_F eel_lice_state::gfx_showmenu(void* opaque, EEL_F** parms, int nparms) { if (!hwnd_standalone) return 0.0; const char* p=EEL_STRING_GET_FOR_INDEX(parms[0][0], NULL); if (!p || !p[0]) return 0.0; int id=1; HMENU hm=PopulateMenuFromStr(&p, &id); int ret=0; if (hm) { POINT pt = { (short)*m_gfx_x, (short)*m_gfx_y }; ClientToScreen(hwnd_standalone, &pt); ret=TrackPopupMenu(hm, TPM_NONOTIFY|TPM_RETURNCMD, pt.x, pt.y, 0, hwnd_standalone, NULL); DestroyMenu(hm); } return (EEL_F)ret; } EEL_F eel_lice_state::gfx_setcursor(void* opaque, EEL_F** parms, int nparms) { if (!hwnd_standalone) return 0.0; m_cursor_resid=(int)parms[0][0]; #ifdef EEL_LICE_LOADTHEMECURSOR m_cursor_name[0]=0; if (nparms > 1) { const char* p=EEL_STRING_GET_FOR_INDEX(parms[1][0], NULL); if (p && p[0]) lstrcpyn(m_cursor_name, p, sizeof(m_cursor_name)); } #endif return 1.0; } void eel_lice_state::gfx_drawstr(void *opaque, EEL_F **parms, int nparms, int formatmode)// formatmode=1 for format, 2 for purely measure no format { int nfmtparms = nparms-1; EEL_F **fmtparms = parms+1; const char *funcname = formatmode==1?"gfx_printf": formatmode==2?"gfx_measurestr": formatmode==3?"gfx_measurechar" : "gfx_drawstr"; LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,funcname); if (!dest) return; #ifdef DYNAMIC_LICE if (!LICE__GetWidth || !LICE__GetHeight) return; #endif EEL_STRING_MUTEXLOCK_SCOPE WDL_FastString *fs=NULL; char buf[4096]; int s_len=0; const char *s; if (formatmode==3) { s_len = WDL_MakeUTFChar(buf, (int)parms[0][0], sizeof(buf)); s=buf; } else { s=EEL_STRING_GET_FOR_INDEX(parms[0][0],&fs); #ifdef EEL_STRING_DEBUGOUT if (!s) EEL_STRING_DEBUGOUT("gfx_%s: invalid string identifier %f",funcname,parms[0][0]); #endif if (!s) { s=""; s_len = 12; } else if (formatmode==1) { extern int eel_format_strings(void *, const char *s, const char *ep, char *, int, int, EEL_F **); s_len = eel_format_strings(opaque,s,fs?(s+fs->GetLength()):NULL,buf,sizeof(buf),nfmtparms,fmtparms); if (s_len<1) return; s=buf; } else { s_len = fs?fs->GetLength():(int)strlen(s); } } if (s_len) { SetImageDirty(dest); if (formatmode>=2) { if (nfmtparms==2) { RECT r={0,0,0,0}; __drawTextWithFont(dest,&r,GetActiveFont(),s,s_len, getCurColor(),getCurMode(),(float)*m_gfx_a,0,NULL,fmtparms); } } else { RECT r={(int)floor(*m_gfx_x),(int)floor(*m_gfx_y),0,0}; int flags=DT_NOCLIP; if (formatmode == 0 && nparms >= 4) { flags=(int)*parms[1]; flags &= (DT_CENTER|DT_RIGHT|DT_VCENTER|DT_BOTTOM|DT_NOCLIP); r.right=(int)*parms[2]; r.bottom=(int)*parms[3]; } *m_gfx_x=__drawTextWithFont(dest,&r,GetActiveFont(),s,s_len, getCurColor(),getCurMode(),(float)*m_gfx_a,flags,m_gfx_y,NULL); } } } void eel_lice_state::gfx_drawchar(EEL_F ch) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_drawchar"); if (!dest) return; SetImageDirty(dest); int a=(int)(ch+0.5); if (a == '\r' || a=='\n') a=' '; char buf[32]; const int buflen = WDL_MakeUTFChar(buf, a, sizeof(buf)); RECT r={(int)floor(*m_gfx_x),(int)floor(*m_gfx_y),0,0}; *m_gfx_x = __drawTextWithFont(dest,&r, GetActiveFont(),buf,buflen, getCurColor(),getCurMode(),(float)*m_gfx_a,DT_NOCLIP,NULL,NULL); } void eel_lice_state::gfx_drawnumber(EEL_F n, EEL_F ndigits) { LICE_IBitmap *dest = GetImageForIndex(*m_gfx_dest,"gfx_drawnumber"); if (!dest) return; SetImageDirty(dest); char buf[512]; int a=(int)(ndigits+0.5); if (a <0)a=0; else if (a > 16) a=16; snprintf(buf,sizeof(buf),"%.*f",a,n); RECT r={(int)floor(*m_gfx_x),(int)floor(*m_gfx_y),0,0}; *m_gfx_x = __drawTextWithFont(dest,&r, GetActiveFont(),buf,(int)strlen(buf), getCurColor(),getCurMode(),(float)*m_gfx_a,DT_NOCLIP,NULL,NULL); } int eel_lice_state::setup_frame(HWND hwnd, RECT r, int _mouse_x, int _mouse_y) { int use_w = r.right - r.left; int use_h = r.bottom - r.top; POINT pt = { _mouse_x, _mouse_y }; if (hwnd) { GetCursorPos(&pt); ScreenToClient(hwnd,&pt); } *m_mouse_x=pt.x-r.left; *m_mouse_y=pt.y-r.top; if (*m_gfx_ext_retina > 0.0) { #ifdef __APPLE__ *m_gfx_ext_retina = (hwnd && SWELL_IsRetinaHWND(hwnd)) ? 2.0 : 1.0; if (*m_gfx_ext_retina > 1.0) { *m_mouse_x *= 2.0; *m_mouse_y *= 2.0; use_w*=2; use_h*=2; } #else *m_gfx_ext_retina = 1.0; #ifdef _WIN32 static UINT (WINAPI *__GetDpiForWindow)(HWND); if (!__GetDpiForWindow) { HINSTANCE h = LoadLibrary("user32.dll"); if (h) *(void **)&__GetDpiForWindow = GetProcAddress(h,"GetDpiForWindow"); if (!__GetDpiForWindow) *(void **)&__GetDpiForWindow = (void*)(INT_PTR)1; } if (hwnd && (UINT_PTR)__GetDpiForWindow > (UINT_PTR)1) { int dpi = __GetDpiForWindow(hwnd); if (dpi != 96) *m_gfx_ext_retina = dpi / 96.0; } #endif #endif } int dr=0; if (!m_framebuffer && LICE_FUNCTION_VALID(__LICE_CreateBitmap)) { m_framebuffer=__LICE_CreateBitmap(1,use_w,use_h); dr=1; } if (!m_framebuffer || !LICE_FUNCTION_VALID(LICE__GetHeight) || !LICE_FUNCTION_VALID(LICE__GetWidth)) return -1; if (use_w != LICE__GetWidth(m_framebuffer) || use_h != LICE__GetHeight(m_framebuffer)) { LICE__resize(m_framebuffer,use_w,use_h); dr=1; } *m_gfx_w = use_w; *m_gfx_h = use_h; if (*m_gfx_clear > -1.0 && dr) { const int a=(int)*m_gfx_clear; if (LICE_FUNCTION_VALID(LICE_Clear)) LICE_Clear(m_framebuffer,LICE_RGBA((a&0xff),((a>>8)&0xff),((a>>16)&0xff),0)); } m_framebuffer_dirty = dr; int vflags=0; if (m_has_cap) { bool swap = false; #ifdef _WIN32 swap = !!GetSystemMetrics(SM_SWAPBUTTON); #endif vflags|=m_has_cap&0xffff; if (GetAsyncKeyState(VK_LBUTTON)&0x8000) vflags|=swap?2:1; if (GetAsyncKeyState(VK_RBUTTON)&0x8000) vflags|=swap?1:2; if (GetAsyncKeyState(VK_MBUTTON)&0x8000) vflags|=64; } if (m_has_cap || (m_has_had_getch && hwnd && GetFocus()==hwnd)) { if (GetAsyncKeyState(VK_CONTROL)&0x8000) vflags|=4; if (GetAsyncKeyState(VK_SHIFT)&0x8000) vflags|=8; if (GetAsyncKeyState(VK_MENU)&0x8000) vflags|=16; if (GetAsyncKeyState(VK_LWIN)&0x8000) vflags|=32; } m_has_cap &= 0xf0000; *m_mouse_cap=(EEL_F)vflags; *m_gfx_dest = -1.0; // m_framebuffer *m_gfx_a= 1.0; // default to full alpha every call int fh; if (m_gfx_font_active>=0&&m_gfx_font_active0) *m_gfx_texth=fh; else *m_gfx_texth = 8; return dr; } #ifndef EEL_LICE_NO_REGISTER void eel_lice_register() { NSEEL_addfunc_retptr("gfx_lineto",3,NSEEL_PProc_THIS,&_gfx_lineto); NSEEL_addfunc_retptr("gfx_lineto",2,NSEEL_PProc_THIS,&_gfx_lineto2); NSEEL_addfunc_retptr("gfx_rectto",2,NSEEL_PProc_THIS,&_gfx_rectto); NSEEL_addfunc_varparm("gfx_rect",4,NSEEL_PProc_THIS,&_gfx_rect); NSEEL_addfunc_varparm("gfx_line",4,NSEEL_PProc_THIS,&_gfx_line); // 5th param is optionally AA NSEEL_addfunc_varparm("gfx_gradrect",8,NSEEL_PProc_THIS,&_gfx_gradrect); NSEEL_addfunc_varparm("gfx_muladdrect",7,NSEEL_PProc_THIS,&_gfx_muladdrect); NSEEL_addfunc_varparm("gfx_deltablit",9,NSEEL_PProc_THIS,&_gfx_deltablit); NSEEL_addfunc_exparms("gfx_transformblit",8,NSEEL_PProc_THIS,&_gfx_transformblit); NSEEL_addfunc_varparm("gfx_circle",3,NSEEL_PProc_THIS,&_gfx_circle); NSEEL_addfunc_varparm("gfx_triangle", 6, NSEEL_PProc_THIS, &_gfx_triangle); NSEEL_addfunc_varparm("gfx_roundrect",5,NSEEL_PProc_THIS,&_gfx_roundrect); NSEEL_addfunc_varparm("gfx_arc",5,NSEEL_PProc_THIS,&_gfx_arc); NSEEL_addfunc_retptr("gfx_blurto",2,NSEEL_PProc_THIS,&_gfx_blurto); NSEEL_addfunc_exparms("gfx_showmenu",1,NSEEL_PProc_THIS,&_gfx_showmenu); NSEEL_addfunc_varparm("gfx_setcursor",1, NSEEL_PProc_THIS, &_gfx_setcursor); NSEEL_addfunc_retptr("gfx_drawnumber",2,NSEEL_PProc_THIS,&_gfx_drawnumber); NSEEL_addfunc_retptr("gfx_drawchar",1,NSEEL_PProc_THIS,&_gfx_drawchar); NSEEL_addfunc_varparm("gfx_drawstr",1,NSEEL_PProc_THIS,&_gfx_drawstr); NSEEL_addfunc_retptr("gfx_measurestr",3,NSEEL_PProc_THIS,&_gfx_measurestr); NSEEL_addfunc_retptr("gfx_measurechar",3,NSEEL_PProc_THIS,&_gfx_measurechar); NSEEL_addfunc_varparm("gfx_printf",1,NSEEL_PProc_THIS,&_gfx_printf); NSEEL_addfunc_retptr("gfx_setpixel",3,NSEEL_PProc_THIS,&_gfx_setpixel); NSEEL_addfunc_retptr("gfx_getpixel",3,NSEEL_PProc_THIS,&_gfx_getpixel); NSEEL_addfunc_retptr("gfx_getimgdim",3,NSEEL_PProc_THIS,&_gfx_getimgdim); NSEEL_addfunc_retval("gfx_setimgdim",3,NSEEL_PProc_THIS,&_gfx_setimgdim); NSEEL_addfunc_retval("gfx_loadimg",2,NSEEL_PProc_THIS,&_gfx_loadimg); NSEEL_addfunc_retptr("gfx_blit",3,NSEEL_PProc_THIS,&_gfx_blit); NSEEL_addfunc_retptr("gfx_blitext",3,NSEEL_PProc_THIS,&_gfx_blitext); NSEEL_addfunc_varparm("gfx_blit",4,NSEEL_PProc_THIS,&_gfx_blit2); NSEEL_addfunc_varparm("gfx_setfont",1,NSEEL_PProc_THIS,&_gfx_setfont); NSEEL_addfunc_varparm("gfx_getfont",1,NSEEL_PProc_THIS,&_gfx_getfont); NSEEL_addfunc_varparm("gfx_set",1,NSEEL_PProc_THIS,&_gfx_set); } #endif #ifdef EEL_LICE_WANT_STANDALONE #ifdef _WIN32 static HINSTANCE eel_lice_hinstance; static const char *eel_lice_standalone_classname; #endif HWND eel_lice_standalone_owner; #ifdef EEL_LICE_WANT_STANDALONE_UPDATE static EEL_F * NSEEL_CGEN_CALL _gfx_update(void *opaque, EEL_F *n) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) { if (ctx->hwnd_standalone) { if (ctx->m_framebuffer_dirty) { #ifdef __APPLE__ void *p = SWELL_InitAutoRelease(); #endif InvalidateRect(ctx->hwnd_standalone,NULL,FALSE); UpdateWindow(ctx->hwnd_standalone); #ifdef __APPLE__ SWELL_QuitAutoRelease(p); #endif } // run message pump #ifndef EEL_LICE_WANT_STANDALONE_UPDATE_NO_MSGPUMP #ifdef _WIN32 MSG msg; while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } #else void SWELL_RunEvents(); SWELL_RunEvents(); #endif #endif RECT r; GetClientRect(ctx->hwnd_standalone,&r); ctx->setup_frame(ctx->hwnd_standalone,r); } } return n; } #endif static EEL_F NSEEL_CGEN_CALL _gfx_getchar(void *opaque, EEL_F *p) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) { ctx->m_has_had_getch=true; if (*p >= 2.0) { int x; const int n = sizeof(ctx->hwnd_standalone_kb_state) / sizeof(ctx->hwnd_standalone_kb_state[0]); int *st = ctx->hwnd_standalone_kb_state; int a = (int)*p; for (x=0;xhwnd_standalone) return -1.0; if (ctx->m_kb_queue_valid) { const int qsize = sizeof(ctx->m_kb_queue)/sizeof(ctx->m_kb_queue[0]); const int a = ctx->m_kb_queue[ctx->m_kb_queue_pos & (qsize-1)]; ctx->m_kb_queue_pos++; ctx->m_kb_queue_valid--; return a; } } return 0.0; } static int eel_lice_key_xlate(int msg, int wParam, int lParam, bool *isAltOut) { #define EEL_MB_C(a) (sizeof(a)<=2 ? a[0] : \ sizeof(a)==3 ? (((a[0])<<8)+(a[1])) : \ sizeof(a)==4 ? (((a[0])<<16)+((a[1])<<8)+(a[2])) : \ (((a[0])<<24)+((a[1])<<16)+((a[2])<<8)+(a[3]))) if (msg != WM_CHAR) { #ifndef _WIN32 if (lParam & FVIRTKEY) #endif switch (wParam) { case VK_HOME: return EEL_MB_C("home"); case VK_UP: return EEL_MB_C("up"); case VK_PRIOR: return EEL_MB_C("pgup"); case VK_LEFT: return EEL_MB_C("left"); case VK_RIGHT: return EEL_MB_C("rght"); case VK_END: return EEL_MB_C("end"); case VK_DOWN: return EEL_MB_C("down"); case VK_NEXT: return EEL_MB_C("pgdn"); case VK_INSERT: return EEL_MB_C("ins"); case VK_DELETE: return EEL_MB_C("del"); case VK_F1: return EEL_MB_C("f1"); case VK_F2: return EEL_MB_C("f2"); case VK_F3: return EEL_MB_C("f3"); case VK_F4: return EEL_MB_C("f4"); case VK_F5: return EEL_MB_C("f5"); case VK_F6: return EEL_MB_C("f6"); case VK_F7: return EEL_MB_C("f7"); case VK_F8: return EEL_MB_C("f8"); case VK_F9: return EEL_MB_C("f9"); case VK_F10: return EEL_MB_C("f10"); case VK_F11: return EEL_MB_C("f11"); case VK_F12: return EEL_MB_C("f12"); #ifndef _WIN32 case VK_SUBTRACT: return '-'; // numpad - case VK_ADD: return '+'; case VK_MULTIPLY: return '*'; case VK_DIVIDE: return '/'; case VK_DECIMAL: return '.'; case VK_NUMPAD0: return '0'; case VK_NUMPAD1: return '1'; case VK_NUMPAD2: return '2'; case VK_NUMPAD3: return '3'; case VK_NUMPAD4: return '4'; case VK_NUMPAD5: return '5'; case VK_NUMPAD6: return '6'; case VK_NUMPAD7: return '7'; case VK_NUMPAD8: return '8'; case VK_NUMPAD9: return '9'; case (32768|VK_RETURN): return VK_RETURN; #endif } switch (wParam) { case VK_RETURN: case VK_BACK: case VK_TAB: case VK_ESCAPE: return wParam; case VK_CONTROL: break; default: { const bool isctrl = !!(GetAsyncKeyState(VK_CONTROL)&0x8000); const bool isalt = !!(GetAsyncKeyState(VK_MENU)&0x8000); if(isctrl || isalt) { if (wParam>='a' && wParam<='z') { if (isctrl) wParam += 1-'a'; if (isalt) wParam += 256; *isAltOut=isalt; return wParam; } if (wParam>='A' && wParam<='Z') { if (isctrl) wParam += 1-'A'; if (isalt) wParam += 256; *isAltOut=isalt; return wParam; } } if (isctrl) { if ((wParam&~0x80) == '[') return 27; if ((wParam&~0x80) == ']') return 29; } } break; } } if(wParam>=32) { #ifdef _WIN32 if (msg == WM_CHAR) return wParam; #else if (!(GetAsyncKeyState(VK_SHIFT)&0x8000)) { if (wParam>='A' && wParam<='Z') { if ((GetAsyncKeyState(VK_LWIN)&0x8000)) wParam -= 'A'-1; else wParam += 'a'-'A'; } } return wParam; #endif } return 0; } #undef EEL_MB_C static LRESULT WINAPI eel_lice_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); #ifdef __APPLE__ extern "C" { void *objc_getClass(const char *p); void *sel_getUid(const char *p); void *objc_msgSend(void *, void *, ...); }; #endif HWND eel_lice_state::create_wnd(HWND par, int isChild) { if (hwnd_standalone) return hwnd_standalone; #ifdef _WIN32 return CreateWindowEx(0,eel_lice_standalone_classname,"", isChild ? (WS_CHILD|WS_TABSTOP) : (WS_POPUP|WS_CAPTION|WS_THICKFRAME|WS_SYSMENU),CW_USEDEFAULT,CW_USEDEFAULT,100,100,par,NULL,eel_lice_hinstance,this); #else return SWELL_CreateDialog(NULL,isChild ? NULL : ((const char *)(INT_PTR)0x400001),par,(DLGPROC)eel_lice_wndproc,(LPARAM)this); #endif } #ifdef EEL_LICE_WANTDOCK #ifndef ID_DOCKWINDOW #define ID_DOCKWINDOW 40269 #endif static EEL_F NSEEL_CGEN_CALL _gfx_dock(void *opaque, INT_PTR np, EEL_F **parms) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) { if (np > 0 && parms[0][0] >= 0.0 && ctx->hwnd_standalone) EEL_LICE_WANTDOCK(ctx,(int)parms[0][0]); if (np > 1 && parms[1]) parms[1][0] = ctx->m_last_undocked_r.left; if (np > 2 && parms[2]) parms[2][0] = ctx->m_last_undocked_r.top; if (np > 3 && parms[3]) parms[3][0] = ctx->m_last_undocked_r.right; if (np > 4 && parms[4]) parms[4][0] = ctx->m_last_undocked_r.bottom; #ifdef EEL_LICE_ISDOCKED return EEL_LICE_ISDOCKED(ctx); #endif } return 0.0; } #endif //EEL_LICE_WANTDOCK #ifndef EEL_LICE_STANDALONE_NOINITQUIT static EEL_F * NSEEL_CGEN_CALL _gfx_quit(void *opaque, EEL_F *n) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) { if (ctx->hwnd_standalone) { DestroyWindow(ctx->hwnd_standalone); } ctx->hwnd_standalone=0; } return n; } static EEL_F NSEEL_CGEN_CALL _gfx_init(void *opaque, INT_PTR np, EEL_F **parms) { #ifdef EEL_LICE_GET_CONTEXT_INIT eel_lice_state *ctx=EEL_LICE_GET_CONTEXT_INIT(opaque); #else eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); #endif if (ctx) { bool wantShow=false; if (!ctx->hwnd_standalone) { #ifdef __APPLE__ void *nsapp=objc_msgSend( objc_getClass("NSApplication"), sel_getUid("sharedApplication")); objc_msgSend(nsapp,sel_getUid("setActivationPolicy:"), 0); objc_msgSend(nsapp,sel_getUid("activateIgnoringOtherApps:"), 1); #endif #ifdef EEL_LICE_STANDALONE_PARENT HWND par = EEL_LICE_STANDALONE_PARENT(opaque); #elif defined(_WIN32) HWND par=GetDesktopWindow(); #else HWND par=NULL; #endif ctx->create_wnd(par,0); // resize client if (ctx->hwnd_standalone) { int sug_w = np > 1 ? (int)parms[1][0] : 640; int sug_h = np > 2 ? (int)parms[2][0] : 480; if (sug_w < 16) sug_w=16; else if (sug_w > 2048) sug_w=2048; if (sug_h < 16) sug_h=16; else if (sug_h > 1600) sug_w=1600; #ifdef EEL_LICE_WANTDOCK const int pos_offs = 4; #else const int pos_offs = 3; #endif int px=0,py=0; if (np >= pos_offs+2) { px = (int) floor(parms[pos_offs][0] + 0.5); py = (int) floor(parms[pos_offs+1][0] + 0.5); #ifdef EEL_LICE_VALIDATE_RECT_ON_SCREEN RECT r = {px,py,px+sug_w,py+sug_h}; EEL_LICE_VALIDATE_RECT_ON_SCREEN(r); px=r.left; py=r.top; sug_w = r.right-r.left; sug_h = r.bottom-r.top; #endif ctx->m_last_undocked_r.left = px; ctx->m_last_undocked_r.top = py; ctx->m_last_undocked_r.right = sug_w; ctx->m_last_undocked_r.bottom = sug_h; } RECT r1,r2; GetWindowRect(ctx->hwnd_standalone,&r1); GetClientRect(ctx->hwnd_standalone,&r2); sug_w += (r1.right-r1.left) - r2.right; sug_h += abs(r1.bottom-r1.top) - r2.bottom; SetWindowPos(ctx->hwnd_standalone,NULL,px,py,sug_w,sug_h,(np >= pos_offs+2 ? 0:SWP_NOMOVE)|SWP_NOZORDER|SWP_NOACTIVATE); wantShow=true; #ifdef EEL_LICE_WANTDOCK if (np > 3) EEL_LICE_WANTDOCK(ctx,parms[3][0]); #endif #ifdef EEL_LICE_WANT_STANDALONE_UPDATE { RECT r; GetClientRect(ctx->hwnd_standalone,&r); ctx->setup_frame(ctx->hwnd_standalone,r); } #endif } } if (np>0) { EEL_STRING_MUTEXLOCK_SCOPE const char *title=EEL_STRING_GET_FOR_INDEX(parms[0][0],NULL); #ifdef EEL_STRING_DEBUGOUT if (!title) EEL_STRING_DEBUGOUT("gfx_init: invalid string identifier %f",parms[0][0]); #endif if (title&&*title) SetWindowText(ctx->hwnd_standalone,title); } if (wantShow) ShowWindow(ctx->hwnd_standalone,SW_SHOW); return !!ctx->hwnd_standalone; } return 0; } static EEL_F NSEEL_CGEN_CALL _gfx_screentoclient(void *opaque, EEL_F *x, EEL_F *y) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx && ctx->hwnd_standalone) { POINT pt={(int) *x, (int) *y}; ScreenToClient(ctx->hwnd_standalone,&pt); *x = pt.x; *y = pt.y; return 1.0; } return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_clienttoscreen(void *opaque, EEL_F *x, EEL_F *y) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx && ctx->hwnd_standalone) { POINT pt={(int) *x, (int) *y}; ClientToScreen(ctx->hwnd_standalone,&pt); *x = pt.x; *y = pt.y; return 1.0; } return 0.0; } #endif // !EEL_LICE_STANDALONE_NOINITQUIT #ifndef WM_MOUSEWHEEL #define WM_MOUSEWHEEL 0x20A #endif #ifndef WM_MOUSEHWHEEL #define WM_MOUSEHWHEEL 0x20E #endif LRESULT WINAPI eel_lice_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { #ifdef WIN32 static UINT Scroll_Message; static bool sm_init; if (!sm_init) { sm_init=true; Scroll_Message = RegisterWindowMessage("MSWHEEL_ROLLMSG"); } if (Scroll_Message && uMsg == Scroll_Message) { uMsg=WM_MOUSEWHEEL; wParam<<=16; } #endif switch (uMsg) { case WM_CREATE: { #ifdef _WIN32 LPCREATESTRUCT lpcs= (LPCREATESTRUCT )lParam; eel_lice_state *ctx=(eel_lice_state*)lpcs->lpCreateParams; SetWindowLongPtr(hwnd,GWLP_USERDATA,(LPARAM)lpcs->lpCreateParams); #else eel_lice_state *ctx=(eel_lice_state*)lParam; SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam); #endif ctx->m_kb_queue_valid=0; ctx->hwnd_standalone=hwnd; } return 0; #ifndef _WIN32 case WM_CLOSE: DestroyWindow(hwnd); return 0; #endif case WM_DESTROY: { eel_lice_state *ctx=(eel_lice_state*)GetWindowLongPtr(hwnd,GWLP_USERDATA); if (ctx) { #ifdef EEL_LICE_WANTDOCK EEL_LICE_WANTDOCK(ctx,0); #endif ctx->hwnd_standalone=NULL; } } return 0; case WM_ACTIVATE: { eel_lice_state *ctx=(eel_lice_state*)GetWindowLongPtr(hwnd,GWLP_USERDATA); if (ctx) memset(&ctx->hwnd_standalone_kb_state,0,sizeof(ctx->hwnd_standalone_kb_state)); } break; case WM_SETCURSOR: { eel_lice_state *ctx=(eel_lice_state*)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (ctx && ctx->m_cursor_resid > 0) { POINT p; GetCursorPos(&p); ScreenToClient(hwnd, &p); RECT r; GetClientRect(hwnd, &r); if (p.x >= 0 && p.x < r.right && p.y >= 0 && p.y < r.bottom) { #ifdef EEL_LICE_LOADTHEMECURSOR if (ctx->m_cursor_name[0]) SetCursor(EEL_LICE_LOADTHEMECURSOR(ctx->m_cursor_resid, ctx->m_cursor_name)); else #endif SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(ctx->m_cursor_resid))); return TRUE; } } } break; #ifdef EEL_LICE_WANTDOCK case WM_CONTEXTMENU: { eel_lice_state *ctx=(eel_lice_state*)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (ctx) { char title[512], buf[1024]; GetWindowText(hwnd, title, sizeof(title)-1); if (!title[0]) strcpy(title, "ReaScript"); HMENU hm=CreatePopupMenu(); int pos=0; int flag=((EEL_LICE_ISDOCKED(ctx)&1) ? MF_CHECKED : 0); snprintf(buf, sizeof(buf), "Dock %s window in Docker", title); InsertMenu(hm, pos++, MF_BYPOSITION|MF_STRING|flag, ID_DOCKWINDOW, buf); snprintf(buf, sizeof(buf), "Close %s window", title); InsertMenu(hm, pos++, MF_BYPOSITION|MF_STRING, IDCANCEL, buf); POINT pt; GetCursorPos(&pt); TrackPopupMenu(hm, 0, pt.x, pt.y, 0, hwnd, NULL); DestroyMenu(hm); } } return 0; #endif case WM_COMMAND: switch (LOWORD(wParam)) { #ifdef EEL_LICE_WANTDOCK case ID_DOCKWINDOW: { eel_lice_state *ctx=(eel_lice_state*)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (ctx) EEL_LICE_WANTDOCK(ctx, EEL_LICE_ISDOCKED(ctx)^1); } return 0; #endif case IDCANCEL: DestroyWindow(hwnd); return 0; } break; case WM_MOUSEHWHEEL: case WM_MOUSEWHEEL: { eel_lice_state *ctx=(eel_lice_state*)GetWindowLongPtr(hwnd,GWLP_USERDATA); if (ctx) { EEL_F *p= uMsg==WM_MOUSEHWHEEL ? ctx->m_mouse_hwheel : ctx->m_mouse_wheel; if (p) *p += (EEL_F) (short)HIWORD(wParam); } } return -1; #ifdef _WIN32 case WM_SYSKEYDOWN: case WM_SYSKEYUP: #endif case WM_KEYDOWN: case WM_KEYUP: case WM_CHAR: { eel_lice_state *ctx=(eel_lice_state*)GetWindowLongPtr(hwnd,GWLP_USERDATA); bool hadAltAdj=false; int a=eel_lice_key_xlate(uMsg,(int)wParam,(int)lParam, &hadAltAdj); #ifdef _WIN32 if (!a && (uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP) && wParam >= 'A' && wParam <= 'Z') a=(int)wParam + 'a' - 'A'; #endif const int mask = hadAltAdj ? ~256 : ~0; if (a & mask) { int a_no_alt = (a&mask); const int lowera = a_no_alt >= 1 && a_no_alt < 27 ? (a_no_alt+'a'-1) : a_no_alt >= 'A' && a_no_alt <= 'Z' ? a_no_alt+'a'-'A' : a_no_alt; int *st = ctx->hwnd_standalone_kb_state; const int n = sizeof(ctx->hwnd_standalone_kb_state) / sizeof(ctx->hwnd_standalone_kb_state[0]); int zp=n-1,x; for (x=0;xm_kb_queue)/sizeof(ctx->m_kb_queue[0]); if (ctx->m_kb_queue_valid>=qsize) // queue full, dump an old event! { ctx->m_kb_queue_valid--; ctx->m_kb_queue_pos++; } ctx->m_kb_queue[(ctx->m_kb_queue_pos + ctx->m_kb_queue_valid++) & (qsize-1)] = a; } } return 0; case WM_LBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: case WM_LBUTTONDOWN: { POINT p = { (short)LOWORD(lParam), (short)HIWORD(lParam) }; RECT r; GetClientRect(hwnd, &r); if (p.x >= r.left && p.x < r.right && p.y >= r.top && p.y < r.bottom) { if (GetCapture()!=hwnd) SetFocus(hwnd); eel_lice_state *ctx=(eel_lice_state*)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (ctx) { if (GetCapture()!=hwnd) SetCapture(hwnd); int f = 0; if (uMsg == WM_LBUTTONDBLCLK || uMsg == WM_LBUTTONDOWN) f=0x10001; else if (uMsg == WM_RBUTTONDBLCLK || uMsg == WM_RBUTTONDOWN) f=0x20002; else if (uMsg == WM_MBUTTONDBLCLK || uMsg == WM_MBUTTONDOWN) f=0x40040; if (GetAsyncKeyState(VK_CONTROL)&0x8000) f|=4; if (GetAsyncKeyState(VK_SHIFT)&0x8000) f|=8; if (GetAsyncKeyState(VK_MENU)&0x8000) f|=16; if (GetAsyncKeyState(VK_LWIN)&0x8000) f|=32; ctx->m_has_cap|=f; } } } return 1; case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: case WM_CAPTURECHANGED: { eel_lice_state *ctx=(eel_lice_state*)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (ctx) { if (uMsg == WM_CAPTURECHANGED) { ctx->m_has_cap &= 0xffff; } else { if (uMsg == WM_LBUTTONUP) ctx->m_has_cap &= ~0x10000; else if (uMsg == WM_RBUTTONUP) ctx->m_has_cap &= ~0x20000; else if (uMsg == WM_MBUTTONUP) ctx->m_has_cap &= ~0x40000; if (!(ctx->m_has_cap & 0xf0000)) { ReleaseCapture(); } } } } return 1; #ifdef _WIN32 case WM_GETDLGCODE: if (GetWindowLong(hwnd,GWL_STYLE)&WS_CHILD) return DLGC_WANTALLKEYS; break; #endif case WM_SIZE: // fall through #ifndef EEL_LICE_STANDALONE_NOINITQUIT case WM_MOVE: if (uMsg != WM_SIZE || wParam != SIZE_MINIMIZED) { eel_lice_state *ctx=(eel_lice_state*)GetWindowLongPtr(hwnd,GWLP_USERDATA); if (ctx #ifdef EEL_LICE_ISDOCKED && !(GetWindowLong(hwnd,GWL_STYLE)&WS_CHILD) #endif ) { RECT r; GetWindowRect(hwnd,&ctx->m_last_undocked_r); GetClientRect(hwnd,&r); if (ctx->m_last_undocked_r.bottom < ctx->m_last_undocked_r.top) ctx->m_last_undocked_r.top = ctx->m_last_undocked_r.bottom; ctx->m_last_undocked_r.right = r.right; ctx->m_last_undocked_r.bottom = r.bottom; } } #endif break; case WM_PAINT: { PAINTSTRUCT ps; if (BeginPaint(hwnd,&ps)) { eel_lice_state *ctx=(eel_lice_state*)GetWindowLongPtr(hwnd,GWLP_USERDATA); if (ctx && ctx->m_framebuffer && LICE_FUNCTION_VALID(LICE__GetDC) && LICE_FUNCTION_VALID(LICE__GetWidth) && LICE_FUNCTION_VALID(LICE__GetHeight)) { int w = LICE__GetWidth(ctx->m_framebuffer); int h = LICE__GetHeight(ctx->m_framebuffer); #ifdef __APPLE__ if (*ctx->m_gfx_ext_retina > 1.0) { StretchBlt(ps.hdc,0,0,w/2,h/2,LICE__GetDC(ctx->m_framebuffer),0,0,w,h,SRCCOPY); } else #endif BitBlt(ps.hdc,0,0,w,h,LICE__GetDC(ctx->m_framebuffer),0,0,SRCCOPY); } EndPaint(hwnd,&ps); } } return 0; case WM_GETMINMAXINFO: { LPMINMAXINFO p=(LPMINMAXINFO)lParam; if (p->ptMinTrackSize.x > 10) p->ptMinTrackSize.x = 10; if (p->ptMinTrackSize.y > 10) p->ptMinTrackSize.y = 10; } return 0; } return DefWindowProc(hwnd,uMsg,wParam,lParam); } void eel_lice_register_standalone(HINSTANCE hInstance, const char *classname, HWND hwndPar, HICON icon) { #ifdef _WIN32 static bool reg; if (!reg) { eel_lice_hinstance=hInstance; eel_lice_standalone_classname=classname && *classname ? classname : "EEL_LICE_gfx_standalone"; WNDCLASS wc={CS_DBLCLKS,eel_lice_wndproc,0,0,hInstance,icon,LoadCursor(NULL,IDC_ARROW), NULL, NULL,eel_lice_standalone_classname}; RegisterClass(&wc); reg = true; } #endif #ifndef EEL_LICE_NO_REGISTER // gfx_init(title[, w,h, flags]) #ifndef EEL_LICE_STANDALONE_NOINITQUIT NSEEL_addfunc_varparm("gfx_init",1,NSEEL_PProc_THIS,&_gfx_init); NSEEL_addfunc_retptr("gfx_quit",1,NSEEL_PProc_THIS,&_gfx_quit); NSEEL_addfunc_retval("gfx_screentoclient",2,NSEEL_PProc_THIS,&_gfx_screentoclient); NSEEL_addfunc_retval("gfx_clienttoscreen",2,NSEEL_PProc_THIS,&_gfx_clienttoscreen); #endif #ifdef EEL_LICE_WANTDOCK NSEEL_addfunc_varparm("gfx_dock",1,NSEEL_PProc_THIS,&_gfx_dock); #endif #ifdef EEL_LICE_WANT_STANDALONE_UPDATE NSEEL_addfunc_retptr("gfx_update",1,NSEEL_PProc_THIS,&_gfx_update); #endif NSEEL_addfunc_retval("gfx_getchar",1,NSEEL_PProc_THIS,&_gfx_getchar); #endif } #endif #endif//!EEL_LICE_API_ONLY #ifdef DYNAMIC_LICE static void eel_lice_initfuncs(void *(*getFunc)(const char *name)) { if (!getFunc) return; *(void **)&__LICE_CreateBitmap = getFunc("LICE_CreateBitmap"); *(void **)&LICE_Clear = getFunc("LICE_Clear"); *(void **)&LICE_Line = getFunc("LICE_LineInt"); *(void **)&LICE_ClipLine = getFunc("LICE_ClipLine"); *(void **)&LICE_FillRect = getFunc("LICE_FillRect"); *(void **)&LICE_DrawRect = getFunc("LICE_DrawRect"); *(void **)&LICE_PutPixel = getFunc("LICE_PutPixel"); *(void **)&LICE_GetPixel = getFunc("LICE_GetPixel"); *(void **)&LICE_DrawText = getFunc("LICE_DrawText"); *(void **)&LICE_DrawChar = getFunc("LICE_DrawChar"); *(void **)&LICE_MeasureText = getFunc("LICE_MeasureText"); *(void **)&LICE_LoadImage = getFunc("LICE_LoadImage"); *(void **)&LICE__GetDC = getFunc("LICE__GetDC"); *(void **)&LICE__Destroy = getFunc("LICE__Destroy"); *(void **)&LICE__GetWidth = getFunc("LICE__GetWidth"); *(void **)&LICE__GetHeight = getFunc("LICE__GetHeight"); *(void **)&LICE__resize = getFunc("LICE__resize"); *(void **)&LICE_Blur = getFunc("LICE_Blur"); *(void **)&LICE_RotatedBlit = getFunc("LICE_RotatedBlit"); *(void **)&LICE_ScaledBlit = getFunc("LICE_ScaledBlit"); *(void **)&LICE_Circle = getFunc("LICE_Circle"); *(void **)&LICE_FillCircle = getFunc("LICE_FillCircle"); *(void **)&LICE_FillTriangle=getFunc("LICE_FillTriangle"); *(void **)&LICE_FillConvexPolygon=getFunc("LICE_FillConvexPolygon"); *(void **)&LICE_RoundRect = getFunc("LICE_RoundRect"); *(void **)&LICE_Arc = getFunc("LICE_Arc"); *(void **)&LICE_MultiplyAddRect = getFunc("LICE_MultiplyAddRect"); *(void **)&LICE_GradRect = getFunc("LICE_GradRect"); *(void **)&LICE_TransformBlit2 = getFunc("LICE_TransformBlit2"); *(void **)&LICE_DeltaBlit = getFunc("LICE_DeltaBlit"); *(void **)&LICE__DestroyFont = getFunc("LICE__DestroyFont"); *(void **)&LICE_CreateFont = getFunc("LICE_CreateFont"); *(void **)&LICE__SetFromHFont = getFunc("LICE__SetFromHFont2"); *(void **)&LICE__SetTextColor = getFunc("LICE__SetTextColor"); *(void **)&LICE__SetBkColor = getFunc("LICE__SetBkColor"); *(void **)&LICE__SetTextCombineMode = getFunc("LICE__SetTextCombineMode"); *(void **)&LICE__DrawText = getFunc("LICE__DrawText"); } #endif #ifdef EEL_WANT_DOCUMENTATION #ifdef EELSCRIPT_LICE_MAX_IMAGES #define MKSTR2(x) #x #define MKSTR(x) MKSTR2(x) #define EEL_LICE_DOC_MAXHANDLE MKSTR(EELSCRIPT_LICE_MAX_IMAGES-1) #else #define EEL_LICE_DOC_MAXHANDLE "127" #endif static const char *eel_lice_function_reference = #ifdef EEL_LICE_WANT_STANDALONE #ifndef EEL_LICE_STANDALONE_NOINITQUIT #ifdef EEL_LICE_WANTDOCK "gfx_init\t\"name\"[,width,height,dockstate,xpos,ypos]\tInitializes the graphics window with title name. Suggested width and height can be specified.\n\n" #else "gfx_init\t\"name\"[,width,height,xpos,ypos]\tInitializes the graphics window with title name. Suggested width and height can be specified.\n\n" #endif "Once the graphics window is open, gfx_update() should be called periodically. \0" "gfx_quit\t\tCloses the graphics window.\0" #endif #ifdef EEL_LICE_WANT_STANDALONE_UPDATE "gfx_update\t\tUpdates the graphics display, if opened\0" #endif #endif #ifdef EEL_LICE_WANTDOCK "gfx_dock\tv[,wx,wy,ww,wh]\tCall with v=-1 to query docked state, otherwise v>=0 to set docked state. State is &1 if docked, second byte is docker index (or last docker index if undocked). If wx-wh are specified, they will be filled with the undocked window position/size\0" #endif "gfx_aaaaa\t\t" "The following global variables are special and will be used by the graphics system:\n\n\3" "\4gfx_r, gfx_g, gfx_b, gfx_a - These represent the current red, green, blue, and alpha components used by drawing operations (0.0..1.0). \n" "\4gfx_w, gfx_h - These are set to the current width and height of the UI framebuffer. \n" "\4gfx_x, gfx_y - These set the \"current\" graphics position in x,y. You can set these yourselves, and many of the drawing functions update them as well. \n" "\4gfx_mode - Set to 0 for default options. Add 1.0 for additive blend mode (if you wish to do subtractive, set gfx_a to negative and use gfx_mode as additive). Add 2.0 to disable source alpha for gfx_blit(). Add 4.0 to disable filtering for gfx_blit(). \n" "\4gfx_clear - If set to a value greater than -1.0, this will result in the framebuffer being cleared to that color. the color for this one is packed RGB (0..255), i.e. red+green*256+blue*65536. The default is 0 (black). \n" "\4gfx_dest - Defaults to -1, set to 0.." EEL_LICE_DOC_MAXHANDLE " to have drawing operations go to an offscreen buffer (or loaded image).\n" "\4gfx_texth - Set to the height of a line of text in the current font. Do not modify this variable.\n" "\4gfx_ext_retina - If set to 1.0 on initialization, will be updated to 2.0 if high resolution display is supported, and if so gfx_w/gfx_h/etc will be doubled.\n" "\4mouse_x, mouse_y - mouse_x and mouse_y are set to the coordinates of the mouse relative to the graphics window.\n" "\4mouse_wheel, mouse_hwheel - mouse wheel (and horizontal wheel) positions. These will change typically by 120 or a multiple thereof, the caller should clear the state to 0 after reading it." "\4mouse_cap is a bitfield of mouse and keyboard modifier state.\3" "\4" "1: left mouse button\n" "\4" "2: right mouse button\n" #ifdef __APPLE__ "\4" "4: Command key\n" "\4" "8: Shift key\n" "\4" "16: Option key\n" "\4" "32: Control key\n" #else "\4" "4: Control key\n" "\4" "8: Shift key\n" "\4" "16: Alt key\n" "\4" "32: Windows key\n" #endif "\4" "64: middle mouse button\n" "\2" "\2\0" "gfx_getchar\t[char]\tIf char is 0 or omitted, returns a character from the keyboard queue, or 0 if no character is available, or -1 if the graphics window is not open. " "If char is specified and nonzero, that character's status will be checked, and the function will return greater than 0 if it is pressed.\n\n" "Common values are standard ASCII, such as 'a', 'A', '=' and '1', but for many keys multi-byte values are used, including 'home', 'up', 'down', 'left', 'rght', 'f1'.. 'f12', 'pgup', 'pgdn', 'ins', and 'del'. \n\n" "Modified and special keys can also be returned, including:\3\n" "\4Ctrl/Cmd+A..Ctrl+Z as 1..26\n" "\4Ctrl/Cmd+Alt+A..Z as 257..282\n" "\4Alt+A..Z as 'A'+256..'Z'+256\n" "\4" "27 for ESC\n" "\4" "13 for Enter\n" "\4' ' for space\n" "\2\0" "gfx_showmenu\t\"str\"\tShows a popup menu at gfx_x,gfx_y. str is a list of fields separated by | characters. " "Each field represents a menu item.\nFields can start with special characters:\n\n" "# : grayed out\n" "! : checked\n" "> : this menu item shows a submenu\n" "< : last item in the current submenu\n\n" "An empty field will appear as a separator in the menu. " "gfx_showmenu returns 0 if the user selected nothing from the menu, 1 if the first field is selected, etc.\nExample:\n\n" "gfx_showmenu(\"first item, followed by separator||!second item, checked|>third item which spawns a submenu|#first item in submenu, grayed out| #endif #include #include #include #define EEL_DCT_MINBITLEN 5 #define EEL_DCT_MAXBITLEN 12 #define PI 3.1415926535897932384626433832795 typedef struct { int n; int log2n; EEL_F *trig; int *bitrev; EEL_F *oldw; EEL_F scale; EEL_F *window; } mdct_lookup; static void mdct(EEL_F *in, EEL_F *out, int len) { int k; EEL_F pioverlen = PI * 0.5 / (EEL_F)len; for (k = 0; k < len / 2; k ++) { int i; EEL_F d = 0.0; for (i = 0; i < len; i ++) { d += in[i] * cos(pioverlen * (2.0 * i + 1.0 + len * 0.5) * (2.0 * k + 1.0)); } out[k] = (EEL_F)d; } } static void imdct(EEL_F *in, EEL_F *out, int len) { int k; EEL_F fourovern = 4.0 / (EEL_F)len; EEL_F pioverlen = PI * 0.5 / (EEL_F)len; for (k = 0; k < len; k ++) { int i; EEL_F d = 0.0; for (i = 0; i < len / 2; i ++) { d += in[i] * cos(pioverlen * (2.0 * k + 1.0 + len * 0.5) * (2 * i + 1.0)); } out[k] = (EEL_F)(d * fourovern); } } // MDCT/iMDCT borrowed from Vorbis, thanks xiph! #define cPI3_8 .38268343236508977175 #define cPI2_8 .70710678118654752441 #define cPI1_8 .92387953251128675613 #define FLOAT_CONV(x) ((EEL_F) ( x )) #define MULT_NORM(x) (x) #define HALVE(x) ((x)*.5f) /* 8 point butterfly (in place, 4 register) */ static void mdct_butterfly_8(EEL_F *x) { EEL_F r0 = x[6] + x[2]; EEL_F r1 = x[6] - x[2]; EEL_F r2 = x[4] + x[0]; EEL_F r3 = x[4] - x[0]; x[6] = r0 + r2; x[4] = r0 - r2; r0 = x[5] - x[1]; r2 = x[7] - x[3]; x[0] = r1 + r0; x[2] = r1 - r0; r0 = x[5] + x[1]; r1 = x[7] + x[3]; x[3] = r2 + r3; x[1] = r2 - r3; x[7] = r1 + r0; x[5] = r1 - r0; } /* 16 point butterfly (in place, 4 register) */ static void mdct_butterfly_16(EEL_F *x) { EEL_F r0 = x[1] - x[9]; EEL_F r1 = x[0] - x[8]; x[8] += x[0]; x[9] += x[1]; x[0] = MULT_NORM((r0 + r1) * cPI2_8); x[1] = MULT_NORM((r0 - r1) * cPI2_8); r0 = x[3] - x[11]; r1 = x[10] - x[2]; x[10] += x[2]; x[11] += x[3]; x[2] = r0; x[3] = r1; r0 = x[12] - x[4]; r1 = x[13] - x[5]; x[12] += x[4]; x[13] += x[5]; x[4] = MULT_NORM((r0 - r1) * cPI2_8); x[5] = MULT_NORM((r0 + r1) * cPI2_8); r0 = x[14] - x[6]; r1 = x[15] - x[7]; x[14] += x[6]; x[15] += x[7]; x[6] = r0; x[7] = r1; mdct_butterfly_8(x); mdct_butterfly_8(x + 8); } /* 32 point butterfly (in place, 4 register) */ static void mdct_butterfly_32(EEL_F *x) { EEL_F r0 = x[30] - x[14]; EEL_F r1 = x[31] - x[15]; x[30] += x[14]; x[31] += x[15]; x[14] = r0; x[15] = r1; r0 = x[28] - x[12]; r1 = x[29] - x[13]; x[28] += x[12]; x[29] += x[13]; x[12] = MULT_NORM( r0 * cPI1_8 - r1 * cPI3_8 ); x[13] = MULT_NORM( r0 * cPI3_8 + r1 * cPI1_8 ); r0 = x[26] - x[10]; r1 = x[27] - x[11]; x[26] += x[10]; x[27] += x[11]; x[10] = MULT_NORM(( r0 - r1 ) * cPI2_8); x[11] = MULT_NORM(( r0 + r1 ) * cPI2_8); r0 = x[24] - x[8]; r1 = x[25] - x[9]; x[24] += x[8]; x[25] += x[9]; x[8] = MULT_NORM( r0 * cPI3_8 - r1 * cPI1_8 ); x[9] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 ); r0 = x[22] - x[6]; r1 = x[7] - x[23]; x[22] += x[6]; x[23] += x[7]; x[6] = r1; x[7] = r0; r0 = x[4] - x[20]; r1 = x[5] - x[21]; x[20] += x[4]; x[21] += x[5]; x[4] = MULT_NORM( r1 * cPI1_8 + r0 * cPI3_8 ); x[5] = MULT_NORM( r1 * cPI3_8 - r0 * cPI1_8 ); r0 = x[2] - x[18]; r1 = x[3] - x[19]; x[18] += x[2]; x[19] += x[3]; x[2] = MULT_NORM(( r1 + r0 ) * cPI2_8); x[3] = MULT_NORM(( r1 - r0 ) * cPI2_8); r0 = x[0] - x[16]; r1 = x[1] - x[17]; x[16] += x[0]; x[17] += x[1]; x[0] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 ); x[1] = MULT_NORM( r1 * cPI1_8 - r0 * cPI3_8 ); mdct_butterfly_16(x); mdct_butterfly_16(x + 16); } /* N point first stage butterfly (in place, 2 register) */ static void mdct_butterfly_first(EEL_F *T, EEL_F *x, int points) { EEL_F *x1 = x + points - 8; EEL_F *x2 = x + (points >> 1) - 8; EEL_F r0; EEL_F r1; do { r0 = x1[6] - x2[6]; r1 = x1[7] - x2[7]; x1[6] += x2[6]; x1[7] += x2[7]; x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]); x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]); r0 = x1[4] - x2[4]; r1 = x1[5] - x2[5]; x1[4] += x2[4]; x1[5] += x2[5]; x2[4] = MULT_NORM(r1 * T[5] + r0 * T[4]); x2[5] = MULT_NORM(r1 * T[4] - r0 * T[5]); r0 = x1[2] - x2[2]; r1 = x1[3] - x2[3]; x1[2] += x2[2]; x1[3] += x2[3]; x2[2] = MULT_NORM(r1 * T[9] + r0 * T[8]); x2[3] = MULT_NORM(r1 * T[8] - r0 * T[9]); r0 = x1[0] - x2[0]; r1 = x1[1] - x2[1]; x1[0] += x2[0]; x1[1] += x2[1]; x2[0] = MULT_NORM(r1 * T[13] + r0 * T[12]); x2[1] = MULT_NORM(r1 * T[12] - r0 * T[13]); x1 -= 8; x2 -= 8; T += 16; } while(x2 >= x); } /* N/stage point generic N stage butterfly (in place, 2 register) */ static void mdct_butterfly_generic(EEL_F *T, EEL_F *x, int points, int trigint) { EEL_F *x1 = x + points - 8; EEL_F *x2 = x + (points >> 1) - 8; EEL_F r0; EEL_F r1; do { r0 = x1[6] - x2[6]; r1 = x1[7] - x2[7]; x1[6] += x2[6]; x1[7] += x2[7]; x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]); x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]); T += trigint; r0 = x1[4] - x2[4]; r1 = x1[5] - x2[5]; x1[4] += x2[4]; x1[5] += x2[5]; x2[4] = MULT_NORM(r1 * T[1] + r0 * T[0]); x2[5] = MULT_NORM(r1 * T[0] - r0 * T[1]); T += trigint; r0 = x1[2] - x2[2]; r1 = x1[3] - x2[3]; x1[2] += x2[2]; x1[3] += x2[3]; x2[2] = MULT_NORM(r1 * T[1] + r0 * T[0]); x2[3] = MULT_NORM(r1 * T[0] - r0 * T[1]); T += trigint; r0 = x1[0] - x2[0]; r1 = x1[1] - x2[1]; x1[0] += x2[0]; x1[1] += x2[1]; x2[0] = MULT_NORM(r1 * T[1] + r0 * T[0]); x2[1] = MULT_NORM(r1 * T[0] - r0 * T[1]); T += trigint; x1 -= 8; x2 -= 8; } while(x2 >= x); } static void mdct_butterflies(mdct_lookup *init, EEL_F *x, int points) { EEL_F *T = init->trig; int stages = init->log2n - 5; int i, j; if(--stages > 0) { mdct_butterfly_first(T, x, points); } for(i = 1; --stages > 0; i++) { for(j = 0; j < (1 << i); j++) mdct_butterfly_generic(T, x + (points >> i)*j, points >> i, 4 << i); } for(j = 0; j < points; j += 32) mdct_butterfly_32(x + j); } static void mdct_bitreverse(mdct_lookup *init, EEL_F *x) { int n = init->n; int *bit = init->bitrev; EEL_F *w0 = x; EEL_F *w1 = x = w0 + (n >> 1); EEL_F *T = init->trig + n; do { EEL_F *x0 = x + bit[0]; EEL_F *x1 = x + bit[1]; EEL_F r0 = x0[1] - x1[1]; EEL_F r1 = x0[0] + x1[0]; EEL_F r2 = MULT_NORM(r1 * T[0] + r0 * T[1]); EEL_F r3 = MULT_NORM(r1 * T[1] - r0 * T[0]); w1 -= 4; r0 = HALVE(x0[1] + x1[1]); r1 = HALVE(x0[0] - x1[0]); w0[0] = r0 + r2; w1[2] = r0 - r2; w0[1] = r1 + r3; w1[3] = r3 - r1; x0 = x + bit[2]; x1 = x + bit[3]; r0 = x0[1] - x1[1]; r1 = x0[0] + x1[0]; r2 = MULT_NORM(r1 * T[2] + r0 * T[3]); r3 = MULT_NORM(r1 * T[3] - r0 * T[2]); r0 = HALVE(x0[1] + x1[1]); r1 = HALVE(x0[0] - x1[0]); w0[2] = r0 + r2; w1[0] = r0 - r2; w0[3] = r1 + r3; w1[1] = r3 - r1; T += 4; bit += 4; w0 += 4; } while(w0 < w1); } static void megabuf_mdct_apply_window(void *init, EEL_F *inbuf, EEL_F *outbuf) { mdct_lookup *p = (mdct_lookup *)init; EEL_F *w; int cnt; if (!p) return; w = p->window; if (!w) return; cnt = p->n / 2; while (cnt--) *outbuf++ = *inbuf++ * *w++; cnt = p->n / 2; while (cnt--) *outbuf++ = *inbuf++ * *--w; } static void *megabuf_mdct_init(int n) { mdct_lookup *lookup = (mdct_lookup *)calloc(sizeof(mdct_lookup), 1); int i; EEL_F c = (PI / (EEL_F) n); int *bitrev; EEL_F *T, *oldw; int n2, log2n; if (!lookup) return 0; lookup->n = n; lookup->window = (EEL_F *)calloc(sizeof(EEL_F), n / 2); if (!lookup->window) return lookup; for (i = 0; i < n / 2; i ++) { lookup->window[i] = sin(c * (i + 0.5)); } if (n <= 32) return lookup; bitrev = (int*)calloc(sizeof(int), (n / 4)); lookup->bitrev = bitrev; if (!bitrev) return lookup; T = (EEL_F*)calloc(sizeof(EEL_F), (n + n / 4)); lookup->trig = T; if (!T) return lookup; oldw = (EEL_F*)calloc(n, sizeof(EEL_F)); lookup->oldw = oldw; if (!oldw) return lookup; n2 = n >> 1; log2n = lookup->log2n = (int)(log((double)n) / log(2.0) + 0.5); /* trig lookups... */ for(i = 0; i < n / 4; i++) { T[i * 2] = FLOAT_CONV(cos((PI / n) * (4 * i))); T[i * 2 + 1] = FLOAT_CONV(-sin((PI / n) * (4 * i))); T[n2 + i * 2] = FLOAT_CONV(cos((PI / (2 * n)) * (2 * i + 1))); T[n2 + i * 2 + 1] = FLOAT_CONV(sin((PI / (2 * n)) * (2 * i + 1))); } for(i = 0; i < n / 8; i++) { T[n + i * 2] = FLOAT_CONV(cos((PI / n) * (4 * i + 2)) * .5); T[n + i * 2 + 1] = FLOAT_CONV(-sin((PI / n) * (4 * i + 2)) * .5); } /* bitreverse lookup... */ { int mask = (1 << (log2n - 1)) - 1, j; int msb = 1 << (log2n - 2); for(i = 0; i < n / 8; i++) { int acc = 0; for(j = 0; msb >> j; j++) if((msb >> j)&i)acc |= 1 << j; bitrev[i * 2] = ((~acc)&mask) - 1; bitrev[i * 2 + 1] = acc; } } lookup->scale = FLOAT_CONV(4.f / n); return lookup; } static void megabuf_mdct_backward(void *init, EEL_F *in, EEL_F *out) { mdct_lookup *lookup = (mdct_lookup *)init; int n, n2, n4; EEL_F *iX, *oX, *T; if (!lookup) return; n = lookup->n; if (n <= 32 || !lookup->bitrev || !lookup->trig || !lookup->oldw) { imdct(in, out, n); return; } n2 = n >> 1; n4 = n >> 2; /* rotate */ iX = in + n2 - 7; oX = out + n2 + n4; T = lookup->trig + n4; do { oX -= 4; oX[0] = MULT_NORM(-iX[2] * T[3] - iX[0] * T[2]); oX[1] = MULT_NORM (iX[0] * T[3] - iX[2] * T[2]); oX[2] = MULT_NORM(-iX[6] * T[1] - iX[4] * T[0]); oX[3] = MULT_NORM (iX[4] * T[1] - iX[6] * T[0]); iX -= 8; T += 4; } while(iX >= in); iX = in + n2 - 8; oX = out + n2 + n4; T = lookup->trig + n4; do { T -= 4; oX[0] = MULT_NORM (iX[4] * T[3] + iX[6] * T[2]); oX[1] = MULT_NORM (iX[4] * T[2] - iX[6] * T[3]); oX[2] = MULT_NORM (iX[0] * T[1] + iX[2] * T[0]); oX[3] = MULT_NORM (iX[0] * T[0] - iX[2] * T[1]); iX -= 8; oX += 4; } while(iX >= in); mdct_butterflies(lookup, out + n2, n2); mdct_bitreverse(lookup, out); /* roatate + window */ { EEL_F *oX1 = out + n2 + n4; EEL_F *oX2 = out + n2 + n4; iX = out; T = lookup->trig + n2; do { oX1 -= 4; oX1[3] = MULT_NORM (iX[0] * T[1] - iX[1] * T[0]); oX2[0] = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]); oX1[2] = MULT_NORM (iX[2] * T[3] - iX[3] * T[2]); oX2[1] = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]); oX1[1] = MULT_NORM (iX[4] * T[5] - iX[5] * T[4]); oX2[2] = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]); oX1[0] = MULT_NORM (iX[6] * T[7] - iX[7] * T[6]); oX2[3] = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]); oX2 += 4; iX += 8; T += 8; } while(iX < oX1); iX = out + n2 + n4; oX1 = out + n4; oX2 = oX1; do { oX1 -= 4; iX -= 4; oX2[0] = -(oX1[3] = iX[3]); oX2[1] = -(oX1[2] = iX[2]); oX2[2] = -(oX1[1] = iX[1]); oX2[3] = -(oX1[0] = iX[0]); oX2 += 4; } while(oX2 < iX); iX = out + n2 + n4; oX1 = out + n2 + n4; oX2 = out + n2; do { oX1 -= 4; oX1[0] = iX[3]; oX1[1] = iX[2]; oX1[2] = iX[1]; oX1[3] = iX[0]; iX += 4; } while(oX1 > oX2); } } static void megabuf_mdct_forward(void *init, EEL_F *in, EEL_F *out) { mdct_lookup *lookup = (mdct_lookup *)init; int n, n2, n4, n8; EEL_F *oldw, *w, *w2; if (!lookup) return; n = lookup->n; if (n <= 32 || !lookup->bitrev || !lookup->trig || !lookup->oldw) { mdct(in, out, n); return; } n2 = n >> 1; n4 = n >> 2; n8 = n >> 3; oldw = lookup->oldw; w = oldw; w2 = w + n2; /* rotate */ /* window + rotate + step 1 */ { EEL_F r0; EEL_F r1; EEL_F *x0 = in + n2 + n4; EEL_F *x1 = x0 + 1; EEL_F *T = lookup->trig + n2; int i = 0; for(i = 0; i < n8; i += 2) { x0 -= 4; T -= 2; r0 = x0[2] + x1[0]; r1 = x0[0] + x1[2]; w2[i] = MULT_NORM(r1 * T[1] + r0 * T[0]); w2[i + 1] = MULT_NORM(r1 * T[0] - r0 * T[1]); x1 += 4; } x1 = in + 1; for(; i < n2 - n8; i += 2) { T -= 2; x0 -= 4; r0 = x0[2] - x1[0]; r1 = x0[0] - x1[2]; w2[i] = MULT_NORM(r1 * T[1] + r0 * T[0]); w2[i + 1] = MULT_NORM(r1 * T[0] - r0 * T[1]); x1 += 4; } x0 = in + n; for(; i < n2; i += 2) { T -= 2; x0 -= 4; r0 = -x0[2] - x1[0]; r1 = -x0[0] - x1[2]; w2[i] = MULT_NORM(r1 * T[1] + r0 * T[0]); w2[i + 1] = MULT_NORM(r1 * T[0] - r0 * T[1]); x1 += 4; } mdct_butterflies(lookup, w + n2, n2); mdct_bitreverse(lookup, w); /* roatate + window */ T = lookup->trig + n2; x0 = out + n2; for(i = 0; i < n4; i++) { x0--; out[i] = MULT_NORM((w[0] * T[0] + w[1] * T[1]) * lookup->scale); x0[0] = MULT_NORM((w[0] * T[1] - w[1] * T[0]) * lookup->scale); w += 2; T += 2; } } } #if 0 static void dct(EEL_F *in, EEL_F *out, int len) { int k; EEL_F wk = sqrt(2.0 / len); EEL_F overtwolen = 0.5 / (EEL_F)len; for (k = 0; k < len; k ++) { int n; EEL_F d = 0.0; for (n = 0; n < len; n ++) { int an = n + 1; d += in[n] * cos(PI * (2.0 * n + 1.0) * (EEL_F)k * overtwolen); } if (!k) d /= sqrt(len); else d *= wk; out[k] = (EEL_F)d; } } static void idct(EEL_F *in, EEL_F *out, int len) { int n; EEL_F dd0 = 1.0 / sqrt(len); EEL_F dd1 = sqrt(2.0 / len); EEL_F overtwolen = 0.5 / len; for (n = 0; n < len; n ++) { int k; EEL_F d = 0.0; for (k = 0; k < len; k ++) { EEL_F dd; if (!k) dd = dd0 * in[k]; else dd = dd1 * in[k]; d += dd * cos(PI * (2.0 * n + 1.0) * k * overtwolen); } out[n] = (EEL_F)d; } } #endif // 0 is megabuf blocks // 1 is need_free flag static EEL_F * NSEEL_CGEN_CALL mdct_func(int dir, EEL_F **blocks, EEL_F *start, EEL_F *length) { int l = (int)(*length + 0.0001); int offs = (int)(*start + 0.0001); int bitl = 0; int ilen; int bidx; EEL_F *ptr; while (l > 1 && bitl < EEL_DCT_MAXBITLEN) { bitl++; l >>= 1; } if (bitl < EEL_DCT_MINBITLEN) { return start; } ilen = 1 << bitl; bidx = bitl - EEL_DCT_MINBITLEN; // check to make sure we don't cross a boundary if (offs / NSEEL_RAM_ITEMSPERBLOCK != (offs + ilen * 2 - 1) / NSEEL_RAM_ITEMSPERBLOCK) { return start; } ptr = __NSEEL_RAMAlloc(blocks, offs); if (!ptr || ptr == &nseel_ramalloc_onfail) { return start; } if (ilen > 1) { static void *mdct_ctxs[1 + EEL_DCT_MAXBITLEN - EEL_DCT_MINBITLEN]; if (!mdct_ctxs[bidx]) { NSEEL_HOSTSTUB_EnterMutex(); if (!mdct_ctxs[bidx]) mdct_ctxs[bidx] = megabuf_mdct_init(ilen); NSEEL_HOSTSTUB_LeaveMutex(); } if (mdct_ctxs[bidx]) { EEL_F buf[1 << EEL_DCT_MAXBITLEN]; if (dir < 0) { megabuf_mdct_backward(mdct_ctxs[bidx], ptr, buf); megabuf_mdct_apply_window(mdct_ctxs[bidx], buf, ptr); } else { megabuf_mdct_apply_window(mdct_ctxs[bidx], ptr, buf); megabuf_mdct_forward(mdct_ctxs[bidx], buf, ptr); } } } return start; } static EEL_F * NSEEL_CGEN_CALL megabuf_mdct(EEL_F **blocks, EEL_F *start, EEL_F *length) { return mdct_func(0, blocks, start, length); } static EEL_F * NSEEL_CGEN_CALL megabuf_imdct(EEL_F **blocks, EEL_F *start, EEL_F *length) { return mdct_func(-1, blocks, start, length); } void EEL_mdct_register() { NSEEL_addfunc_retptr("mdct", 2, NSEEL_PProc_RAM, &megabuf_mdct); NSEEL_addfunc_retptr("imdct", 2, NSEEL_PProc_RAM, &megabuf_imdct); } #ifdef EEL_WANT_DOCUMENTATION static const char *eel_mdct_function_reference = "mdct\tbuffer,length\tPerforms a windowed modified DCT, taking length inputs and producing length/2 outputs. buffer must not cross a 65,536 item boundary, and length must be 64, 128, 256, 512, 2048 or 4096.\0" "imdct\tbuffer,length\tPerforms a windowed inverse modified DCT, taking length/2 inputs and producing length outputs. buffer must not cross a 65,536 item boundary, and length must be 64, 128, 256, 512, 2048 or 4096.\0" ; #endif #endif jsusfx-0.4.0/src/WDL/eel2/eel_misc.h000066400000000000000000000040061353477307700170520ustar00rootroot00000000000000#ifndef _EEL_MISC_H_ #define _EEL_MISC_H_ #ifndef _WIN32 #include #endif #include // some generic EEL functions for things like time #ifndef EEL_MISC_NO_SLEEP static EEL_F NSEEL_CGEN_CALL _eel_sleep(void *opaque, EEL_F *amt) { if (*amt >= 0.0) { #ifdef _WIN32 if (*amt > 30000000.0) Sleep(30000000); else Sleep((DWORD)(*amt+0.5)); #else if (*amt > 30000000.0) usleep(((useconds_t)30000000)*1000); else usleep((useconds_t)(*amt*1000.0+0.5)); #endif } return 0.0; } #endif static EEL_F * NSEEL_CGEN_CALL _eel_time(void *opaque, EEL_F *v) { *v = (EEL_F) time(NULL); return v; } static EEL_F * NSEEL_CGEN_CALL _eel_time_precise(void *opaque, EEL_F *v) { #ifdef _WIN32 LARGE_INTEGER freq,now; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&now); *v = (double)now.QuadPart / (double)freq.QuadPart; // *v = (EEL_F)timeGetTime() * 0.001; #else struct timeval tm={0,}; gettimeofday(&tm,NULL); *v = tm.tv_sec + tm.tv_usec*0.000001; #endif return v; } void EEL_misc_register() { #ifndef EEL_MISC_NO_SLEEP NSEEL_addfunc_retval("sleep",1,NSEEL_PProc_THIS,&_eel_sleep); #endif NSEEL_addfunc_retptr("time",1,NSEEL_PProc_THIS,&_eel_time); NSEEL_addfunc_retptr("time_precise",1,NSEEL_PProc_THIS,&_eel_time_precise); } #ifdef EEL_WANT_DOCUMENTATION static const char *eel_misc_function_reference = #ifndef EEL_MISC_NO_SLEEP "sleep\tms\tYields the CPU for the millisecond count specified, calling Sleep() on Windows or usleep() on other platforms.\0" #endif "time\t[&val]\tSets the parameter (or a temporary buffer if omitted) to the number of seconds since January 1, 1970, and returns a reference to that value. " "The granularity of the value returned is 1 second.\0" "time_precise\t[&val]\tSets the parameter (or a temporary buffer if omitted) to a system-local timestamp in seconds, and returns a reference to that value. " "The granularity of the value returned is system defined (but generally significantly smaller than one second).\0" ; #endif #endif jsusfx-0.4.0/src/WDL/eel2/eel_net.h000066400000000000000000000375561353477307700167250ustar00rootroot00000000000000#ifndef _EEL_NET_H_ #define _EEL_NET_H_ // x = tcp_listen(port[,interface, connected_ip_out]) poll this, returns connection id > 0, or <0 on error, or 0 if no new connect -- interface only valid on first call (or after tcp_listen_end(port)) // tcp_listen_end(port); // connection = tcp_connect(host, port[, block]) // connection id > 0 on ok // tcp_set_block(connection, block?) // tcp_close(connection) // tcp_send(connection, string[, length]) // can return 0 if block, -1 if error, otherwise returns length sent // tcp_recv(connection, string[, maxlength]) // 0 on nothing, -1 on error, otherwise returns length recv'd // need: // #define EEL_NET_GET_CONTEXT(opaque) (((sInst *)opaque)->m_net_state) // you must pass a JNL_AsyncDNS object to eel_net_state to support nonblocking connect with DNS resolution, otherwise DNS will block // #define EEL_NET_NO_SYNC_DNS -- never ever call gethostbyname() synchronously, may disable DNS for blocking connect, or if a JNL_IAsyncDNS is not provided. #ifndef EEL_NET_MAXSEND #define EEL_NET_MAXSEND (EEL_STRING_MAXUSERSTRING_LENGTH_HINT+4096) #endif #include "../jnetlib/netinc.h" #define JNL_NO_IMPLEMENTATION #include "../jnetlib/asyncdns.h" #ifndef _WIN32 // this can probably be removed after a merge... typedef int SOCKET; #ifndef INVALID_SOCKET #define INVALID_SOCKET (-1) #endif #else #ifndef ENOTCONN #define ENOTCONN WSAENOTCONN #endif #endif class eel_net_state { public: enum { STATE_FREE=0, STATE_RESOLVING, STATE_CONNECTED, STATE_ERR }; enum { CONNECTION_ID_BASE=0x110000 }; eel_net_state(int max_con, JNL_IAsyncDNS *dns); ~eel_net_state(); struct connection_state { char *hostname; // set during resolve only SOCKET sock; int state; // STATE_RESOLVING... int port; bool blockmode; }; WDL_TypedBuf m_cons; WDL_IntKeyedArray m_listens; JNL_IAsyncDNS *m_dns; EEL_F onConnect(char *hostNameOwned, int port, int block); EEL_F onClose(void *opaque, EEL_F handle); EEL_F set_block(void *opaque, EEL_F handle, bool block); EEL_F onListen(void *opaque, EEL_F handle, int mode, EEL_F *ifStr, EEL_F *ipOut); int __run_connect(connection_state *cs, unsigned int ip); int __run(connection_state *cs); int do_send(void *opaque, EEL_F h, const char *src, int len); int do_recv(void *opaque, EEL_F h, char *buf, int maxlen); #ifdef _WIN32 bool m_had_socketlib_init; #endif }; eel_net_state::eel_net_state(int max_con, JNL_IAsyncDNS *dns) { #ifdef _WIN32 m_had_socketlib_init=false; #endif m_cons.Resize(max_con); int x; for (x=0;xstate == STATE_FREE) { unsigned int ip=inet_addr(hostNameOwned); if (m_dns && ip == INADDR_NONE && !block) { const int r=m_dns->resolve(hostNameOwned,&ip); if (r<0) break; // error! if (r>0) ip = INADDR_NONE; } #ifndef EEL_NET_NO_SYNC_DNS else if (ip == INADDR_NONE) { struct hostent *he = gethostbyname(hostNameOwned); if (he) ip = *(int *)he->h_addr; } #endif if (hostNameOwned || ip != INADDR_NONE) { if (ip != INADDR_NONE) { free(hostNameOwned); hostNameOwned=NULL; } s->state = STATE_RESOLVING; s->hostname = hostNameOwned; s->blockmode = !!block; s->port = port; if (hostNameOwned || __run_connect(s,ip)) return x + CONNECTION_ID_BASE; s->state=STATE_FREE; s->hostname=NULL; } break; } } free(hostNameOwned); return -1; } EEL_F eel_net_state::onListen(void *opaque, EEL_F handle, int mode, EEL_F *ifStr, EEL_F *ipOut) { const int port = (int) handle; if (port < 1 || port > 65535) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("tcp_listen(%d): invalid port specified, will never succeed",port); #endif return 0.0; } #ifdef _WIN32 if (!m_had_socketlib_init) { m_had_socketlib_init=1; WSADATA wsaData; WSAStartup(MAKEWORD(1, 1), &wsaData); } #endif SOCKET *sockptr = m_listens.GetPtr(port); if (mode<0) { if (!sockptr) return -1.0; SOCKET ss=*sockptr; m_listens.Delete(port); if (ss != INVALID_SOCKET) closesocket(ss); return 0.0; } if (!sockptr) { struct sockaddr_in sin; memset((char *) &sin, 0,sizeof(sin)); if (ifStr) { EEL_STRING_MUTEXLOCK_SCOPE const char *fn = EEL_STRING_GET_FOR_INDEX(*ifStr,NULL); #ifdef EEL_STRING_DEBUGOUT if (!fn) EEL_STRING_DEBUGOUT("tcp_listen(%d): bad string identifier %f for second parameter (interface)",port,*ifStr); #endif if (fn && *fn) sin.sin_addr.s_addr=inet_addr(fn); } if (!sin.sin_addr.s_addr || sin.sin_addr.s_addr==INADDR_NONE) sin.sin_addr.s_addr = INADDR_ANY; sin.sin_family = AF_INET; sin.sin_port = htons( (short) port ); SOCKET sock = socket(AF_INET,SOCK_STREAM,0); if (sock != INVALID_SOCKET) { SET_SOCK_BLOCK(sock,0); if (bind(sock,(struct sockaddr *)&sin,sizeof(sin)) || listen(sock,8)==-1) { closesocket(sock); sock=INVALID_SOCKET; } } #ifdef EEL_STRING_DEBUGOUT //if (sock == INVALID_SOCKET) EEL_STRING_DEBUGOUT("tcp_listen(%d): failed listening on port",port); // we report -1 to the caller, no need to error message #endif m_listens.Insert(port,sock); sockptr = m_listens.GetPtr(port); } if (!sockptr || *sockptr == INVALID_SOCKET) return -1; struct sockaddr_in saddr; socklen_t length = sizeof(struct sockaddr_in); SOCKET newsock = accept(*sockptr, (struct sockaddr *) &saddr, &length); if (newsock == INVALID_SOCKET) { return 0; // nothing to report here } int x; for(x=0;xstate == STATE_FREE) { cs->state=STATE_CONNECTED; free(cs->hostname); cs->hostname=NULL; cs->sock = newsock; cs->blockmode=0; cs->port=0; if (ipOut) { EEL_STRING_MUTEXLOCK_SCOPE WDL_FastString *ws=NULL; EEL_STRING_GET_FOR_WRITE(*ipOut,&ws); if (ws) { const unsigned int a = ntohl(saddr.sin_addr.s_addr); ws->SetFormatted(128,"%d.%d.%d.%d",(a>>24)&0xff,(a>>16)&0xff,(a>>8)&0xff,a&0xff); } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("tcp_listen(%d): bad string identifier %f for third parameter (IP-out)",port,*ipOut); #endif } } return x + CONNECTION_ID_BASE; } } closesocket(newsock); return -1; } int eel_net_state::__run_connect(connection_state *cs, unsigned int ip) { SOCKET s=socket(AF_INET,SOCK_STREAM,0); if (s == INVALID_SOCKET) return 0; if (!cs->blockmode) SET_SOCK_BLOCK(s,0); struct sockaddr_in sa={0,}; sa.sin_family=AF_INET; sa.sin_addr.s_addr = ip; sa.sin_port = htons(cs->port); if (!connect(s,(struct sockaddr *)&sa,16) || (!cs->blockmode && ERRNO == EINPROGRESS)) { cs->state = STATE_CONNECTED; cs->sock = s; return 1; } closesocket(s); return 0; } int eel_net_state::__run(connection_state *cs) { if (cs->sock != INVALID_SOCKET) return 0; if (!cs->hostname) return -1; unsigned int ip=INADDR_NONE; const int r=m_dns ? m_dns->resolve(cs->hostname,&ip) : -1; if (r>0) return 0; free(cs->hostname); cs->hostname=NULL; if (r<0 || !__run_connect(cs,ip)) { cs->state = STATE_ERR; return -1; } return 0; } int eel_net_state::do_recv(void *opaque, EEL_F h, char *buf, int maxlen) { const int idx=(int)h-CONNECTION_ID_BASE; if (idx>=0 && idxsock == INVALID_SOCKET && !s->hostname) EEL_STRING_DEBUGOUT("tcp_recv: connection identifier %f is not open",h); #endif if (__run(s) || s->sock == INVALID_SOCKET) return s->state == STATE_ERR ? -1 : 0; if (maxlen == 0) return 0; const int rv=(int)recv(s->sock,buf,maxlen,0); if (rv < 0 && !s->blockmode && (ERRNO == EWOULDBLOCK||ERRNO==ENOTCONN)) return 0; if (!rv) return -1; // TCP, 0=connection terminated return rv; } #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("tcp_recv: connection identifier %f is out of range",h); #endif return -1; } int eel_net_state::do_send(void *opaque, EEL_F h, const char *src, int len) { const int idx=(int)h-CONNECTION_ID_BASE; if (idx>=0 && idxsock == INVALID_SOCKET && !s->hostname) EEL_STRING_DEBUGOUT("tcp_send: connection identifier %f is not open",h); #endif if (__run(s) || s->sock == INVALID_SOCKET) return s->state == STATE_ERR ? -1 : 0; const int rv=(int)send(s->sock,src,len,0); if (rv < 0 && !s->blockmode && (ERRNO == EWOULDBLOCK || ERRNO==ENOTCONN)) return 0; return rv; } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("tcp_send: connection identifier %f out of range",h); #endif } return -1; } EEL_F eel_net_state::set_block(void *opaque, EEL_F handle, bool block) { int idx=(int)handle-CONNECTION_ID_BASE; if (idx>=0 && idxblockmode != block) { s->blockmode=block; if (s->sock != INVALID_SOCKET) { SET_SOCK_BLOCK(s->sock,(block?1:0)); } else { #ifdef EEL_STRING_DEBUGOUT if (!s->hostname) EEL_STRING_DEBUGOUT("tcp_set_block: connection identifier %f is not open",handle); #endif } return 1; } } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("tcp_set_block: connection identifier %f out of range",handle); #endif } return 0; } EEL_F eel_net_state::onClose(void *opaque, EEL_F handle) { int idx=(int)handle-CONNECTION_ID_BASE; if (idx>=0 && idxhostname; free(s->hostname); s->hostname = NULL; s->state = STATE_ERR; if (s->sock != INVALID_SOCKET) { shutdown(s->sock,SHUT_RDWR); closesocket(s->sock); s->sock = INVALID_SOCKET; return 1.0; } else if (!hadhn) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("tcp_close: connection identifier %f is not open",handle); #endif } } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("tcp_close: connection identifier %f is out of range",handle); #endif } return 0.0; } static EEL_F NSEEL_CGEN_CALL _eel_tcp_connect(void *opaque, INT_PTR np, EEL_F **parms) { eel_net_state *ctx; if (np > 1 && NULL != (ctx=EEL_NET_GET_CONTEXT(opaque))) { char *dest=NULL; { EEL_STRING_MUTEXLOCK_SCOPE const char *fn = EEL_STRING_GET_FOR_INDEX(parms[0][0],NULL); if (fn) dest=strdup(fn); else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("tcp_connect(): host string identifier %f invalid",parms[0][0]); #endif } } if (dest) return ctx->onConnect(dest, (int) (parms[1][0]+0.5), np < 3 || parms[2][0] >= 0.5); } return -1.0; } static EEL_F NSEEL_CGEN_CALL _eel_tcp_set_block(void *opaque, EEL_F *handle, EEL_F *bl) { eel_net_state *ctx; if (NULL != (ctx=EEL_NET_GET_CONTEXT(opaque))) return ctx->set_block(opaque,*handle, *bl >= 0.5); return 0; } static EEL_F NSEEL_CGEN_CALL _eel_tcp_close(void *opaque, EEL_F *handle) { eel_net_state *ctx; if (NULL != (ctx=EEL_NET_GET_CONTEXT(opaque))) return ctx->onClose(opaque,*handle); return 0; } static EEL_F NSEEL_CGEN_CALL _eel_tcp_recv(void *opaque, INT_PTR np, EEL_F **parms) { eel_net_state *ctx; if (np > 1 && NULL != (ctx=EEL_NET_GET_CONTEXT(opaque))) { char buf[EEL_STRING_MAXUSERSTRING_LENGTH_HINT]; int ml = np > 2 ? (int)parms[2][0] : 4096; if (ml < 0 || ml > EEL_STRING_MAXUSERSTRING_LENGTH_HINT) ml = EEL_STRING_MAXUSERSTRING_LENGTH_HINT; ml=ctx->do_recv(opaque,parms[0][0],buf,ml); { EEL_STRING_MUTEXLOCK_SCOPE WDL_FastString *ws=NULL; EEL_STRING_GET_FOR_WRITE(parms[1][0],&ws); if (ws) { if (ml<=0) ws->Set(""); else ws->SetRaw(buf,ml); } } return ml; } return -1; } static EEL_F NSEEL_CGEN_CALL _eel_tcp_send(void *opaque, INT_PTR np, EEL_F **parms) { eel_net_state *ctx; if (np > 1 && NULL != (ctx=EEL_NET_GET_CONTEXT(opaque))) { char buf[EEL_NET_MAXSEND]; int l; { EEL_STRING_MUTEXLOCK_SCOPE WDL_FastString *ws=NULL; const char *fn = EEL_STRING_GET_FOR_INDEX(parms[1][0],&ws); l = ws ? ws->GetLength() : (int) strlen(fn); if (np > 2) { int al=(int)parms[2][0]; if (al<0) al=0; if (al 0) memcpy(buf,fn,l); } if (l>0) return ctx->do_send(opaque,parms[0][0],buf,l); return 0; } return -1; } static EEL_F NSEEL_CGEN_CALL _eel_tcp_listen(void *opaque, INT_PTR np, EEL_F **parms) { eel_net_state *ctx; if (NULL != (ctx=EEL_NET_GET_CONTEXT(opaque))) return ctx->onListen(opaque,parms[0][0],1,np>1?parms[1]:NULL,np>2?parms[2]:NULL); return 0; } static EEL_F NSEEL_CGEN_CALL _eel_tcp_listen_end(void *opaque, EEL_F *handle) { eel_net_state *ctx; if (NULL != (ctx=EEL_NET_GET_CONTEXT(opaque))) return ctx->onListen(opaque,*handle,-1,NULL,NULL); return 0; } void EEL_tcp_register() { NSEEL_addfunc_varparm("tcp_listen",1,NSEEL_PProc_THIS,&_eel_tcp_listen); NSEEL_addfunc_retval("tcp_listen_end",1,NSEEL_PProc_THIS,&_eel_tcp_listen_end); NSEEL_addfunc_varparm("tcp_connect",2,NSEEL_PProc_THIS,&_eel_tcp_connect); NSEEL_addfunc_varparm("tcp_send",2,NSEEL_PProc_THIS,&_eel_tcp_send); NSEEL_addfunc_varparm("tcp_recv",2,NSEEL_PProc_THIS,&_eel_tcp_recv); NSEEL_addfunc_retval("tcp_set_block",2,NSEEL_PProc_THIS,&_eel_tcp_set_block); NSEEL_addfunc_retval("tcp_close",1,NSEEL_PProc_THIS,&_eel_tcp_close); } #ifdef EEL_WANT_DOCUMENTATION const char *eel_net_function_reference = "tcp_listen\tport[,\"interface\",#ip_out]\tListens on port specified. Returns less than 0 if could not listen, 0 if no new connection available, or greater than 0 (as a TCP connection ID) if a new connection was made. If a connection made and #ip_out specified, it will be set to the remote IP. interface can be empty for all interfaces, otherwise an interface IP as a string.\0" "tcp_listen_end\tport\tEnds listening on port specified.\0" "tcp_connect\t\"address\",port[,block]\tCreate a new TCP connection to address:port. If block is specified and 0, connection will be made nonblocking. Returns TCP connection ID greater than 0 on success.\0" "tcp_send\tconnection,\"str\"[,len]\tSends a string to connection. Returns -1 on error, 0 if connection is non-blocking and would block, otherwise returns length sent. If len is specified and not less than 1, only the first len bytes of the string parameter will be sent.\0" "tcp_recv\tconnection,#str[,maxlen]\tReceives data from a connection to #str. If maxlen is specified, no more than maxlen bytes will be received. If non-blocking, 0 will be returned if would block. Returns less than 0 if error.\0" "tcp_set_block\tconnection,block\tSets whether a connection blocks.\0" "tcp_close\tconnection\tCloses a TCP connection created by tcp_listen() or tcp_connect().\0" ; #endif #endif jsusfx-0.4.0/src/WDL/eel2/eel_strings.h000066400000000000000000001433021353477307700176130ustar00rootroot00000000000000#ifndef __EEL__STRINGS_H__ #define __EEL__STRINGS_H__ #include "ns-eel-int.h" #include "../wdlcstring.h" #include "../wdlstring.h" // required for context // #define EEL_STRING_GET_CONTEXT_POINTER(opaque) (((sInst *)opaque)->m_eel_string_state) /* // writeable user-strings are 0..1023 (EEL_STRING_MAX_USER_STRINGS-1), and can be up to about EEL_STRING_MAXUSERSTRING_LENGTH_HINT bytes long printf("string %d blah"); -- output to log, allows %d %u %f etc, if host implements formats [1] sprintf(str,"string %d blah"); -- output to str [1] strlen(str); -- returns string length match("*test*", "this is a test") -- search for first parameter regex-style in second parameter matchi("*test*", "this is a test") -- search for first parameter regex-style in second parameter (case insensitive) // %s means 1 or more chars // %0s means 0 or more chars // %5s means exactly 5 chars // %5-s means 5 or more chars // %-10s means 1-10 chars // %3-5s means 3-5 chars. // %0-5s means 0-5 chars. // %S (uppercase) indicates lazy match (%D, %F, %X, etc) strcpy(str, srcstr); -- replaces str with srcstr strcat(str, srcstr); -- appends srcstr to str strcmp(str, str2) -- compares strings stricmp(str, str2) -- compares strings (ignoring case) strncmp(str, str2, maxlen) -- compares strings up to maxlen bytes strnicmp(str, str2, maxlen) -- compares strings (ignoring case) up to maxlen bytes strncpy(str, srcstr, maxlen); -- replaces str with srcstr, up to maxlen (-1 for unlimited) strncat(str, srcstr, maxlen); -- appends up to maxlen of srcstr to str (-1 for unlimited) strcpy_from(str,srcstr, offset); -- copies srcstr to str, but starts reading srcstr at offset offset strcpy_substr(str, srcstr, offs, ml) -- php-style (start at offs, offs<0 means from end, ml for maxlen, ml<0 = reduce length by this amt) str_getchar(str, offset[, type]); -- returns value at offset offset, type can be omitted or 0 or 'c', 's', 'S', 'i', 'I', 'f', 'F', 'd', 'D', 'uc', 'us', 'US', 'ui', 'UI' -- negative offset is offset from end of string str_setchar(str, offset, val[, type]); - sets value at offset offset, type optional. offset must be [0,length], if length it can lengthen string, if >length then call fails -- negative offset is offset from end of string str_setlen(str, len); -- sets length of string (if increasing, will be space-padded) str_delsub(str, pos, len); -- deletes len chars at pos str_insert(str, srcstr, pos); -- inserts srcstr at pos [1]: note: printf/sprintf are NOT binary safe when using %s with modifiers (such as %100s etc) -- the source string being formatted will terminate at the first NULL character ); */ // define this to allow modifying literal strings via code, i.e. foobar = strcat("foo","bar"); // disabled by default, so literals can be pooled/reused/etc // #define EEL_STRINGS_MUTABLE_LITERALS #ifndef EEL_STRING_MAXUSERSTRING_LENGTH_HINT #define EEL_STRING_MAXUSERSTRING_LENGTH_HINT 16384 #endif #ifndef EEL_STRING_MAX_USER_STRINGS // strings 0...x-1 #define EEL_STRING_MAX_USER_STRINGS 1024 #endif #ifndef EEL_STRING_LITERAL_BASE // strings defined by "xyz" #define EEL_STRING_LITERAL_BASE 10000 #endif // base for named mutable strings (#xyz) #ifndef EEL_STRING_NAMED_BASE #define EEL_STRING_NAMED_BASE 90000 #endif // base for unnamed mutable strings (#) #ifndef EEL_STRING_UNNAMED_BASE #define EEL_STRING_UNNAMED_BASE 190000 #endif // define EEL_STRING_MUTEXLOCK_SCOPE for custom, otherwise EEL_STRING_WANT_MUTEX for builtin locking #ifndef EEL_STRING_MUTEXLOCK_SCOPE #ifdef EEL_STRING_WANT_MUTEX #include "../mutex.h" #define EEL_STRING_MUTEXLOCK_SCOPE WDL_MutexLock __lock(&(EEL_STRING_GET_CONTEXT_POINTER(opaque)->m_mutex)); #else #define EEL_STRING_MUTEXLOCK_SCOPE #endif #endif // allow overriding behavior #ifndef EEL_STRING_GET_FOR_INDEX #define EEL_STRING_GET_FOR_INDEX(x, wr) (EEL_STRING_GET_CONTEXT_POINTER(opaque)->GetStringForIndex(x, wr, false)) #endif #ifndef EEL_STRING_GET_FOR_WRITE #define EEL_STRING_GET_FOR_WRITE(x, wr) (EEL_STRING_GET_CONTEXT_POINTER(opaque)->GetStringForIndex(x, wr, true)) #endif #ifndef EEL_STRING_GETFMTVAR #define EEL_STRING_GETFMTVAR(x) (EEL_STRING_GET_CONTEXT_POINTER(opaque)->GetVarForFormat(x)) #endif #ifndef EEL_STRING_GETNAMEDVAR #define EEL_STRING_GETNAMEDVAR(x,createOK,altOut) (EEL_STRING_GET_CONTEXT_POINTER(opaque)->GetNamedVar(x,createOK,altOut)) #endif #ifndef EEL_STRING_STORAGECLASS #define EEL_STRING_STORAGECLASS WDL_FastString #endif class eel_string_context_state { public: static int cmpistr(const char **a, const char **b) { return stricmp(*a,*b); } eel_string_context_state() : m_named_strings_names(false), m_varname_cache(cmpistr) { m_vm=0; memset(m_user_strings,0,sizeof(m_user_strings)); } ~eel_string_context_state() { clear_state(true); } void clear_state(bool full) { if (full) { int x; for (x=0;x=0 && idx < EEL_STRING_MAX_USER_STRINGS) { if (stringContainerOut) { if (!m_user_strings[idx]) m_user_strings[idx] = new EEL_STRING_STORAGECLASS; *stringContainerOut = m_user_strings[idx]; } return m_user_strings[idx]?m_user_strings[idx]->Get():""; } EEL_STRING_STORAGECLASS *s; s = m_unnamed_strings.Get(idx - EEL_STRING_UNNAMED_BASE); if (!s) s= m_named_strings.Get(idx - EEL_STRING_NAMED_BASE); if (s) { // mutable string if (stringContainerOut) *stringContainerOut=s; } else { s = m_literal_strings.Get(idx - EEL_STRING_LITERAL_BASE); #ifdef EEL_STRINGS_MUTABLE_LITERALS if (stringContainerOut) *stringContainerOut=s; #else if (stringContainerOut) *stringContainerOut=is_for_write ? NULL : s; #endif } return s ? s->Get() : NULL; } WDL_PtrList m_literal_strings; // "this kind", normally immutable WDL_PtrList m_unnamed_strings; // # WDL_PtrList m_named_strings; // #xyz by index, but stringkeyed below for names WDL_StringKeyedArray m_named_strings_names; // #xyz->index EEL_STRING_STORAGECLASS *m_user_strings[EEL_STRING_MAX_USER_STRINGS]; // indices 0-1023 (etc) WDL_AssocArray m_varname_cache; // cached pointers when using %{xyz}s, %{#xyz}s bypasses NSEEL_VMCTX m_vm; #ifdef EEL_STRING_WANT_MUTEX WDL_Mutex m_mutex; #endif static EEL_F addNamedStringCallback(void *opaque, const char *name) { if (!opaque) return -1.0; eel_string_context_state *_this = EEL_STRING_GET_CONTEXT_POINTER(opaque); if (!_this) return -1.0; EEL_STRING_MUTEXLOCK_SCOPE if (!name || !name[0]) { _this->m_unnamed_strings.Add(new EEL_STRING_STORAGECLASS); return (EEL_F) (_this->m_unnamed_strings.GetSize()-1 + EEL_STRING_UNNAMED_BASE); } int a = _this->m_named_strings_names.Get(name); if (a) return (EEL_F)a; a = _this->m_named_strings.GetSize() + EEL_STRING_NAMED_BASE; _this->m_named_strings.Add(new EEL_STRING_STORAGECLASS); _this->m_named_strings_names.Insert(name,a); return (EEL_F)a; } static EEL_F addStringCallback(void *opaque, struct eelStringSegmentRec *list) { if (!opaque) return -1.0; eel_string_context_state *_this = EEL_STRING_GET_CONTEXT_POINTER(opaque); if (!_this) return -1.0; EEL_STRING_STORAGECLASS *ns = new EEL_STRING_STORAGECLASS; // could probably do a faster implementation using AddRaw() etc but this should also be OK int sz=nseel_stringsegments_tobuf(NULL,0,list); ns->SetLen(sz+32); sz=nseel_stringsegments_tobuf((char *)ns->Get(),sz,list); ns->SetLen(sz); EEL_STRING_MUTEXLOCK_SCOPE return (EEL_F)_this->AddString(ns); } int AddString(EEL_STRING_STORAGECLASS *ns) { const int l = ns->GetLength(); #ifdef EEL_STRINGS_MUTABLE_LITERALS m_literal_strings.Add(ns); return m_literal_strings.GetSize()-1+EEL_STRING_LITERAL_BASE; #else const int sz=m_literal_strings.GetSize(); int x; for (x=0;xGetLength() == l && !strcmp(s->Get(),ns->Get())) break; } if (xm_varname_cache.AddUnsorted(name,val); return 1; } }; static int eel_validate_format_specifier(const char *fmt_in, char *typeOut, char *fmtOut, int fmtOut_sz, char *varOut, int varOut_sz, int *varOut_used ) { const char *fmt = fmt_in+1; int state=0; if (fmt_in[0] != '%') return 0; // ugh passed a non-specifier *varOut_used = 0; *varOut = 0; if (fmtOut_sz-- < 2) return 0; *fmtOut++ = '%'; while (*fmt) { const char c = *fmt++; if (fmtOut_sz < 2) return 0; if (c == 'f'|| c=='e' || c=='E' || c=='g' || c=='G' || c == 'd' || c == 'u' || c == 'x' || c == 'X' || c == 'c' || c == 'C' || c =='s' || c=='S' || c=='i') { *typeOut = c; fmtOut[0] = c; fmtOut[1] = 0; return (int) (fmt - fmt_in); } else if (c == '.') { *fmtOut++ = c; fmtOut_sz--; if (state&(2)) break; state |= 2; } else if (c == '+') { *fmtOut++ = c; fmtOut_sz--; if (state&(32|16|8|4)) break; state |= 8; } else if (c == '-' || c == ' ') { *fmtOut++ = c; fmtOut_sz--; if (state&(32|16|8|4)) break; state |= 16; } else if (c >= '0' && c <= '9') { *fmtOut++ = c; fmtOut_sz--; state|=4; } else if (c == '{') { if (state & 64) break; state|=64; if (*fmt == '.' || (*fmt >= '0' && *fmt <= '9')) return 0; // symbol name can't start with 0-9 or . while (*fmt != '}') { if ((*fmt >= 'a' && *fmt <= 'z') || (*fmt >= 'A' && *fmt <= 'Z') || (*fmt >= '0' && *fmt <= '9') || *fmt == '_' || *fmt == '.' || *fmt == '#') { if (varOut_sz < 2) return 0; *varOut++ = *fmt++; varOut_sz -- ; } else { return 0; // bad character in variable name } } fmt++; *varOut = 0; *varOut_used=1; } else { break; } } return 0; } int eel_format_strings(void *opaque, const char *fmt, const char *fmt_end, char *buf, int buf_sz, int num_fmt_parms, EEL_F **fmt_parms) { int fmt_parmpos = 0; char *op = buf; while ((fmt_end ? fmt < fmt_end : *fmt) && op < buf+buf_sz-128) { if (fmt[0] == '%' && fmt[1] == '%') { *op++ = '%'; fmt+=2; } else if (fmt[0] == '%') { char ct=0; char fs[128]; char varname[128]; int varname_used=0; const int l=eel_validate_format_specifier(fmt,&ct,fs,sizeof(fs),varname,sizeof(varname),&varname_used); if (!l || !ct) { *op=0; return -1; } EEL_F vv=0.0; const EEL_F *varptr = NULL; if (varname_used) { #ifdef EEL_STRING_GETNAMEDVAR if (varname[0]) varptr=EEL_STRING_GETNAMEDVAR(varname,0,&vv); #endif } else { if (fmt_parmpos < num_fmt_parms) varptr = fmt_parms[fmt_parmpos]; #ifdef EEL_STRING_GETFMTVAR if (!varptr) varptr = EEL_STRING_GETFMTVAR(fmt_parmpos); #endif fmt_parmpos++; } double v = varptr ? (double)*varptr : 0.0; if (ct == 's' || ct=='S') { EEL_STRING_STORAGECLASS *wr=NULL; const char *str = EEL_STRING_GET_FOR_INDEX(v,&wr); const int maxl=(int) (buf+buf_sz - 2 - op); if (wr && !fs[2]) // %s or %S -- todo: implement padding modes for binary compat too? { int wl = wr->GetLength(); if (wl > maxl) wl=maxl; memcpy(op,wr->Get(),wl); op += wl; *op=0; } else { snprintf(op,maxl,fs,str ? str : ""); } } else { if (varptr == &vv) // passed %{#str}d etc, convert to float { const char *str = EEL_STRING_GET_FOR_INDEX(v,NULL); v = str ? atof(str) : 0.0; } if (ct == 'x' || ct == 'X' || ct == 'd' || ct == 'u' || ct=='i') { snprintf(op,64,fs,(int) (v)); } else if (ct == 'c') { *op++=(char) (int)v; *op=0; } else if (ct == 'C') { const unsigned int iv = (unsigned int) v; int bs = 0; if (iv & 0xff000000) bs=24; else if (iv & 0x00ff0000) bs=16; else if (iv & 0x0000ff00) bs=8; while (bs>=0) { const char c=(char) (iv>>bs); *op++=c?c:' '; bs-=8; } *op=0; } else snprintf(op,64,fs,v); } while (*op) op++; fmt += l; } else { *op++ = *fmt++; } } *op=0; return (int) (op - buf); } static int eel_string_match(void *opaque, const char *fmt, const char *msg, int match_fmt_pos, int ignorecase, const char *fmt_endptr, const char *msg_endptr, int num_fmt_parms, EEL_F **fmt_parms) { // check for match, updating EEL_STRING_GETFMTVAR(*) as necessary // %d=12345 // %f=12345[.678] // %c=any nonzero char, ascii value // %x=12354ab // %*, %?, %+, %% literals // * ? + match minimal groups of 0+,1, or 1+ chars for (;;) { if (fmt>=fmt_endptr) { if (msg>=msg_endptr) return 1; return 0; // format ends before matching string } // if string ends and format is not on a wildcard, early-out to 0 if (msg>=msg_endptr && *fmt != '*' && *fmt != '%') return 0; switch (*fmt) { case '*': case '+': // if last char of search pattern, we're done! if (fmt+1>=fmt_endptr || (fmt[1] == '?' && fmt+2>=fmt_endptr)) return *fmt == '*' || msg= 0 && !eel_string_match(opaque,fmt, msg+len,match_fmt_pos,ignorecase,fmt_endptr, msg_endptr,num_fmt_parms,fmt_parms)) len--; return len >= 0; } break; case '?': fmt++; msg++; break; case '%': { fmt++; unsigned short fmt_minlen = 1, fmt_maxlen = 0; if (*fmt >= '0' && *fmt <= '9') { fmt_minlen = *fmt++ - '0'; while (*fmt >= '0' && *fmt <= '9') fmt_minlen = fmt_minlen * 10 + (*fmt++ - '0'); fmt_maxlen = fmt_minlen; } if (*fmt == '-') { fmt++; fmt_maxlen = 0; while (*fmt >= '0' && *fmt <= '9') fmt_maxlen = fmt_maxlen * 10 + (*fmt++ - '0'); } const char *dest_varname=NULL; if (*fmt == '{') { dest_varname=++fmt; while (*fmt && fmt < fmt_endptr && *fmt != '}') fmt++; if (fmt >= fmt_endptr-1 || *fmt != '}') return 0; // malformed %{var}s fmt++; // skip '}' } char fmt_char = *fmt++; if (!fmt_char) return 0; // malformed if (fmt_char == '*' || fmt_char == '?' || fmt_char == '+' || fmt_char == '%') { if (*msg++ != fmt_char) return 0; } else if (fmt_char == 'c') { EEL_F *varOut = NULL; EEL_F vv=0.0; if (!dest_varname) { if (match_fmt_pos < num_fmt_parms) varOut = fmt_parms[match_fmt_pos]; #ifdef EEL_STRING_GETFMTVAR if (!varOut) varOut = EEL_STRING_GETFMTVAR(match_fmt_pos); #endif match_fmt_pos++; } else { #ifdef EEL_STRING_GETNAMEDVAR char tmp[128]; int idx=0; while (dest_varname < fmt_endptr && *dest_varname && *dest_varname != '}' && idx<(int)sizeof(tmp)-1) tmp[idx++] = *dest_varname++; tmp[idx]=0; if (idx>0) varOut = EEL_STRING_GETNAMEDVAR(tmp,1,&vv); #endif } if (msg >= msg_endptr) return 0; // out of chars if (varOut) { if (varOut == &vv) // %{#foo}c { EEL_STRING_STORAGECLASS *wr=NULL; EEL_STRING_GET_FOR_WRITE(vv, &wr); if (wr) wr->Set(msg,1); } else { *varOut = (EEL_F)*(unsigned char *)msg; } } msg++; } else { int len=0; int lazy=0; if (fmt_char>='A'&&fmt_char<='Z') { lazy=1; fmt_char += 'a' - 'A'; } if (fmt_char == 's') { len = (int) (msg_endptr-msg); } else if (fmt_char == 'x') { while ((msg[len] >= '0' && msg[len] <= '9') || (msg[len] >= 'A' && msg[len] <= 'F') || (msg[len] >= 'a' && msg[len] <= 'f')) len++; } else if (fmt_char == 'f') { if (msg[len] == '-') len++; while (msg[len] >= '0' && msg[len] <= '9') len++; if (msg[len] == '.') { len++; while (msg[len] >= '0' && msg[len] <= '9') len++; } } else if (fmt_char == 'd' || fmt_char == 'u' || fmt_char == 'i') { if (fmt_char != 'u' && msg[len] == '-') len++; while (msg[len] >= '0' && msg[len] <= '9') len++; } else { // bad format return 0; } if (fmt_maxlen>0 && len > fmt_maxlen) len = fmt_maxlen; if (!dest_varname) match_fmt_pos++; if (lazy) { if (fmt_maxlen<1 || fmt_maxlen>len) fmt_maxlen=len; len=fmt_minlen; while (len <= fmt_maxlen && !eel_string_match(opaque,fmt, msg+len,match_fmt_pos,ignorecase,fmt_endptr, msg_endptr,num_fmt_parms,fmt_parms)) len++; if (len > fmt_maxlen) return 0; } else { while (len >= fmt_minlen && !eel_string_match(opaque,fmt, msg+len,match_fmt_pos,ignorecase,fmt_endptr, msg_endptr,num_fmt_parms,fmt_parms)) len--; if (len < fmt_minlen) return 0; } EEL_F vv=0.0; EEL_F *varOut = NULL; if (!dest_varname) { if (match_fmt_pos>0 && match_fmt_pos-1 < num_fmt_parms) varOut = fmt_parms[match_fmt_pos-1]; #ifdef EEL_STRING_GETFMTVAR if (!varOut) varOut = EEL_STRING_GETFMTVAR(match_fmt_pos-1); #endif } else { #ifdef EEL_STRING_GETNAMEDVAR char tmp[128]; int idx=0; while (dest_varname < fmt_endptr && *dest_varname && *dest_varname != '}' && idx<(int)sizeof(tmp)-1) tmp[idx++] = *dest_varname++; tmp[idx]=0; if (idx>0) varOut = EEL_STRING_GETNAMEDVAR(tmp,1,&vv); #endif } if (varOut) { if (fmt_char == 's') { EEL_STRING_STORAGECLASS *wr=NULL; EEL_STRING_GET_FOR_WRITE(*varOut, &wr); if (wr) { if (msg_endptr >= wr->Get() && msg_endptr <= wr->Get() + wr->GetLength()) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("match: destination specifier passed is also haystack, will not update"); #endif } else if (fmt_endptr >= wr->Get() && fmt_endptr <= wr->Get() + wr->GetLength()) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("match: destination specifier passed is also format, will not update"); #endif } else { wr->SetRaw(msg,len); } } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("match: bad destination specifier passed as %d: %f",match_fmt_pos,*varOut); #endif } } else { char tmp[128]; lstrcpyn_safe(tmp,msg,wdl_min(len+1,(int)sizeof(tmp))); if (varOut == &vv) { EEL_STRING_STORAGECLASS *wr=NULL; EEL_STRING_GET_FOR_WRITE(vv, &wr); if (wr) wr->Set(tmp); } else { char *bl=(char*)msg; if (fmt_char == 'u') *varOut = (EEL_F)strtoul(tmp,&bl,10); else if (fmt_char == 'x') *varOut = (EEL_F)strtoul(msg,&bl,16); else *varOut = (EEL_F)atof(tmp); } } } return 1; } } break; default: if (ignorecase ? (toupper(*fmt) != toupper(*msg)) : (*fmt!= *msg)) return 0; fmt++; msg++; break; } } } static EEL_F NSEEL_CGEN_CALL _eel_sprintf(void *opaque, INT_PTR num_param, EEL_F **parms) { if (num_param<2) return 0.0; if (opaque) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL; EEL_STRING_GET_FOR_WRITE(*(parms[0]), &wr); if (!wr) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("sprintf: bad destination specifier passed %f",*(parms[0])); #endif } else { EEL_STRING_STORAGECLASS *wr_src=NULL; const char *fmt = EEL_STRING_GET_FOR_INDEX(*(parms[1]),&wr_src); if (fmt) { char buf[16384]; const int fmt_len = eel_format_strings(opaque,fmt,wr_src?(fmt+wr_src->GetLength()):NULL,buf,(int)sizeof(buf), (int)num_param-2, parms+2); if (fmt_len>=0) { wr->SetRaw(buf,fmt_len); } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("sprintf: bad format string %s",fmt); #endif } } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("sprintf: bad format specifier passed %f",*(parms[1])); #endif } } } return *(parms[0]); } static EEL_F NSEEL_CGEN_CALL _eel_strncat(void *opaque, EEL_F *strOut, EEL_F *fmt_index, EEL_F *maxlen) { if (opaque) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL, *wr_src=NULL; EEL_STRING_GET_FOR_WRITE(*strOut, &wr); if (!wr) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str%scat: bad destination specifier passed %f",maxlen ? "n":"",*strOut); #endif } else { const char *fmt = EEL_STRING_GET_FOR_INDEX(*fmt_index,&wr_src); if (fmt||wr_src) { if (wr->GetLength() > EEL_STRING_MAXUSERSTRING_LENGTH_HINT) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str%scat: will not grow string since it is already %d bytes",maxlen ? "n":"",wr->GetLength()); #endif } else { int ml=0; if (maxlen && *maxlen > 0) ml = (int)*maxlen; if (wr_src) { EEL_STRING_STORAGECLASS tmp; if (wr_src == wr) *(wr_src=&tmp) = *wr; wr->AppendRaw(wr_src->Get(), ml > 0 && ml < wr_src->GetLength() ? ml : wr_src->GetLength()); } else wr->Append(fmt, ml); } } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str%scat: bad format specifier passed %f",maxlen ? "n":"",*fmt_index); #endif } } } return *strOut; } static EEL_F NSEEL_CGEN_CALL _eel_strcpysubstr(void *opaque, INT_PTR nparm, EEL_F **parms) //EEL_F *strOut, EEL_F *fmt_index, EEL_F *offs { if (opaque && nparm>=3) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL, *wr_src=NULL; EEL_STRING_GET_FOR_WRITE(parms[0][0], &wr); if (!wr) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("strcpy_substr: bad destination specifier passed %f",parms[0][0]); #endif } else { const char *fmt = EEL_STRING_GET_FOR_INDEX(parms[1][0],&wr_src); if (fmt) { const int fmt_len = wr_src ? wr_src->GetLength() : (int) strlen(fmt); int maxlen, o = (int) parms[2][0]; if (o < 0) { o = fmt_len + o; if (o < 0) o=0; } maxlen = fmt_len - o; if (nparm >= 4) { const int a = (int) parms[3][0]; if (a<0) maxlen += a; else if (a= fmt_len) { wr->Set(""); } else { if (wr_src==wr) { wr->DeleteSub(0,o); if (wr->GetLength() > maxlen) wr->SetLen(maxlen); } else { wr->SetRaw(fmt+o,maxlen); } } } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("strcpy_substr: bad format specifier passed %f",parms[1][0]); #endif } } return parms[0][0]; } return 0.0; } static EEL_F NSEEL_CGEN_CALL _eel_strncpy(void *opaque, EEL_F *strOut, EEL_F *fmt_index, EEL_F *maxlen) { if (opaque) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL, *wr_src=NULL; EEL_STRING_GET_FOR_WRITE(*strOut, &wr); if (!wr) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str%scpy: bad destination specifier passed %f",maxlen ? "n":"",*strOut); #endif } else { const char *fmt = EEL_STRING_GET_FOR_INDEX(*fmt_index,&wr_src); if (fmt) { int ml=-1; if (maxlen && *maxlen >= 0) ml = (int)*maxlen; if (wr_src == wr) { if (ml>=0 && ml < wr->GetLength()) wr->SetLen(ml); // shorten string if strncpy(x,x,len) and len >=0 return *strOut; } if (wr_src) wr->SetRaw(fmt, ml>0 && ml < wr_src->GetLength() ? ml : wr_src->GetLength()); else wr->Set(fmt,ml); } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str%scpy: bad format specifier passed %f",maxlen ? "n":"",*fmt_index); #endif } } } return *strOut; } static EEL_F _eel_strcmp_int(const char *a, int a_len, const char *b, int b_len, int ml, bool ignorecase) { // binary-safe comparison (at least if a_len>=0 etc) int pos = 0; for (;;) { if (ml > 0 && pos == ml) return 0.0; const bool a_end = a_len >= 0 ? pos == a_len : !a[pos]; const bool b_end = b_len >= 0 ? pos == b_len : !b[pos]; if (a_end || b_end) { if (!b_end) return -1.0; // b[pos] is nonzero, a[pos] is zero if (!a_end) return 1.0; return 0.0; } char av = a[pos]; char bv = b[pos]; if (ignorecase) { av=toupper(av); bv=toupper(bv); } if (bv > av) return -1.0; if (av > bv) return 1.0; pos++; } } static EEL_F NSEEL_CGEN_CALL _eel_strncmp(void *opaque, EEL_F *aa, EEL_F *bb, EEL_F *maxlen) { if (opaque) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr_a=NULL,*wr_b=NULL; const char *a = EEL_STRING_GET_FOR_INDEX(*aa,&wr_a); const char *b = EEL_STRING_GET_FOR_INDEX(*bb,&wr_b); if (!a || !b) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str%scmp: bad specifier(s) passed %f/%f",maxlen ? "n" : "",*aa,*bb); #endif } else { const int ml = maxlen ? (int) *maxlen : -1; if (!ml || a==b) return 0; // strncmp(x,y,0) == 0 return _eel_strcmp_int(a,wr_a ? wr_a->GetLength() : -1,b,wr_b ? wr_b->GetLength() : -1, ml, false); } } return -1.0; } static EEL_F NSEEL_CGEN_CALL _eel_strnicmp(void *opaque, EEL_F *aa, EEL_F *bb, EEL_F *maxlen) { if (opaque) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr_a=NULL,*wr_b=NULL; const char *a = EEL_STRING_GET_FOR_INDEX(*aa,&wr_a); const char *b = EEL_STRING_GET_FOR_INDEX(*bb,&wr_b); if (!a || !b) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str%sicmp: bad specifier(s) passed %f/%f",maxlen ? "n" : "",*aa,*bb); #endif } else { const int ml = maxlen ? (int) *maxlen : -1; if (!ml || a==b) return 0; // strncmp(x,y,0) == 0 return _eel_strcmp_int(a,wr_a ? wr_a->GetLength() : -1,b,wr_b ? wr_b->GetLength() : -1, ml, true); } } return -1.0; } static EEL_F NSEEL_CGEN_CALL _eel_strcat(void *opaque, EEL_F *strOut, EEL_F *fmt_index) { return _eel_strncat(opaque,strOut,fmt_index,NULL); } static EEL_F NSEEL_CGEN_CALL _eel_strcpy(void *opaque, EEL_F *strOut, EEL_F *fmt_index) { return _eel_strncpy(opaque,strOut,fmt_index,NULL); } static EEL_F NSEEL_CGEN_CALL _eel_strcmp(void *opaque, EEL_F *strOut, EEL_F *fmt_index) { return _eel_strncmp(opaque,strOut,fmt_index,NULL); } static EEL_F NSEEL_CGEN_CALL _eel_stricmp(void *opaque, EEL_F *strOut, EEL_F *fmt_index) { return _eel_strnicmp(opaque,strOut,fmt_index,NULL); } static EEL_F NSEEL_CGEN_CALL _eel_strgetchar(void *opaque, EEL_F *strOut, EEL_F *idx) { if (opaque) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL; const char *fmt = EEL_STRING_GET_FOR_INDEX(*strOut, &wr); if (!fmt) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str_getchar: bad specifier passed %f",*strOut); #endif } else { const int wl=(wr?wr->GetLength():(int)strlen(fmt)); int l = (int) *idx; if (*idx < 0.0) l+=wl; if (l>=0 && l < wl) return ((unsigned char *)fmt)[l]; } } return 0; } #define EEL_GETCHAR_FLAG_ENDIANSWAP 0x10 #define EEL_GETCHAR_FLAG_UNSIGNED 0x20 #define EEL_GETCHAR_FLAG_FLOAT 0x40 static int eel_getchar_flag(int type) { #ifdef __ppc__ int ret=EEL_GETCHAR_FLAG_ENDIANSWAP; // default to LE #else int ret=0; #endif if (toupper((type>>8)&0xff) == 'U') ret|=EEL_GETCHAR_FLAG_UNSIGNED; else if (type>255 && toupper(type&0xff) == 'U') { ret|=EEL_GETCHAR_FLAG_UNSIGNED; type>>=8; } type&=0xff; if (isupper(type)) ret^=EEL_GETCHAR_FLAG_ENDIANSWAP; else type += 'A'-'a'; switch (type) { case 'F': return ret|4|EEL_GETCHAR_FLAG_FLOAT; case 'D': return ret|8|EEL_GETCHAR_FLAG_FLOAT; case 'S': return ret|2; case 'I': return ret|4; } return ret|1; } static void eel_setchar_do(int flag, char *dest, EEL_F val) { union { char buf[8]; float asFloat; double asDouble; int asInt; short asShort; char asChar; unsigned int asUInt; unsigned short asUShort; unsigned char asUChar; } a; const int type_sz=flag&0xf; if (flag & EEL_GETCHAR_FLAG_FLOAT) { if (type_sz==8) a.asDouble=val; else a.asFloat=(float)val; } else if (flag & EEL_GETCHAR_FLAG_UNSIGNED) { if (type_sz==4) a.asUInt=(unsigned int)val; else if (type_sz==2) a.asUShort=(unsigned short)val; else a.asUChar=(unsigned char)val; } else if (type_sz==4) a.asInt=(int)val; else if (type_sz==2) a.asShort=(short)val; else a.asChar=(char)val; if (flag & EEL_GETCHAR_FLAG_ENDIANSWAP) { dest += type_sz; int x; for(x=0;x=3) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL; const char *fmt = EEL_STRING_GET_FOR_INDEX(parms[0][0], &wr); if (!fmt) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str_getchar: bad specifier passed %f",parms[0][0]); #endif } else { const int wl=(wr?wr->GetLength():(int)strlen(fmt)); const int flags=eel_getchar_flag((int) parms[2][0]); int l = (int) parms[1][0]; if (parms[1][0] < 0.0) l+=wl; if (l>=0 && l <= wl-(flags&0xf)) { return eel_getchar_do(flags,fmt+l); } } } return 0; } static EEL_F NSEEL_CGEN_CALL _eel_strsetchar2(void *opaque, INT_PTR np, EEL_F **parms) { if (opaque && np>=4) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL; EEL_STRING_GET_FOR_WRITE(parms[0][0], &wr); if (!wr) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str_setchar: bad destination specifier passed %f",parms[0][0]); #endif } else { const int wl=wr->GetLength(); int l = (int) parms[1][0]; if (parms[1][0] < 0.0) l+=wl; if (l>=0 && l <= wl) { const int flags=eel_getchar_flag((int) parms[3][0]); if (l==wl) { if (wl > EEL_STRING_MAXUSERSTRING_LENGTH_HINT) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str_setchar: will not grow string since it is already %d bytes",wl); #endif } else { char buf[32]; eel_setchar_do(flags,buf,parms[2][0]); wr->AppendRaw(buf,flags&0xf); } } else eel_setchar_do(flags,(char*)wr->Get()+l,parms[2][0]); } } } return parms[0][0]; } static EEL_F NSEEL_CGEN_CALL _eel_strsetchar(void *opaque, EEL_F *strOut, EEL_F *idx, EEL_F *val) { if (opaque) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL; EEL_STRING_GET_FOR_WRITE(*strOut, &wr); if (!wr) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str_setchar: bad destination specifier passed %f",*strOut); #endif } else { const int wl=wr->GetLength(); int l = (int) *idx; if (*idx < 0.0) l+=wl; if (l>=0 && l <= wl) { const unsigned char v=((int)*val)&255; if (l==wl) { if (wl > EEL_STRING_MAXUSERSTRING_LENGTH_HINT) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str_setchar: will not grow string since it is already %d bytes",wl); #endif } else wr->AppendRaw((const char*)&v,1); } else ((unsigned char *)wr->Get())[l]=v; // allow putting nulls in string, strlen() will still get the full size } } } return *strOut; } static EEL_F NSEEL_CGEN_CALL _eel_strinsert(void *opaque, EEL_F *strOut, EEL_F *fmt_index, EEL_F *pos) { if (opaque) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL, *wr_src=NULL; EEL_STRING_GET_FOR_WRITE(*strOut, &wr); if (!wr) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str_insert: bad destination specifier passed %f",*strOut); #endif } else { const char *fmt = EEL_STRING_GET_FOR_INDEX(*fmt_index,&wr_src); if (fmt) { EEL_STRING_STORAGECLASS tmp; if (wr_src == wr) *(wr_src=&tmp) = *wr; // insert from copy // if wr_src, fmt is guaranteed to be wr_src.Get() int p = (int)*pos; int insert_l = wr_src ? wr_src->GetLength() : (int)strlen(fmt); if (p < 0) { insert_l += p; // decrease insert_l fmt -= p; // advance fmt -- if fmt gets advanced past NULL term, insert_l will be < 0 anyway p=0; } if (insert_l>0) { if (wr->GetLength() > EEL_STRING_MAXUSERSTRING_LENGTH_HINT) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str_insert: will not grow string since it is already %d bytes",wr->GetLength()); #endif } else { if (wr_src) { wr->InsertRaw(fmt,p, insert_l); } else { wr->Insert(fmt,p); } } } } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str_insert: bad source specifier passed %f",*fmt_index); #endif } } } return *strOut; } static EEL_F NSEEL_CGEN_CALL _eel_strdelsub(void *opaque, EEL_F *strOut, EEL_F *pos, EEL_F *len) { if (opaque) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL; EEL_STRING_GET_FOR_WRITE(*strOut, &wr); if (!wr) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str_delsub: bad destination specifier passed %f",*strOut); #endif } else { int p=(int)*pos; int l=(int)*len; if (p<0) { l+=p; p=0; } if (l>0) wr->DeleteSub(p,l); } } return *strOut; } static EEL_F NSEEL_CGEN_CALL _eel_strsetlen(void *opaque, EEL_F *strOut, EEL_F *newlen) { if (opaque) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL; EEL_STRING_GET_FOR_WRITE(*strOut, &wr); if (!wr) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str_setlen: bad destination specifier passed %f",*strOut); #endif } else { int l = (int) *newlen; if (l < 0) l=0; if (l > EEL_STRING_MAXUSERSTRING_LENGTH_HINT) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("str_setlen: clamping requested length of %d to %d",l,EEL_STRING_MAXUSERSTRING_LENGTH_HINT); #endif l=EEL_STRING_MAXUSERSTRING_LENGTH_HINT; } wr->SetLen(l); } } return *strOut; } static EEL_F NSEEL_CGEN_CALL _eel_strlen(void *opaque, EEL_F *fmt_index) { if (opaque) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr=NULL; const char *fmt = EEL_STRING_GET_FOR_INDEX(*fmt_index,&wr); if (wr) return (EEL_F) wr->GetLength(); if (fmt) return (EEL_F) strlen(fmt); } return 0.0; } static EEL_F NSEEL_CGEN_CALL _eel_printf(void *opaque, INT_PTR num_param, EEL_F **parms) { if (num_param>0 && opaque) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *wr_src=NULL; const char *fmt = EEL_STRING_GET_FOR_INDEX(*(parms[0]),&wr_src); if (fmt) { char buf[16384]; const int len = eel_format_strings(opaque,fmt,wr_src?(fmt+wr_src->GetLength()):NULL,buf,(int)sizeof(buf), (int)num_param-1, parms+1); if (len >= 0) { #ifdef EEL_STRING_STDOUT_WRITE EEL_STRING_STDOUT_WRITE(buf,len); #endif return 1.0; } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("printf: bad format string %s",fmt); #endif } } else { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("printf: bad format specifier passed %f",*(parms[0])); #endif } } return 0.0; } static EEL_F NSEEL_CGEN_CALL _eel_match(void *opaque, INT_PTR num_parms, EEL_F **parms) { if (opaque && num_parms >= 2) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *fmt_wr=NULL, *msg_wr=NULL; const char *fmt = EEL_STRING_GET_FOR_INDEX(*(parms[0]),&fmt_wr); const char *msg = EEL_STRING_GET_FOR_INDEX(*(parms[1]),&msg_wr); if (fmt && msg) return eel_string_match(opaque,fmt,msg,0,0, fmt + (fmt_wr?fmt_wr->GetLength():strlen(fmt)), msg + (msg_wr?msg_wr->GetLength():strlen(msg)),(int)num_parms-2,parms+2) ? 1.0 : 0.0; } return 0.0; } static EEL_F NSEEL_CGEN_CALL _eel_matchi(void *opaque, INT_PTR num_parms, EEL_F **parms) { if (opaque && num_parms >= 2) { EEL_STRING_MUTEXLOCK_SCOPE EEL_STRING_STORAGECLASS *fmt_wr=NULL, *msg_wr=NULL; const char *fmt = EEL_STRING_GET_FOR_INDEX(*(parms[0]),&fmt_wr); const char *msg = EEL_STRING_GET_FOR_INDEX(*(parms[1]),&msg_wr); if (fmt && msg) return eel_string_match(opaque,fmt,msg,0,1, fmt + (fmt_wr?fmt_wr->GetLength():strlen(fmt)), msg + (msg_wr?msg_wr->GetLength():strlen(msg)),(int)num_parms-2,parms+2) ? 1.0 : 0.0; } return 0.0; } void EEL_string_register() { NSEEL_addfunc_retval("strlen",1,NSEEL_PProc_THIS,&_eel_strlen); NSEEL_addfunc_retval("strcat",2,NSEEL_PProc_THIS,&_eel_strcat); NSEEL_addfunc_retval("strcpy",2,NSEEL_PProc_THIS,&_eel_strcpy); NSEEL_addfunc_retval("strcmp",2,NSEEL_PProc_THIS,&_eel_strcmp); NSEEL_addfunc_retval("stricmp",2,NSEEL_PProc_THIS,&_eel_stricmp); NSEEL_addfunc_retval("strncat",3,NSEEL_PProc_THIS,&_eel_strncat); NSEEL_addfunc_retval("strncpy",3,NSEEL_PProc_THIS,&_eel_strncpy); NSEEL_addfunc_retval("strncmp",3,NSEEL_PProc_THIS,&_eel_strncmp); NSEEL_addfunc_retval("strnicmp",3,NSEEL_PProc_THIS,&_eel_strnicmp); NSEEL_addfunc_retval("str_setlen",2,NSEEL_PProc_THIS,&_eel_strsetlen); NSEEL_addfunc_exparms("strcpy_from",3,NSEEL_PProc_THIS,&_eel_strcpysubstr); // alias NSEEL_addfunc_exparms("strcpy_substr",3,NSEEL_PProc_THIS,&_eel_strcpysubstr); // only allow 3 or 4 parms NSEEL_addfunc_exparms("strcpy_substr",4,NSEEL_PProc_THIS,&_eel_strcpysubstr); NSEEL_addfunc_retval("str_getchar",2,NSEEL_PProc_THIS,&_eel_strgetchar); NSEEL_addfunc_retval("str_setchar",3,NSEEL_PProc_THIS,&_eel_strsetchar); NSEEL_addfunc_exparms("str_getchar",3,NSEEL_PProc_THIS,&_eel_strgetchar2); NSEEL_addfunc_exparms("str_setchar",4,NSEEL_PProc_THIS,&_eel_strsetchar2); NSEEL_addfunc_retval("str_insert",3,NSEEL_PProc_THIS,&_eel_strinsert); NSEEL_addfunc_retval("str_delsub",3,NSEEL_PProc_THIS,&_eel_strdelsub); NSEEL_addfunc_varparm("sprintf",2,NSEEL_PProc_THIS,&_eel_sprintf); NSEEL_addfunc_varparm("printf",1,NSEEL_PProc_THIS,&_eel_printf); NSEEL_addfunc_varparm("match",2,NSEEL_PProc_THIS,&_eel_match); NSEEL_addfunc_varparm("matchi",2,NSEEL_PProc_THIS,&_eel_matchi); } void eel_string_initvm(NSEEL_VMCTX vm) { NSEEL_VM_SetStringFunc(vm, eel_string_context_state::addStringCallback, eel_string_context_state::addNamedStringCallback); } #ifdef EEL_WANT_DOCUMENTATION static const char *eel_strings_function_reference = #ifdef EEL_STRING_STDOUT_WRITE "printf\t\"format\"[, ...]\tOutput formatted string to system-specific destination, see sprintf() for more information\0" #endif "sprintf\t#dest,\"format\"[, ...]\tFormats a string and stores it in #dest. Format specifiers begin with %, and may include:\3\n" "\4 %% = %\n" "\4 %s = string from parameter\n" "\4 %d = parameter as integer\n" "\4 %i = parameter as integer\n" "\4 %u = parameter as unsigned integer\n" "\4 %x = parameter as hex (lowercase) integer\n" "\4 %X = parameter as hex (uppercase) integer\n" "\4 %c = parameter as character\n" "\4 %f = parameter as floating point\n" "\4 %e = parameter as floating point (scientific notation, lowercase)\n" "\4 %E = parameter as floating point (scientific notation, uppercase)\n" "\4 %g = parameter as floating point (shortest representation, lowercase)\n" "\4 %G = parameter as floating point (shortest representation, uppercase)\n" "\2\n" "Many standard C printf() modifiers can be used, including:\3\n" "\4 %.10s = string, but only print up to 10 characters\n" "\4 %-10s = string, left justified to 10 characters\n" "\4 %10s = string, right justified to 10 characters\n" "\4 %+f = floating point, always show sign\n" "\4 %.4f = floating point, minimum of 4 digits after decimal point\n" "\4 %10d = integer, minimum of 10 digits (space padded)\n" "\4 %010f = integer, minimum of 10 digits (zero padded)\n" "\2\n" "Values for format specifiers can be specified as additional parameters to sprintf, or within {} in the format specifier (such as %{varname}d, in that case a global variable is always used).\0" "matchi\t\"needle\",\"haystack\"[, ...]\tCase-insensitive version of match().\0" "match\t\"needle\",\"haystack\"[, ...]\tSearches for the first parameter in the second parameter, using a simplified regular expression syntax.\3\n" "\4* = match 0 or more characters\n" "\4*? = match 0 or more characters, lazy\n" "\4+ = match 1 or more characters\n" "\4+? = match 1 or more characters, lazy\n" "\4? = match one character\n" "\2\n" "You can also use format specifiers to match certain types of data, and optionally put that into a variable:\3\n" "\4%s means 1 or more chars\n" "\4%0s means 0 or more chars\n" "\4%5s means exactly 5 chars\n" "\4%5-s means 5 or more chars\n" "\4%-10s means 1-10 chars\n" "\4%3-5s means 3-5 chars\n" "\4%0-5s means 0-5 chars\n" "\4%x, %d, %u, and %f are available for use similarly\n" "\4%c can be used, but can't take any length modifiers\n" "\4Use uppercase (%S, %D, etc) for lazy matching\n" "\2\n" "See also sprintf() for other notes, including specifying direct variable references via {}.\0" "strlen\t\"str\"\tReturns the length of the string passed as a parameter\0" "strcpy\t#str,\"srcstr\"\tCopies the contents of srcstr to #str, and returns #str\0" "strcat\t#str,\"srcstr\"\tAppends srcstr to #str, and returns #str\0" "strcmp\t\"str\",\"str2\"\tCompares strings, returning 0 if equal\0" "stricmp\t\"str\",\"str2\"\tCompares strings ignoring case, returning 0 if equal\0" "strncmp\t\"str\",\"str2\",maxlen\tCompares strings giving up after maxlen characters, returning 0 if equal\0" "strnicmp\t\"str\",\"str2\",maxlen\tCompares strings giving up after maxlen characters, ignoring case, returning 0 if equal\0" "strncpy\t#str,\"srcstr\",maxlen\tCopies srcstr to #str, stopping after maxlen characters. Returns #str.\0" "strncat\t#str,\"srcstr\",maxlen\tAppends srcstr to #str, stopping after maxlen characters of srcstr. Returns #str.\0" "strcpy_from\t#str,\"srcstr\",offset\tCopies srcstr to #str, but starts reading srcstr at offset offset\0" "strcpy_substr\t#str,\"srcstr\",offs,ml)\tPHP-style (start at offs, offs<0 means from end, ml for maxlen, ml<0 = reduce length by this amt)\0" "str_getchar\t\"str\",offset[,type]\tReturns the data at byte-offset offset of str. If offset is negative, position is relative to end of string." "type defaults to signed char, but can be specified to read raw binary data in other formats (note the single quotes, these are single/multi-byte characters):\3\n" "\4'c' - signed char\n" "\4'cu' - unsigned char\n" "\4's' - signed short\n" "\4'S' - signed short, big endian\n" "\4'su' - unsigned short\n" "\4'Su' - unsigned short, big endian\n" "\4'i' - signed int\n" "\4'I' - signed int, big endian\n" "\4'iu' - unsigned int\n" "\4'Iu' - unsigned int, big endian\n" "\4'f' - float\n" "\4'F' - float, big endian\n" "\4'd' - double\n" "\4'D' - double, big endian\n" "\2\0" "str_setchar\t#str,offset,val[,type])\tSets value at offset offset, type optional. offset may be negative to refer to offset relative to end of string, or between 0 and length, inclusive, and if set to length it will lengthen string. See str_getchar() for more information on types.\0" "str_setlen\t#str,len\tSets length of #str (if increasing, will be space-padded), and returns #str.\0" "str_delsub\t#str,pos,len\tDeletes len characters at offset pos from #str, and returns #str.\0" "str_insert\t#str,\"srcstr\",pos\tInserts srcstr into #str at offset pos. Returns #str\0" ; #endif #endif jsusfx-0.4.0/src/WDL/eel2/eelscript.h000066400000000000000000000443071353477307700172740ustar00rootroot00000000000000#ifndef _WIN32 #include #ifndef EELSCRIPT_NO_LICE #include "../swell/swell.h" #endif #endif #include "../wdltypes.h" #include "../ptrlist.h" #include "../wdlstring.h" #include "../assocarray.h" #include "../queue.h" #include "ns-eel.h" #ifndef EELSCRIPT_MAX_FILE_HANDLES #define EELSCRIPT_MAX_FILE_HANDLES 512 #endif #ifndef EELSCRIPT_FILE_HANDLE_INDEX_BASE #define EELSCRIPT_FILE_HANDLE_INDEX_BASE 1000000 #endif #ifndef EEL_STRING_MAXUSERSTRING_LENGTH_HINT #define EEL_STRING_MAXUSERSTRING_LENGTH_HINT (1<<16) // 64KB per string max #endif #ifndef EEL_STRING_MAX_USER_STRINGS #define EEL_STRING_MAX_USER_STRINGS 32768 #endif #ifndef EEL_STRING_LITERAL_BASE #define EEL_STRING_LITERAL_BASE 2000000 #endif #ifndef EELSCRIPT_LICE_MAX_IMAGES #define EELSCRIPT_LICE_MAX_IMAGES 1024 #endif #ifndef EELSCRIPT_LICE_MAX_FONTS #define EELSCRIPT_LICE_MAX_FONTS 128 #endif #ifndef EELSCRIPT_NET_MAXCON #define EELSCRIPT_NET_MAXCON 4096 #endif #ifndef EELSCRIPT_LICE_CLASSNAME #define EELSCRIPT_LICE_CLASSNAME "eelscript_gfx" #endif // #define EELSCRIPT_NO_NET // #define EELSCRIPT_NO_LICE // #define EELSCRIPT_NO_FILE // #define EELSCRIPT_NO_FFT // #define EELSCRIPT_NO_MDCT // #define EELSCRIPT_NO_EVAL class eel_string_context_state; #ifndef EELSCRIPT_NO_NET class eel_net_state; #endif #ifndef EELSCRIPT_NO_LICE class eel_lice_state; #endif class eelScriptInst { public: static int init(); eelScriptInst(); virtual ~eelScriptInst(); NSEEL_CODEHANDLE compile_code(const char *code, const char **err); int runcode(const char *code, int showerr, const char *showerrfn, bool canfree, bool ignoreEndOfInputChk, bool doExec); int loadfile(const char *fn, const char *callerfn, bool allowstdin); NSEEL_VMCTX m_vm; WDL_PtrList m_code_freelist; #ifndef EELSCRIPT_NO_FILE FILE *m_handles[EELSCRIPT_MAX_FILE_HANDLES]; virtual EEL_F OpenFile(const char *fn, const char *mode) { if (!*fn || !*mode) return 0.0; #ifndef EELSCRIPT_NO_STDIO if (!strcmp(fn,"stdin")) return 1; if (!strcmp(fn,"stdout")) return 2; if (!strcmp(fn,"stderr")) return 3; #endif WDL_FastString fnstr(fn); if (!translateFilename(&fnstr,mode)) return 0.0; int x; for (x=0;x= EELSCRIPT_MAX_FILE_HANDLES) return 0.0; FILE *fp = fopen(fnstr.Get(),mode); if (!fp) return 0.0; m_handles[x]=fp; return x + EELSCRIPT_FILE_HANDLE_INDEX_BASE; } virtual EEL_F CloseFile(int fp_idx) { fp_idx-=EELSCRIPT_FILE_HANDLE_INDEX_BASE; if (fp_idx>=0 && fp_idx=0 && fp_idx m_eval_cache; virtual char *evalCacheGet(const char *str, NSEEL_CODEHANDLE *ch); virtual void evalCacheDispose(char *key, NSEEL_CODEHANDLE ch); WDL_Queue m_defer_eval, m_atexit_eval; void runCodeQ(WDL_Queue *q, const char *fname); void runAtExitCode() { runCodeQ(&m_atexit_eval,"atexit"); m_atexit_eval.Clear(); // make sure nothing gets added in atexit(), in case the user called runAtExitCode before destroying } #endif virtual bool run_deferred(); // requires eval support to be useful virtual bool has_deferred(); WDL_StringKeyedArray m_loaded_fnlist; // imported file list (to avoid repeats) }; //#define EEL_STRINGS_MUTABLE_LITERALS //#define EEL_STRING_WANT_MUTEX #define EEL_STRING_GET_CONTEXT_POINTER(opaque) (((eelScriptInst *)opaque)->m_string_context) #ifndef EEL_STRING_STDOUT_WRITE #ifndef EELSCRIPT_NO_STDIO #define EEL_STRING_STDOUT_WRITE(x,len) { fwrite(x,len,1,stdout); fflush(stdout); } #endif #endif #include "eel_strings.h" #include "eel_misc.h" #ifndef EELSCRIPT_NO_FILE #define EEL_FILE_OPEN(fn,mode) ((eelScriptInst*)opaque)->OpenFile(fn,mode) #define EEL_FILE_GETFP(fp) ((eelScriptInst*)opaque)->GetFileFP(fp) #define EEL_FILE_CLOSE(fpindex) ((eelScriptInst*)opaque)->CloseFile(fpindex) #include "eel_files.h" #endif #ifndef EELSCRIPT_NO_FFT #include "eel_fft.h" #endif #ifndef EELSCRIPT_NO_MDCT #include "eel_mdct.h" #endif #ifndef EELSCRIPT_NO_NET #define EEL_NET_GET_CONTEXT(opaque) (((eelScriptInst *)opaque)->m_net_state) #include "eel_net.h" #endif #ifndef EELSCRIPT_NO_LICE #ifndef EEL_LICE_WANT_STANDALONE #define EEL_LICE_WANT_STANDALONE #endif #ifndef EELSCRIPT_LICE_NOUPDATE #define EEL_LICE_WANT_STANDALONE_UPDATE // gfx_update() which runs message pump and updates screen etc #endif #define EEL_LICE_GET_FILENAME_FOR_STRING(idx, fs, p) (((eelScriptInst*)opaque)->GetFilenameForParameter(idx,fs,p)) #define EEL_LICE_GET_CONTEXT(opaque) ((opaque) ? (((eelScriptInst *)opaque)->m_gfx_state) : NULL) #include "eel_lice.h" #endif #ifndef EELSCRIPT_NO_EVAL #define EEL_EVAL_GET_CACHED(str, ch) ((eelScriptInst *)opaque)->evalCacheGet(str,&(ch)) #define EEL_EVAL_SET_CACHED(str, ch) ((eelScriptInst *)opaque)->evalCacheDispose(str,ch) #define EEL_EVAL_GET_VMCTX(opaque) (((eelScriptInst *)opaque)->m_vm) #include "eel_eval.h" static EEL_F NSEEL_CGEN_CALL _eel_defer(void *opaque, EEL_F *s) { EEL_STRING_MUTEXLOCK_SCOPE const char *str=EEL_STRING_GET_FOR_INDEX(*s,NULL); if (str && *str && *s >= EEL_STRING_MAX_USER_STRINGS) // don't allow defer(0) etc { eelScriptInst *inst = (eelScriptInst *)opaque; if (inst->m_defer_eval.Available() < EEL_STRING_MAXUSERSTRING_LENGTH_HINT) { inst->m_defer_eval.Add(str,strlen(str)+1); return 1.0; } #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("defer(): too much defer() code already added, ignoring"); #endif } #ifdef EEL_STRING_DEBUGOUT else if (!str) { EEL_STRING_DEBUGOUT("defer(): invalid string identifier specified %f",*s); } else if (*s < EEL_STRING_MAX_USER_STRINGS) { EEL_STRING_DEBUGOUT("defer(): user string identifier %f specified but not allowed",*s); } #endif return 0.0; } static EEL_F NSEEL_CGEN_CALL _eel_atexit(void *opaque, EEL_F *s) { EEL_STRING_MUTEXLOCK_SCOPE const char *str=EEL_STRING_GET_FOR_INDEX(*s,NULL); if (str && *str && *s >= EEL_STRING_MAX_USER_STRINGS) // don't allow atexit(0) etc { eelScriptInst *inst = (eelScriptInst *)opaque; if (inst->m_atexit_eval.Available() < EEL_STRING_MAXUSERSTRING_LENGTH_HINT) { inst->m_atexit_eval.Add(str,strlen(str)+1); return 1.0; } #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("atexit(): too much atexit() code already added, ignoring"); #endif } #ifdef EEL_STRING_DEBUGOUT else if (!str) { EEL_STRING_DEBUGOUT("atexit(): invalid string identifier specified %f",*s); } else if (*s < EEL_STRING_MAX_USER_STRINGS) { EEL_STRING_DEBUGOUT("atexit(): user string identifier %f specified but not allowed",*s); } #endif return 0.0; } #endif #define opaque ((void *)this) eelScriptInst::eelScriptInst() : m_loaded_fnlist(false) { #ifndef EELSCRIPT_NO_FILE memset(m_handles,0,sizeof(m_handles)); #endif m_vm = NSEEL_VM_alloc(); #ifdef EEL_STRING_DEBUGOUT if (!m_vm) EEL_STRING_DEBUGOUT("NSEEL_VM_alloc(): failed"); #endif NSEEL_VM_SetCustomFuncThis(m_vm,this); #ifdef NSEEL_ADDFUNC_DESTINATION NSEEL_VM_SetFunctionTable(m_vm,NSEEL_ADDFUNC_DESTINATION); #endif m_string_context = new eel_string_context_state; eel_string_initvm(m_vm); #ifndef EELSCRIPT_NO_NET m_net_state = new eel_net_state(EELSCRIPT_NET_MAXCON,NULL); #endif #ifndef EELSCRIPT_NO_LICE m_gfx_state = new eel_lice_state(m_vm,this,EELSCRIPT_LICE_MAX_IMAGES,EELSCRIPT_LICE_MAX_FONTS); m_gfx_state->resetVarsToStock(); #endif } eelScriptInst::~eelScriptInst() { #ifndef EELSCRIPT_NO_EVAL if (m_atexit_eval.GetSize()>0) runAtExitCode(); #endif int x; m_code_freelist.Empty((void (*)(void *))NSEEL_code_free); #ifndef EELSCRIPT_NO_EVAL for (x=0;xSet(fmt); return translateFilename(fs,iswrite?"w":"r"); } NSEEL_CODEHANDLE eelScriptInst::compile_code(const char *code, const char **err) { if (!m_vm) { *err = "EEL VM not initialized"; return NULL; } NSEEL_CODEHANDLE ch = NSEEL_code_compile_ex(m_vm, code, 0, NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS); if (ch) { m_string_context->update_named_vars(m_vm); m_code_freelist.Add((void*)ch); return ch; } *err = NSEEL_code_getcodeerror(m_vm); return NULL; } int eelScriptInst::runcode(const char *codeptr, int showerr, const char *showerrfn, bool canfree, bool ignoreEndOfInputChk, bool doExec) { if (m_vm) { NSEEL_CODEHANDLE code = NSEEL_code_compile_ex(m_vm,codeptr,0,canfree ? 0 : NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS); if (code) m_string_context->update_named_vars(m_vm); char *err; if (!code && (err=NSEEL_code_getcodeerror(m_vm))) { if (!ignoreEndOfInputChk && (NSEEL_code_geterror_flag(m_vm)&1)) return 1; if (showerr) { #ifdef EEL_STRING_DEBUGOUT if (showerr==2) { EEL_STRING_DEBUGOUT("Warning: %s:%s",WDL_get_filepart(showerrfn),err); } else { EEL_STRING_DEBUGOUT("%s:%s",WDL_get_filepart(showerrfn),err); } #endif } return -1; } else { if (code) { if (doExec) NSEEL_code_execute(code); if (canfree) NSEEL_code_free(code); else m_code_freelist.Add((void*)code); } return 0; } } return -1; } FILE *eelscript_resolvePath(WDL_FastString &usefn, const char *fn, const char *callerfn) { // resolve path relative to current int x; bool had_abs=false; for (x=0;x<2; x ++) { #ifdef _WIN32 if (!x && ((fn[0] == '\\' && fn[1] == '\\') || (fn[0] && fn[1] == ':'))) #else if (!x && fn[0] == '/') #endif { usefn.Set(fn); had_abs=true; } else { const char *fnu = fn; if (x) { while (*fnu) fnu++; while (fnu >= fn && *fnu != '\\' && *fnu != '/') fnu--; if (fnu < fn) break; fnu++; } usefn.Set(callerfn); int l=usefn.GetLength(); while (l > 0 && usefn.Get()[l-1] != '\\' && usefn.Get()[l-1] != '/') l--; if (l > 0) { usefn.SetLen(l); usefn.Append(fnu); } else { usefn.Set(fnu); } int last_slash_pos=-1; for (l = 0; l < usefn.GetLength(); l ++) { if (usefn.Get()[l] == '/' || usefn.Get()[l] == '\\') { if (usefn.Get()[l+1] == '.' && usefn.Get()[l+2] == '.' && (usefn.Get()[l+3] == '/' || usefn.Get()[l+3] == '\\')) { if (last_slash_pos >= 0) usefn.DeleteSub(last_slash_pos, l+3-last_slash_pos); else usefn.DeleteSub(0,l+3+1); } else { last_slash_pos=l; } } // take currentfn, remove filename part, add fnu } } FILE *fp = fopen(usefn.Get(),"r"); if (fp) return fp; } if (had_abs) usefn.Set(fn); return NULL; } int eelScriptInst::loadfile(const char *fn, const char *callerfn, bool allowstdin) { WDL_FastString usefn; FILE *fp = NULL; if (!strcmp(fn,"-")) { if (callerfn) { #ifdef EEL_STRING_DEBUGOUT EEL_STRING_DEBUGOUT("@import: can't import \"-\" (stdin)"); #endif return -1; } if (allowstdin) { fp = stdin; fn = "(stdin)"; } } else if (!callerfn) { fp = fopen(fn,"r"); if (fp) m_loaded_fnlist.Insert(fn,true); } else { fp = eelscript_resolvePath(usefn,fn,callerfn); if (fp) { if (m_loaded_fnlist.Get(usefn.Get())) { fclose(fp); return 0; } m_loaded_fnlist.Insert(usefn.Get(),true); fn = usefn.Get(); } } if (!fp) { #ifdef EEL_STRING_DEBUGOUT if (callerfn) EEL_STRING_DEBUGOUT("Warning: @import could not open '%s'",fn); else EEL_STRING_DEBUGOUT("Error opening %s",fn); #endif return -1; } WDL_FastString code; char line[4096]; for (;;) { line[0]=0; fgets(line,sizeof(line),fp); if (!line[0]) break; if (!strnicmp(line,"@import",7) && isspace(line[7])) { char *p=line+7; while (isspace(*p)) p++; char *ep=p; while (*ep) ep++; while (ep>p && isspace(ep[-1])) ep--; *ep=0; if (*p) loadfile(p,fn,false); } else { code.Append(line); } } if (fp != stdin) fclose(fp); return runcode(code.Get(),callerfn ? 2 : 1, fn,false,true,!callerfn); } char *eelScriptInst::evalCacheGet(const char *str, NSEEL_CODEHANDLE *ch) { // should mutex protect if multiple threads access this eelScriptInst context int x=m_eval_cache.GetSize(); while (--x >= 0) { char *ret; if (!strcmp(ret=m_eval_cache.Get()[x].str, str)) { *ch = m_eval_cache.Get()[x].ch; m_eval_cache.Delete(x); return ret; } } return NULL; } void eelScriptInst::evalCacheDispose(char *key, NSEEL_CODEHANDLE ch) { // should mutex protect if multiple threads access this eelScriptInst context evalCacheEnt ecc; ecc.str= key; ecc.ch = ch; if (m_eval_cache.GetSize() > 1024) { NSEEL_code_free(m_eval_cache.Get()->ch); free(m_eval_cache.Get()->str); m_eval_cache.Delete(0); } m_eval_cache.Add(ecc); } int eelScriptInst::init() { EEL_string_register(); #ifndef EELSCRIPT_NO_FILE EEL_file_register(); #endif #ifndef EELSCRIPT_NO_FFT EEL_fft_register(); #endif #ifndef EELSCRIPT_NO_MDCT EEL_mdct_register(); #endif EEL_misc_register(); #ifndef EELSCRIPT_NO_EVAL EEL_eval_register(); NSEEL_addfunc_retval("defer",1,NSEEL_PProc_THIS,&_eel_defer); NSEEL_addfunc_retval("runloop", 1, NSEEL_PProc_THIS, &_eel_defer); NSEEL_addfunc_retval("atexit",1,NSEEL_PProc_THIS,&_eel_atexit); #endif #ifndef EELSCRIPT_NO_NET EEL_tcp_register(); #endif #ifndef EELSCRIPT_NO_LICE eel_lice_register(); #ifdef _WIN32 eel_lice_register_standalone(GetModuleHandle(NULL),EELSCRIPT_LICE_CLASSNAME,NULL,NULL); #else eel_lice_register_standalone(NULL,EELSCRIPT_LICE_CLASSNAME,NULL,NULL); #endif #endif return 0; } bool eelScriptInst::has_deferred() { #ifndef EELSCRIPT_NO_EVAL return m_defer_eval.Available() && m_vm; #else return false; #endif } #ifndef EELSCRIPT_NO_EVAL void eelScriptInst::runCodeQ(WDL_Queue *q, const char *callername) { const int endptr = q->Available(); int offs = 0; while (offs < endptr) { if (q->Available() < endptr) break; // should never happen, but safety first! const char *ptr = (const char *)q->Get() + offs; offs += strlen(ptr)+1; NSEEL_CODEHANDLE ch=NULL; char *sv=evalCacheGet(ptr,&ch); if (!sv) sv=strdup(ptr); if (!ch) ch=NSEEL_code_compile(m_vm,sv,0); if (!ch) { free(sv); #ifdef EEL_STRING_DEBUGOUT const char *err = NSEEL_code_getcodeerror(m_vm); if (err) EEL_STRING_DEBUGOUT("%s: error in code: %s",callername,err); #endif } else { NSEEL_code_execute(ch); evalCacheDispose(sv,ch); } } q->Advance(endptr); } #endif bool eelScriptInst::run_deferred() { #ifndef EELSCRIPT_NO_EVAL if (!m_defer_eval.Available()||!m_vm) return false; runCodeQ(&m_defer_eval,"defer"); m_defer_eval.Compact(); return m_defer_eval.Available()>0; #else return false; #endif } #ifdef EEL_WANT_DOCUMENTATION #include "ns-eel-func-ref.h" void EELScript_GenerateFunctionList(WDL_PtrList *fs) { const char *p = nseel_builtin_function_reference; while (*p) { fs->Add(p); p += strlen(p) + 1; } p = eel_strings_function_reference; while (*p) { fs->Add(p); p += strlen(p) + 1; } p = eel_misc_function_reference; while (*p) { fs->Add(p); p += strlen(p) + 1; } #ifndef EELSCRIPT_NO_EVAL fs->Add("atexit\t\"code\"\t" #ifndef EELSCRIPT_HELP_NO_DEFER_DESC "Adds code to be executed when the script finishes." #endif ); fs->Add("defer\t\"code\"\t" #ifndef EELSCRIPT_HELP_NO_DEFER_DESC "Adds code which will be executed some small amount of time after the current code finishes. Identical to runloop()" #endif ); fs->Add("runloop\t\"code\"\t" #ifndef EELSCRIPT_HELP_NO_DEFER_DESC "Adds code which will be executed some small amount of time after the current code finishes. Identical to defer()" #endif ); p = eel_eval_function_reference; while (*p) { fs->Add(p); p += strlen(p) + 1; } #endif #ifndef EELSCRIPT_NO_NET p = eel_net_function_reference; while (*p) { fs->Add(p); p += strlen(p) + 1; } #endif #ifndef EELSCRIPT_NO_FFT p = eel_fft_function_reference; while (*p) { fs->Add(p); p += strlen(p) + 1; } #endif #ifndef EELSCRIPT_NO_FILE p = eel_file_function_reference; while (*p) { fs->Add(p); p += strlen(p) + 1; } #endif #ifndef EELSCRIPT_NO_MDCT p = eel_mdct_function_reference; while (*p) { fs->Add(p); p += strlen(p) + 1; } #endif #ifndef EELSCRIPT_NO_LICE p = eel_lice_function_reference; while (*p) { fs->Add(p); p += strlen(p) + 1; } #endif } #endif #undef opaque jsusfx-0.4.0/src/WDL/eel2/gen-lex-yacc000066400000000000000000000000411353477307700173130ustar00rootroot00000000000000yacc -v -d eel2.y && flex eel2.l jsusfx-0.4.0/src/WDL/eel2/glue_arm.h000066400000000000000000000161061353477307700170710ustar00rootroot00000000000000#ifndef _NSEEL_GLUE_ARM_H_ #define _NSEEL_GLUE_ARM_H_ // r0=return value, first parm, r1-r2 parms // r3+ should be reserved // blx addr // stmfd sp!, {register list, lr} // ldmfd sp!, {register list, pc} // let's make r8 = worktable // let's make r7 = ramtable // r6 = consttab // r5 = worktable ptr // r0=p1 // r1=p2 // r2=p3 // d0 is return value? #define GLUE_MAX_FPSTACK_SIZE 0 // no stack support #define GLUE_MAX_JMPSIZE ((1<<25) - 1024) // maximum relative jump size // endOfInstruction is end of jump with relative offset, offset passed in is offset from end of dest instruction. // TODO: verify, but offset probably from next instruction (PC is ahead) #define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((int *)(endOfInstruction))[-1] = (((int *)(endOfInstruction))[-1]&0xFF000000)|((((offset)>>2)-1))) // /=conditional=always = 0xE // |/= 101(L), so 8+2+0 = 10 = A static const unsigned int GLUE_JMP_NC[] = { 0xEA000000 }; static const unsigned int GLUE_JMP_IF_P1_Z[]= { 0xe1100000, // tst r0, r0 0x0A000000, // branch if Z set }; static const unsigned int GLUE_JMP_IF_P1_NZ[]= { 0xe1100000, // tst r0, r0 0x1A000000, // branch if Z clear }; #define GLUE_MOV_PX_DIRECTVALUE_SIZE 8 static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, unsigned int wv) { // requires ARMv6thumb2 or later const unsigned int reg_add = wv << 12; static const unsigned int tab[2] = { 0xe3000000, // movw r0, #0000 0xe3400000, // movt r0, #0000 }; // 0xABAAA, B is register, A are bits of word unsigned int *p=(unsigned int *)b; p[0] = tab[0] | reg_add | (v&0xfff) | ((v&0xf000)<<4); p[1] = tab[1] | reg_add | ((v>>16)&0xfff) | ((v&0xf0000000)>>12); } const static unsigned int GLUE_FUNC_ENTER[1] = { 0xe92d4010 }; // push {r4, lr} #define GLUE_FUNC_ENTER_SIZE 4 const static unsigned int GLUE_FUNC_LEAVE[1] = { 0 }; // let GLUE_RET pop #define GLUE_FUNC_LEAVE_SIZE 0 const static unsigned int GLUE_RET[]={ 0xe8bd8010 }; // pop {r4, pc} static int GLUE_RESET_WTP(unsigned char *out, void *ptr) { const static unsigned int GLUE_SET_WTP_FROM_R8 = 0xe1a05008; // mov r5, r8 if (out) memcpy(out,&GLUE_SET_WTP_FROM_R8,sizeof(GLUE_SET_WTP_FROM_R8)); return sizeof(GLUE_SET_WTP_FROM_R8); } const static unsigned int GLUE_PUSH_P1[1]={ 0xe52d0008 }; // push {r0}, aligned to 8 #define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE 4 static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs) { // str r0, [sp, #offs] *(unsigned int *)b = 0xe58d0000 + offs; } #define GLUE_MOVE_PX_STACKPTR_SIZE 4 static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv) { // mov rX, sp *(unsigned int *)b = 0xe1a0000d + (wv<<12); } #define GLUE_MOVE_STACK_SIZE 4 static void GLUE_MOVE_STACK(void *b, int amt) { if (amt>=0) *(unsigned int*)b = 0xe28dd000 | amt; else *(unsigned int*)b = 0xe24dd000 | (- amt); } #define GLUE_POP_PX_SIZE 4 static void GLUE_POP_PX(void *b, int wv) { ((unsigned int *)b)[0] = 0xe49d0008 | (wv<<12); // pop {rX}, aligned to 8 } #define GLUE_SET_PX_FROM_P1_SIZE 4 static void GLUE_SET_PX_FROM_P1(void *b, int wv) { *(unsigned int *)b = 0xe1a00000 | (wv<<12); // mov rX, r0 } static const unsigned int GLUE_PUSH_P1PTR_AS_VALUE[] = { 0xed907b00, // fldd d7, [r0] 0xe24dd008, // sub sp, sp, #8 0xed8d7b00, // fstd d7, [sp] }; static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) { if (buf) { unsigned int *bufptr = (unsigned int *)buf; *bufptr++ = 0xed9d7b00; // fldd d7, [sp] *bufptr++ = 0xe28dd008; // add sp, sp, #8 GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0); bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4; *bufptr++ = 0xed807b00; // fstd d7, [r0] } return 3*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE; } static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) { if (buf) { unsigned int *bufptr = (unsigned int *)buf; *bufptr++ = 0xed907b00; // fldd d7, [r0] GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0); bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4; *bufptr++ = 0xed807b00; // fstd d7, [r0] } return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE; } #ifndef _MSC_VER static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR rt) { //fwrite((void *)cp,4,20,stdout); //return; static const double consttab[] = { NSEEL_CLOSEFACTOR, 0.0, 1.0, -1.0, -0.5, // for invsqrt 1.5, }; __asm__( "mov r7, %2\n" "mov r6, %3\n" "mov r8, %1\n" "mov r0, %0\n" "mov r1, sp\n" "bic sp, sp, #7\n" "push {r1, lr}\n" "blx r0\n" "pop {r1, lr}\n" "mov sp, r1\n" ::"r" (cp), "r" (bp), "r" (rt), "r" (consttab) : "r5", "r6", "r7", "r8", "r10"); }; #endif static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) { unsigned int *p=(unsigned int *)_p; while ((p[0]&0x000F0FFF) != 0x000d0ead && (p[1]&0x000F0FFF) != 0x000b0eef) p++; p[0] = (p[0]&0xFFF0F000) | (newv&0xFFF) | ((newv << 4) & 0xF0000); p[1] = (p[1]&0xFFF0F000) | ((newv>>16)&0xFFF) | ((newv >> 12)&0xF0000); return (unsigned char *)(p+1); } #define GLUE_SET_PX_FROM_WTP_SIZE sizeof(int) static void GLUE_SET_PX_FROM_WTP(void *b, int wv) { *(unsigned int *)b = 0xe1a00005 + (wv<<12); // mov rX, r5 } static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) { if (buf) { unsigned int *bufptr = (unsigned int *)buf; GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0); bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4; *bufptr++ = 0xed800b00; // fstd d0, [r0] } return GLUE_MOV_PX_DIRECTVALUE_SIZE + sizeof(int); } #define GLUE_POP_FPSTACK_SIZE 0 static const unsigned int GLUE_POP_FPSTACK[1] = { 0 }; // no need to pop, not a stack static const unsigned int GLUE_POP_FPSTACK_TOSTACK[] = { 0xe24dd008, // sub sp, sp, #8 0xed8d0b00, // fstd d0, [sp] }; static const unsigned int GLUE_POP_FPSTACK_TO_WTP[] = { 0xed850b00, // fstd d0, [r5] 0xe2855008, // add r5, r5, #8 }; #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 4 static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) { *(unsigned int *)b = 0xed900b00 + (wv<<16); // fldd d0, [rX] } #define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE) static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) { GLUE_SET_PX_FROM_WTP(buf,wv); memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); }; static unsigned int GLUE_POP_STACK_TO_FPSTACK[2] = { 0xed9d0b00, // fldd d0, [sp] 0xe28dd008, // add sp, sp, #8 }; static const unsigned int GLUE_SET_P1_Z[] = { 0xe3a00000 }; // mov r0, #0 static const unsigned int GLUE_SET_P1_NZ[] = { 0xe3a00001 }; // mov r0, #1 static void *GLUE_realAddress(void *fn, void *fn_e, int *size) { static const unsigned int sig[3] = { 0xe1a00000, 0xe1a01001, 0xe1a02002 }; unsigned char *p = (unsigned char *)fn; while (memcmp(p,sig,sizeof(sig))) p+=4; p+=sizeof(sig); fn = p; while (memcmp(p,sig,sizeof(sig))) p+=4; *size = p - (unsigned char *)fn; return fn; } #endif jsusfx-0.4.0/src/WDL/eel2/glue_port.h000066400000000000000000000754671353477307700173150ustar00rootroot00000000000000#ifndef _EEL_GLUE_PORTABLE_H_ #define _EEL_GLUE_PORTABLE_H_ #define DECL_ASMFUNC(x) #define GLUE_JMP_TYPE int #define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((GLUE_JMP_TYPE *)(endOfInstruction))[-1] = (offset)) #define GLUE_HAS_FXCH #define GLUE_MAX_FPSTACK_SIZE 64 #define BIF_FPSTACKUSE(x) (0) // fp stack is not used within functions #define BIF_GETFPSTACKUSE(x) (1) enum { EEL_BC_NOP=1, EEL_BC_RET, EEL_BC_JMP_NC, // followed by GLUE_JMP_TYPE EEL_BC_JMP_IF_P1_Z, EEL_BC_JMP_IF_P1_NZ, EEL_BC_MOV_FPTOP_DV, EEL_BC_MOV_P1_DV, // followed by INT_PTR ptr EEL_BC_MOV_P2_DV, EEL_BC_MOV_P3_DV, EEL_BC__RESET_WTP, EEL_BC_PUSH_P1, EEL_BC_PUSH_P1PTR_AS_VALUE, EEL_BC_POP_P1, EEL_BC_POP_P2, EEL_BC_POP_P3, EEL_BC_POP_VALUE_TO_ADDR, EEL_BC_MOVE_STACK, EEL_BC_STORE_P1_TO_STACK_AT_OFFS, EEL_BC_MOVE_STACKPTR_TO_P1, EEL_BC_MOVE_STACKPTR_TO_P2, EEL_BC_MOVE_STACKPTR_TO_P3, EEL_BC_SET_P2_FROM_P1, EEL_BC_SET_P3_FROM_P1, EEL_BC_COPY_VALUE_AT_P1_TO_ADDR, EEL_BC_SET_P1_FROM_WTP, EEL_BC_SET_P2_FROM_WTP, EEL_BC_SET_P3_FROM_WTP, EEL_BC_POP_FPSTACK_TO_PTR, EEL_BC_POP_FPSTACK_TOSTACK, EEL_BC_PUSH_VAL_AT_P1_TO_FPSTACK, EEL_BC_PUSH_VAL_AT_P2_TO_FPSTACK, EEL_BC_PUSH_VAL_AT_P3_TO_FPSTACK, EEL_BC_POP_FPSTACK_TO_WTP, EEL_BC_SET_P1_Z, EEL_BC_SET_P1_NZ, EEL_BC_LOOP_LOADCNT, EEL_BC_LOOP_END, #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 EEL_BC_WHILE_SETUP, #endif EEL_BC_WHILE_BEGIN, EEL_BC_WHILE_END, EEL_BC_WHILE_CHECK_RV, EEL_BC_BNOT, EEL_BC_BNOTNOT, EEL_BC_EQUAL, EEL_BC_EQUAL_EXACT, EEL_BC_NOTEQUAL, EEL_BC_NOTEQUAL_EXACT, EEL_BC_ABOVE, EEL_BC_BELOWEQ, EEL_BC_ADD, EEL_BC_SUB, EEL_BC_MUL, EEL_BC_DIV, EEL_BC_AND, EEL_BC_OR, EEL_BC_OR0, EEL_BC_XOR, EEL_BC_ADD_OP, EEL_BC_SUB_OP, EEL_BC_ADD_OP_FAST, EEL_BC_SUB_OP_FAST, EEL_BC_MUL_OP, EEL_BC_DIV_OP, EEL_BC_MUL_OP_FAST, EEL_BC_DIV_OP_FAST, EEL_BC_AND_OP, EEL_BC_OR_OP, EEL_BC_XOR_OP, EEL_BC_UMINUS, EEL_BC_ASSIGN, EEL_BC_ASSIGN_FAST, EEL_BC_ASSIGN_FAST_FROMFP, EEL_BC_ASSIGN_FROMFP, EEL_BC_MOD, EEL_BC_MOD_OP, EEL_BC_SHR, EEL_BC_SHL, EEL_BC_SQR, EEL_BC_MIN, EEL_BC_MAX, EEL_BC_MIN_FP, EEL_BC_MAX_FP, EEL_BC_ABS, EEL_BC_SIGN, EEL_BC_INVSQRT, EEL_BC_FXCH, EEL_BC_POP_FPSTACK, EEL_BC_FCALL, EEL_BC_BOOLTOFP, EEL_BC_FPTOBOOL, EEL_BC_FPTOBOOL_REV, EEL_BC_CFUNC_1PDD, EEL_BC_CFUNC_2PDD, EEL_BC_CFUNC_2PDDS, EEL_BC_MEGABUF, EEL_BC_GMEGABUF, EEL_BC_GENERIC1PARM, EEL_BC_GENERIC2PARM, EEL_BC_GENERIC3PARM, EEL_BC_GENERIC1PARM_RETD, EEL_BC_GENERIC2PARM_RETD, EEL_BC_GENERIC3PARM_RETD, EEL_BC_USERSTACK_PUSH, EEL_BC_USERSTACK_POP, EEL_BC_USERSTACK_POPFAST, EEL_BC_USERSTACK_PEEK, EEL_BC_USERSTACK_PEEK_INT, EEL_BC_USERSTACK_PEEK_TOP, EEL_BC_USERSTACK_EXCH, EEL_BC_DBG_GETSTACKPTR, }; #define BC_DECL(x) static const EEL_BC_TYPE GLUE_##x[] = { EEL_BC_##x }; #define BC_DECL_JMP(x) static const EEL_BC_TYPE GLUE_##x[1 + sizeof(GLUE_JMP_TYPE) / sizeof(EEL_BC_TYPE)] = { EEL_BC_##x }; BC_DECL_JMP(JMP_NC) BC_DECL_JMP(JMP_IF_P1_Z) BC_DECL_JMP(JMP_IF_P1_NZ) BC_DECL(RET) BC_DECL(FXCH) BC_DECL(POP_FPSTACK) #define GLUE_POP_FPSTACK_SIZE sizeof(EEL_BC_TYPE) BC_DECL(PUSH_P1) BC_DECL(PUSH_P1PTR_AS_VALUE) BC_DECL(POP_FPSTACK_TOSTACK) BC_DECL(POP_FPSTACK_TO_WTP) BC_DECL(SET_P1_Z) BC_DECL(SET_P1_NZ) BC_DECL_JMP(LOOP_LOADCNT) BC_DECL_JMP(LOOP_END) #define GLUE_LOOP_BEGIN_SIZE 0 #define GLUE_LOOP_BEGIN ((void*)"") #define GLUE_LOOP_CLAMPCNT_SIZE 0 #define GLUE_LOOP_CLAMPCNT ((void*)"") #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 BC_DECL(WHILE_SETUP) #define GLUE_WHILE_SETUP_SIZE sizeof(GLUE_WHILE_SETUP) BC_DECL_JMP(WHILE_END) #else #define GLUE_WHILE_SETUP_SIZE 0 #define GLUE_WHILE_SETUP ((void *)"") #define GLUE_WHILE_END_NOJUMP BC_DECL(WHILE_END) #endif BC_DECL(WHILE_BEGIN); BC_DECL_JMP(WHILE_CHECK_RV) #define GLUE_MOV_PX_DIRECTVALUE_SIZE (sizeof(EEL_BC_TYPE) + sizeof(INT_PTR)) #define GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE GLUE_MOV_PX_DIRECTVALUE_SIZE static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv) { static const EEL_BC_TYPE tab[] = { EEL_BC_MOV_FPTOP_DV, EEL_BC_MOV_P1_DV, EEL_BC_MOV_P2_DV, EEL_BC_MOV_P3_DV, }; *(EEL_BC_TYPE *)b = tab[wv+1]; *(INT_PTR *) ((char *)b + sizeof(EEL_BC_TYPE)) = v; } #define GLUE_FUNC_ENTER_SIZE 0 #define GLUE_FUNC_LEAVE_SIZE 0 static const EEL_BC_TYPE GLUE_FUNC_ENTER[1]={-1}; static const EEL_BC_TYPE GLUE_FUNC_LEAVE[1]={-1}; static int GLUE_RESET_WTP(unsigned char *out, void *ptr) { BC_DECL(_RESET_WTP) if (out) memcpy(out,&GLUE__RESET_WTP,sizeof(GLUE__RESET_WTP)); if (out) *(void **) (out+sizeof(GLUE__RESET_WTP)) = ptr; return sizeof(GLUE__RESET_WTP) + sizeof(void *); } #define GLUE_POP_PX_SIZE sizeof(EEL_BC_TYPE) static void GLUE_POP_PX(void *b, int wv) { static const EEL_BC_TYPE tab[3] ={ EEL_BC_POP_P1, EEL_BC_POP_P2, EEL_BC_POP_P3, }; *(EEL_BC_TYPE *)b = tab[wv]; } #define GLUE_SET_PX_FROM_P1_SIZE sizeof(EEL_BC_TYPE) static void GLUE_SET_PX_FROM_P1(void *b, int wv) { static const unsigned int tab[3]={ EEL_BC_NOP, EEL_BC_SET_P2_FROM_P1, EEL_BC_SET_P3_FROM_P1, }; *(EEL_BC_TYPE *)b = tab[wv]; } #define GLUE_MOVE_STACK_SIZE (sizeof(EEL_BC_TYPE) + sizeof(int)) static void GLUE_MOVE_STACK(void *b, int amt) { *(EEL_BC_TYPE *)b = EEL_BC_MOVE_STACK; *(int *)(((EEL_BC_TYPE *)b)+1) = amt; } #define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE (sizeof(EEL_BC_TYPE) + sizeof(int)) static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs) { *(EEL_BC_TYPE *)b = EEL_BC_STORE_P1_TO_STACK_AT_OFFS; *(int *)(((EEL_BC_TYPE *)b)+1) = offs; } #define GLUE_MOVE_PX_STACKPTR_SIZE sizeof(EEL_BC_TYPE) static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv) { static const EEL_BC_TYPE tab[3] = { EEL_BC_MOVE_STACKPTR_TO_P1, EEL_BC_MOVE_STACKPTR_TO_P2, EEL_BC_MOVE_STACKPTR_TO_P3 }; *(EEL_BC_TYPE *)b = tab[wv]; } static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) { if (buf) { *(EEL_BC_TYPE *)buf = EEL_BC_POP_VALUE_TO_ADDR; *(void **) (buf+sizeof(EEL_BC_TYPE)) = destptr; } return sizeof(EEL_BC_TYPE) + sizeof(void *); } static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) { if (buf) { *(EEL_BC_TYPE *)buf = EEL_BC_COPY_VALUE_AT_P1_TO_ADDR; *(void **) (buf+sizeof(EEL_BC_TYPE)) = destptr; } return sizeof(EEL_BC_TYPE) + sizeof(void *); } static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) { int mv=5; char *p=(char*)_p; p+=sizeof(EEL_BC_TYPE); while (*(INT_PTR*)p && mv-- > 0) p++; if (!mv) return (unsigned char *)p; *(INT_PTR *)p = newv; return (unsigned char *) p + sizeof(INT_PTR) - sizeof(EEL_BC_TYPE); } #define GLUE_SET_PX_FROM_WTP_SIZE sizeof(EEL_BC_TYPE) static void GLUE_SET_PX_FROM_WTP(void *b, int wv) { static const EEL_BC_TYPE tab[3]={ EEL_BC_SET_P1_FROM_WTP, EEL_BC_SET_P2_FROM_WTP, EEL_BC_SET_P3_FROM_WTP, }; *(EEL_BC_TYPE *)b = tab[wv]; } static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) { if (buf) { *(EEL_BC_TYPE *)buf = EEL_BC_POP_FPSTACK_TO_PTR; *(void **) (buf+sizeof(EEL_BC_TYPE)) = destptr; } return sizeof(EEL_BC_TYPE) + sizeof(void *); } #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE sizeof(EEL_BC_TYPE) static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) { static const EEL_BC_TYPE tab[3] = { EEL_BC_PUSH_VAL_AT_P1_TO_FPSTACK, EEL_BC_PUSH_VAL_AT_P2_TO_FPSTACK, EEL_BC_PUSH_VAL_AT_P3_TO_FPSTACK, }; *(EEL_BC_TYPE *)b = tab[wv]; } #define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE) static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) { GLUE_SET_PX_FROM_WTP(buf,wv); memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); }; static unsigned char GLUE_POP_STACK_TO_FPSTACK[1] = { 0 }; // todo #define GLUE_INLINE_LOOPS // end of bytecode glue, now for stubbage #define EEL_BC_ENDOF(x) (((char*)(x))+sizeof(x)) #define BC_DECLASM(x,y) static EEL_BC_TYPE nseel_asm_##x[1]={EEL_BC_##y}; BC_DECLASM(band,NOP) BC_DECLASM(bor,NOP) BC_DECLASM(bnot,BNOT) BC_DECLASM(bnotnot,BNOTNOT) BC_DECLASM(equal,EQUAL) BC_DECLASM(equal_exact,EQUAL_EXACT) BC_DECLASM(notequal_exact,NOTEQUAL_EXACT) BC_DECLASM(notequal,NOTEQUAL) BC_DECLASM(above,ABOVE) BC_DECLASM(beloweq,BELOWEQ) BC_DECLASM(add,ADD) BC_DECLASM(sub,SUB) BC_DECLASM(mul,MUL) BC_DECLASM(div,DIV) BC_DECLASM(and,AND) BC_DECLASM(or,OR) BC_DECLASM(or0,OR0) BC_DECLASM(xor,XOR) BC_DECLASM(add_op,ADD_OP) BC_DECLASM(sub_op,SUB_OP) BC_DECLASM(add_op_fast,ADD_OP_FAST) BC_DECLASM(sub_op_fast,SUB_OP_FAST) BC_DECLASM(mul_op,MUL_OP) BC_DECLASM(div_op,DIV_OP) BC_DECLASM(mul_op_fast,MUL_OP_FAST) BC_DECLASM(div_op_fast,DIV_OP_FAST) BC_DECLASM(and_op,AND_OP) BC_DECLASM(or_op,OR_OP) BC_DECLASM(xor_op,XOR_OP) BC_DECLASM(uminus,UMINUS) BC_DECLASM(assign,ASSIGN) BC_DECLASM(assign_fast,ASSIGN_FAST) BC_DECLASM(assign_fast_fromfp,ASSIGN_FAST_FROMFP) BC_DECLASM(assign_fromfp,ASSIGN_FROMFP) BC_DECLASM(mod,MOD) BC_DECLASM(mod_op,MOD_OP) BC_DECLASM(shr,SHR) BC_DECLASM(shl,SHL) BC_DECLASM(sqr,SQR) BC_DECLASM(min,MIN) BC_DECLASM(max,MAX) BC_DECLASM(min_fp,MIN_FP) BC_DECLASM(max_fp,MAX_FP) BC_DECLASM(abs,ABS) BC_DECLASM(sign,SIGN) BC_DECLASM(invsqrt,INVSQRT) BC_DECLASM(dbg_getstackptr,DBG_GETSTACKPTR) BC_DECLASM(booltofp,BOOLTOFP) BC_DECLASM(fptobool,FPTOBOOL) BC_DECLASM(fptobool_rev,FPTOBOOL_REV) #define BC_DECLASM_N(x,y,n) static EEL_BC_TYPE nseel_asm_##x[1 + (n*sizeof(INT_PTR))/sizeof(EEL_BC_TYPE)]={EEL_BC_##y, }; #define BC_DECLASM_N2(x,y,n) static EEL_BC_TYPE _asm_##x[1 + (n*sizeof(INT_PTR))/sizeof(EEL_BC_TYPE)]={EEL_BC_##y, }; #define BC_DECLASM_N_EXPORT(x,y,n) EEL_BC_TYPE _asm_##x[1 + (n*sizeof(INT_PTR))/sizeof(EEL_BC_TYPE)]={EEL_BC_##y, }; const void *const _asm_##x##_end = EEL_BC_ENDOF(_asm_##x); BC_DECLASM_N(stack_push,USERSTACK_PUSH,3) BC_DECLASM_N(stack_pop,USERSTACK_POP,3) BC_DECLASM_N(stack_pop_fast,USERSTACK_POPFAST,3) BC_DECLASM_N(stack_peek,USERSTACK_PEEK,3) BC_DECLASM_N(stack_peek_int,USERSTACK_PEEK_INT,4) BC_DECLASM_N(stack_peek_top,USERSTACK_PEEK_TOP,1) BC_DECLASM_N(stack_exch,USERSTACK_EXCH,1) BC_DECLASM_N(fcall,FCALL,1) BC_DECLASM_N(1pdd,CFUNC_1PDD,1) BC_DECLASM_N(2pdd,CFUNC_2PDD,1) BC_DECLASM_N(2pdds,CFUNC_2PDDS,1) BC_DECLASM_N2(megabuf,MEGABUF,0) BC_DECLASM_N2(gmegabuf,GMEGABUF,2) #define _asm_megabuf_end EEL_BC_ENDOF(_asm_megabuf) #define _asm_gmegabuf_end EEL_BC_ENDOF(_asm_gmegabuf) BC_DECLASM_N_EXPORT(generic1parm,GENERIC1PARM,2) BC_DECLASM_N_EXPORT(generic2parm,GENERIC2PARM,2) BC_DECLASM_N_EXPORT(generic3parm,GENERIC3PARM,2) BC_DECLASM_N_EXPORT(generic1parm_retd,GENERIC1PARM_RETD,2) BC_DECLASM_N_EXPORT(generic2parm_retd,GENERIC2PARM_RETD,2) BC_DECLASM_N_EXPORT(generic3parm_retd,GENERIC3PARM_RETD,2) #define _asm_generic1parm_end EEL_BC_ENDOF(_asm_generic1parm) #define _asm_generic2parm_end EEL_BC_ENDOF(_asm_generic2parm) #define _asm_generic3parm_end EEL_BC_ENDOF(_asm_generic3parm) #define _asm_generic1parm_retd_end EEL_BC_ENDOF(_asm_generic1parm_retd) #define _asm_generic2parm_retd_end EEL_BC_ENDOF(_asm_generic2parm_retd) #define _asm_generic3parm_retd_end EEL_BC_ENDOF(_asm_generic3parm_retd) #define nseel_asm_1pdd_end EEL_BC_ENDOF(nseel_asm_1pdd) #define nseel_asm_2pdd_end EEL_BC_ENDOF(nseel_asm_2pdd) #define nseel_asm_2pdds_end EEL_BC_ENDOF(nseel_asm_2pdds) #define nseel_asm_fcall_end EEL_BC_ENDOF(nseel_asm_fcall) #define nseel_asm_band_end EEL_BC_ENDOF(nseel_asm_band) #define nseel_asm_bor_end EEL_BC_ENDOF(nseel_asm_bor) #define nseel_asm_bnot_end EEL_BC_ENDOF(nseel_asm_bnot) #define nseel_asm_bnotnot_end EEL_BC_ENDOF(nseel_asm_bnotnot) #define nseel_asm_equal_end EEL_BC_ENDOF(nseel_asm_equal) #define nseel_asm_equal_exact_end EEL_BC_ENDOF(nseel_asm_equal_exact) #define nseel_asm_notequal_end EEL_BC_ENDOF(nseel_asm_notequal) #define nseel_asm_notequal_exact_end EEL_BC_ENDOF(nseel_asm_notequal_exact) #define nseel_asm_above_end EEL_BC_ENDOF(nseel_asm_above) #define nseel_asm_beloweq_end EEL_BC_ENDOF(nseel_asm_beloweq) #define nseel_asm_min_end EEL_BC_ENDOF(nseel_asm_min) #define nseel_asm_max_end EEL_BC_ENDOF(nseel_asm_max) #define nseel_asm_abs_end EEL_BC_ENDOF(nseel_asm_abs) #define nseel_asm_min_fp_end EEL_BC_ENDOF(nseel_asm_min_fp) #define nseel_asm_max_fp_end EEL_BC_ENDOF(nseel_asm_max_fp) #define nseel_asm_sign_end EEL_BC_ENDOF(nseel_asm_sign) #define nseel_asm_invsqrt_end EEL_BC_ENDOF(nseel_asm_invsqrt) #define nseel_asm_dbg_getstackptr_end EEL_BC_ENDOF(nseel_asm_dbg_getstackptr) #define nseel_asm_add_end EEL_BC_ENDOF(nseel_asm_add) #define nseel_asm_sub_end EEL_BC_ENDOF(nseel_asm_sub) #define nseel_asm_mul_end EEL_BC_ENDOF(nseel_asm_mul) #define nseel_asm_div_end EEL_BC_ENDOF(nseel_asm_div) #define nseel_asm_and_end EEL_BC_ENDOF(nseel_asm_and) #define nseel_asm_or_end EEL_BC_ENDOF(nseel_asm_or) #define nseel_asm_or0_end EEL_BC_ENDOF(nseel_asm_or0) #define nseel_asm_xor_end EEL_BC_ENDOF(nseel_asm_xor) #define nseel_asm_add_op_end EEL_BC_ENDOF(nseel_asm_add_op) #define nseel_asm_sub_op_end EEL_BC_ENDOF(nseel_asm_sub_op) #define nseel_asm_add_op_fast_end EEL_BC_ENDOF(nseel_asm_add_op_fast) #define nseel_asm_sub_op_fast_end EEL_BC_ENDOF(nseel_asm_sub_op_fast) #define nseel_asm_mul_op_end EEL_BC_ENDOF(nseel_asm_mul_op) #define nseel_asm_mul_op_fast_end EEL_BC_ENDOF(nseel_asm_mul_op_fast) #define nseel_asm_div_op_end EEL_BC_ENDOF(nseel_asm_div_op) #define nseel_asm_div_op_fast_end EEL_BC_ENDOF(nseel_asm_div_op_fast) #define nseel_asm_and_op_end EEL_BC_ENDOF(nseel_asm_and_op) #define nseel_asm_or_op_end EEL_BC_ENDOF(nseel_asm_or_op) #define nseel_asm_xor_op_end EEL_BC_ENDOF(nseel_asm_xor_op) #define nseel_asm_uminus_end EEL_BC_ENDOF(nseel_asm_uminus) #define nseel_asm_assign_end EEL_BC_ENDOF(nseel_asm_assign) #define nseel_asm_assign_fast_end EEL_BC_ENDOF(nseel_asm_assign_fast) #define nseel_asm_assign_fast_fromfp_end EEL_BC_ENDOF(nseel_asm_assign_fast_fromfp) #define nseel_asm_assign_fromfp_end EEL_BC_ENDOF(nseel_asm_assign_fromfp) #define nseel_asm_mod_end EEL_BC_ENDOF(nseel_asm_mod) #define nseel_asm_mod_op_end EEL_BC_ENDOF(nseel_asm_mod_op) #define nseel_asm_shr_end EEL_BC_ENDOF(nseel_asm_shr) #define nseel_asm_shl_end EEL_BC_ENDOF(nseel_asm_shl) #define nseel_asm_sqr_end EEL_BC_ENDOF(nseel_asm_sqr) #define nseel_asm_booltofp_end EEL_BC_ENDOF(nseel_asm_booltofp) #define nseel_asm_fptobool_end EEL_BC_ENDOF(nseel_asm_fptobool) #define nseel_asm_fptobool_rev_end EEL_BC_ENDOF(nseel_asm_fptobool_rev) #define nseel_asm_stack_push_end EEL_BC_ENDOF(nseel_asm_stack_push) #define nseel_asm_stack_pop_end EEL_BC_ENDOF(nseel_asm_stack_pop) #define nseel_asm_stack_pop_fast_end EEL_BC_ENDOF(nseel_asm_stack_pop_fast) #define nseel_asm_stack_peek_end EEL_BC_ENDOF(nseel_asm_stack_peek) #define nseel_asm_stack_peek_int_end EEL_BC_ENDOF(nseel_asm_stack_peek_int) #define nseel_asm_stack_peek_top_end EEL_BC_ENDOF(nseel_asm_stack_peek_top) #define nseel_asm_stack_exch_end EEL_BC_ENDOF(nseel_asm_stack_exch) static void *GLUE_realAddress(void *fn, void *fn_e, int *size) { *size = (char *)fn_e - (char *)fn; return fn; } #define EEL_BC_STACKSIZE (65536) // todo: check for stack overflows! we could determine if this is possible at compile time. #define EEL_BC_STACK_POP_SIZE 8 #define EEL_BC_STACK_PUSH(type, val) (*(type *)(stackptr -= EEL_BC_STACK_POP_SIZE)) = (val) #define EEL_BC_STACK_POP() (stackptr += EEL_BC_STACK_POP_SIZE) #define EEL_BC_TRUE ((EEL_F*)(INT_PTR)1) static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR rt) { char __stack[EEL_BC_STACKSIZE]; char *iptr = (char*)cp; char *stackptr=__stack + EEL_BC_STACKSIZE; EEL_F *p1 = NULL, *p2 = NULL, *p3 = NULL, *wtp = (EEL_F*)bp; #define fp_top (_fpstacktop[0]) #define fp_top2 (_fpstacktop[-1]) #define fp_push(x) *++_fpstacktop=(x) #define fp_pop() (*_fpstacktop--) #define fp_rewind(x) (_fpstacktop -= (x)) EEL_F fpstack[GLUE_MAX_FPSTACK_SIZE]; EEL_F *_fpstacktop=fpstack-1; for (;;) { EEL_BC_TYPE inst = *(EEL_BC_TYPE *)iptr; iptr += sizeof(EEL_BC_TYPE); switch (inst) { case EEL_BC_FXCH: { EEL_F a = fp_top; fp_top=fp_top2; fp_top2=a; } break; case EEL_BC_POP_FPSTACK: fp_rewind(1); break; case EEL_BC_NOP: break; case EEL_BC_RET: if (EEL_BC_STACK_POP() > __stack+EEL_BC_STACKSIZE) { return; } iptr = *(void **)(stackptr - EEL_BC_STACK_POP_SIZE); break; case EEL_BC_JMP_NC: iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; break; case EEL_BC_JMP_IF_P1_Z: iptr += p1 ? sizeof(GLUE_JMP_TYPE) : sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; break; case EEL_BC_JMP_IF_P1_NZ: iptr += p1 ? sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr : sizeof(GLUE_JMP_TYPE); break; case EEL_BC_MOV_FPTOP_DV: fp_push(**(EEL_F **)iptr); iptr += sizeof(void*); break; case EEL_BC_MOV_P1_DV: p1 = *(void **)iptr; iptr += sizeof(void*); break; case EEL_BC_MOV_P2_DV: p2 = *(void **)iptr; iptr += sizeof(void*); break; case EEL_BC_MOV_P3_DV: p3 = *(void **)iptr; iptr += sizeof(void*); break; case EEL_BC__RESET_WTP: wtp = *(void **)iptr; iptr += sizeof(void*); break; case EEL_BC_PUSH_P1: EEL_BC_STACK_PUSH(void *, p1); break; case EEL_BC_PUSH_P1PTR_AS_VALUE: EEL_BC_STACK_PUSH(EEL_F, *p1); break; case EEL_BC_POP_P1: p1 = *(EEL_F **) stackptr; EEL_BC_STACK_POP(); break; case EEL_BC_POP_P2: p2 = *(EEL_F **) stackptr; EEL_BC_STACK_POP(); break; case EEL_BC_POP_P3: p3 = *(EEL_F **) stackptr; EEL_BC_STACK_POP(); break; case EEL_BC_POP_VALUE_TO_ADDR: **(EEL_F**)iptr = *(EEL_F *)stackptr; EEL_BC_STACK_POP(); iptr += sizeof(void*); break; case EEL_BC_MOVE_STACK: stackptr += *(int *)iptr; iptr += sizeof(int); break; case EEL_BC_STORE_P1_TO_STACK_AT_OFFS: *(void **) (stackptr + *(int *)iptr) = p1; iptr += sizeof(int); break; case EEL_BC_MOVE_STACKPTR_TO_P1: p1 = (double *)stackptr; break; case EEL_BC_MOVE_STACKPTR_TO_P2: p2 = (double *)stackptr; break; case EEL_BC_MOVE_STACKPTR_TO_P3: p3 = (double *)stackptr; break; case EEL_BC_SET_P2_FROM_P1: p2=p1; break; case EEL_BC_SET_P3_FROM_P1: p3=p1; break; case EEL_BC_COPY_VALUE_AT_P1_TO_ADDR: **(EEL_F **)iptr = *p1; iptr += sizeof(void*); break; case EEL_BC_SET_P1_FROM_WTP: p1 = wtp; break; case EEL_BC_SET_P2_FROM_WTP: p2 = wtp; break; case EEL_BC_SET_P3_FROM_WTP: p3 = wtp; break; case EEL_BC_POP_FPSTACK_TO_PTR: **((EEL_F **)iptr) = fp_pop(); iptr += sizeof(void *); break; case EEL_BC_POP_FPSTACK_TOSTACK: EEL_BC_STACK_PUSH(EEL_F, fp_pop()); break; case EEL_BC_PUSH_VAL_AT_P1_TO_FPSTACK: fp_push(*p1); break; case EEL_BC_PUSH_VAL_AT_P2_TO_FPSTACK: fp_push(*p2); break; case EEL_BC_PUSH_VAL_AT_P3_TO_FPSTACK: fp_push(*p3); break; case EEL_BC_POP_FPSTACK_TO_WTP: *wtp++ = fp_pop(); break; case EEL_BC_SET_P1_Z: p1=NULL; break; case EEL_BC_SET_P1_NZ: p1 = EEL_BC_TRUE; break; case EEL_BC_LOOP_LOADCNT: if ((EEL_BC_STACK_PUSH(int, (int)fp_pop())) < 1) { EEL_BC_STACK_POP(); iptr+= sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; } else { iptr += sizeof(GLUE_JMP_TYPE); #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 if ((*(int *)stackptr) > NSEEL_LOOPFUNC_SUPPORT_MAXLEN) (*(int *)stackptr) = NSEEL_LOOPFUNC_SUPPORT_MAXLEN; #endif EEL_BC_STACK_PUSH(void *, wtp); } break; case EEL_BC_LOOP_END: wtp = *(void **) (stackptr); if (--(*(int *)(stackptr+EEL_BC_STACK_POP_SIZE)) <= 0) { stackptr += EEL_BC_STACK_POP_SIZE*2; iptr += sizeof(GLUE_JMP_TYPE); } else { iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; // back to the start! } break; #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 case EEL_BC_WHILE_SETUP: EEL_BC_STACK_PUSH(int,NSEEL_LOOPFUNC_SUPPORT_MAXLEN); break; #endif case EEL_BC_WHILE_BEGIN: EEL_BC_STACK_PUSH(void *, wtp); break; case EEL_BC_WHILE_END: wtp = *(EEL_F **) stackptr; EEL_BC_STACK_POP(); #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 if (--(*(int *)stackptr) <= 0) { EEL_BC_STACK_POP(); iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; // endpt } else { iptr += sizeof(GLUE_JMP_TYPE); } #endif break; case EEL_BC_WHILE_CHECK_RV: if (p1) { iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; // loop } else { // done #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 EEL_BC_STACK_POP(); #endif iptr += sizeof(GLUE_JMP_TYPE); } break; case EEL_BC_BNOT: p1 = p1 ? NULL : EEL_BC_TRUE; break; case EEL_BC_BNOTNOT: p1 = p1 ? EEL_BC_TRUE : NULL; break; case EEL_BC_EQUAL: p1 = fabs(fp_top - fp_top2) < NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL; fp_rewind(2); break; case EEL_BC_EQUAL_EXACT: p1 = fp_top == fp_top2 ? EEL_BC_TRUE : NULL; fp_rewind(2); break; case EEL_BC_NOTEQUAL: p1 = fabs(fp_top - fp_top2) >= NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL; fp_rewind(2); break; case EEL_BC_NOTEQUAL_EXACT: p1 = fp_top != fp_top2 ? EEL_BC_TRUE : NULL; fp_rewind(2); break; case EEL_BC_ABOVE: p1 = fp_top < fp_top2 ? EEL_BC_TRUE : NULL; fp_rewind(2); break; case EEL_BC_BELOWEQ: p1 = fp_top >= fp_top2 ? EEL_BC_TRUE : NULL; fp_rewind(2); break; case EEL_BC_ADD: fp_top2 += fp_top; fp_rewind(1); break; case EEL_BC_SUB: fp_top2 -= fp_top; fp_rewind(1); break; case EEL_BC_MUL: fp_top2 *= fp_top; fp_rewind(1); break; case EEL_BC_DIV: fp_top2 /= fp_top; fp_rewind(1); break; case EEL_BC_AND: fp_top2 = (EEL_F) (((int)fp_top) & (int)(fp_top2)); fp_rewind(1); break; case EEL_BC_OR: fp_top2 = (EEL_F) (((int)fp_top) | (int)(fp_top2)); fp_rewind(1); break; case EEL_BC_OR0: fp_top = (EEL_F) ((int)(fp_top)); break; case EEL_BC_XOR: fp_top2 = (EEL_F) (((int)fp_top) ^ (int)(fp_top2)); fp_rewind(1); break; case EEL_BC_ADD_OP: *(p1 = p2) = denormal_filter_double2(*p2 + fp_pop()); break; case EEL_BC_SUB_OP: *(p1 = p2) = denormal_filter_double2(*p2 - fp_pop()); break; case EEL_BC_ADD_OP_FAST: *(p1 = p2) += fp_pop(); break; case EEL_BC_SUB_OP_FAST: *(p1 = p2) -= fp_pop(); break; case EEL_BC_MUL_OP: *(p1 = p2) = denormal_filter_double2(*p2 * fp_pop()); break; case EEL_BC_DIV_OP: *(p1 = p2) = denormal_filter_double2(*p2 / fp_pop()); break; case EEL_BC_MUL_OP_FAST: *(p1 = p2) *= fp_pop(); break; case EEL_BC_DIV_OP_FAST: *(p1 = p2) /= fp_pop(); break; case EEL_BC_AND_OP: p1 = p2; *p2 = (EEL_F) (((int)*p2) & (int)fp_pop()); break; case EEL_BC_OR_OP: p1 = p2; *p2 = (EEL_F) (((int)*p2) | (int)fp_pop()); break; case EEL_BC_XOR_OP: p1 = p2; *p2 = (EEL_F) (((int)*p2) ^ (int)fp_pop()); break; case EEL_BC_UMINUS: fp_top = -fp_top; break; case EEL_BC_ASSIGN: *p2 = denormal_filter_double2(*p1); p1 = p2; break; case EEL_BC_ASSIGN_FAST: *p2 = *p1; p1 = p2; break; case EEL_BC_ASSIGN_FAST_FROMFP: *p2 = fp_pop(); p1 = p2; break; case EEL_BC_ASSIGN_FROMFP: *p2 = denormal_filter_double2(fp_pop()); p1 = p2; break; case EEL_BC_MOD: { int a = (int) (fp_pop()); fp_top = a ? (EEL_F) ((int)fp_top % a) : 0.0; } break; case EEL_BC_MOD_OP: { int a = (int) (fp_pop()); *p2 = a ? (EEL_F) ((int)*p2 % a) : 0.0; p1=p2; } break; case EEL_BC_SHR: fp_top2 = (EEL_F) (((int)fp_top2) >> (int)fp_top); fp_rewind(1); break; case EEL_BC_SHL: fp_top2 = (EEL_F) (((int)fp_top2) << (int)fp_top); fp_rewind(1); break; case EEL_BC_SQR: fp_top *= fp_top; break; case EEL_BC_MIN: if (*p1 > *p2) p1 = p2; break; case EEL_BC_MAX: if (*p1 < *p2) p1 = p2; break; case EEL_BC_MIN_FP: { EEL_F a=fp_pop(); if (afp_top) fp_top=a; } break; case EEL_BC_ABS: fp_top = fabs(fp_top); break; case EEL_BC_SIGN: if (fp_top<0.0) fp_top=-1.0; else if (fp_top>0.0) fp_top=1.0; break; case EEL_BC_DBG_GETSTACKPTR: fp_top = (int)(stackptr - __stack); break; case EEL_BC_INVSQRT: { float y = (float)fp_top; int i = 0x5f3759df - ( (* (int *) &y) >> 1 ); y = *(float *) &i; fp_top = y * ( 1.5F - ( (fp_top * 0.5) * y * y ) ); } break; case EEL_BC_FCALL: { char *newiptr = *(char **)iptr; EEL_BC_STACK_PUSH(void *, (iptr += sizeof(void *))); iptr = newiptr; } break; case EEL_BC_BOOLTOFP: fp_push(p1 ? 1.0 : 0.0); break; case EEL_BC_FPTOBOOL: p1 = fabs(fp_pop()) >= NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL; break; case EEL_BC_FPTOBOOL_REV: p1 = fabs(fp_pop()) < NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL; break; case EEL_BC_CFUNC_1PDD: { double (*f)(double) = *(double (**)(double)) iptr; fp_top = f(fp_top); iptr += sizeof(void *); } break; case EEL_BC_CFUNC_2PDD: { double (*f)(double,double) = *(double (**)(double,double))iptr; fp_top2 = f(fp_top2,fp_top); fp_rewind(1); iptr += sizeof(void *); } break; case EEL_BC_CFUNC_2PDDS: { double (*f)(double,double) = *(double (**)(double,double))iptr; *p2 = f(*p2,fp_pop()); p1 = p2; iptr += sizeof(void *); } break; case EEL_BC_MEGABUF: { unsigned int idx=(unsigned int) (fp_pop() + NSEEL_CLOSEFACTOR); EEL_F **f = (EEL_F **)rt,*f2; p1 = (idx < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK && (f2=f[idx/NSEEL_RAM_ITEMSPERBLOCK])) ? (f2 + (idx&(NSEEL_RAM_ITEMSPERBLOCK-1))) : __NSEEL_RAMAlloc((void*)rt,idx); } break; case EEL_BC_GMEGABUF: { p1 = __NSEEL_RAMAllocGMEM(*(EEL_F ****)iptr,(int) (fp_pop() + NSEEL_CLOSEFACTOR)); iptr += sizeof(void *)*2; // also includes ptr to __NSEEL_RAMAllocGMEM, which we ignore } break; case EEL_BC_GENERIC1PARM: { EEL_F *(*f)(void *,EEL_F*) = *(EEL_F *(**)(void *, EEL_F *)) (iptr+sizeof(void *)); p1 = f(*(void **)iptr,p1); iptr += sizeof(void *)*2; } break; case EEL_BC_GENERIC2PARM: { EEL_F *(*f)(void *,EEL_F*,EEL_F*) = *(EEL_F *(**)(void *, EEL_F *, EEL_F *)) (iptr+sizeof(void *)); p1 = f(*(void **)iptr,p2, p1); iptr += sizeof(void *)*2; } break; case EEL_BC_GENERIC3PARM: { EEL_F *(*f)(void *,EEL_F*,EEL_F*,EEL_F*) = *(EEL_F *(**)(void *, EEL_F *, EEL_F *, EEL_F *)) (iptr+sizeof(void *)); p1 = f(*(void **)iptr,p3, p2, p1); iptr += sizeof(void *)*2; } break; case EEL_BC_GENERIC1PARM_RETD: { EEL_F (*f)(void *,EEL_F*) = *(EEL_F (**)(void *, EEL_F *)) (iptr+sizeof(void *)); fp_push(f(*(void **)iptr,p1)); iptr += sizeof(void *)*2; } break; case EEL_BC_GENERIC2PARM_RETD: { EEL_F (*f)(void *,EEL_F*,EEL_F*) = *(EEL_F (**)(void *, EEL_F *, EEL_F *)) (iptr+sizeof(void *)); fp_push(f(*(void **)iptr,p2, p1)); iptr += sizeof(void *)*2; } break; case EEL_BC_GENERIC3PARM_RETD: { EEL_F (*f)(void *,EEL_F*,EEL_F*,EEL_F*) = *(EEL_F (**)(void *, EEL_F *, EEL_F *, EEL_F *)) (iptr+sizeof(void *)); fp_push(f(*(void **)iptr,p3, p2, p1)); iptr += sizeof(void *)*2; } break; case EEL_BC_USERSTACK_PUSH: { UINT_PTR *sptr = *(UINT_PTR **)iptr; (*sptr) += 8; (*sptr) &= *(UINT_PTR*)(iptr+sizeof(void *)); (*sptr) |= *(UINT_PTR*)(iptr+2*sizeof(void *)); *(EEL_F *)*sptr = *p1; } iptr += sizeof(void*)*3; break; case EEL_BC_USERSTACK_POP: { UINT_PTR *sptr = *(UINT_PTR **)iptr; *p1 = *(EEL_F *)*sptr; (*sptr) -= 8; (*sptr) &= *(UINT_PTR*)(iptr+sizeof(void *)); (*sptr) |= *(UINT_PTR*)(iptr+2*sizeof(void *)); } iptr += sizeof(void*)*3; break; case EEL_BC_USERSTACK_POPFAST: { UINT_PTR *sptr = *(UINT_PTR **)iptr; p1 = (EEL_F *)*sptr; (*sptr) -= 8; (*sptr) &= *(UINT_PTR*)(iptr+sizeof(void *)); (*sptr) |= *(UINT_PTR*)(iptr+2*sizeof(void *)); } iptr += sizeof(void*)*3; break; case EEL_BC_USERSTACK_PEEK: { UINT_PTR sptr = **(UINT_PTR **)iptr; sptr -= sizeof(EEL_F) * (int)(fp_pop()); sptr &= *(UINT_PTR*)(iptr+sizeof(void *)); sptr |= *(UINT_PTR*)(iptr+2*sizeof(void *)); p1 = (EEL_F *)sptr; } iptr += sizeof(void*)*3; break; case EEL_BC_USERSTACK_PEEK_INT: { UINT_PTR sptr = **(UINT_PTR **)iptr; sptr -= *(UINT_PTR*)(iptr+sizeof(void*)); sptr &= *(UINT_PTR*)(iptr+2*sizeof(void *)); sptr |= *(UINT_PTR*)(iptr+3*sizeof(void *)); p1 = (EEL_F *)sptr; } iptr += sizeof(void*)*4; break; case EEL_BC_USERSTACK_PEEK_TOP: p1 = **(EEL_F ***)iptr; iptr += sizeof(void*); break; case EEL_BC_USERSTACK_EXCH: { EEL_F *p=**(EEL_F ***)iptr; EEL_F a=*p; *p=*p1; *p1=a; } iptr += sizeof(void*); break; } } #undef fp_top #undef fp_top2 #undef fp_pop #undef fp_push }; #endif jsusfx-0.4.0/src/WDL/eel2/glue_ppc.h000066400000000000000000000203521353477307700170720ustar00rootroot00000000000000#ifndef _NSEEL_GLUE_PPC_H_ #define _NSEEL_GLUE_PPC_H_ #define GLUE_MAX_FPSTACK_SIZE 0 // no stack support #define GLUE_MAX_JMPSIZE 30000 // maximum relative jump size for this arch (if not defined, any jump is possible) // endOfInstruction is end of jump with relative offset, offset passed in is offset from end of dest instruction. // on PPC the offset needs to be from the start of the instruction (hence +4), and also the low two bits are flags so // we make sure they are clear (they should always be clear, anyway, since we always generate 4 byte instructions) #define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((short *)(endOfInstruction))[-1] = ((offset) + 4) & 0xFFFC) static const unsigned char GLUE_JMP_NC[] = { 0x48,0, 0, 0, }; // b static const unsigned int GLUE_JMP_IF_P1_Z[]= { 0x2f830000, //cmpwi cr7, r3, 0 0x419e0000, // beq cr7, offset-bytes-from-startofthisinstruction }; static const unsigned int GLUE_JMP_IF_P1_NZ[]= { 0x2f830000, //cmpwi cr7, r3, 0 0x409e0000, // bne cr7, offset-bytes-from-startofthisinstruction }; #define GLUE_MOV_PX_DIRECTVALUE_SIZE 8 static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv) { static const unsigned short tab[3][2] = { {0x3C60, 0x6063}, // addis r3, r0, hw -- ori r3,r3, lw {0x3DC0, 0x61CE}, // addis r14, r0, hw -- ori r14, r14, lw {0x3DE0, 0x61EF}, // addis r15, r0, hw -- oris r15, r15, lw }; unsigned int uv=(unsigned int)v; unsigned short *p=(unsigned short *)b; *p++ = tab[wv][0]; // addis rX, r0, hw *p++ = (uv>>16)&0xffff; *p++ = tab[wv][1]; // ori rX, rX, lw *p++ = uv&0xffff; } // mflr r5 // stwu r5, -16(r1) const static unsigned int GLUE_FUNC_ENTER[2] = { 0x7CA802A6, 0x94A1FFF0 }; #define GLUE_FUNC_ENTER_SIZE 8 // lwz r5, 0(r1) // addi r1, r1, 16 // mtlr r5 const static unsigned int GLUE_FUNC_LEAVE[3] = { 0x80A10000, 0x38210010, 0x7CA803A6 }; #define GLUE_FUNC_LEAVE_SIZE 12 const static unsigned int GLUE_RET[]={0x4E800020}; // blr static int GLUE_RESET_WTP(unsigned char *out, void *ptr) { const static unsigned int GLUE_SET_WTP_FROM_R17=0x7E308B78; // mr r16 (dest), r17 (src) if (out) memcpy(out,&GLUE_SET_WTP_FROM_R17,sizeof(GLUE_SET_WTP_FROM_R17)); return sizeof(GLUE_SET_WTP_FROM_R17); } // stwu r3, -16(r1) const static unsigned int GLUE_PUSH_P1[1]={ 0x9461FFF0}; #define GLUE_POP_PX_SIZE 8 static void GLUE_POP_PX(void *b, int wv) { static const unsigned int tab[3] ={ 0x80610000, // lwz r3, 0(r1) 0x81c10000, // lwz r14, 0(r1) 0x81e10000, // lwz r15, 0(r1) }; ((unsigned int *)b)[0] = tab[wv]; ((unsigned int *)b)[1] = 0x38210010; // addi r1,r1, 16 } #define GLUE_SET_PX_FROM_P1_SIZE 4 static void GLUE_SET_PX_FROM_P1(void *b, int wv) { static const unsigned int tab[3]={ 0x7c631b78, // never used: mr r3, r3 0x7c6e1b78, // mr r14, r3 0x7c6f1b78, // mr r15, r3 }; *(unsigned int *)b = tab[wv]; } // lfd f2, 0(r3) // stfdu f2, -16(r1) static const unsigned int GLUE_PUSH_P1PTR_AS_VALUE[] = { 0xC8430000, 0xDC41FFF0 }; static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) { // lfd f2, 0(r1) // addi r1,r1,16 // GLUE_MOV_PX_DIRECTVALUE_GEN / GLUE_MOV_PX_DIRECTVALUE_SIZE (r3) // stfd f2, 0(r3) if (buf) { unsigned int *bufptr = (unsigned int *)buf; *bufptr++ = 0xC8410000; *bufptr++ = 0x38210010; GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0); bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4; *bufptr++ = 0xd8430000; } return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE + 4; } static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) { // lfd f2, 0(r3) // GLUE_MOV_PX_DIRECTVALUE_GEN / GLUE_MOV_PX_DIRECTVALUE_SIZE (r3) // stfd f2, 0(r3) if (buf) { unsigned int *bufptr = (unsigned int *)buf; *bufptr++ = 0xc8430000; GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0); bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4; *bufptr++ = 0xd8430000; } return 4 + GLUE_MOV_PX_DIRECTVALUE_SIZE + 4; } static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR rt) { static const double consttab[] = { NSEEL_CLOSEFACTOR, 4503601774854144.0 /* 0x43300000, 0x80000000, used for integer conversion*/, }; // we could have r18 refer to the current user-stack pointer, someday, perhaps __asm__( "subi r1, r1, 128\n" "stfd f31, 8(r1)\n" "stfd f30, 16(r1)\n" "stmw r13, 32(r1)\n" "mtctr %0\n" "mr r17, %1\n" "mr r13, %2\n" "lfd f31, 0(%3)\n" "lfd f30, 8(%3)\n" "subi r17, r17, 8\n" "mflr r0\n" "stw r0, 24(r1)\n" "bctrl\n" "lwz r0, 24(r1)\n" "mtlr r0\n" "lmw r13, 32(r1)\n" "lfd f31, 8(r1)\n" "lfd f30, 16(r1)\n" "addi r1, r1, 128\n" ::"r" (cp), "r" (bp), "r" (rt), "r" (consttab)); }; static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) { // 64 bit ppc would take some work unsigned int *p=(unsigned int *)_p; while ((p[0]&0x0000FFFF) != 0x0000dead && (p[1]&0x0000FFFF) != 0x0000beef) p++; p[0] = (p[0]&0xFFFF0000) | (((newv)>>16)&0xFFFF); p[1] = (p[1]&0xFFFF0000) | ((newv)&0xFFFF); return (unsigned char *)(p+1); } #define GLUE_SET_PX_FROM_WTP_SIZE sizeof(int) static void GLUE_SET_PX_FROM_WTP(void *b, int wv) { static const unsigned int tab[3]={ 0x7e038378, // mr r3, r16 0x7e0e8378, // mr r14, r16 0x7e0f8378, // mr r15, r16 }; *(unsigned int *)b = tab[wv]; } static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) { // set r3 to destptr // stfd f1, 0(r3) if (buf) { unsigned int *bufptr = (unsigned int *)buf; GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0); bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4; *bufptr++ = 0xD8230000; // stfd f1, 0(r3) } return GLUE_MOV_PX_DIRECTVALUE_SIZE + sizeof(int); } #define GLUE_POP_FPSTACK_SIZE 0 static const unsigned int GLUE_POP_FPSTACK[1] = { 0 }; // no need to pop, not a stack static const unsigned int GLUE_POP_FPSTACK_TOSTACK[] = { 0xdc21fff0, // stfdu f1, -16(r1) }; static const unsigned int GLUE_POP_FPSTACK_TO_WTP[] = { 0xdc300008, // stfdu f1, 8(r16) }; #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 4 static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) { static const unsigned int tab[3] = { 0xC8230000, // lfd f1, 0(r3) 0xC82E0000, // lfd f1, 0(r14) 0xC82F0000, // lfd f1, 0(r15) }; *(unsigned int *)b = tab[wv]; } #define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE) static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) { memcpy(buf,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); GLUE_SET_PX_FROM_WTP(buf + sizeof(GLUE_POP_FPSTACK_TO_WTP),wv); // ppc preincs the WTP, so we do this after }; static unsigned int GLUE_POP_STACK_TO_FPSTACK[1] = { 0 }; // todo static const unsigned int GLUE_SET_P1_Z[] = { 0x38600000 }; // li r3, 0 static const unsigned int GLUE_SET_P1_NZ[] = { 0x38600001 }; // li r3, 1 static void *GLUE_realAddress(void *fn, void *fn_e, int *size) { // magic numbers: mr r0,r0 ; mr r1,r1 ; mr r2, r2 static const unsigned char sig[12] = { 0x7c, 0x00, 0x03, 0x78, 0x7c, 0x21, 0x0b, 0x78, 0x7c, 0x42, 0x13, 0x78 }; unsigned char *p = (unsigned char *)fn; while (memcmp(p,sig,sizeof(sig))) p+=4; p+=sizeof(sig); fn = p; while (memcmp(p,sig,sizeof(sig))) p+=4; *size = p - (unsigned char *)fn; return fn; } #define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE 4 static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs) { // limited to 32k offset *(unsigned int *)b = 0x90610000 + (offs&0xffff); } #define GLUE_MOVE_PX_STACKPTR_SIZE 4 static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv) { static const unsigned int tab[3] = { 0x7c230b78, // mr r3, r1 0x7c2e0b78, // mr r14, r1 0x7c2f0b78, // mr r15, r1 }; * (unsigned int *)b = tab[wv]; } #define GLUE_MOVE_STACK_SIZE 4 static void GLUE_MOVE_STACK(void *b, int amt) { // this should be updated to allow for more than 32k moves, but no real need ((unsigned int *)b)[0] = 0x38210000 + (amt&0xffff); // addi r1,r1, amt } // end of ppc #endif jsusfx-0.4.0/src/WDL/eel2/glue_x86.h000066400000000000000000000303541353477307700167400ustar00rootroot00000000000000#ifndef _NSEEL_GLUE_X86_H_ #define _NSEEL_GLUE_X86_H_ #define GLUE_MAX_FPSTACK_SIZE 8 // endOfInstruction is end of jump with relative offset, offset is offset from end of instruction to jump to #define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((int *)(endOfInstruction))[-1] = (offset)) static const unsigned char GLUE_JMP_NC[] = { 0xE9, 0,0,0,0, }; // jmp static const unsigned char GLUE_JMP_IF_P1_Z[] = {0x85, 0xC0, 0x0F, 0x84, 0,0,0,0 }; // test eax, eax, jz static const unsigned char GLUE_JMP_IF_P1_NZ[] = {0x85, 0xC0, 0x0F, 0x85, 0,0,0,0 }; // test eax, eax, jnz #define GLUE_FUNC_ENTER_SIZE 0 #define GLUE_FUNC_LEAVE_SIZE 0 const static unsigned int GLUE_FUNC_ENTER[1]; const static unsigned int GLUE_FUNC_LEAVE[1]; // x86 // stack is 16 byte aligned // when pushing values to stack, alignment pushed first, then value (value is at the lower address) // when pushing pointers to stack, alignment pushed first, then pointer (pointer is at the lower address) static const unsigned char GLUE_PUSH_P1PTR_AS_VALUE[] = { 0x83, 0xEC, 8, /* sub esp, 8 */ 0xff, 0x70, 0x4, /* push dword [eax+4] */ 0xff, 0x30, /* push dword [eax] */ }; static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) { if (buf) { *buf++ = 0xB8; *(void **) buf = destptr; buf+=4; // mov eax, directvalue *buf++ = 0x8f; *buf++ = 0x00; // pop dword [eax] *buf++ = 0x8f; *buf++ = 0x40; *buf++ = 4; // pop dword [eax+4] *buf++ = 0x59; // pop ecx (alignment) *buf++ = 0x59; // pop ecx (alignment) } return 12; } static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) { if (buf) { *buf++ = 0x8B; *buf++ = 0x38; // mov edi, [eax] *buf++ = 0x8B; *buf++ = 0x48; *buf++ = 0x04; // mov ecx, [eax+4] *buf++ = 0xB8; *(void **) buf = destptr; buf+=4; // mov eax, directvalue *buf++ = 0x89; *buf++ = 0x38; // mov [eax], edi *buf++ = 0x89; *buf++ = 0x48; *buf++ = 0x04; // mov [eax+4], ecx } return 2 + 3 + 5 + 2 + 3; } static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) { if (buf) { *buf++ = 0xB8; *(void **) buf = destptr; buf+=4; // mov eax, directvalue *buf++ = 0xDD; *buf++ = 0x18; // fstp qword [eax] } return 1+4+2; } #define GLUE_MOV_PX_DIRECTVALUE_SIZE 5 #define GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE 6 // length when wv == -1 static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv) { if (wv==-1) { const static unsigned char t[2] = {0xDD, 0x05}; memcpy(b,t,2); b= ((unsigned char *)b)+2; } else { const static unsigned char tab[3] = { 0xB8 /* mov eax, dv*/, 0xBF /* mov edi, dv */ , 0xB9 /* mov ecx, dv */ }; *((unsigned char *)b) = tab[wv]; // mov eax, dv b= ((unsigned char *)b)+1; } *(INT_PTR *)b = v; } const static unsigned char GLUE_PUSH_P1[4]={0x83, 0xEC, 12, 0x50}; // sub esp, 12, push eax #define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE 7 static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs) { ((unsigned char *)b)[0] = 0x89; // mov [esp+offs], eax ((unsigned char *)b)[1] = 0x84; ((unsigned char *)b)[2] = 0x24; *(int *)((unsigned char *)b+3) = offs; } #define GLUE_MOVE_PX_STACKPTR_SIZE 2 static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv) { static const unsigned char tab[3][GLUE_MOVE_PX_STACKPTR_SIZE]= { { 0x89, 0xe0 }, // mov eax, esp { 0x89, 0xe7 }, // mov edi, esp { 0x89, 0xe1 }, // mov ecx, esp }; memcpy(b,tab[wv],GLUE_MOVE_PX_STACKPTR_SIZE); } #define GLUE_MOVE_STACK_SIZE 6 static void GLUE_MOVE_STACK(void *b, int amt) { ((unsigned char *)b)[0] = 0x81; if (amt <0) { ((unsigned char *)b)[1] = 0xEC; *(int *)((char*)b+2) = -amt; // sub esp, -amt } else { ((unsigned char *)b)[1] = 0xc4; *(int *)((char*)b+2) = amt; // add esp, amt } } #define GLUE_POP_PX_SIZE 4 static void GLUE_POP_PX(void *b, int wv) { static const unsigned char tab[3][GLUE_POP_PX_SIZE]= { {0x58,/*pop eax*/ 0x83, 0xC4, 12 /* add esp, 12*/}, {0x5F,/*pop edi*/ 0x83, 0xC4, 12}, {0x59,/*pop ecx*/ 0x83, 0xC4, 12}, }; memcpy(b,tab[wv],GLUE_POP_PX_SIZE); } #define GLUE_SET_PX_FROM_P1_SIZE 2 static void GLUE_SET_PX_FROM_P1(void *b, int wv) { static const unsigned char tab[3][GLUE_SET_PX_FROM_P1_SIZE]={ {0x90,0x90}, // should never be used! (nopnop) {0x89,0xC7}, // mov edi, eax {0x89,0xC1}, // mov ecx, eax }; memcpy(b,tab[wv],GLUE_SET_PX_FROM_P1_SIZE); } #define GLUE_POP_FPSTACK_SIZE 2 static const unsigned char GLUE_POP_FPSTACK[2] = { 0xDD, 0xD8 }; // fstp st0 static const unsigned char GLUE_POP_FPSTACK_TOSTACK[] = { 0x83, 0xEC, 16, // sub esp, 16 0xDD, 0x1C, 0x24 // fstp qword (%esp) }; static const unsigned char GLUE_POP_STACK_TO_FPSTACK[] = { 0xDD, 0x04, 0x24, // fld qword (%esp) 0x83, 0xC4, 16 // add esp, 16 }; static const unsigned char GLUE_POP_FPSTACK_TO_WTP[] = { 0xDD, 0x1E, /* fstp qword [esi] */ 0x83, 0xC6, 8, /* add esi, 8 */ }; #define GLUE_SET_PX_FROM_WTP_SIZE 2 static void GLUE_SET_PX_FROM_WTP(void *b, int wv) { static const unsigned char tab[3][GLUE_SET_PX_FROM_WTP_SIZE]={ {0x89,0xF0}, // mov eax, esi {0x89,0xF7}, // mov edi, esi {0x89,0xF1}, // mov ecx, esi }; memcpy(b,tab[wv],GLUE_SET_PX_FROM_WTP_SIZE); } #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 2 static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) { static const unsigned char tab[3][GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE]={ {0xDD,0x00}, // fld qword [eax] {0xDD,0x07}, // fld qword [edi] {0xDD,0x01}, // fld qword [ecx] }; memcpy(b,tab[wv],GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE); } #define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (GLUE_SET_PX_FROM_WTP_SIZE + sizeof(GLUE_POP_FPSTACK_TO_WTP)) static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) { GLUE_SET_PX_FROM_WTP(buf,wv); memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); }; const static unsigned char GLUE_RET=0xC3; static int GLUE_RESET_WTP(unsigned char *out, void *ptr) { if (out) { *out++ = 0xBE; // mov esi, constant memcpy(out,&ptr,sizeof(void *)); out+=sizeof(void *); } return 1+sizeof(void *); } static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR ramptr) { #ifndef NSEEL_EEL1_COMPAT_MODE short oldsw, newsw; #endif #ifdef _MSC_VER __asm { #ifndef NSEEL_EEL1_COMPAT_MODE fnstcw [oldsw] mov ax, [oldsw] or ax, 0xE3F // 53 or 64 bit precision (depending on whether 0x100 is set), trunc, and masking all exceptions mov [newsw], ax fldcw [newsw] #endif mov eax, cp mov ebx, ramptr pushad mov ebp, esp and esp, -16 // on win32, which _MSC_VER implies, we keep things aligned to 16 bytes, and if we call a win32 function, // the stack is 16 byte aligned before the call, meaning that if calling a function with no frame pointer, // the stack would be aligned to a 16 byte boundary +4, which isn't good for performance. Having said that, // normally we compile with frame pointers (which brings that to 16 byte + 8, which is fine), or ICC, which // for nontrivial functions will align the stack itself (for very short functions, it appears to weigh the // cost of aligning the stack vs that of the slower misaligned double accesses). // it may be worthwhile (at some point) to put some logic in the code that calls out to functions // (generic1parm etc) to detect which alignment would be most optimal. sub esp, 12 call eax mov esp, ebp popad #ifndef NSEEL_EEL1_COMPAT_MODE fldcw [oldsw] #endif }; #else // gcc x86 __asm__( #ifndef NSEEL_EEL1_COMPAT_MODE "fnstcw %2\n" "movw %2, %%ax\n" "orw $0xE3F, %%ax\n" // 53 or 64 bit precision (depending on whether 0x100 is set), trunc, and masking all exceptions "movw %%ax, %3\n" "fldcw %3\n" #endif "pushl %%ebx\n" "movl %%ecx, %%ebx\n" "pushl %%ebp\n" "movl %%esp, %%ebp\n" "andl $-16, %%esp\n" // align stack to 16 bytes "subl $12, %%esp\n" // call will push 4 bytes on stack, align for that "call *%%edx\n" "leave\n" "popl %%ebx\n" #ifndef NSEEL_EEL1_COMPAT_MODE "fldcw %2\n" #endif :: "d" (cp), "c" (ramptr) #ifndef NSEEL_EEL1_COMPAT_MODE , "m" (oldsw), "m" (newsw) #endif : "%eax","%esi","%edi"); #endif //gcc x86 } static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) { char *p=(char*)_p; INT_PTR scan = 0xFEFEFEFE; while (*(INT_PTR *)p != scan) p++; *(INT_PTR *)p = newv; return (unsigned char *) (((INT_PTR*)p)+1); } #define INT_TO_LECHARS(x) ((x)&0xff),(((x)>>8)&0xff), (((x)>>16)&0xff), (((x)>>24)&0xff) #define GLUE_INLINE_LOOPS static const unsigned char GLUE_LOOP_LOADCNT[]={ 0xDB, 0x1E, //fistp dword [esi] 0x8B, 0x0E, // mov ecx, [esi] 0x81, 0xf9, 1,0,0,0, // cmp ecx, 1 0x0F, 0x8C, 0,0,0,0, // JL }; #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 #define GLUE_LOOP_CLAMPCNT_SIZE sizeof(GLUE_LOOP_CLAMPCNT) static const unsigned char GLUE_LOOP_CLAMPCNT[]={ 0x81, 0xf9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // cmp ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN 0x0F, 0x8C, 5,0,0,0, // JL over-the-mov 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // mov ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN }; #else #define GLUE_LOOP_CLAMPCNT_SIZE 0 #define GLUE_LOOP_CLAMPCNT "" #endif #define GLUE_LOOP_BEGIN_SIZE sizeof(GLUE_LOOP_BEGIN) static const unsigned char GLUE_LOOP_BEGIN[]={ 0x56, //push esi 0x51, // push ecx 0x81, 0xEC, 0x08, 0,0,0, // sub esp, 8 }; static const unsigned char GLUE_LOOP_END[]={ 0x81, 0xC4, 0x08, 0,0,0, // add esp, 8 0x59, //pop ecx 0x5E, // pop esi 0x49, // dec ecx 0x0f, 0x85, 0,0,0,0, // jnz ... }; #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 #define GLUE_WHILE_SETUP_SIZE sizeof(GLUE_WHILE_SETUP) static const unsigned char GLUE_WHILE_SETUP[]={ 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // mov ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN }; static const unsigned char GLUE_WHILE_BEGIN[]={ 0x56, //push esi 0x51, // push ecx 0x81, 0xEC, 0x08, 0,0,0, // sub esp, 8 }; static const unsigned char GLUE_WHILE_END[]={ 0x81, 0xC4, 0x08, 0,0,0, // add esp, 8 0x59, //pop ecx 0x5E, // pop esi 0x49, // dec ecx 0x0f, 0x84, 0,0,0,0, // jz endpt }; #else #define GLUE_WHILE_SETUP_SIZE 0 #define GLUE_WHILE_SETUP "" #define GLUE_WHILE_END_NOJUMP static const unsigned char GLUE_WHILE_BEGIN[]={ 0x56, //push esi 0x81, 0xEC, 12, 0,0,0, // sub esp, 12 }; static const unsigned char GLUE_WHILE_END[]={ 0x81, 0xC4, 12, 0,0,0, // add esp, 12 0x5E, // pop esi }; #endif static const unsigned char GLUE_WHILE_CHECK_RV[] = { 0x85, 0xC0, // test eax, eax 0x0F, 0x85, 0,0,0,0 // jnz looppt }; static const unsigned char GLUE_SET_P1_Z[] = { 0x29, 0xC0 }; // sub eax, eax static const unsigned char GLUE_SET_P1_NZ[] = { 0xb0, 0x01 }; // mov al, 1 #define GLUE_HAS_FXCH static const unsigned char GLUE_FXCH[] = {0xd9, 0xc9}; #define GLUE_HAS_FLDZ static const unsigned char GLUE_FLDZ[] = {0xd9, 0xee}; #define GLUE_HAS_FLD1 static const unsigned char GLUE_FLD1[] = {0xd9, 0xe8}; static EEL_F negativezeropointfive=-0.5f; static EEL_F onepointfive=1.5f; #define GLUE_INVSQRT_NEEDREPL &negativezeropointfive, &onepointfive, #define GLUE_HAS_NATIVE_TRIGSQRTLOG static void *GLUE_realAddress(void *fn, void *fn_e, int *size) { static const unsigned char sig[12] = { 0x89, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; unsigned char *p = (unsigned char *)fn; #if defined(_DEBUG) && defined(_MSC_VER) if (*p == 0xE9) // this means jump to the following address (debug stub) { p += 5 + *(int *)(p+1); } #endif while (memcmp(p,sig,sizeof(sig))) p++; p+=sizeof(sig); fn = p; while (memcmp(p,sig,sizeof(sig))) p++; *size = p - (unsigned char *)fn; return fn; } #endif jsusfx-0.4.0/src/WDL/eel2/glue_x86_64.h000066400000000000000000000231031353477307700172430ustar00rootroot00000000000000#ifndef _NSEEL_GLUE_X86_64_H_ #define _NSEEL_GLUE_X86_64_H_ #define GLUE_MAX_FPSTACK_SIZE 8 #define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((int *)(endOfInstruction))[-1] = (int) (offset)) #define GLUE_PREFER_NONFP_DV_ASSIGNS static const unsigned char GLUE_JMP_NC[] = { 0xE9, 0,0,0,0, }; // jmp static const unsigned char GLUE_JMP_IF_P1_Z[] = {0x85, 0xC0, 0x0F, 0x84, 0,0,0,0 }; // test eax, eax, jz static const unsigned char GLUE_JMP_IF_P1_NZ[] = {0x85, 0xC0, 0x0F, 0x85, 0,0,0,0 }; // test eax, eax, jnz #define GLUE_FUNC_ENTER_SIZE 0 #define GLUE_FUNC_LEAVE_SIZE 0 const static unsigned int GLUE_FUNC_ENTER[1]; const static unsigned int GLUE_FUNC_LEAVE[1]; // on x86-64: // stack is always 16 byte aligned // pushing values to the stack (for eel functions) has alignment pushed first, then value (value is at the lower address) // pushing pointers to the stack has the pointer pushed first, then the alignment (pointer is at the higher address) #define GLUE_MOV_PX_DIRECTVALUE_SIZE 10 static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wr) { const static unsigned short tab[3] = { 0xB848 /* mov rax, dv*/, 0xBF48 /* mov rdi, dv */ , 0xB948 /* mov rcx, dv */ }; unsigned short *bb = (unsigned short *)b; *bb++ = tab[wr]; // mov rax, directvalue *(INT_PTR *)bb = v; } const static unsigned char GLUE_PUSH_P1[2]={ 0x50,0x50}; // push rax (pointer); push rax (alignment) #define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE 8 static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs) { ((unsigned char *)b)[0] = 0x48; // mov [rsp+offs], rax ((unsigned char *)b)[1] = 0x89; ((unsigned char *)b)[2] = 0x84; ((unsigned char *)b)[3] = 0x24; *(int *)((unsigned char *)b+4) = offs; } #define GLUE_MOVE_PX_STACKPTR_SIZE 3 static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv) { static const unsigned char tab[3][GLUE_MOVE_PX_STACKPTR_SIZE]= { { 0x48, 0x89, 0xe0 }, // mov rax, rsp { 0x48, 0x89, 0xe7 }, // mov rdi, rsp { 0x48, 0x89, 0xe1 }, // mov rcx, rsp }; memcpy(b,tab[wv],GLUE_MOVE_PX_STACKPTR_SIZE); } #define GLUE_MOVE_STACK_SIZE 7 static void GLUE_MOVE_STACK(void *b, int amt) { ((unsigned char *)b)[0] = 0x48; ((unsigned char *)b)[1] = 0x81; if (amt < 0) { ((unsigned char *)b)[2] = 0xEC; *(int *)((char*)b+3) = -amt; // sub rsp, -amt32 } else { ((unsigned char *)b)[2] = 0xc4; *(int *)((char*)b+3) = amt; // add rsp, amt32 } } #define GLUE_POP_PX_SIZE 2 static void GLUE_POP_PX(void *b, int wv) { static const unsigned char tab[3][GLUE_POP_PX_SIZE]= { {0x58,/*pop rax*/ 0x58}, // pop alignment, then pop pointer {0x5F,/*pop rdi*/ 0x5F}, {0x59,/*pop rcx*/ 0x59}, }; memcpy(b,tab[wv],GLUE_POP_PX_SIZE); } static const unsigned char GLUE_PUSH_P1PTR_AS_VALUE[] = { 0x50, /*push rax - for alignment */ 0xff, 0x30, /* push qword [rax] */ }; static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) // trashes P2 (rdi) and P3 (rcx) { if (buf) { *buf++ = 0x48; *buf++ = 0xB9; *(void **) buf = destptr; buf+=8; // mov rcx, directvalue *buf++ = 0x8f; *buf++ = 0x01; // pop qword [rcx] *buf++ = 0x5F ; // pop rdi (alignment, safe to trash rdi though) } return 1+10+2; } static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) // trashes P2/P3 { if (buf) { *buf++ = 0x48; *buf++ = 0xB9; *(void **) buf = destptr; buf+=8; // mov rcx, directvalue *buf++ = 0x48; *buf++ = 0x8B; *buf++ = 0x38; // mov rdi, [rax] *buf++ = 0x48; *buf++ = 0x89; *buf++ = 0x39; // mov [rcx], rdi } return 3 + 10 + 3; } static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) { if (buf) { *buf++ = 0x48; *buf++ = 0xB8; *(void **) buf = destptr; buf+=8; // mov rax, directvalue *buf++ = 0xDD; *buf++ = 0x18; // fstp qword [rax] } return 2+8+2; } #define GLUE_SET_PX_FROM_P1_SIZE 3 static void GLUE_SET_PX_FROM_P1(void *b, int wv) { static const unsigned char tab[3][GLUE_SET_PX_FROM_P1_SIZE]={ {0x90,0x90,0x90}, // should never be used! (nopnop) {0x48,0x89,0xC7}, // mov rdi, rax {0x48,0x89,0xC1}, // mov rcx, rax }; memcpy(b,tab[wv],GLUE_SET_PX_FROM_P1_SIZE); } #define GLUE_POP_FPSTACK_SIZE 2 static const unsigned char GLUE_POP_FPSTACK[2] = { 0xDD, 0xD8 }; // fstp st0 static const unsigned char GLUE_POP_FPSTACK_TOSTACK[] = { 0x48, 0x81, 0xEC, 16, 0,0,0, // sub rsp, 16 0xDD, 0x1C, 0x24 // fstp qword (%rsp) }; static const unsigned char GLUE_POP_FPSTACK_TO_WTP[] = { 0xDD, 0x1E, /* fstp qword [rsi] */ 0x48, 0x81, 0xC6, 8, 0,0,0,/* add rsi, 8 */ }; #define GLUE_SET_PX_FROM_WTP_SIZE 3 static void GLUE_SET_PX_FROM_WTP(void *b, int wv) { static const unsigned char tab[3][GLUE_SET_PX_FROM_WTP_SIZE]={ {0x48, 0x89,0xF0}, // mov rax, rsi {0x48, 0x89,0xF7}, // mov rdi, rsi {0x48, 0x89,0xF1}, // mov rcx, rsi }; memcpy(b,tab[wv],GLUE_SET_PX_FROM_WTP_SIZE); } #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 2 static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) { static const unsigned char tab[3][GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE]={ {0xDD,0x00}, // fld qword [rax] {0xDD,0x07}, // fld qword [rdi] {0xDD,0x01}, // fld qword [rcx] }; memcpy(b,tab[wv],GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE); } static unsigned char GLUE_POP_STACK_TO_FPSTACK[] = { 0xDD, 0x04, 0x24, // fld qword (%rsp) 0x48, 0x81, 0xC4, 16, 0,0,0, // add rsp, 16 }; #define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (GLUE_SET_PX_FROM_WTP_SIZE + sizeof(GLUE_POP_FPSTACK_TO_WTP)) static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) { GLUE_SET_PX_FROM_WTP(buf,wv); memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); }; const static unsigned char GLUE_RET=0xC3; static int GLUE_RESET_WTP(unsigned char *out, void *ptr) { if (out) { *out++ = 0x48; *out++ = 0xBE; // mov rsi, constant64 *(void **)out = ptr; out+=sizeof(void *); } return 2+sizeof(void *); } extern void eel_callcode64(INT_PTR code, INT_PTR ram_tab); #define GLUE_CALL_CODE(bp, cp, rt) eel_callcode64(cp, rt) #define GLUE_TABPTR_IGNORED static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) { char *p=(char*)_p; INT_PTR scan = 0xFEFEFEFEFEFEFEFE; while (*(INT_PTR *)p != scan) p++; *(INT_PTR *)p = newv; return (unsigned char *) (((INT_PTR*)p)+1); } #define INT_TO_LECHARS(x) ((x)&0xff),(((x)>>8)&0xff), (((x)>>16)&0xff), (((x)>>24)&0xff) #define GLUE_INLINE_LOOPS static const unsigned char GLUE_LOOP_LOADCNT[]={ 0xDD, 0x0E, //fistTp qword [rsi] 0x48, 0x8B, 0x0E, // mov rcx, [rsi] 0x48, 0x81, 0xf9, 1,0,0,0, // cmp rcx, 1 0x0F, 0x8C, 0,0,0,0, // JL }; #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 #define GLUE_LOOP_CLAMPCNT_SIZE sizeof(GLUE_LOOP_CLAMPCNT) static const unsigned char GLUE_LOOP_CLAMPCNT[]={ 0x48, 0x81, 0xf9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // cmp rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN 0x0F, 0x8C, 10,0,0,0, // JL over-the-mov 0x48, 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), 0,0,0,0, // mov rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN }; #else #define GLUE_LOOP_CLAMPCNT_SIZE 0 #define GLUE_LOOP_CLAMPCNT "" #endif #define GLUE_LOOP_BEGIN_SIZE sizeof(GLUE_LOOP_BEGIN) static const unsigned char GLUE_LOOP_BEGIN[]={ 0x56, //push rsi 0x51, // push rcx }; static const unsigned char GLUE_LOOP_END[]={ 0x59, //pop rcx 0x5E, // pop rsi 0xff, 0xc9, // dec rcx 0x0f, 0x85, 0,0,0,0, // jnz ... }; #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 static const unsigned char GLUE_WHILE_SETUP[]={ 0x48, 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), 0,0,0,0, // mov rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN }; #define GLUE_WHILE_SETUP_SIZE sizeof(GLUE_WHILE_SETUP) static const unsigned char GLUE_WHILE_BEGIN[]={ 0x56, //push rsi 0x51, // push rcx }; static const unsigned char GLUE_WHILE_END[]={ 0x59, //pop rcx 0x5E, // pop rsi 0xff, 0xc9, // dec rcx 0x0f, 0x84, 0,0,0,0, // jz endpt }; #else #define GLUE_WHILE_SETUP "" #define GLUE_WHILE_SETUP_SIZE 0 #define GLUE_WHILE_END_NOJUMP static const unsigned char GLUE_WHILE_BEGIN[]={ 0x56, //push rsi 0x51, // push rcx }; static const unsigned char GLUE_WHILE_END[]={ 0x59, //pop rcx 0x5E, // pop rsi }; #endif static const unsigned char GLUE_WHILE_CHECK_RV[] = { 0x85, 0xC0, // test eax, eax 0x0F, 0x85, 0,0,0,0 // jnz looppt }; static const unsigned char GLUE_SET_P1_Z[] = { 0x48, 0x29, 0xC0 }; // sub rax, rax static const unsigned char GLUE_SET_P1_NZ[] = { 0xb0, 0x01 }; // mov al, 1 #define GLUE_HAS_FXCH static const unsigned char GLUE_FXCH[] = {0xd9, 0xc9}; #define GLUE_HAS_FLDZ static const unsigned char GLUE_FLDZ[] = {0xd9, 0xee}; #define GLUE_HAS_FLD1 static const unsigned char GLUE_FLD1[] = {0xd9, 0xe8}; static EEL_F negativezeropointfive=-0.5f; static EEL_F onepointfive=1.5f; #define GLUE_INVSQRT_NEEDREPL &negativezeropointfive, &onepointfive, #define GLUE_HAS_NATIVE_TRIGSQRTLOG static void *GLUE_realAddress(void *fn, void *fn_e, int *size) { static const unsigned char sig[12] = { 0x89, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; unsigned char *p = (unsigned char *)fn; while (memcmp(p,sig,sizeof(sig))) p++; p+=sizeof(sig); fn = p; while (memcmp(p,sig,sizeof(sig))) p++; *size = (int) (p - (unsigned char *)fn); return fn; } // end of x86-64 #endif jsusfx-0.4.0/src/WDL/eel2/loose_eel.cpp000066400000000000000000000072221353477307700175760ustar00rootroot00000000000000#include #include #include #include #include int g_verbose, g_interactive; static void writeToStandardError(const char *fmt, ...) { va_list arglist; va_start(arglist, fmt); vfprintf(stderr,fmt,arglist); fprintf(stderr,"\n"); fflush(stderr); va_end(arglist); } #define EEL_STRING_DEBUGOUT writeToStandardError // no parameters, since it takes varargs #ifndef EEL_LICE_WANT_STANDALONE #define EELSCRIPT_NO_LICE #endif #include "eelscript.h" void NSEEL_HOSTSTUB_EnterMutex() { } void NSEEL_HOSTSTUB_LeaveMutex() { } int main(int argc, char **argv) { bool want_args = true; int argpos = 1; const char *scriptfn = argv[0]; while (argpos < argc && argv[argpos][0] == '-' && argv[argpos][1]) { if (!strcmp(argv[argpos],"-v")) g_verbose++; else if (!strcmp(argv[argpos],"-i")) g_interactive++; else if (!strcmp(argv[argpos],"--no-args")) want_args=false; else { fprintf(stderr,"Usage: %s [-v] [--no-args] [-i | scriptfile | -]\n",argv[0]); return -1; } argpos++; } if (argpos < argc && !g_interactive) { scriptfn = argv[argpos++]; } else { #ifndef _WIN32 if (!g_interactive && isatty(0)) #else if (1) #endif g_interactive=1; } if (eelScriptInst::init()) { fprintf(stderr,"NSEEL_init(): error initializing\n"); return -1; } #ifndef EELSCRIPT_NO_LICE #ifdef __APPLE__ SWELL_InitAutoRelease(); #endif #endif WDL_FastString code,t; eelScriptInst inst; if (want_args) { const int argv_offs = 1<<22; code.SetFormatted(64,"argc=0; argv=%d;\n",argv_offs); int x; for (x=argpos-1;xAddString(new WDL_FastString(xm_gfx_clear) inst.m_gfx_state->m_gfx_clear[0] = -1; #endif printf("EEL interactive mode, type quit to quit, abort to abort multiline entry\n"); EEL_F *resultVar = NSEEL_VM_regvar(inst.m_vm,"__result"); code.Set(""); char line[4096]; for (;;) { #ifndef EELSCRIPT_NO_LICE _gfx_update(&inst,NULL); #endif if (!code.Get()[0]) printf("EEL> "); else printf("> "); fflush(stdout); line[0]=0; fgets(line,sizeof(line),stdin); if (!line[0]) break; code.Append(line); while (line[0] && ( line[strlen(line)-1] == '\r' || line[strlen(line)-1] == '\n' || line[strlen(line)-1] == '\t' || line[strlen(line)-1] == ' ' )) line[strlen(line)-1]=0; if (!strcmp(line,"quit")) break; if (!strcmp(line,"abort")) code.Set(""); t.Set("__result = ("); t.Append(code.Get()); t.Append(");"); int res=inst.runcode(t.Get(),false,"",true,true,true); // allow free, since functions can't be defined locally if (!res) { if (resultVar) printf("=%g ",*resultVar); code.Set(""); } else // try compiling again allowing function definitions (and not allowing free) // but show errors if not continuation { res=inst.runcode(code.Get(),true,"(stdin)", false,false,true); if (res<=0) code.Set(""); // res>0 means need more lines } while (inst.run_deferred()); } } else { inst.loadfile(scriptfn,NULL,true); while (inst.run_deferred()); } return 0; } #ifndef _WIN32 INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2) { return 0; } #endif jsusfx-0.4.0/src/WDL/eel2/loose_eel.dsp000066400000000000000000000127171353477307700176070ustar00rootroot00000000000000# Microsoft Developer Studio Project File - Name="loose_eel" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 CFG=loose_eel - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "loose_eel.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "loose_eel.mak" CFG="loose_eel - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "loose_eel - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "loose_eel - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "loose_eel - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D WDL_FFT_REALSIZE=8 /D NSEEL_LOOPFUNC_SUPPORT_MAXLEN=0 /D "EEL_LICE_WANT_STANDALONE" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 !ELSEIF "$(CFG)" == "loose_eel - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D WDL_FFT_REALSIZE=8 /D NSEEL_LOOPFUNC_SUPPORT_MAXLEN=0 /D "EEL_LICE_WANT_STANDALONE" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF # Begin Target # Name "loose_eel - Win32 Release" # Name "loose_eel - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Group "eel2" # PROP Default_Filter "" # Begin Source File SOURCE=".\ns-eel-addfuncs.h" # End Source File # Begin Source File SOURCE=".\ns-eel-int.h" # End Source File # Begin Source File SOURCE=".\ns-eel.h" # End Source File # Begin Source File SOURCE=".\nseel-caltab.c" # End Source File # Begin Source File SOURCE=".\nseel-cfunc.c" # End Source File # Begin Source File SOURCE=".\nseel-compiler.c" # End Source File # Begin Source File SOURCE=".\nseel-eval.c" # End Source File # Begin Source File SOURCE=".\nseel-lextab.c" # End Source File # Begin Source File SOURCE=".\nseel-ram.c" # End Source File # Begin Source File SOURCE=".\nseel-yylex.c" # End Source File # End Group # Begin Group "lice" # PROP Default_Filter "" # Begin Source File SOURCE=..\lice\lice.cpp # End Source File # Begin Source File SOURCE=..\lice\lice_arc.cpp # End Source File # Begin Source File SOURCE=..\lice\lice_bmp.cpp # End Source File # Begin Source File SOURCE=..\lice\lice_ico.cpp # End Source File # Begin Source File SOURCE=..\lice\lice_image.cpp # End Source File # Begin Source File SOURCE=..\lice\lice_line.cpp # End Source File # Begin Source File SOURCE=..\lice\lice_lvg.cpp # End Source File # Begin Source File SOURCE=..\lice\lice_pcx.cpp # End Source File # Begin Source File SOURCE=..\lice\lice_text.cpp # End Source File # Begin Source File SOURCE=..\lice\lice_textnew.cpp # End Source File # End Group # Begin Source File SOURCE=..\fft.c # End Source File # Begin Source File SOURCE=.\loose_eel.cpp # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project jsusfx-0.4.0/src/WDL/eel2/loose_eel.dsw000066400000000000000000000010351353477307700176050ustar00rootroot00000000000000Microsoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "loose_eel"=.\loose_eel.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### jsusfx-0.4.0/src/WDL/eel2/loose_eel.sln000066400000000000000000000025011353477307700176030ustar00rootroot00000000000000 Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Express 2013 for Windows Desktop VisualStudioVersion = 12.0.30110.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loose_eel", "loose_eel.vcxproj", "{893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Debug|Win32.ActiveCfg = Debug|Win32 {893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Debug|Win32.Build.0 = Debug|Win32 {893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Debug|x64.ActiveCfg = Debug|x64 {893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Debug|x64.Build.0 = Debug|x64 {893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Release|Win32.ActiveCfg = Release|Win32 {893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Release|Win32.Build.0 = Release|Win32 {893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Release|x64.ActiveCfg = Release|x64 {893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal jsusfx-0.4.0/src/WDL/eel2/loose_eel.vcxproj000066400000000000000000000246171353477307700205160ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 true true {893B9C0E-73CA-4843-A3BC-8A3FF9055FA8} Win32Proj loose_eel Application true v120 MultiByte Application true v120 MultiByte Application false v120 true MultiByte Application false v120 true MultiByte true $(Configuration)_new\ $(SolutionDir)$(Configuration)_new\ .exe true .exe false $(Configuration)_new\ $(SolutionDir)$(Configuration)_new\ .exe false .exe Level3 Disabled WIN32;BUILD_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WDL_FFT_REALSIZE=8;EEL_LICE_WANT_STANDALONE;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) true false Console true kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) Level3 Disabled WIN32;BUILD_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WDL_FFT_REALSIZE=8;EEL_LICE_WANT_STANDALONE;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) true false Console true kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) Level3 NotUsing MaxSpeed true true WIN32;BUILD_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WDL_FFT_REALSIZE=8;EEL_LICE_WANT_STANDALONE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) true MultiThreaded Console true true true kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) Level3 NotUsing MaxSpeed true true WIN32;BUILD_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WDL_FFT_REALSIZE=8;EEL_LICE_WANT_STANDALONE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) true MultiThreaded Console true true true kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) jsusfx-0.4.0/src/WDL/eel2/loose_eel.vcxproj.filters000066400000000000000000000065261353477307700221640ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms {3A983C0A-E7C1-449D-B869-8CC1CE792C2F} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files\lice Source Files\lice Source Files\lice Source Files\lice Source Files\lice Source Files\lice Source Files\lice Source Files\lice Source Files\lice Source Files\lice Source Files Source Files Header Files Header Files Header Files Source Files jsusfx-0.4.0/src/WDL/eel2/makefile.vc000066400000000000000000000022361353477307700172330ustar00rootroot00000000000000 EEL_SOURCE = nseel-caltab.c nseel-cfunc.c nseel-compiler.c nseel-eval.c nseel-lextab.c nseel-ram.c nseel-yylex.c LICE_SOURCE = ../lice/lice.cpp ../lice/lice_image.cpp ../lice/lice_line.cpp ../lice/lice_ico.cpp ../lice/lice_bmp.cpp ../lice/lice_textnew.cpp ../lice/lice_text.cpp ../lice/lice_arc.cpp FFT_SOURCE = ../fft.c CFLAGS = /DWDL_FFT_REALSIZE=8 /DEEL_LICE_WANT_STANDALONE CFLAGS = $(CFLAGS) -DNSEEL_LOOPFUNC_SUPPORT_MAXLEN=0 LFLAGS = !ifndef VC6 CFLAGS = $(CFLAGS) /MT !else CFLAGS = $(CFLAGS) /MD LFLAGS = $(LFLAGS) /OPT:NOWIN98 !endif !ifdef x64 !ifndef PORTABLE EEL_SOURCE = $(EEL_SOURCE) asm-nseel-x64.obj !endif !endif default: loose_eel.exe !ifdef PORTABLE CFLAGS = $(CFLAGS) -DEEL_TARGET_PORTABLE !endif loose_eel.cpp: eel*.h ns-eel*.h $(EEL_SOURCE): ns-eel*.h loose_eel.exe: loose_eel.cpp $(EEL_SOURCE) $(FFT_SOURCE) $(LICE_SOURCE) cl $(CFLAGS) $** /link wsock32.lib user32.lib gdi32.lib advapi32.lib $(LFLAGS) /out:$@ eel_disasm.exe: eel_disasm.cpp $(EEL_SOURCE) cl $(CFLAGS) $** /link wsock32.lib user32.lib gdi32.lib advapi32.lib $(LFLAGS) /out:$@ test: eel_disasm.exe eel_disasm "buf[a] = x*y" jsusfx-0.4.0/src/WDL/eel2/ns-eel-addfuncs.h000066400000000000000000000056561353477307700202560ustar00rootroot00000000000000/* Nullsoft Expression Evaluator Library (NS-EEL) Copyright (C) 1999-2003 Nullsoft, Inc. ns-eel-addfuncs.h: defines macros useful for adding functions to the compiler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #ifndef __NS_EEL_ADDFUNCS_H__ #define __NS_EEL_ADDFUNCS_H__ #ifdef __cplusplus extern "C" { #endif struct _compileContext; void *NSEEL_PProc_RAM(void *data, int data_size, struct _compileContext *ctx); void *NSEEL_PProc_THIS(void *data, int data_size, struct _compileContext *ctx); #ifdef EEL_TARGET_PORTABLE extern EEL_BC_TYPE _asm_generic3parm[]; // 3 double * parms, returning double * extern EEL_BC_TYPE _asm_generic3parm_retd[]; // 3 double * parms, returning double extern EEL_BC_TYPE _asm_generic2parm[]; // 2 double * parms, returning double * extern EEL_BC_TYPE _asm_generic2parm_retd[]; // 2 double * parms, returning double extern EEL_BC_TYPE _asm_generic1parm[]; // 1 double * parms, returning double * extern EEL_BC_TYPE _asm_generic1parm_retd[]; // 1 double * parms, returning double extern const void *const _asm_generic1parm_retd_end; extern const void *const _asm_generic1parm_end; extern const void *const _asm_generic2parm_retd_end; extern const void *const _asm_generic2parm_end; extern const void *const _asm_generic3parm_retd_end; extern const void *const _asm_generic3parm_end; #else void _asm_generic3parm(void); // 3 double * parms, returning double * void _asm_generic3parm_end(void); void _asm_generic3parm_retd(void); // 3 double * parms, returning double void _asm_generic3parm_retd_end(void); void _asm_generic2parm(void); // 2 double * parms, returning double * void _asm_generic2parm_end(void); void _asm_generic2parm_retd(void); // 2 double * parms, returning double void _asm_generic2parm_retd_end(void); void _asm_generic1parm(void); // 1 double * parms, returning double * void _asm_generic1parm_end(void); void _asm_generic1parm_retd(void); // 1 double * parms, returning double void _asm_generic1parm_retd_end(void); #endif #if EEL_F_SIZE == 4 #define EEL_F_SSTR "4" #define EEL_F_SUFFIX "s" #else #define EEL_F_SSTR "8" #define EEL_F_SUFFIX "l" #endif #ifdef __cplusplus }; #endif #endif//__NS_EEL_ADDFUNCS_H__ jsusfx-0.4.0/src/WDL/eel2/ns-eel-func-ref.h000066400000000000000000000133651353477307700201700ustar00rootroot00000000000000#ifndef _NSEEL_FUNC_REF_H_ #define _NSEEL_FUNC_REF_H_ #include "ns-eel.h" #define TMP_MKSTR2(x) #x #define TMP_MKSTR(x) TMP_MKSTR2(x) const char *nseel_builtin_function_reference= "while\texpression\tExecutes expression until expression evaluates to zero" #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN ", or until " TMP_MKSTR(NSEEL_LOOPFUNC_SUPPORT_MAXLEN) "iterations occur" #endif ". An alternate and more useful syntax is while (expression) ( statements ), which evaluates statements after " "every non-zero evaluation of expression.\0" "loop\tcount,expression\tEvaluates count once, and then executes expression count" #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN ", but not more than " TMP_MKSTR(NSEEL_LOOPFUNC_SUPPORT_MAXLEN) "," #endif " times.\0" "sin\tangle\tReturns the sine of the angle specified (specified in radians -- to convert from degrees to radians, multiply by $pi/180, or 0.017453).\0" "cos\tangle\tReturns the cosine of the angle specified (specified in radians).\0" "tan\tangle\tReturns the tangent of the angle specified (specified in radians).\0" "sqrt\tvalue\tReturns the square root of the parameter. If the parameter is negative, the return value is undefined.\0" "log\tvalue\tReturns the natural logarithm (base e) of the parameter. If the value is not greater than 0, the return value is undefined.\0" "log10\tvalue\tReturns the base-10 logarithm of the parameter. If the value is not greater than 0, the return value is undefined.\0" "asin\tvalue\tReturns the arc sine of the value specified (return value is in radians). If the parameter is not between -1.0 and 1.0 inclusive, the return value is undefined.\0" "acos\tvalue\tReturns the arc cosine of the value specified (return value is in radians). If the parameter is not between -1.0 and 1.0 inclusive, the return value is undefined.\0" "atan\tvalue\tReturns the arc tangent of the value specified (return value is in radians). If the parameter is not between -1.0 and 1.0 inclusive, the return value is undefined.\0" "atan2\tnumerator,denominator\tReturns the arc tangent of the numerator divided by the denominator, allowing the denominator to be 0, and using their signs to produce a more meaningful result.\0" "exp\texponent\tReturns the number e ($e, approximately 2.718) raised to the parameter-th power. This function is significantly faster than pow() or the ^ operator.\0" "abs\tvalue\tReturns the absolute value of the parameter.\0" "sqr\tvalue\tReturns the square of the parameter (similar to value*value, but only evaluating value once).\0" "min\t&value,&value\tReturns (by reference) the minimum value of the two parameters. Since min() returns by reference, expressions such as min(x,y) = 5 are possible.\0" "max\t&value,&value\tReturns (by reference) the maximum value of the two parameters. Since max() returns by reference, expressions such as max(x,y) = 5 are possible.\0" "sign\tvalue\tReturns 1.0 if the parameter is greater than 0, -1.0 if the parameter is less than 0, or 0 if the parameter is 0.\0" "floor\tvalue\tReturns the value rounded to the next lowest integer (floor(3.9)==3, floor(-3.1)==-4).\0" "ceil\tvalue\tReturns the value rounded to the next highest integer (ceil(3.1)==4, ceil(-3.9)==-3).\0" "invsqrt\tvalue\tReturns a fast inverse square root (1/sqrt(x)) approximation of the parameter.\0" "freembuf\taddress\tHints the runtime that memory above the address specified may no longer be used. The runtime may, at its leisure, choose to lose the contents of memory above the address specified.\0" "memcpy\tdest,src,length\tCopies length items of memory from src to dest. Regions are permitted to overlap.\0" "memset\toffset,value,length\tSets length items of memory at offset to value.\0" "mem_get_values\toffset, ...\tReads values from memory starting at offset into variables specified. Slower than regular memory reads for less than a few variables, faster for more than a few. Undefined behavior if used with more than 32767 variables.\0" "mem_set_values\toffset, ...\tWrites values to memory starting at offset from variables specified. Slower than regular memory writes for less than a few variables, faster for more than a few. Undefined behavior if used with more than 32767 variables.\0" "stack_push\t&value\tPushes value onto the user stack, returns a reference to the parameter.\0" "stack_pop\t&value\tPops a value from the user stack into value, or into a temporary buffer if value is not specified, and returns a reference to where the stack was popped. Note that no checking is done to determine if the stack is empty, and as such stack_pop() will never fail.\0" "stack_peek\tindex\tReturns a reference to the item on the top of the stack (if index is 0), or to the Nth item on the stack if index is greater than 0. \0" "stack_exch\t&value\tExchanges a value with the top of the stack, and returns a reference to the parameter (with the new value).\0" #ifdef NSEEL_EEL1_COMPAT_MODE "rand\tmax\tReturns a psuedorandom non-negative integer number less than the parameter.\0" "sigmoid\tvalue,constraint\tReturns 1.0/(1+exp(-x * (constraint))), or 0 if a divide by 0 would occur.\0" "band\tx,y\tReturns 1 if both x and y evaluate to nonzero, 0 if otherwise. Both parameters are always evaluated.\0" "bor\tx,y\tReturns 1 if either x or y evaluate to nonzero, 0 if otherwise. Both parameters are always evaluated.\0" "exec2\tx,y\tEvaluates x, then evaluates and returns y.\0" "exec3\tx,y,z\tEvaluates x, evaluates y, then evaluates and returns z.\0" #else "rand\t[max]\tReturns a psuedorandom real number between 0 and the parameter, inclusive. If the parameter is omitted or less than 1.0, 1.0 is used as a maximum instead.\0" #endif ; #undef TMP_MKSTR #endif jsusfx-0.4.0/src/WDL/eel2/ns-eel-int.h000066400000000000000000000243011353477307700172450ustar00rootroot00000000000000/* Nullsoft Expression Evaluator Library (NS-EEL) Copyright (C) 1999-2003 Nullsoft, Inc. ns-eel-int.h: internal code definition header. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #ifndef __NS_EELINT_H__ #define __NS_EELINT_H__ #ifdef _WIN32 #include #else #include "../wdltypes.h" #endif #include "ns-eel.h" #include "ns-eel-addfuncs.h" #ifdef __cplusplus extern "C" { #endif enum { // these ignore fn in opcodes, just use fntype to determine function FN_MULTIPLY=0, FN_DIVIDE, FN_JOIN_STATEMENTS, FN_DENORMAL_LIKELY, FN_DENORMAL_UNLIKELY, FN_ADD, FN_SUB, FN_AND, FN_OR, FN_UMINUS, FN_NOT, FN_NOTNOT, FN_XOR, FN_SHL, FN_SHR, FN_MOD, FN_POW, FN_LT, FN_GT, FN_LTE, FN_GTE, FN_EQ, FN_EQ_EXACT, FN_NE, FN_NE_EXACT, FN_LOGICAL_AND, FN_LOGICAL_OR, FN_IF_ELSE, FN_MEMORY, FN_GMEMORY, FN_NONCONST_BEGIN, FN_ASSIGN=FN_NONCONST_BEGIN, FN_ADD_OP, FN_SUB_OP, FN_MOD_OP, FN_OR_OP, FN_AND_OP, FN_XOR_OP, FN_DIV_OP, FN_MUL_OP, FN_POW_OP, FN_WHILE, FN_LOOP, FUNCTYPE_SIMPLEMAX, FUNCTYPE_FUNCTIONTYPEREC=1000, // fn is a functionType * FUNCTYPE_EELFUNC, // fn is a _codeHandleFunctionRec * }; #define YYSTYPE opcodeRec * #define NSEEL_CLOSEFACTOR 0.00001 typedef struct opcodeRec opcodeRec; typedef struct _codeHandleFunctionRec { struct _codeHandleFunctionRec *next; // main linked list (only used for high level functions) struct _codeHandleFunctionRec *derivedCopies; // separate linked list, head being the main function, other copies being derived versions void *startptr; // compiled code (may be cleared + recompiled when shraed) opcodeRec *opcodes; int startptr_size; int tmpspace_req; int num_params; int rvMode; // RETURNVALUE_* int fpStackUsage; // 0-8, usually int canHaveDenormalOutput; // local storage's first items are the parameters, then locals. Note that the opcodes will reference localstorage[] via VARPTRPTR, but // the values localstorage[x] points are reallocated from context-to-context, if it is a common function. // separately allocated list of pointers, the contents of the list should be zeroed on context changes if a common function // note that when making variations on a function (context), it is shared, but since it is zeroed on context changes, it is context-local int localstorage_size; EEL_F **localstorage; int isCommonFunction; int usesNamespaces; unsigned int parameterAsNamespaceMask; char fname[NSEEL_MAX_FUNCSIG_NAME+1]; } _codeHandleFunctionRec; #define LLB_DSIZE (65536-64) typedef struct _llBlock { struct _llBlock *next; int sizeused; char block[LLB_DSIZE]; } llBlock; typedef struct { llBlock *blocks, *blocks_data; void *workTable; // references a chunk in blocks_data void *code; int code_size; // in case the caller wants to write it out int code_stats[4]; int want_stack; void *stack; // references a chunk in blocks_data, somewhere within the complete NSEEL_STACK_SIZE aligned at NSEEL_STACK_SIZE void *ramPtr; int workTable_size; // size (minus padding/extra space) of workTable -- only used if EEL_VALIDATE_WORKTABLE_USE set, but might be handy to have around too } codeHandleType; typedef struct _compileContext { eel_function_table *registered_func_tab; const char *(*func_check)(const char *fn_name, void *user); // return error message if not permitted void *func_check_user; EEL_F **varTable_Values; char ***varTable_Names; int varTable_numBlocks; int errVar,gotEndOfInput; opcodeRec *result; char last_error_string[256]; void *scanner; const char *rdbuf_start, *rdbuf, *rdbuf_end; llBlock *tmpblocks_head, // used while compiling, and freed after compiling *blocks_head, // used while compiling, transferred to code context (these are pages marked as executable) *blocks_head_data, // used while compiling, transferred to code context *pblocks; // persistent blocks, stores data used by varTable_Names, varTable_Values, etc. int l_stats[4]; // source bytes, static code bytes, call code bytes, data bytes int has_used_global_vars; _codeHandleFunctionRec *functions_local, *functions_common; // state used while generating functions int optimizeDisableFlags; struct opcodeRec *directValueCache; // linked list using fn as next int isSharedFunctions; int isGeneratingCommonFunction; int function_usesNamespaces; int function_globalFlag; // set if restrict globals to function_localTable_Names[2] // [0] is parameter+local symbols (combined space) // [1] is symbols which get implied "this." if used // [2] is globals permitted int function_localTable_Size[3]; // for parameters only char **function_localTable_Names[3]; // lists of pointers EEL_F **function_localTable_ValuePtrs; const char *function_curName; // name of current function EEL_F (*onString)(void *caller_this, struct eelStringSegmentRec *list); EEL_F (*onNamedString)(void *caller_this, const char *name); codeHandleType *tmpCodeHandle; struct { int needfree; int maxblocks; double closefact; EEL_F *blocks[NSEEL_RAM_BLOCKS]; } ram_state #ifdef __GNUC__ __attribute__ ((aligned (8))) #endif ; void *gram_blocks; void *caller_this; } compileContext; #define NSEEL_VARS_PER_BLOCK 64 #define NSEEL_NPARAMS_FLAG_CONST 0x80000 typedef struct functionType { const char *name; void *afunc; void *func_e; int nParams; void *replptrs[4]; NSEEL_PPPROC pProc; } functionType; typedef struct { int refcnt; char isreg; } varNameHdr; functionType *nseel_getFunctionFromTable(int idx); functionType *nseel_getFunctionFromTableEx(compileContext *ctx, int idx); opcodeRec *nseel_createCompiledValue(compileContext *ctx, EEL_F value); opcodeRec *nseel_createCompiledValuePtr(compileContext *ctx, EEL_F *addrValue, const char *namestr); opcodeRec *nseel_createMoreParametersOpcode(compileContext *ctx, opcodeRec *code1, opcodeRec *code2); opcodeRec *nseel_createSimpleCompiledFunction(compileContext *ctx, int fn, int np, opcodeRec *code1, opcodeRec *code2); opcodeRec *nseel_createMemoryAccess(compileContext *ctx, opcodeRec *code1, opcodeRec *code2); opcodeRec *nseel_createIfElse(compileContext *ctx, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3); opcodeRec *nseel_createFunctionByName(compileContext *ctx, const char *name, int np, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3); // converts a generic identifier (VARPTR) opcode into either an actual variable reference (parmcnt = -1), // or if parmcnt >= 0, to a function call (see nseel_setCompiledFunctionCallParameters()) opcodeRec *nseel_resolve_named_symbol(compileContext *ctx, opcodeRec *rec, int parmcnt, int *errOut); // sets parameters and calculates parameter count for opcode, and calls nseel_resolve_named_symbol() with the right // parameter count opcodeRec *nseel_setCompiledFunctionCallParameters(compileContext *ctx, opcodeRec *fn, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3, opcodeRec *postCode, int *errOut); // errOut will be set if return NULL: // -1 if postCode set when not wanted (i.e. not while()) // 0 if func not found, // 1 if function requires 2+ parameters but was given more // 2 if function needs more parameters // 4 if function requires 1 parameter but was given more struct eelStringSegmentRec *nseel_createStringSegmentRec(compileContext *ctx, const char *str, int len); opcodeRec *nseel_eelMakeOpcodeFromStringSegments(compileContext *ctx, struct eelStringSegmentRec *rec); EEL_F *nseel_int_register_var(compileContext *ctx, const char *name, int isReg, const char **namePtrOut); _codeHandleFunctionRec *eel_createFunctionNamespacedInstance(compileContext *ctx, _codeHandleFunctionRec *fr, const char *nameptr); typedef struct nseel_globalVarItem { EEL_F data; struct nseel_globalVarItem *_next; char name[1]; // varlen, does not include _global. prefix } nseel_globalVarItem; extern nseel_globalVarItem *nseel_globalreg_list; // if NSEEL_EEL1_COMPAT_MODE, must use NSEEL_getglobalregs() for regxx values #include "y.tab.h" // nseel_simple_tokenizer will return comments as tokens if state is non-NULL const char *nseel_simple_tokenizer(const char **ptr, const char *endptr, int *lenOut, int *state); int nseel_filter_escaped_string(char *outbuf, int outbuf_sz, const char *rdptr, size_t rdptr_size, char delim_char); // returns length used, minus NUL char opcodeRec *nseel_translate(compileContext *ctx, const char *tmp, size_t tmplen); // tmplen=0 for nul-term int nseel_lookup(compileContext *ctx, opcodeRec **opOut, const char *sname); EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAlloc(EEL_F **blocks, unsigned int w); EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAllocGMEM(EEL_F ***blocks, unsigned int w); EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemSet(EEL_F **blocks,EEL_F *dest, EEL_F *v, EEL_F *lenptr); EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemFree(void *blocks, EEL_F *which); EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemTop(void *blocks, EEL_F *which); EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemCpy(EEL_F **blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr); EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_Mem_SetValues(EEL_F **blocks, INT_PTR np, EEL_F **parms); EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_Mem_GetValues(EEL_F **blocks, INT_PTR np, EEL_F **parms); extern EEL_F nseel_ramalloc_onfail; // address returned by __NSEEL_RAMAlloc et al on failure extern EEL_F * volatile nseel_gmembuf_default; // can free/zero this on DLL unload if needed #ifdef __cplusplus } #endif #endif//__NS_EELINT_H__ jsusfx-0.4.0/src/WDL/eel2/ns-eel.h000066400000000000000000000246521353477307700164660ustar00rootroot00000000000000/* Nullsoft Expression Evaluator Library (NS-EEL) Copyright (C) 1999-2003 Nullsoft, Inc. ns-eel.h: main application interface header This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #ifndef __NS_EEL_H__ #define __NS_EEL_H__ // put standard includes here #include #include #ifndef EEL_F_SIZE #define EEL_F_SIZE 8 #endif #include "../wdltypes.h" #if EEL_F_SIZE == 4 typedef float EEL_F; typedef float *EEL_F_PTR; #else typedef double EEL_F WDL_FIXALIGN; typedef double *EEL_F_PTR; #endif #ifdef _MSC_VER #define NSEEL_CGEN_CALL __cdecl #else #define NSEEL_CGEN_CALL #endif #ifdef __cplusplus extern "C" { #endif // host should implement these (can be empty stub functions if no VM will execute code in multiple threads at once) // implement if you will be running the code in same VM from multiple threads, // or VMs that have the same GRAM pointer from different threads, or multiple // VMs that have a NULL GRAM pointer from multiple threads. // if you give each VM it's own unique GRAM and only run each VM in one thread, then you can leave it blank. // or if you're daring.... void NSEEL_HOSTSTUB_EnterMutex(); void NSEEL_HOSTSTUB_LeaveMutex(); int NSEEL_init(); // returns nonzero on failure (only if EEL_VALIDATE_FSTUBS defined), otherwise the same as NSEEL_quit(), and completely optional void NSEEL_quit(); // clears any added functions // adds a function that returns a value (EEL_F) #define NSEEL_addfunc_retval(name,np,pproc,fptr) \ NSEEL_addfunc_ret_type(name,np,1,pproc,(void *)(fptr),NSEEL_ADDFUNC_DESTINATION) // adds a function that returns a pointer (EEL_F*) #define NSEEL_addfunc_retptr(name,np,pproc,fptr) \ NSEEL_addfunc_ret_type(name,np,0,pproc,(void *)(fptr),NSEEL_ADDFUNC_DESTINATION) // adds a void or bool function #define NSEEL_addfunc_retbool(name,np,pproc,fptr) \ NSEEL_addfunc_ret_type(name,np,-1,pproc,(void *)(fptr),NSEEL_ADDFUNC_DESTINATION) // adds a function that takes min_np or more parameters (func sig needs to be EEL_F func(void *ctx, INT_PTR np, EEL_F **parms) #define NSEEL_addfunc_varparm(name, min_np, pproc, fptr) \ NSEEL_addfunc_varparm_ex(name,min_np,0,pproc,fptr,NSEEL_ADDFUNC_DESTINATION) // adds a function that takes np parameters via func: sig needs to be EEL_F func(void *ctx, INT_PTR np, EEL_F **parms) #define NSEEL_addfunc_exparms(name, np, pproc, fptr) \ NSEEL_addfunc_varparm_ex(name,np,1,pproc,fptr,NSEEL_ADDFUNC_DESTINATION) // deprecated #define NSEEL_addfunction(name,nparms,code,len) NSEEL_addfunctionex((name),(nparms),(code),(len),0,0) #define NSEEL_addfunctionex(name,nparms,code,len,pproc,fptr) NSEEL_addfunctionex2((name),(nparms),(code),(len),(pproc),(fptr),0, NSEEL_ADDFUNC_DESTINATION) #ifndef NSEEL_ADDFUNC_DESTINATION #define NSEEL_ADDFUNC_DESTINATION (NULL) #endif struct functionType; typedef struct { struct functionType *list; int list_size; } eel_function_table; struct _compileContext; typedef void *(*NSEEL_PPPROC)(void *data, int data_size, struct _compileContext *userfunc_data); void NSEEL_addfunctionex2(const char *name, int nparms, char *code_startaddr, int code_len, NSEEL_PPPROC pproc, void *fptr, void *fptr2, eel_function_table *destination); void NSEEL_addfunc_ret_type(const char *name, int np, int ret_type, NSEEL_PPPROC pproc, void *fptr, eel_function_table *destination); // ret_type=-1 for bool, 1 for value, 0 for ptr void NSEEL_addfunc_varparm_ex(const char *name, int min_np, int want_exact, NSEEL_PPPROC pproc, EEL_F (NSEEL_CGEN_CALL *fptr)(void *, INT_PTR, EEL_F **), eel_function_table *destination); int *NSEEL_getstats(); // returns a pointer to 5 ints... source bytes, static code bytes, call code bytes, data bytes, number of code handles typedef void *NSEEL_VMCTX; typedef void *NSEEL_CODEHANDLE; NSEEL_VMCTX NSEEL_VM_alloc(); // return a handle void NSEEL_VM_free(NSEEL_VMCTX ctx); // free when done with a VM and ALL of its code have been freed, as well void NSEEL_VM_SetFunctionTable(NSEEL_VMCTX, eel_function_table *tab); // use NULL to use default (global) table // validateFunc can return error message if not permitted void NSEEL_VM_SetFunctionValidator(NSEEL_VMCTX, const char * (*validateFunc)(const char *fn_name, void *user), void *user); void NSEEL_VM_remove_unused_vars(NSEEL_VMCTX _ctx); void NSEEL_VM_clear_var_refcnts(NSEEL_VMCTX _ctx); void NSEEL_VM_remove_all_nonreg_vars(NSEEL_VMCTX _ctx); void NSEEL_VM_enumallvars(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F *val, void *ctx), void *userctx); // return false from func to stop EEL_F *NSEEL_VM_regvar(NSEEL_VMCTX ctx, const char *name); // register a variable (before compilation) EEL_F *NSEEL_VM_getvar(NSEEL_VMCTX ctx, const char *name); // get a variable (if registered or created by code) int NSEEL_VM_get_var_refcnt(NSEEL_VMCTX _ctx, const char *name); // returns -1 if not registered, or >=0 void NSEEL_VM_freeRAM(NSEEL_VMCTX ctx); // clears and frees all (VM) RAM used void NSEEL_VM_freeRAMIfCodeRequested(NSEEL_VMCTX); // call after code to free the script-requested memory int NSEEL_VM_wantfreeRAM(NSEEL_VMCTX ctx); // want NSEEL_VM_freeRAMIfCodeRequested? // if you set this, it uses a local GMEM context. // Must be set before compilation. // void *p=NULL; // NSEEL_VM_SetGRAM(ctx,&p); // .. do stuff // NSEEL_VM_FreeGRAM(&p); void NSEEL_VM_SetGRAM(NSEEL_VMCTX ctx, void **gram); void NSEEL_VM_FreeGRAM(void **ufd); // frees a gmem context. void NSEEL_VM_SetCustomFuncThis(NSEEL_VMCTX ctx, void *thisptr); EEL_F *NSEEL_VM_getramptr(NSEEL_VMCTX ctx, unsigned int offs, int *validCount); EEL_F *NSEEL_VM_getramptr_noalloc(NSEEL_VMCTX ctx, unsigned int offs, int *validCount); // set 0 to query. returns actual value used (limits, granularity apply -- see NSEEL_RAM_BLOCKS) int NSEEL_VM_setramsize(NSEEL_VMCTX ctx, int maxent); struct eelStringSegmentRec { struct eelStringSegmentRec *_next; const char *str_start; // escaped characters, including opening/trailing characters int str_len; }; void NSEEL_VM_SetStringFunc(NSEEL_VMCTX ctx, EEL_F (*onString)(void *caller_this, struct eelStringSegmentRec *list), EEL_F (*onNamedString)(void *caller_this, const char *name)); // call with NULL to calculate size, or non-null to generate to buffer (returning size used -- will not null terminate, caller responsibility) int nseel_stringsegments_tobuf(char *bufOut, int bufout_sz, struct eelStringSegmentRec *list); NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX ctx, const char *code, int lineoffs); #define NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS 1 // allows that code's functions to be used in other code (note you shouldn't destroy that codehandle without destroying others first if used) #define NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS_RESET 2 // resets common code functions NSEEL_CODEHANDLE NSEEL_code_compile_ex(NSEEL_VMCTX ctx, const char *code, int lineoffs, int flags); char *NSEEL_code_getcodeerror(NSEEL_VMCTX ctx); int NSEEL_code_geterror_flag(NSEEL_VMCTX ctx); void NSEEL_code_execute(NSEEL_CODEHANDLE code); void NSEEL_code_free(NSEEL_CODEHANDLE code); int *NSEEL_code_getstats(NSEEL_CODEHANDLE code); // 4 ints...source bytes, static code bytes, call code bytes, data bytes // global memory control/view extern unsigned int NSEEL_RAM_limitmem; // if nonzero, memory limit for user data, in bytes extern unsigned int NSEEL_RAM_memused; extern int NSEEL_RAM_memused_errors; // configuration: // use the handwritten lexer -- the flex (eel2.l generated) lexer mostly works, but doesn't support string parsing at the moment // this mode is faster and uses less ram than eel2.l anyway, so leave it on #define NSEEL_SUPER_MINIMAL_LEXER // #define NSEEL_EEL1_COMPAT_MODE // supports old behaviors (continue after failed compile), old functions _bnot etc. disables string support (strings were used as comments in eel1 etc) #define NSEEL_MAX_VARIABLE_NAMELEN 128 // define this to override the max variable length #define NSEEL_MAX_EELFUNC_PARAMETERS 40 #define NSEEL_MAX_FUNCSIG_NAME 2048 // longer than variable maxlen, due to multiple namespaces // maximum loop length (0 for unlimited) #ifndef NSEEL_LOOPFUNC_SUPPORT_MAXLEN #define NSEEL_LOOPFUNC_SUPPORT_MAXLEN 1048576 #endif #define NSEEL_MAX_FUNCTION_SIZE_FOR_INLINE 2048 // when a VM ctx doesn't have a GRAM context set, make the global one this big #define NSEEL_SHARED_GRAM_SIZE (1<<20) //#define EEL_DUMP_OPS // used for testing frontend parser/logic changes // note: if you wish to change NSEEL_RAM_*, and your target is x86-64, you will need to regenerate things. // on osx: // php a2x64.php win64x // php a2x64.php macho64 // or on win32: // php a2x64.php // php a2x64.php macho64x // this will regenerate the .asm files and object files // 512 * 65536 = 32 million entries maximum (256MB RAM) // default is limited to 128 * 65536 = 8 million entries (64MB RAM) // default to 8 million entries, use NSEEL_VM_setramsize() to change at runtime #define NSEEL_RAM_BLOCKS_DEFAULTMAX 128 // 512 entry block table maximum (2k/4k per VM) #define NSEEL_RAM_BLOCKS_LOG2 9 // 65536 items per block (512KB) #define NSEEL_RAM_ITEMSPERBLOCK_LOG2 16 #define NSEEL_RAM_BLOCKS (1 << NSEEL_RAM_BLOCKS_LOG2) #define NSEEL_RAM_ITEMSPERBLOCK (1< #include // these are used by our assembly code #define N 624 #define M 397 #define MATRIX_A 0x9908b0dfUL /* constant vector a */ #define UPPER_MASK 0x80000000UL /* most significant w-r bits */ #define LOWER_MASK 0x7fffffffUL /* least significant r bits */ static unsigned int genrand_int32(void) { unsigned int y; static unsigned int mag01[2]={0x0UL, MATRIX_A}; /* mag01[x] = x * MATRIX_A for x=0,1 */ static unsigned int mt[N]; /* the array for the state vector */ static int mti; /* mti==N+1 means mt[N] is not initialized */ if (!mti) { unsigned int s=0x4141f00d; mt[0]= s & 0xffffffffUL; for (mti=1; mti> 30)) + mti); /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ /* In the previous versions, MSBs of the seed affect */ /* only MSBs of the array mt[]. */ /* 2002/01/09 modified by Makoto Matsumoto */ mt[mti] &= 0xffffffffUL; /* for >32 bit machines */ } } if (mti >= N) { /* generate N words at one time */ int kk; for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; } for (;kk> 1) ^ mag01[y & 0x1UL]; } y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; mti = 0; } y = mt[mti++]; /* Tempering */ y ^= (y >> 11); y ^= (y << 7) & 0x9d2c5680UL; y ^= (y << 15) & 0xefc60000UL; y ^= (y >> 18); return y; } //--------------------------------------------------------------------------------------------------------------- EEL_F NSEEL_CGEN_CALL nseel_int_rand(EEL_F f) { EEL_F x=floor(f); if (x < 1.0) x=1.0; #ifdef NSEEL_EEL1_COMPAT_MODE return (EEL_F)(genrand_int32()%(int)x); #else return (EEL_F) (genrand_int32()*(1.0/(double)0xFFFFFFFF)*x); #endif } //--------------------------------------------------------------------------------------------------------------- #ifndef EEL_TARGET_PORTABLE #ifdef __ppc__ #include "asm-nseel-ppc-gcc.c" #elif defined(__arm__) #include "asm-nseel-arm-gcc.c" #elif defined (_M_ARM) && _M_ARM == 7 // vc on ARM, tbd #else #ifdef _MSC_VER #ifdef _WIN64 //nasm #else #include "asm-nseel-x86-msvc.c" void eel_setfp_round() { short oldsw; __asm { fnstcw [oldsw] mov ax, [oldsw] and ax, 0xF3FF // round to nearest mov [oldsw], ax fldcw [oldsw] } } void eel_setfp_trunc() { short oldsw; __asm { fnstcw [oldsw] mov ax, [oldsw] or ax, 0xC00 // truncate mov [oldsw], ax fldcw [oldsw] } } #endif #elif !defined(__LP64__) #define FUNCTION_MARKER "\n.byte 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90\n" #include "asm-nseel-x86-gcc.c" void eel_setfp_round() { __asm__( "subl $16, %esp\n" "fnstcw (%esp)\n" "mov (%esp), %ax\n" "and $0xF3FF, %ax\n" // set round to nearest "mov %ax, 4(%esp)\n" "fldcw 4(%esp)\n" "addl $16, %esp\n" ); } void eel_setfp_trunc() { __asm__( "subl $16, %esp\n" "fnstcw (%esp)\n" "mov (%esp), %ax\n" "or $0xC00, %ax\n" // set to truncate "mov %ax, 4(%esp)\n" "fldcw 4(%esp)\n" "addl $16, %esp\n" ); } #endif #endif #endif #if defined(__ppc__) || defined(__arm__) || defined(EEL_TARGET_PORTABLE) // blank stubs for PPC, portable modes void eel_setfp_round() { } void eel_setfp_trunc() { } #endif jsusfx-0.4.0/src/WDL/eel2/nseel-compiler.c000066400000000000000000005616151353477307700202210ustar00rootroot00000000000000/* Expression Evaluator Library (NS-EEL) v2 Copyright (C) 2004-2013 Cockos Incorporated Copyright (C) 1999-2003 Nullsoft, Inc. nseel-compiler.c This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ // for VirtualProtect #include "ns-eel-int.h" #include "../denormal.h" #include "../wdlcstring.h" #include #include #include #include #ifndef EEL_TARGET_PORTABLE #ifdef __APPLE__ #include #if defined(__LP64__) || defined(MAC_OS_X_VERSION_10_6) // using 10.6+ SDK, force mprotect use #ifndef EEL_USE_MPROTECT #define EEL_USE_MPROTECT #endif #endif #endif #if defined(__linux__) && !defined(EEL_USE_MPROTECT) // always use mprotect on linux #define EEL_USE_MPROTECT #endif #endif #ifdef EEL_USE_MPROTECT #include #include #include #endif #define NSEEL_VARS_MALLOC_CHUNKSIZE 8 //#define LOG_OPT //#define EEL_PRINT_FAILS //#define EEL_VALIDATE_WORKTABLE_USE //#define EEL_VALIDATE_FSTUBS #ifdef EEL_PRINT_FAILS #ifdef _WIN32 #define RET_MINUS1_FAIL(x) { OutputDebugString(x); return -1; } #else #define RET_MINUS1_FAIL(x) { printf("%s\n",x); return -1; } #endif #else #define RET_MINUS1_FAIL(x) return -1; #endif #ifdef EEL_DUMP_OPS FILE *g_eel_dump_fp, *g_eel_dump_fp2; #endif #ifdef EEL_VALIDATE_WORKTABLE_USE #define MIN_COMPUTABLE_SIZE 0 #define COMPUTABLE_EXTRA_SPACE 64 // safety buffer, if EEL_VALIDATE_WORKTABLE_USE set, used for magic-value-checking #else #define MIN_COMPUTABLE_SIZE 32 // always use at least this big of a temp storage table (and reset the temp ptr when it goes past this boundary) #define COMPUTABLE_EXTRA_SPACE 16 // safety buffer, if EEL_VALIDATE_WORKTABLE_USE set, used for magic-value-checking #endif /* P1 is rightmost parameter P2 is second rightmost, if any P3 is third rightmost, if any registers on x86 are (RAX etc on x86-64) P1(ret) EAX P2 EDI P3 ECX WTP RSI x86_64: r12 is a pointer to ram_state.blocks x86_64: r13 is a pointer to closenessfactor registers on PPC are: P1(ret) r3 P2 r14 P3 r15 WTP r16 (r17 has the original value) r13 is a pointer to ram_state.blocks ppc uses f31 and f30 and others for certain constants */ #ifdef EEL_TARGET_PORTABLE #define EEL_DOESNT_NEED_EXEC_PERMS #include "glue_port.h" #elif defined(__ppc__) #include "glue_ppc.h" #elif defined(__arm__) || (defined (_M_ARM) && _M_ARM == 7) #include "glue_arm.h" #elif defined(_WIN64) || defined(__LP64__) #include "glue_x86_64.h" #else #include "glue_x86.h" #endif #ifndef GLUE_INVSQRT_NEEDREPL #define GLUE_INVSQRT_NEEDREPL 0 #endif // used by //#eel-no-optimize:xxx, in ctx->optimizeDisableFlags #define OPTFLAG_NO_OPTIMIZE 1 #define OPTFLAG_NO_FPSTACK 2 #define OPTFLAG_NO_INLINEFUNC 4 #define OPTFLAG_FULL_DENORMAL_CHECKS 8 // if set, denormals/NaN are always filtered on assign #define OPTFLAG_NO_DENORMAL_CHECKS 16 // if set and FULL not set, denormals/NaN are never filtered on assign #define MAX_SUB_NAMESPACES 32 typedef struct { const char *namespacePathToThis; const char *subParmInfo[MAX_SUB_NAMESPACES]; } namespaceInformation; static int nseel_evallib_stats[5]; // source bytes, static code bytes, call code bytes, data bytes, segments int *NSEEL_getstats() { return nseel_evallib_stats; } static int findLineNumber(const char *exp, int byteoffs) { int lc=0; while (byteoffs-->0 && *exp) if (*exp++ =='\n') lc++; return lc; } static int nseel_vms_referencing_globallist_cnt; nseel_globalVarItem *nseel_globalreg_list; static EEL_F *get_global_var(compileContext *ctx, const char *gv, int addIfNotPresent); static void *__newBlock(llBlock **start,int size, int wantMprotect); #define OPCODE_IS_TRIVIAL(x) ((x)->opcodeType <= OPCODETYPE_VARPTRPTR) enum { OPCODETYPE_DIRECTVALUE=0, OPCODETYPE_DIRECTVALUE_TEMPSTRING, // like directvalue, but will generate a new tempstring value on generate OPCODETYPE_VALUE_FROM_NAMESPACENAME, // this.* or namespace.* are encoded this way OPCODETYPE_VARPTR, OPCODETYPE_VARPTRPTR, OPCODETYPE_FUNC1, OPCODETYPE_FUNC2, OPCODETYPE_FUNC3, OPCODETYPE_FUNCX, OPCODETYPE_MOREPARAMS, OPCODETYPE_INVALID, }; struct opcodeRec { int opcodeType; int fntype; void *fn; union { struct opcodeRec *parms[3]; struct { double directValue; EEL_F *valuePtr; // if direct value, valuePtr can be cached } dv; } parms; int namespaceidx; // OPCODETYPE_VALUE_FROM_NAMESPACENAME (relname is either empty or blah) // OPCODETYPE_VARPTR if it represents a global variable, will be nonempty // OPCODETYPE_FUNC* with fntype=FUNCTYPE_EELFUNC const char *relname; }; static void *newTmpBlock(compileContext *ctx, int size) { const int align = 8; const int a1=align-1; char *p=(char*)__newBlock(&ctx->tmpblocks_head,size+a1, 0); return p+((align-(((INT_PTR)p)&a1))&a1); } static void *__newBlock_align(compileContext *ctx, int size, int align, int isForCode) { const int a1=align-1; char *p=(char*)__newBlock( ( isForCode < 0 ? (isForCode == -2 ? &ctx->pblocks : &ctx->tmpblocks_head) : isForCode > 0 ? &ctx->blocks_head : &ctx->blocks_head_data) ,size+a1, isForCode>0); return p+((align-(((INT_PTR)p)&a1))&a1); } static opcodeRec *newOpCode(compileContext *ctx, const char *str, int opType) { const size_t strszfull = str ? strlen(str) : 0; const size_t str_sz = wdl_min(NSEEL_MAX_VARIABLE_NAMELEN, strszfull); opcodeRec *rec = (opcodeRec*)__newBlock_align(ctx, (int) (sizeof(opcodeRec) + (str_sz>0 ? str_sz+1 : 0)), 8, ctx->isSharedFunctions ? 0 : -1); if (rec) { memset(rec,0,sizeof(*rec)); rec->opcodeType = opType; if (str_sz > 0) { char *p = (char *)(rec+1); memcpy(p,str,str_sz); p[str_sz]=0; rec->relname = p; } else { rec->relname = ""; } } return rec; } #define newCodeBlock(x,a) __newBlock_align(ctx,x,a,1) #define newDataBlock(x,a) __newBlock_align(ctx,x,a,0) #define newCtxDataBlock(x,a) __newBlock_align(ctx,x,a,-2) static void freeBlocks(llBlock **start); #ifndef DECL_ASMFUNC #define DECL_ASMFUNC(x) \ void nseel_asm_##x(void); \ void nseel_asm_##x##_end(void); void _asm_megabuf(void); void _asm_megabuf_end(void); void _asm_gmegabuf(void); void _asm_gmegabuf_end(void); #endif DECL_ASMFUNC(booltofp) DECL_ASMFUNC(fptobool) DECL_ASMFUNC(fptobool_rev) DECL_ASMFUNC(sin) DECL_ASMFUNC(cos) DECL_ASMFUNC(tan) DECL_ASMFUNC(1pdd) DECL_ASMFUNC(2pdd) DECL_ASMFUNC(2pdds) DECL_ASMFUNC(1pp) DECL_ASMFUNC(2pp) DECL_ASMFUNC(sqr) DECL_ASMFUNC(sqrt) DECL_ASMFUNC(log) DECL_ASMFUNC(log10) DECL_ASMFUNC(abs) DECL_ASMFUNC(min) DECL_ASMFUNC(max) DECL_ASMFUNC(min_fp) DECL_ASMFUNC(max_fp) DECL_ASMFUNC(sig) DECL_ASMFUNC(sign) DECL_ASMFUNC(band) DECL_ASMFUNC(bor) DECL_ASMFUNC(bnot) DECL_ASMFUNC(bnotnot) DECL_ASMFUNC(if) DECL_ASMFUNC(fcall) DECL_ASMFUNC(repeat) DECL_ASMFUNC(repeatwhile) DECL_ASMFUNC(equal) DECL_ASMFUNC(equal_exact) DECL_ASMFUNC(notequal_exact) DECL_ASMFUNC(notequal) DECL_ASMFUNC(below) DECL_ASMFUNC(above) DECL_ASMFUNC(beloweq) DECL_ASMFUNC(aboveeq) DECL_ASMFUNC(assign) DECL_ASMFUNC(assign_fromfp) DECL_ASMFUNC(assign_fast) DECL_ASMFUNC(assign_fast_fromfp) DECL_ASMFUNC(add) DECL_ASMFUNC(sub) DECL_ASMFUNC(add_op) DECL_ASMFUNC(sub_op) DECL_ASMFUNC(add_op_fast) DECL_ASMFUNC(sub_op_fast) DECL_ASMFUNC(mul) DECL_ASMFUNC(div) DECL_ASMFUNC(mul_op) DECL_ASMFUNC(div_op) DECL_ASMFUNC(mul_op_fast) DECL_ASMFUNC(div_op_fast) DECL_ASMFUNC(mod) DECL_ASMFUNC(shl) DECL_ASMFUNC(shr) DECL_ASMFUNC(mod_op) DECL_ASMFUNC(or) DECL_ASMFUNC(or0) DECL_ASMFUNC(xor) DECL_ASMFUNC(xor_op) DECL_ASMFUNC(and) DECL_ASMFUNC(or_op) DECL_ASMFUNC(and_op) DECL_ASMFUNC(uplus) DECL_ASMFUNC(uminus) DECL_ASMFUNC(invsqrt) DECL_ASMFUNC(dbg_getstackptr) #ifdef NSEEL_EEL1_COMPAT_MODE DECL_ASMFUNC(exec2) #endif DECL_ASMFUNC(stack_push) DECL_ASMFUNC(stack_pop) DECL_ASMFUNC(stack_pop_fast) // just returns value, doesn't mod param DECL_ASMFUNC(stack_peek) DECL_ASMFUNC(stack_peek_int) DECL_ASMFUNC(stack_peek_top) DECL_ASMFUNC(stack_exch) static void *NSEEL_PProc_GRAM(void *data, int data_size, compileContext *ctx) { if (data_size>0) data=EEL_GLUE_set_immediate(data, (INT_PTR)ctx->gram_blocks); return data; } static void *NSEEL_PProc_Stack(void *data, int data_size, compileContext *ctx) { codeHandleType *ch=ctx->tmpCodeHandle; if (data_size>0) { UINT_PTR m1=(UINT_PTR)(NSEEL_STACK_SIZE * sizeof(EEL_F) - 1); UINT_PTR stackptr = ((UINT_PTR) (&ch->stack)); ch->want_stack=1; if (!ch->stack) ch->stack = newDataBlock(NSEEL_STACK_SIZE*sizeof(EEL_F),NSEEL_STACK_SIZE*sizeof(EEL_F)); data=EEL_GLUE_set_immediate(data, stackptr); data=EEL_GLUE_set_immediate(data, m1); // and data=EEL_GLUE_set_immediate(data, ((UINT_PTR)ch->stack&~m1)); //or } return data; } static void *NSEEL_PProc_Stack_PeekInt(void *data, int data_size, compileContext *ctx, INT_PTR offs) { codeHandleType *ch=ctx->tmpCodeHandle; if (data_size>0) { UINT_PTR m1=(UINT_PTR)(NSEEL_STACK_SIZE * sizeof(EEL_F) - 1); UINT_PTR stackptr = ((UINT_PTR) (&ch->stack)); ch->want_stack=1; if (!ch->stack) ch->stack = newDataBlock(NSEEL_STACK_SIZE*sizeof(EEL_F),NSEEL_STACK_SIZE*sizeof(EEL_F)); data=EEL_GLUE_set_immediate(data, stackptr); data=EEL_GLUE_set_immediate(data, offs); data=EEL_GLUE_set_immediate(data, m1); // and data=EEL_GLUE_set_immediate(data, ((UINT_PTR)ch->stack&~m1)); //or } return data; } static void *NSEEL_PProc_Stack_PeekTop(void *data, int data_size, compileContext *ctx) { codeHandleType *ch=ctx->tmpCodeHandle; if (data_size>0) { UINT_PTR stackptr = ((UINT_PTR) (&ch->stack)); ch->want_stack=1; if (!ch->stack) ch->stack = newDataBlock(NSEEL_STACK_SIZE*sizeof(EEL_F),NSEEL_STACK_SIZE*sizeof(EEL_F)); data=EEL_GLUE_set_immediate(data, stackptr); } return data; } #if defined(_MSC_VER) && _MSC_VER >= 1400 static double __floor(double a) { return floor(a); } static double __ceil(double a) { return ceil(a); } #define floor __floor #define ceil __ceil #endif #ifdef NSEEL_EEL1_COMPAT_MODE static double eel1band(double a, double b) { return (fabs(a)>NSEEL_CLOSEFACTOR && fabs(b) > NSEEL_CLOSEFACTOR) ? 1.0 : 0.0; } static double eel1bor(double a, double b) { return (fabs(a)>NSEEL_CLOSEFACTOR || fabs(b) > NSEEL_CLOSEFACTOR) ? 1.0 : 0.0; } static double eel1sigmoid(double x, double constraint) { double t = (1+exp(-x * (constraint))); return fabs(t)>NSEEL_CLOSEFACTOR ? 1.0/t : 0; } #endif #define FUNCTIONTYPE_PARAMETERCOUNTMASK 0xff #define BIF_NPARAMS_MASK 0x7ffff00 #define BIF_RETURNSONSTACK 0x0000100 #define BIF_LASTPARMONSTACK 0x0000200 #define BIF_RETURNSBOOL 0x0000400 #define BIF_LASTPARM_ASBOOL 0x0000800 // 0x00?0000 -- taken by FP stack flags #define BIF_TAKES_VARPARM 0x0400000 #define BIF_TAKES_VARPARM_EX 0x0C00000 // this is like varparm but check count exactly #define BIF_WONTMAKEDENORMAL 0x0100000 #define BIF_CLEARDENORMAL 0x0200000 #if defined(GLUE_HAS_FXCH) && GLUE_MAX_FPSTACK_SIZE > 0 #define BIF_SECONDLASTPARMST 0x0001000 // use with BIF_LASTPARMONSTACK only (last two parameters get passed on fp stack) #define BIF_LAZYPARMORDERING 0x0002000 // allow optimizer to avoid fxch when using BIF_TWOPARMSONFPSTACK_LAZY etc #define BIF_REVERSEFPORDER 0x0004000 // force a fxch (reverse order of last two parameters on fp stack, used by comparison functions) #ifndef BIF_FPSTACKUSE #define BIF_FPSTACKUSE(x) (((x)>=0&&(x)<8) ? ((7-(x))<<16):0) #endif #ifndef BIF_GETFPSTACKUSE #define BIF_GETFPSTACKUSE(x) (7 - (((x)>>16)&7)) #endif #else // do not support fp stack use unless GLUE_HAS_FXCH and GLUE_MAX_FPSTACK_SIZE>0 #define BIF_SECONDLASTPARMST 0 #define BIF_LAZYPARMORDERING 0 #define BIF_REVERSEFPORDER 0 #define BIF_FPSTACKUSE(x) 0 #define BIF_GETFPSTACKUSE(x) 0 #endif #define BIF_TWOPARMSONFPSTACK (BIF_SECONDLASTPARMST|BIF_LASTPARMONSTACK) #define BIF_TWOPARMSONFPSTACK_LAZY (BIF_LAZYPARMORDERING|BIF_SECONDLASTPARMST|BIF_LASTPARMONSTACK) #ifndef GLUE_HAS_NATIVE_TRIGSQRTLOG static double sqrt_fabs(double a) { return sqrt(fabs(a)); } #endif EEL_F NSEEL_CGEN_CALL nseel_int_rand(EEL_F f); #define FNPTR_HAS_CONDITIONAL_EXEC(op) \ (op->fntype == FN_LOGICAL_AND || \ op->fntype == FN_LOGICAL_OR || \ op->fntype == FN_IF_ELSE || \ op->fntype == FN_WHILE || \ op->fntype == FN_LOOP) static functionType fnTable1[] = { #ifndef GLUE_HAS_NATIVE_TRIGSQRTLOG { "sin", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_WONTMAKEDENORMAL, {&sin} }, { "cos", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_CLEARDENORMAL, {&cos} }, { "tan", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&tan} }, { "sqrt", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_WONTMAKEDENORMAL, {&sqrt_fabs}, }, { "log", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&log} }, { "log10", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&log10} }, #else { "sin", nseel_asm_sin,nseel_asm_sin_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_WONTMAKEDENORMAL|BIF_FPSTACKUSE(1) }, { "cos", nseel_asm_cos,nseel_asm_cos_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_CLEARDENORMAL|BIF_FPSTACKUSE(1) }, { "tan", nseel_asm_tan,nseel_asm_tan_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }, { "sqrt", nseel_asm_sqrt,nseel_asm_sqrt_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1)|BIF_WONTMAKEDENORMAL }, { "log", nseel_asm_log,nseel_asm_log_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(3), }, { "log10", nseel_asm_log10,nseel_asm_log10_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(3), }, #endif { "asin", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&asin}, }, { "acos", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&acos}, }, { "atan", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&atan}, }, { "atan2", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK, {&atan2}, }, { "exp", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&exp}, }, { "abs", nseel_asm_abs,nseel_asm_abs_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(0)|BIF_WONTMAKEDENORMAL }, { "sqr", nseel_asm_sqr,nseel_asm_sqr_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }, { "min", nseel_asm_min,nseel_asm_min_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_FPSTACKUSE(3)|BIF_WONTMAKEDENORMAL }, { "max", nseel_asm_max,nseel_asm_max_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_FPSTACKUSE(3)|BIF_WONTMAKEDENORMAL }, { "sign", nseel_asm_sign,nseel_asm_sign_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL, }, { "rand", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_CLEARDENORMAL, {&nseel_int_rand}, }, { "floor", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_CLEARDENORMAL, {&floor} }, { "ceil", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_CLEARDENORMAL, {&ceil} }, { "invsqrt", nseel_asm_invsqrt,nseel_asm_invsqrt_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(3), {GLUE_INVSQRT_NEEDREPL} }, { "__dbg_getstackptr", nseel_asm_dbg_getstackptr,nseel_asm_dbg_getstackptr_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1), }, #ifdef NSEEL_EEL1_COMPAT_MODE { "sigmoid", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK, {&eel1sigmoid}, }, // these differ from _and/_or, they always evaluate both... { "band", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_CLEARDENORMAL , {&eel1band}, }, { "bor", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_CLEARDENORMAL , {&eel1bor}, }, {"exec2",nseel_asm_exec2,nseel_asm_exec2_end,2|NSEEL_NPARAMS_FLAG_CONST|BIF_WONTMAKEDENORMAL}, {"exec3",nseel_asm_exec2,nseel_asm_exec2_end,3|NSEEL_NPARAMS_FLAG_CONST|BIF_WONTMAKEDENORMAL}, #endif // end EEL1 compat {"freembuf",_asm_generic1parm,_asm_generic1parm_end,1,{&__NSEEL_RAM_MemFree},NSEEL_PProc_RAM}, {"memcpy",_asm_generic3parm,_asm_generic3parm_end,3,{&__NSEEL_RAM_MemCpy},NSEEL_PProc_RAM}, {"memset",_asm_generic3parm,_asm_generic3parm_end,3,{&__NSEEL_RAM_MemSet},NSEEL_PProc_RAM}, {"__memtop",_asm_generic1parm,_asm_generic1parm_end,1,{&__NSEEL_RAM_MemTop},NSEEL_PProc_RAM}, {"mem_set_values",_asm_generic2parm_retd,_asm_generic2parm_retd_end,2|BIF_TAKES_VARPARM|BIF_RETURNSONSTACK,{&__NSEEL_RAM_Mem_SetValues},NSEEL_PProc_RAM}, {"mem_get_values",_asm_generic2parm_retd,_asm_generic2parm_retd_end,2|BIF_TAKES_VARPARM|BIF_RETURNSONSTACK,{&__NSEEL_RAM_Mem_GetValues},NSEEL_PProc_RAM}, {"stack_push",nseel_asm_stack_push,nseel_asm_stack_push_end,1|BIF_FPSTACKUSE(0),{0,},NSEEL_PProc_Stack}, {"stack_pop",nseel_asm_stack_pop,nseel_asm_stack_pop_end,1|BIF_FPSTACKUSE(1),{0,},NSEEL_PProc_Stack}, {"stack_peek",nseel_asm_stack_peek,nseel_asm_stack_peek_end,1|NSEEL_NPARAMS_FLAG_CONST|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(0),{0,},NSEEL_PProc_Stack}, {"stack_exch",nseel_asm_stack_exch,nseel_asm_stack_exch_end,1|BIF_FPSTACKUSE(1), {0,},NSEEL_PProc_Stack_PeekTop}, }; static eel_function_table default_user_funcs; functionType *nseel_getFunctionFromTableEx(compileContext *ctx, int idx) { eel_function_table *tab = ctx && ctx->registered_func_tab ? ctx->registered_func_tab : &default_user_funcs; if (idx<0) return 0; if (idx>=sizeof(fnTable1)/sizeof(fnTable1[0])) { idx -= sizeof(fnTable1)/sizeof(fnTable1[0]); if (!tab->list || idx >= tab->list_size) return 0; return tab->list+idx; } return fnTable1+idx; } functionType *nseel_getFunctionFromTable(int idx) { return nseel_getFunctionFromTableEx(NULL, idx); } int NSEEL_init() // returns 0 on success { #ifdef EEL_VALIDATE_FSTUBS int a; for (a=0;a < sizeof(fnTable1)/sizeof(fnTable1[0]);a++) { char *code_startaddr = (char*)fnTable1[a].afunc; char *endp = (char *)fnTable1[a].func_e; // validate int sz=0; char *f=(char *)GLUE_realAddress(code_startaddr,endp,&sz); if (f+sz > endp) { #ifdef _WIN32 OutputDebugString("bad eel function stub\n"); #else printf("bad eel function stub\n"); #endif *(char *)NULL = 0; } } #ifdef _WIN32 OutputDebugString("eel function stub (builtin) validation complete\n"); #else printf("eel function stub (builtin) validation complete\n"); #endif #endif NSEEL_quit(); return 0; } void NSEEL_quit() { free(default_user_funcs.list); default_user_funcs.list = NULL; default_user_funcs.list_size = 0; } void NSEEL_addfunc_varparm_ex(const char *name, int min_np, int want_exact, NSEEL_PPPROC pproc, EEL_F (NSEEL_CGEN_CALL *fptr)(void *, INT_PTR, EEL_F **), eel_function_table *destination) { const int sz = (int) ((char *)_asm_generic2parm_retd_end-(char *)_asm_generic2parm_retd); NSEEL_addfunctionex2(name,min_np|(want_exact?BIF_TAKES_VARPARM_EX:BIF_TAKES_VARPARM),(char *)_asm_generic2parm_retd,sz,pproc,fptr,NULL,destination); } void NSEEL_addfunc_ret_type(const char *name, int np, int ret_type, NSEEL_PPPROC pproc, void *fptr, eel_function_table *destination) // ret_type=-1 for bool, 1 for value, 0 for ptr { char *stub=NULL; int stubsz=0; #define DOSTUB(np) { \ stub = (ret_type == 1 ? (char*)_asm_generic##np##parm_retd : (char*)_asm_generic##np##parm); \ stubsz = (int) ((ret_type == 1 ? (char*)_asm_generic##np##parm_retd_end : (char *)_asm_generic##np##parm_end) - stub); \ } if (np == 1) DOSTUB(1) else if (np == 2) DOSTUB(2) else if (np == 3) DOSTUB(3) #undef DOSTUB if (stub) NSEEL_addfunctionex2(name,np|(ret_type == -1 ? BIF_RETURNSBOOL:0), stub, stubsz, pproc,fptr,NULL,destination); } void NSEEL_addfunctionex2(const char *name, int nparms, char *code_startaddr, int code_len, NSEEL_PPPROC pproc, void *fptr, void *fptr2, eel_function_table *destination) { functionType *r; if (!destination) destination = &default_user_funcs; if (!destination->list || !(destination->list_size & 15)) { void *nv = realloc(destination->list, (destination->list_size + 16)*sizeof(functionType)); if (!nv) return; destination->list = (functionType *)nv; } if (destination->list) { #ifdef EEL_VALIDATE_FSTUBS { char *endp = code_startaddr+code_len; // validate int sz=0; char *f=(char *)GLUE_realAddress(code_startaddr,endp,&sz); if (f+sz > endp) { #ifdef _WIN32 OutputDebugString("bad eel function stub\n"); #else printf("bad eel function stub\n"); #endif *(char *)NULL = 0; } #ifdef _WIN32 OutputDebugString(name); OutputDebugString(" - validated eel function stub\n"); #else printf("eel function stub validation complete for %s\n",name); #endif } #endif r = &destination->list[destination->list_size++]; memset(r, 0, sizeof(functionType)); if (!(nparms & BIF_RETURNSBOOL)) { if (code_startaddr == (void *)&_asm_generic1parm_retd || code_startaddr == (void *)&_asm_generic2parm_retd || code_startaddr == (void *)&_asm_generic3parm_retd) { nparms |= BIF_RETURNSONSTACK; } } r->nParams = nparms; r->name = name; r->afunc = code_startaddr; r->func_e = code_startaddr + code_len; r->pProc = pproc; r->replptrs[0] = fptr; r->replptrs[1] = fptr2; } } //--------------------------------------------------------------------------------------------------------------- static void freeBlocks(llBlock **start) { llBlock *s=*start; *start=0; while (s) { llBlock *llB = s->next; free(s); s=llB; } } //--------------------------------------------------------------------------------------------------------------- static void *__newBlock(llBlock **start, int size, int wantMprotect) { #if !defined(EEL_DOESNT_NEED_EXEC_PERMS) && defined(_WIN32) DWORD ov; UINT_PTR offs,eoffs; #endif llBlock *llb; int alloc_size; if (*start && (LLB_DSIZE - (*start)->sizeused) >= size) { void *t=(*start)->block+(*start)->sizeused; (*start)->sizeused+=(size+7)&~7; return t; } alloc_size=sizeof(llBlock); if ((int)size > LLB_DSIZE) alloc_size += size - LLB_DSIZE; llb = (llBlock *)malloc(alloc_size); // grab bigger block if absolutely necessary (heh) if (!llb) return NULL; #ifndef EEL_DOESNT_NEED_EXEC_PERMS if (wantMprotect) { #ifdef _WIN32 offs=((UINT_PTR)llb)&~4095; eoffs=((UINT_PTR)llb + alloc_size + 4095)&~4095; VirtualProtect((LPVOID)offs,eoffs-offs,PAGE_EXECUTE_READWRITE,&ov); // MessageBox(NULL,"vprotecting, yay\n","a",0); #elif defined(EEL_USE_MPROTECT) { static int pagesize = 0; if (!pagesize) { pagesize=sysconf(_SC_PAGESIZE); if (!pagesize) pagesize=4096; } uintptr_t offs,eoffs; offs=((uintptr_t)llb)&~(pagesize-1); eoffs=((uintptr_t)llb + alloc_size + pagesize-1)&~(pagesize-1); mprotect((void*)offs,eoffs-offs,PROT_WRITE|PROT_READ|PROT_EXEC); } #endif } #endif llb->sizeused=(size+7)&~7; llb->next = *start; *start = llb; return llb->block; } //--------------------------------------------------------------------------------------------------------------- opcodeRec *nseel_createCompiledValue(compileContext *ctx, EEL_F value) { opcodeRec *r=newOpCode(ctx,NULL,OPCODETYPE_DIRECTVALUE); if (r) { r->parms.dv.directValue = value; } return r; } opcodeRec *nseel_createCompiledValuePtr(compileContext *ctx, EEL_F *addrValue, const char *namestr) { opcodeRec *r=newOpCode(ctx,namestr,OPCODETYPE_VARPTR); if (!r) return 0; r->parms.dv.valuePtr=addrValue; return r; } static int validate_varname_for_function(compileContext *ctx, const char *name) { if (!ctx->function_curName || !ctx->function_globalFlag) return 1; if (ctx->function_localTable_Size[2] > 0 && ctx->function_localTable_Names[2]) { char * const * const namelist = ctx->function_localTable_Names[2]; const int namelist_sz = ctx->function_localTable_Size[2]; int i; const size_t name_len = strlen(name); for (i=0;i 1 && nmchk[l-1] == '*') { if (name_len >= l && !strnicmp(nmchk,name,l-1) && name[l-1]=='.') return 1; } else { if (name_len == l && !stricmp(nmchk,name)) return 1; } } } return 0; } opcodeRec *nseel_resolve_named_symbol(compileContext *ctx, opcodeRec *rec, int parmcnt, int *errOut) { const int isFunctionMode = parmcnt >= 0; int rel_prefix_len=0; int rel_prefix_idx=-2; int i; char match_parmcnt[4]={-1,-1,-1,-1}; // [3] is guess unsigned char match_parmcnt_pos=0; char *sname = (char *)rec->relname; int is_string_prefix = parmcnt < 0 && sname[0] == '#'; const char *prevent_function_calls = NULL; if (errOut) *errOut = 0; if (sname) sname += is_string_prefix; if (rec->opcodeType != OPCODETYPE_VARPTR || !sname || !sname[0]) return NULL; if (!isFunctionMode && !is_string_prefix && !strnicmp(sname,"reg",3) && isdigit(sname[3]) && isdigit(sname[4]) && !sname[5]) { EEL_F *a=get_global_var(ctx,sname,1); if (a) { rec->parms.dv.valuePtr = a; sname[0]=0; // for dump_ops compat really, but this shouldn't be needed anyway } return rec; } if (ctx->function_curName) { if (!strnicmp(sname,"this.",5)) { rel_prefix_len=5; rel_prefix_idx=-1; } else if (!stricmp(sname,"this")) { rel_prefix_len=4; rel_prefix_idx=-1; } // scan for parameters/local variables before user functions if (rel_prefix_idx < -1 && ctx->function_localTable_Size[0] > 0 && ctx->function_localTable_Names[0] && ctx->function_localTable_ValuePtrs) { char * const * const namelist = ctx->function_localTable_Names[0]; const int namelist_sz = ctx->function_localTable_Size[0]; for (i=0; i < namelist_sz; i++) { const char *p = namelist[i]; if (p) { if (!isFunctionMode && !is_string_prefix && !strnicmp(p,sname,NSEEL_MAX_VARIABLE_NAMELEN)) { rec->opcodeType = OPCODETYPE_VARPTRPTR; rec->parms.dv.valuePtr=(EEL_F *)(ctx->function_localTable_ValuePtrs+i); rec->parms.dv.directValue=0.0; return rec; } else { const size_t plen = strlen(p); if (plen > 1 && p[plen-1] == '*' && !strnicmp(p,sname,plen-1) && ((sname[plen-1] == '.'&&sname[plen]) || !sname[plen-1])) { rel_prefix_len=(int) (sname[plen-1] ? plen : plen-1); rel_prefix_idx=i; break; } } } } } // if instance name set, translate sname or sname.* into "this.sname.*" if (rel_prefix_idx < -1 && ctx->function_localTable_Size[1] > 0 && ctx->function_localTable_Names[1]) { char * const * const namelist = ctx->function_localTable_Names[1]; const int namelist_sz = ctx->function_localTable_Size[1]; const char *full_sname = rec->relname; // include # in checks for (i=0; i < namelist_sz; i++) { const char *p = namelist[i]; if (p && *p) { const size_t tl = strlen(p); if (!strnicmp(p,full_sname,tl) && (full_sname[tl] == 0 || full_sname[tl] == '.')) { rel_prefix_len=0; // treat as though this. prefixes is present rel_prefix_idx=-1; break; } } } } if (rel_prefix_idx >= -1) { ctx->function_usesNamespaces=1; } } // ctx->function_curName if (!isFunctionMode) { // instance variables if (rel_prefix_idx >= -1) { rec->opcodeType = OPCODETYPE_VALUE_FROM_NAMESPACENAME; rec->namespaceidx = rel_prefix_idx; if (rel_prefix_len > 0) { if (is_string_prefix) sname[-1] = '#'; memmove(sname, sname+rel_prefix_len, strlen(sname + rel_prefix_len) + 1); } } else { // no namespace index, so it must be a global if (!validate_varname_for_function(ctx,rec->relname)) { if (errOut) *errOut = 1; if (ctx->last_error_string[0]) lstrcatn(ctx->last_error_string, ", ", sizeof(ctx->last_error_string)); snprintf_append(ctx->last_error_string,sizeof(ctx->last_error_string),"global '%s' inaccessible",rec->relname); return NULL; } } return rec; } if (ctx->func_check) prevent_function_calls = ctx->func_check(sname,ctx->func_check_user); ////////// function mode // first off, while() and loop() are special and can't be overridden // if (parmcnt == 1 && !stricmp("while",sname) && !prevent_function_calls) { rec->opcodeType = OPCODETYPE_FUNC1; rec->fntype = FN_WHILE; return rec; } if (parmcnt == 2 && !stricmp("loop",sname) && !prevent_function_calls) { rec->opcodeType = OPCODETYPE_FUNC2; rec->fntype = FN_LOOP; return rec; } // // resolve user function names before builtin functions -- this allows the user to override default functions { _codeHandleFunctionRec *best=NULL; size_t bestlen=0; const char * const ourcall = sname+rel_prefix_len; const size_t ourcall_len = strlen(ourcall); int pass; for (pass=0;pass<2;pass++) { _codeHandleFunctionRec *fr = pass ? ctx->functions_common : ctx->functions_local; // sname is [namespace.[ns.]]function, find best match of function that matches the right end while (fr) { int this_np = fr->num_params; const char *thisfunc = fr->fname; const size_t thisfunc_len = strlen(thisfunc); if (this_np < 1) this_np=1; if (thisfunc_len == ourcall_len && !stricmp(thisfunc,ourcall)) { if (this_np == parmcnt) { bestlen = thisfunc_len; best = fr; break; // found exact match, finished } else { if (match_parmcnt_pos < 3) match_parmcnt[match_parmcnt_pos++] = fr->num_params; } } if (thisfunc_len > bestlen && thisfunc_len < ourcall_len && ourcall[ourcall_len - thisfunc_len - 1] == '.' && !stricmp(thisfunc,ourcall + ourcall_len - thisfunc_len)) { if (this_np == parmcnt) { bestlen = thisfunc_len; best = fr; } else if (match_parmcnt[3]<0) match_parmcnt[3]=fr->num_params; } fr=fr->next; } if (fr) break; // found exact match, finished } if (best) { switch (parmcnt) { case 0: case 1: rec->opcodeType = OPCODETYPE_FUNC1; break; case 2: rec->opcodeType = OPCODETYPE_FUNC2; break; case 3: rec->opcodeType = OPCODETYPE_FUNC3; break; default: rec->opcodeType = OPCODETYPE_FUNCX; break; } if (ourcall != rec->relname) memmove((char *)rec->relname, ourcall, strlen(ourcall)+1); if (ctx->function_curName && rel_prefix_idx<0) { // if no namespace specified, and this.commonprefix.func() called, remove common prefixes and set prefixidx to be this const char *p=ctx->function_curName; if (*p) p++; while (*p && *p != '.') p++; if (*p && p[1]) // we have a dot! { while (p[1]) p++; // go to last char of string, which doesn't allow possible trailing dot to be checked while (--p > ctx->function_curName) // do not check possible leading dot { if (*p == '.') { const size_t cmplen = p+1-ctx->function_curName; if (!strnicmp(rec->relname,ctx->function_curName,cmplen) && rec->relname[cmplen]) { const char *src=rec->relname + cmplen; memmove((char *)rec->relname, src, strlen(src)+1); rel_prefix_idx=-1; ctx->function_usesNamespaces=1; break; } } } } } if (ctx->function_curName && rel_prefix_idx < -1 && strchr(rec->relname,'.') && !validate_varname_for_function(ctx,rec->relname)) { if (errOut) *errOut = 1; if (ctx->last_error_string[0]) lstrcatn(ctx->last_error_string, ", ", sizeof(ctx->last_error_string)); snprintf_append(ctx->last_error_string,sizeof(ctx->last_error_string),"namespaced function '%s' inaccessible",rec->relname); return NULL; } rec->namespaceidx = rel_prefix_idx; rec->fntype = FUNCTYPE_EELFUNC; rec->fn = best; return rec; } } if (prevent_function_calls) { if (ctx->last_error_string[0]) lstrcatn(ctx->last_error_string, ", ", sizeof(ctx->last_error_string)); snprintf_append(ctx->last_error_string,sizeof(ctx->last_error_string),"'%.30s': %s",sname, prevent_function_calls); if (errOut) *errOut = 0; return NULL; } #ifdef NSEEL_EEL1_COMPAT_MODE if (!stricmp(sname,"assign")) { if (parmcnt == 2) { rec->opcodeType = OPCODETYPE_FUNC2; rec->fntype = FN_ASSIGN; return rec; } if (match_parmcnt_pos < 3) match_parmcnt[match_parmcnt_pos++] = 2; } else if (!stricmp(sname,"if")) { if (parmcnt == 3) { rec->opcodeType = OPCODETYPE_FUNC3; rec->fntype = FN_IF_ELSE; return rec; } if (match_parmcnt_pos < 3) match_parmcnt[match_parmcnt_pos++] = 3; } else if (!stricmp(sname,"equal")) { if (parmcnt == 2) { rec->opcodeType = OPCODETYPE_FUNC2; rec->fntype = FN_EQ; return rec; } if (match_parmcnt_pos < 3) match_parmcnt[match_parmcnt_pos++] = 2; } else if (!stricmp(sname,"below")) { if (parmcnt == 2) { rec->opcodeType = OPCODETYPE_FUNC2; rec->fntype = FN_LT; return rec; } if (match_parmcnt_pos < 3) match_parmcnt[match_parmcnt_pos++] = 2; } else if (!stricmp(sname,"above")) { if (parmcnt == 2) { rec->opcodeType = OPCODETYPE_FUNC2; rec->fntype = FN_GT; return rec; } if (match_parmcnt_pos < 3) match_parmcnt[match_parmcnt_pos++] = 2; } else if (!stricmp(sname,"bnot")) { if (parmcnt == 1) { rec->opcodeType = OPCODETYPE_FUNC1; rec->fntype = FN_NOT; return rec; } if (match_parmcnt_pos < 3) match_parmcnt[match_parmcnt_pos++] = 1; } else if (!stricmp(sname,"megabuf")) { if (parmcnt == 1) { rec->opcodeType = OPCODETYPE_FUNC1; rec->fntype = FN_MEMORY; return rec; } if (match_parmcnt_pos < 3) match_parmcnt[match_parmcnt_pos++] = 1; } else if (!stricmp(sname,"gmegabuf")) { if (parmcnt == 1) { rec->opcodeType = OPCODETYPE_FUNC1; rec->fntype = FN_GMEMORY; return rec; } if (match_parmcnt_pos < 3) match_parmcnt[match_parmcnt_pos++] = 1; } else #endif // convert legacy pow() to FN_POW if (!stricmp("pow",sname)) { if (parmcnt == 2) { rec->opcodeType = OPCODETYPE_FUNC2; rec->fntype = FN_POW; return rec; } if (match_parmcnt_pos < 3) match_parmcnt[match_parmcnt_pos++] = 2; } else if (!stricmp("__denormal_likely",sname) || !stricmp("__denormal_unlikely",sname)) { if (parmcnt == 1) { rec->opcodeType = OPCODETYPE_FUNC1; rec->fntype = !stricmp("__denormal_likely",sname) ? FN_DENORMAL_LIKELY : FN_DENORMAL_UNLIKELY; return rec; } } for (i=0;nseel_getFunctionFromTableEx(ctx,i);i++) { functionType *f=nseel_getFunctionFromTableEx(ctx,i); if (!stricmp(f->name, sname)) { const int pc_needed=(f->nParams&FUNCTIONTYPE_PARAMETERCOUNTMASK); if ((f->nParams&BIF_TAKES_VARPARM_EX)==BIF_TAKES_VARPARM ? (parmcnt >= pc_needed) : (parmcnt == pc_needed)) { rec->fntype = FUNCTYPE_FUNCTIONTYPEREC; rec->fn = (void *)f; switch (parmcnt) { case 0: case 1: rec->opcodeType = OPCODETYPE_FUNC1; break; case 2: rec->opcodeType = OPCODETYPE_FUNC2; break; case 3: rec->opcodeType = OPCODETYPE_FUNC3; break; default: rec->opcodeType = OPCODETYPE_FUNCX; break; } return rec; } if (match_parmcnt_pos < 3) match_parmcnt[match_parmcnt_pos++] = (f->nParams&FUNCTIONTYPE_PARAMETERCOUNTMASK); } } if (ctx->last_error_string[0]) lstrcatn(ctx->last_error_string, ", ", sizeof(ctx->last_error_string)); if (match_parmcnt[3] >= 0) { if (match_parmcnt_pos<3) match_parmcnt[match_parmcnt_pos] = match_parmcnt[3]; match_parmcnt_pos++; } if (!match_parmcnt_pos) snprintf_append(ctx->last_error_string,sizeof(ctx->last_error_string),"'%.30s' undefined",sname); else { int x; snprintf_append(ctx->last_error_string,sizeof(ctx->last_error_string),"'%.30s' needs ",sname); for (x = 0; x < match_parmcnt_pos; x++) snprintf_append(ctx->last_error_string,sizeof(ctx->last_error_string),"%s%d",x==0?"" : x == match_parmcnt_pos-1?" or ":",",match_parmcnt[x]); lstrcatn(ctx->last_error_string," parms",sizeof(ctx->last_error_string)); } if (errOut) *errOut = match_parmcnt_pos > 0 ? parmcntopcodeType != OPCODETYPE_VARPTR || !fn->relname || !fn->relname[0]) { return NULL; } fn->parms.parms[0] = code1; fn->parms.parms[1] = code2; fn->parms.parms[2] = code3; for (x=0;x<3;x++) { opcodeRec *prni=fn->parms.parms[x]; while (prni && np < NSEEL_MAX_EELFUNC_PARAMETERS) { const int isMP = prni->opcodeType == OPCODETYPE_MOREPARAMS; np++; if (!isMP) break; prni = prni->parms.parms[1]; } } r = nseel_resolve_named_symbol(ctx, fn, np<1 ? 1 : np ,errOut); if (postCode && r) { if (code1 && r->opcodeType == OPCODETYPE_FUNC1 && r->fntype == FN_WHILE) { // change while(x) (postcode) to be // while ((x) ? (postcode;1) : 0); r->parms.parms[0] = nseel_createIfElse(ctx,r->parms.parms[0], nseel_createSimpleCompiledFunction(ctx,FN_JOIN_STATEMENTS,2,postCode,nseel_createCompiledValue(ctx,1.0f)), NULL); // NULL defaults to 0.0 } else { snprintf_append(ctx->last_error_string,sizeof(ctx->last_error_string),"syntax error following function"); *errOut = -1; return NULL; } } return r; } struct eelStringSegmentRec *nseel_createStringSegmentRec(compileContext *ctx, const char *str, int len) { struct eelStringSegmentRec *r = newTmpBlock(ctx,sizeof(struct eelStringSegmentRec)); if (r) { r->_next=0; r->str_start=str; r->str_len = len; } return r; } opcodeRec *nseel_eelMakeOpcodeFromStringSegments(compileContext *ctx, struct eelStringSegmentRec *rec) { if (ctx && ctx->onString) { return nseel_createCompiledValue(ctx, ctx->onString(ctx->caller_this,rec)); } return NULL; } opcodeRec *nseel_createMoreParametersOpcode(compileContext *ctx, opcodeRec *code1, opcodeRec *code2) { opcodeRec *r=code1 && code2 ? newOpCode(ctx,NULL,OPCODETYPE_MOREPARAMS) : NULL; if (r) { r->parms.parms[0] = code1; r->parms.parms[1] = code2; } return r; } opcodeRec *nseel_createIfElse(compileContext *ctx, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3) { opcodeRec *r=code1 ? newOpCode(ctx,NULL,OPCODETYPE_FUNC3) : NULL; if (r) { if (!code2) code2 = nseel_createCompiledValue(ctx,0.0); if (!code3) code3 = nseel_createCompiledValue(ctx,0.0); if (!code2||!code3) return NULL; r->fntype = FN_IF_ELSE; r->parms.parms[0] = code1; r->parms.parms[1] = code2; r->parms.parms[2] = code3; } return r; } opcodeRec *nseel_createMemoryAccess(compileContext *ctx, opcodeRec *code1, opcodeRec *code2) { if (code1 && code1->opcodeType == OPCODETYPE_VARPTR && !stricmp(code1->relname,"gmem")) { return nseel_createSimpleCompiledFunction(ctx, FN_GMEMORY,1,code2?code2:nseel_createCompiledValue(ctx,0.0),0); } if (code2 && (code2->opcodeType != OPCODETYPE_DIRECTVALUE || code2->parms.dv.directValue != 0.0)) { code1 = nseel_createSimpleCompiledFunction(ctx,FN_ADD,2,code1,code2); } return nseel_createSimpleCompiledFunction(ctx, FN_MEMORY,1,code1,0); } opcodeRec *nseel_createSimpleCompiledFunction(compileContext *ctx, int fn, int np, opcodeRec *code1, opcodeRec *code2) { opcodeRec *r=code1 && (np<2 || code2) ? newOpCode(ctx,NULL,np>=2 ? OPCODETYPE_FUNC2:OPCODETYPE_FUNC1) : NULL; if (r) { r->fntype = fn; r->parms.parms[0] = code1; r->parms.parms[1] = code2; if (fn == FN_JOIN_STATEMENTS) { r->fn = r; // for joins, fn is temporarily used for tail pointers if (code1 && code1->opcodeType == OPCODETYPE_FUNC2 && code1->fntype == fn) { opcodeRec *t = (opcodeRec *)code1->fn; // keep joins in the form of dosomething->morestuff. // in this instance, code1 is previous stuff to do, code2 is new stuff to do r->parms.parms[0] = t->parms.parms[1]; code1->fn = (t->parms.parms[1] = r); return code1; } } } return r; } // these are bitmasks; on request you can tell what is supported, and compileOpcodes will return one of them #define RETURNVALUE_IGNORE 0 // ignore return value #define RETURNVALUE_NORMAL 1 // pointer #define RETURNVALUE_FPSTACK 2 #define RETURNVALUE_BOOL 4 // P1 is nonzero if true #define RETURNVALUE_BOOL_REVERSED 8 // P1 is zero if true static int compileOpcodes(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTable, const namespaceInformation *namespacePathToThis, int supportedReturnValues, int *rvType, int *fpStackUsage, int *canHaveDenormalOutput); static unsigned char *compileCodeBlockWithRet(compileContext *ctx, opcodeRec *rec, int *computTableSize, const namespaceInformation *namespacePathToThis, int supportedReturnValues, int *rvType, int *fpStackUse, int *canHaveDenormalOutput); _codeHandleFunctionRec *eel_createFunctionNamespacedInstance(compileContext *ctx, _codeHandleFunctionRec *fr, const char *nameptr) { size_t n; _codeHandleFunctionRec *subfr = fr->isCommonFunction ? ctx->isSharedFunctions ? newDataBlock(sizeof(_codeHandleFunctionRec),8) : newCtxDataBlock(sizeof(_codeHandleFunctionRec),8) : // if common function, but derived version is in non-common context, set ownership to VM rather than us newTmpBlock(ctx,sizeof(_codeHandleFunctionRec)); if (!subfr) return 0; // fr points to functionname()'s rec, nameptr to blah.functionname() *subfr = *fr; n = strlen(nameptr); if (n > sizeof(subfr->fname)-1) n=sizeof(subfr->fname)-1; memcpy(subfr->fname,nameptr,n); subfr->fname[n]=0; subfr->next = NULL; subfr->startptr=0; // make sure this code gets recompiled (with correct member ptrs) for this instance! // subfr->derivedCopies already points to the right place fr->derivedCopies = subfr; return subfr; } static void combineNamespaceFields(char *nm, const namespaceInformation *namespaceInfo, const char *relname, int thisctx) // nm must be NSEEL_MAX_VARIABLE_NAMELEN+1 bytes { const char *prefix = namespaceInfo ? thisctx<0 ? (thisctx == -1 ? namespaceInfo->namespacePathToThis : NULL) : (thisctx < MAX_SUB_NAMESPACES ? namespaceInfo->subParmInfo[thisctx] : NULL) : NULL; int lfp = 0, lrn=relname ? (int)strlen(relname) : 0; if (prefix) while (prefix[lfp] && prefix[lfp] != ':' && lfp < NSEEL_MAX_VARIABLE_NAMELEN) lfp++; if (!relname) relname = ""; while (*relname == '.') // if relname begins with ., then remove a chunk of context from prefix { relname++; while (lfp>0 && prefix[lfp-1] != '.') lfp--; if (lfp>0) lfp--; } if (lfp > NSEEL_MAX_VARIABLE_NAMELEN-3) lfp=NSEEL_MAX_VARIABLE_NAMELEN-3; if (lfp>0) memcpy(nm,prefix,lfp); if (lrn > NSEEL_MAX_VARIABLE_NAMELEN - lfp - (lfp>0)) lrn=NSEEL_MAX_VARIABLE_NAMELEN - lfp - (lfp>0); if (lrn > 0) { if (lfp>0) nm[lfp++] = '.'; memcpy(nm+lfp,relname,lrn); lfp+=lrn; } nm[lfp++]=0; } //--------------------------------------------------------------------------------------------------------------- static void *nseel_getBuiltinFunctionAddress(compileContext *ctx, int fntype, void *fn, NSEEL_PPPROC *pProc, void ***replList, void **endP, int *abiInfo, int preferredReturnValues, const EEL_F *hasConstParm1, const EEL_F *hasConstParm2) { const EEL_F *firstConstParm = hasConstParm1 ? hasConstParm1 : hasConstParm2; static void *pow_replptrs[4]={&pow,}; switch (fntype) { #define RF(x) *endP = nseel_asm_##x##_end; return (void*)nseel_asm_##x case FN_MUL_OP: *abiInfo=BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(mul_op); case FN_DIV_OP: *abiInfo=BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(div_op); case FN_OR_OP: *abiInfo=BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(or_op); case FN_XOR_OP: *abiInfo=BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(xor_op); case FN_AND_OP: *abiInfo=BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(and_op); case FN_MOD_OP: *abiInfo=BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(mod_op); case FN_ADD_OP: *abiInfo=BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(add_op); case FN_SUB_OP: *abiInfo=BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(sub_op); case FN_POW_OP: *abiInfo=BIF_LASTPARMONSTACK|BIF_CLEARDENORMAL; *replList = pow_replptrs; RF(2pdds); case FN_POW: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK;//BIF_FPSTACKUSE(2) might be safe, need to look at pow()'s implementation, but safer bet is to disallow fp stack caching for this expression *replList = pow_replptrs; RF(2pdd); case FN_ADD: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_WONTMAKEDENORMAL; // for x +- non-denormal-constant, we can set BIF_CLEARDENORMAL if (firstConstParm && fabs(*firstConstParm) > 1.0e-10) *abiInfo |= BIF_CLEARDENORMAL; RF(add); case FN_SUB: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(2)|BIF_WONTMAKEDENORMAL; // for x +- non-denormal-constant, we can set BIF_CLEARDENORMAL if (firstConstParm && fabs(*firstConstParm) > 1.0e-10) *abiInfo |= BIF_CLEARDENORMAL; RF(sub); case FN_MULTIPLY: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2); // for x*constant-greater-than-eq-1, we can set BIF_WONTMAKEDENORMAL if (firstConstParm && fabs(*firstConstParm) >= 1.0) *abiInfo |= BIF_WONTMAKEDENORMAL; RF(mul); case FN_DIVIDE: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(2); // for x/constant-less-than-eq-1, we can set BIF_WONTMAKEDENORMAL if (firstConstParm && fabs(*firstConstParm) <= 1.0) *abiInfo |= BIF_WONTMAKEDENORMAL; RF(div); case FN_MOD: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(1)|BIF_CLEARDENORMAL; RF(mod); case FN_ASSIGN: *abiInfo = BIF_FPSTACKUSE(1)|BIF_CLEARDENORMAL; RF(assign); case FN_AND: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(and); case FN_OR: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(or); case FN_XOR: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(xor); case FN_SHR: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(shr); case FN_SHL: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(shl); #ifndef EEL_TARGET_PORTABLE case FN_NOTNOT: *abiInfo = BIF_LASTPARM_ASBOOL|BIF_RETURNSBOOL|BIF_FPSTACKUSE(1); RF(uplus); #else case FN_NOTNOT: *abiInfo = BIF_LASTPARM_ASBOOL|BIF_RETURNSBOOL|BIF_FPSTACKUSE(1); RF(bnotnot); #endif case FN_UMINUS: *abiInfo = BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_WONTMAKEDENORMAL; RF(uminus); case FN_NOT: *abiInfo = BIF_LASTPARM_ASBOOL|BIF_RETURNSBOOL|BIF_FPSTACKUSE(1); RF(bnot); case FN_EQ: *abiInfo = BIF_TWOPARMSONFPSTACK_LAZY|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2); RF(equal); case FN_EQ_EXACT: *abiInfo=BIF_TWOPARMSONFPSTACK_LAZY|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2); RF(equal_exact); case FN_NE: *abiInfo=BIF_TWOPARMSONFPSTACK_LAZY|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2); RF(notequal); case FN_NE_EXACT: *abiInfo=BIF_TWOPARMSONFPSTACK_LAZY|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2); RF(notequal_exact); case FN_LOGICAL_AND: *abiInfo = BIF_RETURNSBOOL; RF(band); case FN_LOGICAL_OR: *abiInfo = BIF_RETURNSBOOL; RF(bor); #ifdef GLUE_HAS_FXCH case FN_GT: *abiInfo = BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2); RF(above); case FN_GTE: *abiInfo = BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL|BIF_REVERSEFPORDER|BIF_FPSTACKUSE(2); RF(beloweq); case FN_LT: *abiInfo = BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL|BIF_REVERSEFPORDER|BIF_FPSTACKUSE(2); RF(above); case FN_LTE: *abiInfo = BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2); RF(beloweq); #else case FN_GT: *abiInfo = BIF_RETURNSBOOL|BIF_LASTPARMONSTACK; RF(above); case FN_GTE: *abiInfo = BIF_RETURNSBOOL|BIF_LASTPARMONSTACK; RF(aboveeq); case FN_LT: *abiInfo = BIF_RETURNSBOOL|BIF_LASTPARMONSTACK; RF(below); case FN_LTE: *abiInfo = BIF_RETURNSBOOL|BIF_LASTPARMONSTACK; RF(beloweq); #endif #undef RF #define RF(x) *endP = _asm_##x##_end; return (void*)_asm_##x case FN_MEMORY: { static void *replptrs[4]={&__NSEEL_RAMAlloc,}; *replList = replptrs; *abiInfo = BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1)|BIF_CLEARDENORMAL; #ifdef GLUE_MEM_NEEDS_PPROC *pProc = NSEEL_PProc_RAM; #endif RF(megabuf); } break; case FN_GMEMORY: { static void *replptrs[4]={&__NSEEL_RAMAllocGMEM,}; *replList = replptrs; *abiInfo=BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1)|BIF_CLEARDENORMAL; *pProc=NSEEL_PProc_GRAM; RF(gmegabuf); } break; #undef RF case FUNCTYPE_FUNCTIONTYPEREC: if (fn) { functionType *p=(functionType *)fn; // if prefers fpstack or bool, or ignoring value, then use fp-stack versions if ((preferredReturnValues&(RETURNVALUE_BOOL|RETURNVALUE_FPSTACK)) || !preferredReturnValues) { static functionType min2={ "min", nseel_asm_min_fp,nseel_asm_min_fp_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_WONTMAKEDENORMAL }; static functionType max2={ "max", nseel_asm_max_fp,nseel_asm_max_fp_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_WONTMAKEDENORMAL }; if (p->afunc == (void*)nseel_asm_min) p = &min2; else if (p->afunc == (void*)nseel_asm_max) p = &max2; } *replList=p->replptrs; *pProc=p->pProc; *endP = p->func_e; *abiInfo = p->nParams & BIF_NPARAMS_MASK; if (firstConstParm) { const char *name=p->name; if (!strcmp(name,"min") && *firstConstParm < -1.0e-10) *abiInfo |= BIF_CLEARDENORMAL; else if (!strcmp(name,"max") && *firstConstParm > 1.0e-10) *abiInfo |= BIF_CLEARDENORMAL; } return p->afunc; } break; } return 0; } static void *nseel_getEELFunctionAddress(compileContext *ctx, opcodeRec *op, int *customFuncParmSize, int *customFuncLocalStorageSize, EEL_F ***customFuncLocalStorage, int *computTableTop, void **endP, int *isRaw, int wantCodeGenerated, const namespaceInformation *namespacePathToThis, int *rvMode, int *fpStackUse, int *canHaveDenormalOutput, opcodeRec **ordered_parmptrs, int num_ordered_parmptrs ) // if wantCodeGenerated is false, can return bogus pointers in raw mode { _codeHandleFunctionRec *fn = (_codeHandleFunctionRec*)op->fn; namespaceInformation local_namespace={NULL}; char prefix_buf[NSEEL_MAX_VARIABLE_NAMELEN+1], nm[NSEEL_MAX_FUNCSIG_NAME+1]; if (!fn) return NULL; // op->relname ptr is [whatever.]funcname if (fn->parameterAsNamespaceMask || fn->usesNamespaces) { if (wantCodeGenerated) { char *p = prefix_buf; combineNamespaceFields(nm,namespacePathToThis,op->relname,op->namespaceidx); lstrcpyn_safe(prefix_buf,nm,sizeof(prefix_buf)); local_namespace.namespacePathToThis = prefix_buf; // nm is full path of function, prefix_buf will be the path not including function name (unless function name only) while (*p) p++; while (p >= prefix_buf && *p != '.') p--; if (p > prefix_buf) *p=0; } if (fn->parameterAsNamespaceMask) { int x; for(x=0;xnum_params;x++) { if (fn->parameterAsNamespaceMask & (((unsigned int)1)<opcodeType == OPCODETYPE_VARPTR) { rn=ordered_parmptrs[x]->relname; } else if (ordered_parmptrs[x]->opcodeType == OPCODETYPE_VALUE_FROM_NAMESPACENAME) { const char *p=ordered_parmptrs[x]->relname; if (*p == '#') p++; combineNamespaceFields(tmp,namespacePathToThis,p,ordered_parmptrs[x]->namespaceidx); rn = tmp; } } if (!rn) { // todo: figure out how to give correct line number/offset (ugh) snprintf(ctx->last_error_string,sizeof(ctx->last_error_string),"parameter %d to %s() must be namespace",x+1,fn->fname); return NULL; } lstrcatn(nm,":",sizeof(nm)); local_namespace.subParmInfo[x] = nm+strlen(nm); lstrcatn(nm,rn,sizeof(nm)); } ordered_parmptrs[x] = NULL; // prevent caller from bothering generating parameters } } } if (wantCodeGenerated) { _codeHandleFunctionRec *fr = fn; // find namespace-adjusted function (if generating code, otherwise assume size is the same) fn = 0; // if this gets re-set, it will be the new function while (fr && !fn) { if (!stricmp(fr->fname,nm)) fn = fr; fr=fr->derivedCopies; } if (!fn) // generate copy of function { fn = eel_createFunctionNamespacedInstance(ctx,(_codeHandleFunctionRec*)op->fn,nm); } } } if (!fn) return NULL; if (!fn->startptr && fn->opcodes && fn->startptr_size > 0) { int sz; fn->tmpspace_req=0; fn->rvMode = RETURNVALUE_IGNORE; fn->canHaveDenormalOutput=0; sz=compileOpcodes(ctx,fn->opcodes,NULL,128*1024*1024,&fn->tmpspace_req,wantCodeGenerated ? &local_namespace : NULL,RETURNVALUE_NORMAL|RETURNVALUE_FPSTACK,&fn->rvMode,&fn->fpStackUsage,&fn->canHaveDenormalOutput); if (!wantCodeGenerated) { // don't compile anything for now, just give stats if (computTableTop) *computTableTop += fn->tmpspace_req; *customFuncParmSize = fn->num_params; *customFuncLocalStorage = fn->localstorage; *customFuncLocalStorageSize = fn->localstorage_size; *rvMode = fn->rvMode; *fpStackUse = fn->fpStackUsage; if (canHaveDenormalOutput) *canHaveDenormalOutput=fn->canHaveDenormalOutput; if (sz <= NSEEL_MAX_FUNCTION_SIZE_FOR_INLINE && !(ctx->optimizeDisableFlags&OPTFLAG_NO_INLINEFUNC)) { *isRaw = 1; *endP = ((char *)1) + sz; return (char *)1; } *endP = (void*)nseel_asm_fcall_end; return (void*)nseel_asm_fcall; } if (sz <= NSEEL_MAX_FUNCTION_SIZE_FOR_INLINE && !(ctx->optimizeDisableFlags&OPTFLAG_NO_INLINEFUNC)) { void *p=newTmpBlock(ctx,sz); fn->tmpspace_req=0; if (p) { fn->canHaveDenormalOutput=0; if (fn->isCommonFunction) ctx->isGeneratingCommonFunction++; sz=compileOpcodes(ctx,fn->opcodes,(unsigned char*)p,sz,&fn->tmpspace_req,&local_namespace,RETURNVALUE_NORMAL|RETURNVALUE_FPSTACK,&fn->rvMode,&fn->fpStackUsage,&fn->canHaveDenormalOutput); if (fn->isCommonFunction) ctx->isGeneratingCommonFunction--; // recompile function with native context pointers if (sz>0) { fn->startptr_size=sz; fn->startptr=p; } } } else { unsigned char *codeCall; fn->tmpspace_req=0; fn->fpStackUsage=0; fn->canHaveDenormalOutput=0; if (fn->isCommonFunction) ctx->isGeneratingCommonFunction++; codeCall=compileCodeBlockWithRet(ctx,fn->opcodes,&fn->tmpspace_req,&local_namespace,RETURNVALUE_NORMAL|RETURNVALUE_FPSTACK,&fn->rvMode,&fn->fpStackUsage,&fn->canHaveDenormalOutput); if (fn->isCommonFunction) ctx->isGeneratingCommonFunction--; if (codeCall) { void *f=GLUE_realAddress(nseel_asm_fcall,nseel_asm_fcall_end,&sz); fn->startptr = newTmpBlock(ctx,sz); if (fn->startptr) { memcpy(fn->startptr,f,sz); EEL_GLUE_set_immediate(fn->startptr,(INT_PTR)codeCall); fn->startptr_size = sz; } } } } if (fn->startptr) { if (computTableTop) *computTableTop += fn->tmpspace_req; *customFuncParmSize = fn->num_params; *customFuncLocalStorage = fn->localstorage; *customFuncLocalStorageSize = fn->localstorage_size; *rvMode = fn->rvMode; *fpStackUse = fn->fpStackUsage; if (canHaveDenormalOutput) *canHaveDenormalOutput= fn->canHaveDenormalOutput; *endP = (char*)fn->startptr + fn->startptr_size; *isRaw=1; return fn->startptr; } return 0; } // returns true if does something (other than calculating and throwing away a value) static char optimizeOpcodes(compileContext *ctx, opcodeRec *op, int needsResult) { opcodeRec *lastJoinOp=NULL; char retv, retv_parm[3], joined_retv=0; while (op && op->opcodeType == OPCODETYPE_FUNC2 && op->fntype == FN_JOIN_STATEMENTS) { if (!optimizeOpcodes(ctx,op->parms.parms[0], 0) || OPCODE_IS_TRIVIAL(op->parms.parms[0])) { // direct value, can skip ourselves memcpy(op,op->parms.parms[1],sizeof(*op)); } else { joined_retv |= 1; lastJoinOp = op; op = op->parms.parms[1]; } } goto start_over; #define RESTART_DIRECTVALUE(X) { op->parms.dv.directValue = (X); goto start_over_directvalue; } start_over_directvalue: op->opcodeType = OPCODETYPE_DIRECTVALUE; op->parms.dv.valuePtr=NULL; start_over: // when an opcode changed substantially in optimization, goto here to reprocess it retv = retv_parm[0]=retv_parm[1]=retv_parm[2]=0; if (!op || // should never really happen OPCODE_IS_TRIVIAL(op) || // should happen often (vars) op->opcodeType < 0 || op->opcodeType >= OPCODETYPE_INVALID // should never happen (assert would be appropriate heh) ) return joined_retv; if (!needsResult) { if (op->fntype == FUNCTYPE_EELFUNC) { needsResult=1; // assume eel functions are non-const for now } else if (op->fntype == FUNCTYPE_FUNCTIONTYPEREC) { functionType *pfn = (functionType *)op->fn; if (!pfn || !(pfn->nParams&NSEEL_NPARAMS_FLAG_CONST)) needsResult=1; } else if (op->fntype >= FN_NONCONST_BEGIN && op->fntype < FUNCTYPE_SIMPLEMAX) { needsResult=1; } } if (op->opcodeType>=OPCODETYPE_FUNC2) retv_parm[1] = optimizeOpcodes(ctx,op->parms.parms[1], needsResult); if (op->opcodeType>=OPCODETYPE_FUNC3) retv_parm[2] = optimizeOpcodes(ctx,op->parms.parms[2], needsResult); retv_parm[0] = optimizeOpcodes(ctx,op->parms.parms[0], needsResult || (FNPTR_HAS_CONDITIONAL_EXEC(op) && (retv_parm[1] || retv_parm[2] || op->opcodeType <= OPCODETYPE_FUNC1)) ); if (op->opcodeType != OPCODETYPE_MOREPARAMS) { if (op->fntype >= 0 && op->fntype < FUNCTYPE_SIMPLEMAX) { if (op->opcodeType == OPCODETYPE_FUNC1) // within FUNCTYPE_SIMPLE { if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE) { switch (op->fntype) { case FN_NOTNOT: RESTART_DIRECTVALUE(fabs(op->parms.parms[0]->parms.dv.directValue)>=NSEEL_CLOSEFACTOR ? 1.0 : 0.0); case FN_NOT: RESTART_DIRECTVALUE(fabs(op->parms.parms[0]->parms.dv.directValue)>=NSEEL_CLOSEFACTOR ? 0.0 : 1.0); case FN_UMINUS: RESTART_DIRECTVALUE(- op->parms.parms[0]->parms.dv.directValue); } } else if (op->fntype == FN_NOT || op->fntype == FN_NOTNOT) { if (op->parms.parms[0]->opcodeType == OPCODETYPE_FUNC1) { switch (op->parms.parms[0]->fntype) { case FN_UMINUS: case FN_NOTNOT: // ignore any NOTNOTs UMINUS or UPLUS, they would have no effect anyway op->parms.parms[0] = op->parms.parms[0]->parms.parms[0]; goto start_over; case FN_NOT: op->fntype = op->fntype==FN_NOT ? FN_NOTNOT : FN_NOT; // switch between FN_NOT and FN_NOTNOT op->parms.parms[0] = op->parms.parms[0]->parms.parms[0]; goto start_over; } } else if (op->parms.parms[0]->opcodeType == OPCODETYPE_FUNC2) { int repl_type = -1; switch (op->parms.parms[0]->fntype) { case FN_EQ: repl_type = FN_NE; break; case FN_NE: repl_type = FN_EQ; break; case FN_EQ_EXACT: repl_type = FN_NE_EXACT; break; case FN_NE_EXACT: repl_type = FN_EQ_EXACT; break; case FN_LT: repl_type = FN_GTE; break; case FN_LTE: repl_type = FN_GT; break; case FN_GT: repl_type = FN_LTE; break; case FN_GTE: repl_type = FN_LT; break; } if (repl_type != -1) { const int oldtype = op->fntype; memcpy(op,op->parms.parms[0],sizeof(*op)); if (oldtype == FN_NOT) op->fntype = repl_type; goto start_over; } } } } else if (op->opcodeType == OPCODETYPE_FUNC2) // within FUNCTYPE_SIMPLE { const int dv0 = op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE; const int dv1 = op->parms.parms[1]->opcodeType == OPCODETYPE_DIRECTVALUE; if (dv0 && dv1) { int reval = -1; switch (op->fntype) { case FN_MOD: { int a = (int) op->parms.parms[1]->parms.dv.directValue; if (a) { a = (int) op->parms.parms[0]->parms.dv.directValue % a; if (a<0) a=-a; } RESTART_DIRECTVALUE((EEL_F)a); } break; case FN_SHL: RESTART_DIRECTVALUE(((int)op->parms.parms[0]->parms.dv.directValue) << ((int)op->parms.parms[1]->parms.dv.directValue)); case FN_SHR: RESTART_DIRECTVALUE(((int)op->parms.parms[0]->parms.dv.directValue) >> ((int)op->parms.parms[1]->parms.dv.directValue)); case FN_POW: RESTART_DIRECTVALUE(pow(op->parms.parms[0]->parms.dv.directValue, op->parms.parms[1]->parms.dv.directValue)); case FN_DIVIDE: RESTART_DIRECTVALUE(op->parms.parms[0]->parms.dv.directValue / op->parms.parms[1]->parms.dv.directValue); case FN_MULTIPLY: RESTART_DIRECTVALUE(op->parms.parms[0]->parms.dv.directValue * op->parms.parms[1]->parms.dv.directValue); case FN_ADD: RESTART_DIRECTVALUE(op->parms.parms[0]->parms.dv.directValue + op->parms.parms[1]->parms.dv.directValue); case FN_SUB: RESTART_DIRECTVALUE(op->parms.parms[0]->parms.dv.directValue - op->parms.parms[1]->parms.dv.directValue); case FN_AND: RESTART_DIRECTVALUE((double) (((WDL_INT64)op->parms.parms[0]->parms.dv.directValue) & ((WDL_INT64)op->parms.parms[1]->parms.dv.directValue))); case FN_OR: RESTART_DIRECTVALUE((double) (((WDL_INT64)op->parms.parms[0]->parms.dv.directValue) | ((WDL_INT64)op->parms.parms[1]->parms.dv.directValue))); case FN_XOR: RESTART_DIRECTVALUE((double) (((WDL_INT64)op->parms.parms[0]->parms.dv.directValue) ^ ((WDL_INT64)op->parms.parms[1]->parms.dv.directValue))); case FN_EQ: reval = fabs(op->parms.parms[0]->parms.dv.directValue - op->parms.parms[1]->parms.dv.directValue) < NSEEL_CLOSEFACTOR; break; case FN_NE: reval = fabs(op->parms.parms[0]->parms.dv.directValue - op->parms.parms[1]->parms.dv.directValue) >= NSEEL_CLOSEFACTOR; break; case FN_EQ_EXACT: reval = op->parms.parms[0]->parms.dv.directValue == op->parms.parms[1]->parms.dv.directValue; break; case FN_NE_EXACT: reval = op->parms.parms[0]->parms.dv.directValue != op->parms.parms[1]->parms.dv.directValue; break; case FN_LT: reval = op->parms.parms[0]->parms.dv.directValue < op->parms.parms[1]->parms.dv.directValue; break; case FN_LTE: reval = op->parms.parms[0]->parms.dv.directValue <= op->parms.parms[1]->parms.dv.directValue; break; case FN_GT: reval = op->parms.parms[0]->parms.dv.directValue > op->parms.parms[1]->parms.dv.directValue; break; case FN_GTE: reval = op->parms.parms[0]->parms.dv.directValue >= op->parms.parms[1]->parms.dv.directValue; break; case FN_LOGICAL_AND: reval = fabs(op->parms.parms[0]->parms.dv.directValue) >= NSEEL_CLOSEFACTOR && fabs(op->parms.parms[1]->parms.dv.directValue) >= NSEEL_CLOSEFACTOR; break; case FN_LOGICAL_OR: reval = fabs(op->parms.parms[0]->parms.dv.directValue) >= NSEEL_CLOSEFACTOR || fabs(op->parms.parms[1]->parms.dv.directValue) >= NSEEL_CLOSEFACTOR; break; } if (reval >= 0) RESTART_DIRECTVALUE((EEL_F) reval); } else if (dv0 || dv1) { double dvalue = op->parms.parms[!dv0]->parms.dv.directValue; switch (op->fntype) { case FN_OR: case FN_XOR: if (!(WDL_INT64)dvalue) { // replace with or0 static functionType fr={"or0",nseel_asm_or0, nseel_asm_or0_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_LASTPARMONSTACK|BIF_RETURNSONSTACK|BIF_CLEARDENORMAL, {0}, NULL}; op->opcodeType = OPCODETYPE_FUNC1; op->fntype = FUNCTYPE_FUNCTIONTYPEREC; op->fn = &fr; if (dv0) op->parms.parms[0] = op->parms.parms[1]; goto start_over; } break; case FN_SUB: if (dv0) { if (dvalue == 0.0) { op->opcodeType = OPCODETYPE_FUNC1; op->fntype = FN_UMINUS; op->parms.parms[0] = op->parms.parms[1]; goto start_over; } break; } // fall through, if dv1 we can remove +0.0 case FN_ADD: if (dvalue == 0.0) { memcpy(op,op->parms.parms[!!dv0],sizeof(*op)); goto start_over; } break; case FN_AND: if ((WDL_INT64)dvalue) break; dvalue = 0.0; // treat x&0 as x*0, which optimizes to 0 // fall through case FN_MULTIPLY: if (dvalue == 0.0) // remove multiply by 0.0 (using 0.0 direct value as replacement), unless the nonzero side did something { if (!retv_parm[!!dv0]) { memcpy(op,op->parms.parms[!dv0],sizeof(*op)); // set to 0 if other action wouldn't do anything goto start_over; } else { // this is 0.0 * oldexpressionthatmustbeprocessed or oldexpressionthatmustbeprocessed*0.0 op->fntype = FN_JOIN_STATEMENTS; if (dv0) // 0.0*oldexpression, reverse the order so that 0 is returned { // set to (oldexpression;0) opcodeRec *tmp = op->parms.parms[1]; op->parms.parms[1] = op->parms.parms[0]; op->parms.parms[0] = tmp; } goto start_over; } } else if (dvalue == 1.0) // remove multiply by 1.0 (using non-1.0 value as replacement) { memcpy(op,op->parms.parms[!!dv0],sizeof(*op)); goto start_over; } break; case FN_POW: if (dv1) { // x^0 = 1 if (fabs(dvalue) < 1e-30) { RESTART_DIRECTVALUE(1.0); } // x^1 = x if (fabs(dvalue-1.0) < 1e-30) { memcpy(op,op->parms.parms[0],sizeof(*op)); goto start_over; } } else if (dv0) { // pow(constant, x) = exp((x) * ln(constant)), if constant>0 // opcodeRec *parm0 = op->parms.parms[0]; if (dvalue > 0.0) { static functionType expcpy={ "exp", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&exp}, }; // 1^x = 1 if (fabs(dvalue-1.0) < 1e-30) { RESTART_DIRECTVALUE(1.0); } dvalue=log(dvalue); if (fabs(dvalue-1.0) < 1e-9) { // caller wanted e^x op->parms.parms[0]=op->parms.parms[1]; } else { // it would be nice to replace 10^x with exp(log(10)*x) or 2^x with exp(log(2),x), but // doing so breaks rounding. we could maybe only allow 10^x, which is used for dB conversion, // but for now we should just force the programmer do it exp(log(10)*x) themselves. break; /* parm0->opcodeType = OPCODETYPE_FUNC2; parm0->fntype = FN_MULTIPLY; parm0->parms.parms[0] = nseel_createCompiledValue(ctx,dvalue); parm0->parms.parms[1] = op->parms.parms[1]; */ } op->opcodeType = OPCODETYPE_FUNC1; op->fntype = FUNCTYPE_FUNCTIONTYPEREC; op->fn = &expcpy; goto start_over; } } break; case FN_MOD: if (dv1) { const int a = (int) dvalue; if (!a) { RESTART_DIRECTVALUE(0.0); } } break; case FN_DIVIDE: if (dv1) { if (dvalue == 1.0) // remove divide by 1.0 (using non-1.0 value as replacement) { memcpy(op,op->parms.parms[!!dv0],sizeof(*op)); goto start_over; } else { // change to a multiply if (dvalue == 0.0) { op->fntype = FN_MULTIPLY; goto start_over; } else { double d = 1.0/dvalue; WDL_DenormalDoubleAccess *p = (WDL_DenormalDoubleAccess*)&d; // allow conversion to multiply if reciprocal is exact // we could also just look to see if the last few digits of the mantissa were 0, which would probably be good // enough, but if the user really wants it they should do * (1/x) instead to force precalculation of reciprocal. if (!p->w.lw && !(p->w.hw & 0xfffff)) { op->fntype = FN_MULTIPLY; op->parms.parms[1]->parms.dv.directValue = d; op->parms.parms[1]->parms.dv.valuePtr=NULL; goto start_over; } } } } else if (dvalue == 0.0) { if (!retv_parm[!!dv0]) { // if 0/x set to always 0. // this is 0.0 / (oldexpression that can be eliminated) memcpy(op,op->parms.parms[!dv0],sizeof(*op)); // set to 0 if other action wouldn't do anything } else { opcodeRec *tmp; // this is 0.0 / oldexpressionthatmustbeprocessed op->fntype = FN_JOIN_STATEMENTS; tmp = op->parms.parms[1]; op->parms.parms[1] = op->parms.parms[0]; op->parms.parms[0] = tmp; // set to (oldexpression;0) } goto start_over; } break; case FN_EQ: if (dvalue == 0.0) { // convert x == 0.0 to !x op->opcodeType=OPCODETYPE_FUNC1; op->fntype = FN_NOT; if (dv0) op->parms.parms[0]=op->parms.parms[1]; goto start_over; } break; case FN_NE: if (dvalue == 0.0) { // convert x != 0.0 to !! op->opcodeType=OPCODETYPE_FUNC1; op->fntype = FN_NOTNOT; if (dv0) op->parms.parms[0]=op->parms.parms[1]; goto start_over; } break; case FN_LOGICAL_AND: if (dv0) { // dvalue && expr if (fabs(dvalue) < NSEEL_CLOSEFACTOR) { // 0 && expr, replace with 0 RESTART_DIRECTVALUE(0.0); } else { // 1 && expr, replace with 0 != expr op->fntype = FN_NE; op->parms.parms[0]->parms.dv.valuePtr=NULL; op->parms.parms[0]->parms.dv.directValue = 0.0; } } else { // expr && dvalue if (fabs(dvalue) < NSEEL_CLOSEFACTOR) { // expr && 0 if (!retv_parm[0]) { // expr has no consequence, drop it RESTART_DIRECTVALUE(0.0); } else { // replace with (expr; 0) op->fntype = FN_JOIN_STATEMENTS; op->parms.parms[1]->parms.dv.valuePtr=NULL; op->parms.parms[1]->parms.dv.directValue = 0.0; } } else { // expr && 1, replace with expr != 0 op->fntype = FN_NE; op->parms.parms[1]->parms.dv.valuePtr=NULL; op->parms.parms[1]->parms.dv.directValue = 0.0; } } goto start_over; case FN_LOGICAL_OR: if (dv0) { // dvalue || expr if (fabs(dvalue) >= NSEEL_CLOSEFACTOR) { // 1 || expr, replace with 1 RESTART_DIRECTVALUE(1.0); } else { // 0 || expr, replace with 0 != expr op->fntype = FN_NE; op->parms.parms[0]->parms.dv.valuePtr=NULL; op->parms.parms[0]->parms.dv.directValue = 0.0; } } else { // expr || dvalue if (fabs(dvalue) >= NSEEL_CLOSEFACTOR) { // expr || 1 if (!retv_parm[0]) { // expr has no consequence, drop it and return 1 RESTART_DIRECTVALUE(1.0); } else { // replace with (expr; 1) op->fntype = FN_JOIN_STATEMENTS; op->parms.parms[1]->parms.dv.valuePtr=NULL; op->parms.parms[1]->parms.dv.directValue = 1.0; } } else { // expr || 0, replace with expr != 0 op->fntype = FN_NE; op->parms.parms[1]->parms.dv.valuePtr=NULL; op->parms.parms[1]->parms.dv.directValue = 0.0; } } goto start_over; } } // dv0 || dv1 // general optimization of two parameters switch (op->fntype) { case FN_MULTIPLY: { opcodeRec *first_parm = op->parms.parms[0],*second_parm = op->parms.parms[1]; if (second_parm->opcodeType == first_parm->opcodeType) { switch(first_parm->opcodeType) { case OPCODETYPE_VALUE_FROM_NAMESPACENAME: if (first_parm->namespaceidx != second_parm->namespaceidx) break; // fall through case OPCODETYPE_VARPTR: if (first_parm->relname && second_parm->relname && !stricmp(second_parm->relname,first_parm->relname)) second_parm=NULL; break; case OPCODETYPE_VARPTRPTR: if (first_parm->parms.dv.valuePtr && first_parm->parms.dv.valuePtr==second_parm->parms.dv.valuePtr) second_parm=NULL; break; } if (!second_parm) // switch from x*x to sqr(x) { static functionType sqrcpy={ "sqr", nseel_asm_sqr,nseel_asm_sqr_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }; op->opcodeType = OPCODETYPE_FUNC1; op->fntype = FUNCTYPE_FUNCTIONTYPEREC; op->fn = &sqrcpy; goto start_over; } } } break; case FN_POW: { opcodeRec *first_parm = op->parms.parms[0]; if (first_parm->opcodeType == op->opcodeType && first_parm->fntype == FN_POW) { // since first_parm is a pow too, we can multiply the exponents. // set our base to be the base of the inner pow op->parms.parms[0] = first_parm->parms.parms[0]; // make the old extra pow be a multiply of the exponents first_parm->fntype = FN_MULTIPLY; first_parm->parms.parms[0] = op->parms.parms[1]; // put that as the exponent op->parms.parms[1] = first_parm; goto start_over; } } break; case FN_LOGICAL_AND: case FN_LOGICAL_OR: if (op->parms.parms[0]->fntype == FN_NOTNOT) { // remove notnot, unnecessary for input to &&/|| operators op->parms.parms[0] = op->parms.parms[0]->parms.parms[0]; goto start_over; } if (op->parms.parms[1]->fntype == FN_NOTNOT) { // remove notnot, unnecessary for input to &&/|| operators op->parms.parms[1] = op->parms.parms[1]->parms.parms[0]; goto start_over; } break; } } else if (op->opcodeType==OPCODETYPE_FUNC3) // within FUNCTYPE_SIMPLE { if (op->fntype == FN_IF_ELSE) { if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE) { int s = fabs(op->parms.parms[0]->parms.dv.directValue) >= NSEEL_CLOSEFACTOR; memcpy(op,op->parms.parms[s ? 1 : 2],sizeof(opcodeRec)); goto start_over; } if (op->parms.parms[0]->opcodeType == OPCODETYPE_FUNC1) { if (op->parms.parms[0]->fntype == FN_NOTNOT) { // remove notnot, unnecessary for input to ? operator op->parms.parms[0] = op->parms.parms[0]->parms.parms[0]; goto start_over; } } } } if (op->fntype >= FN_NONCONST_BEGIN && op->fntype < FUNCTYPE_SIMPLEMAX) retv|=1; // FUNCTYPE_SIMPLE } else if (op->fntype == FUNCTYPE_FUNCTIONTYPEREC && op->fn) { /* probably worth doing reduction on: _divop (constant change to multiply) _and _or abs maybe: min max also, optimize should (recursively or maybe iteratively?) search transitive functions (mul/div) for more constant reduction possibilities */ functionType *pfn = (functionType *)op->fn; if (!(pfn->nParams&NSEEL_NPARAMS_FLAG_CONST)) retv|=1; if (op->opcodeType==OPCODETYPE_FUNC1) // within FUNCTYPE_FUNCTIONTYPEREC { if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE) { int suc=1; EEL_F v = op->parms.parms[0]->parms.dv.directValue; #define DOF(x) if (!strcmp(pfn->name,#x)) v = x(v); else #define DOF2(x,y) if (!strcmp(pfn->name,#x)) v = x(y); else DOF(sin) DOF(cos) DOF(tan) DOF(asin) DOF(acos) DOF(atan) DOF2(sqrt, fabs(v)) DOF(exp) DOF(log) DOF(log10) /* else */ suc=0; #undef DOF #undef DOF2 if (suc) { RESTART_DIRECTVALUE(v); } } } else if (op->opcodeType==OPCODETYPE_FUNC2) // within FUNCTYPE_FUNCTIONTYPEREC { const int dv0=op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE; const int dv1=op->parms.parms[1]->opcodeType == OPCODETYPE_DIRECTVALUE; if (dv0 && dv1) { if (!strcmp(pfn->name,"atan2")) { RESTART_DIRECTVALUE(atan2(op->parms.parms[0]->parms.dv.directValue, op->parms.parms[1]->parms.dv.directValue)); } } } // FUNCTYPE_FUNCTIONTYPEREC } else { // unknown or eel func, assume non-const retv |= 1; } } // if we need results, or our function has effects itself, then finish if (retv || needsResult) { return retv || joined_retv || retv_parm[0] || retv_parm[1] || retv_parm[2]; } // we don't need results here, and our function is const, which means we can remove it { int cnt=0, idx1=0, idx2=0, x; for (x=0;x<3;x++) if (retv_parm[x]) { if (!cnt++) idx1=x; else idx2=x; } if (!cnt) // none of the parameters do anything, remove this opcode { if (lastJoinOp) { // replace previous join with its first linked opcode, removing this opcode completely memcpy(lastJoinOp,lastJoinOp->parms.parms[0],sizeof(*lastJoinOp)); } else if (op->opcodeType != OPCODETYPE_DIRECTVALUE) { // allow caller to easily detect this as trivial and remove it op->opcodeType = OPCODETYPE_DIRECTVALUE; op->parms.dv.valuePtr=NULL; op->parms.dv.directValue=0.0; } // return joined_retv below } else { // if parameters are non-const, and we're a conditional, preserve our function if (FNPTR_HAS_CONDITIONAL_EXEC(op)) return 1; // otherwise, condense into either the non-const statement, or a join if (cnt==1) { memcpy(op,op->parms.parms[idx1],sizeof(*op)); } else if (cnt == 2) { op->opcodeType = OPCODETYPE_FUNC2; op->fntype = FN_JOIN_STATEMENTS; op->fn = op; op->parms.parms[0] = op->parms.parms[idx1]; op->parms.parms[1] = op->parms.parms[idx2]; op->parms.parms[2] = NULL; } else { // todo need to create a new opcodeRec here, for now just leave as is // (non-conditional const 3 parameter functions are rare anyway) } return 1; } } return joined_retv; } static int generateValueToReg(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int whichReg, const namespaceInformation *functionPrefix, int allowCache) { EEL_F *b=NULL; if (op->opcodeType==OPCODETYPE_VALUE_FROM_NAMESPACENAME) { char nm[NSEEL_MAX_VARIABLE_NAMELEN+1]; const char *p = op->relname; combineNamespaceFields(nm,functionPrefix,p+(*p == '#'),op->namespaceidx); if (!nm[0]) return -1; if (*p == '#') { if (ctx->isGeneratingCommonFunction) b = newCtxDataBlock(sizeof(EEL_F),sizeof(EEL_F)); else b = newDataBlock(sizeof(EEL_F),sizeof(EEL_F)); if (!b) RET_MINUS1_FAIL("error creating storage for str") if (!ctx->onNamedString) return -1; // should never happen, will not generate OPCODETYPE_VALUE_FROM_NAMESPACENAME with # prefix if !onNamedString *b = ctx->onNamedString(ctx->caller_this,nm); } else { b = nseel_int_register_var(ctx,nm,0,NULL); if (!b) RET_MINUS1_FAIL("error registering var") } } else { if (op->opcodeType != OPCODETYPE_DIRECTVALUE) allowCache=0; if (op->opcodeType==OPCODETYPE_DIRECTVALUE_TEMPSTRING && ctx->onNamedString) { op->parms.dv.directValue = ctx->onNamedString(ctx->caller_this,""); op->parms.dv.valuePtr = NULL; } b=op->parms.dv.valuePtr; if (!b && op->opcodeType == OPCODETYPE_VARPTR && op->relname && op->relname[0]) { op->parms.dv.valuePtr = b = nseel_int_register_var(ctx,op->relname,0,NULL); } if (b && op->opcodeType == OPCODETYPE_VARPTRPTR) b = *(EEL_F **)b; if (!b && allowCache) { int n=50; // only scan last X items opcodeRec *r = ctx->directValueCache; while (r && n--) { if (r->parms.dv.directValue == op->parms.dv.directValue && (b=r->parms.dv.valuePtr)) break; r=(opcodeRec*)r->fn; } } if (!b) { ctx->l_stats[3]++; if (ctx->isGeneratingCommonFunction) b = newCtxDataBlock(sizeof(EEL_F),sizeof(EEL_F)); else b = newDataBlock(sizeof(EEL_F),sizeof(EEL_F)); if (!b) RET_MINUS1_FAIL("error allocating data block") if (op->opcodeType != OPCODETYPE_VARPTRPTR) op->parms.dv.valuePtr = b; #if EEL_F_SIZE == 8 *b = denormal_filter_double2(op->parms.dv.directValue); #else *b = denormal_filter_float2(op->parms.dv.directValue); #endif if (allowCache) { op->fn = ctx->directValueCache; ctx->directValueCache = op; } } } GLUE_MOV_PX_DIRECTVALUE_GEN(bufOut,(INT_PTR)b,whichReg); return GLUE_MOV_PX_DIRECTVALUE_SIZE; } unsigned char *compileCodeBlockWithRet(compileContext *ctx, opcodeRec *rec, int *computTableSize, const namespaceInformation *namespacePathToThis, int supportedReturnValues, int *rvType, int *fpStackUsage, int *canHaveDenormalOutput) { unsigned char *p, *newblock2; // generate code call int funcsz=compileOpcodes(ctx,rec,NULL,1024*1024*128,NULL,namespacePathToThis,supportedReturnValues, rvType,fpStackUsage, NULL); if (funcsz<0) return NULL; p = newblock2 = newCodeBlock(funcsz+ sizeof(GLUE_RET)+GLUE_FUNC_ENTER_SIZE+GLUE_FUNC_LEAVE_SIZE,32); if (!newblock2) return NULL; #if GLUE_FUNC_ENTER_SIZE > 0 memcpy(p,&GLUE_FUNC_ENTER,GLUE_FUNC_ENTER_SIZE); p += GLUE_FUNC_ENTER_SIZE; #endif *fpStackUsage=0; funcsz=compileOpcodes(ctx,rec,p, funcsz, computTableSize,namespacePathToThis,supportedReturnValues, rvType,fpStackUsage, canHaveDenormalOutput); if (funcsz<0) return NULL; p+=funcsz; #if GLUE_FUNC_LEAVE_SIZE > 0 memcpy(p,&GLUE_FUNC_LEAVE,GLUE_FUNC_LEAVE_SIZE); p+=GLUE_FUNC_LEAVE_SIZE; #endif memcpy(p,&GLUE_RET,sizeof(GLUE_RET)); p+=sizeof(GLUE_RET); #ifdef __arm__ __clear_cache(newblock2,p); #endif ctx->l_stats[2]+=funcsz+2; return newblock2; } static int compileNativeFunctionCall(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTableSize, const namespaceInformation *namespacePathToThis, int *rvMode, int *fpStackUsage, int preferredReturnValues, int *canHaveDenormalOutput) { // builtin function generation int func_size=0; int cfunc_abiinfo=0; int local_fpstack_use=0; // how many items we have pushed onto the fp stack int parm_size=0; int restore_stack_amt=0; void *func_e=NULL; NSEEL_PPPROC preProc=0; void **repl=NULL; int n_params= 1 + op->opcodeType - OPCODETYPE_FUNC1; const int parm0_dv = op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE; const int parm1_dv = n_params > 1 && op->parms.parms[1]->opcodeType == OPCODETYPE_DIRECTVALUE; void *func = nseel_getBuiltinFunctionAddress(ctx, op->fntype, op->fn, &preProc,&repl,&func_e,&cfunc_abiinfo,preferredReturnValues, parm0_dv ? &op->parms.parms[0]->parms.dv.directValue : NULL, parm1_dv ? &op->parms.parms[1]->parms.dv.directValue : NULL ); if (!func) RET_MINUS1_FAIL("error getting funcaddr") *fpStackUsage=BIF_GETFPSTACKUSE(cfunc_abiinfo); *rvMode = RETURNVALUE_NORMAL; if (cfunc_abiinfo & BIF_TAKES_VARPARM) { #if defined(__arm__) || defined(__ppc__) || (defined (_M_ARM) && _M_ARM == 7) const int max_params=4096; // 32kb max offset addressing for stack, so 4096*4 = 16384, should be safe #else const int max_params=32768; // sanity check, the stack is free to grow on x86/x86-64 #endif int x; // this mode is less efficient in that it creates a list of pointers on the stack to pass to the function // but it is more flexible and works for >3 parameters. if (op->opcodeType == OPCODETYPE_FUNCX) { n_params=0; for (x=0;x<3;x++) { opcodeRec *prni=op->parms.parms[x]; while (prni) { const int isMP = prni->opcodeType == OPCODETYPE_MOREPARAMS; n_params++; if (!isMP||n_params>=max_params) break; prni = prni->parms.parms[1]; } } } restore_stack_amt = (sizeof(void *) * n_params + 15)&~15; if (restore_stack_amt) { int offs = restore_stack_amt; while (offs > 0) { int amt = offs; if (amt > 4096) amt=4096; if (bufOut_len < parm_size+GLUE_MOVE_STACK_SIZE) RET_MINUS1_FAIL("insufficient size for varparm") if (bufOut) GLUE_MOVE_STACK(bufOut+parm_size, - amt); parm_size += GLUE_MOVE_STACK_SIZE; offs -= amt; if (offs>0) // make sure this page is in memory { if (bufOut_len < parm_size+GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE) RET_MINUS1_FAIL("insufficient size for varparm stackchk") if (bufOut) GLUE_STORE_P1_TO_STACK_AT_OFFS(bufOut+parm_size,0); parm_size += GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE; } } } if (op->opcodeType == OPCODETYPE_FUNCX) { n_params=0; for (x=0;x<3;x++) { opcodeRec *prni=op->parms.parms[x]; while (prni) { const int isMP = prni->opcodeType == OPCODETYPE_MOREPARAMS; opcodeRec *r = isMP ? prni->parms.parms[0] : prni; if (r) { int canHaveDenorm=0; int rvt=RETURNVALUE_NORMAL; int subfpstackuse=0; int lsz = compileOpcodes(ctx,r,bufOut ? bufOut + parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, rvt,&rvt, &subfpstackuse, &canHaveDenorm); if (canHaveDenorm && canHaveDenormalOutput) *canHaveDenormalOutput = 1; if (lsz<0) RET_MINUS1_FAIL("call coc for varparmX failed") if (rvt != RETURNVALUE_NORMAL) RET_MINUS1_FAIL("call coc for varparmX gave bad type back"); parm_size += lsz; if (bufOut_len < parm_size+GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE) RET_MINUS1_FAIL("call coc for varparmX size"); if (bufOut) GLUE_STORE_P1_TO_STACK_AT_OFFS(bufOut + parm_size, n_params*sizeof(void *)); parm_size+=GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE; if (subfpstackuse+local_fpstack_use > *fpStackUsage) *fpStackUsage = subfpstackuse+local_fpstack_use; } else RET_MINUS1_FAIL("zero parameter varparmX") n_params++; if (!isMP||n_params>=max_params) break; prni = prni->parms.parms[1]; } } } else for (x=0;xparms.parms[x]; if (r) { int canHaveDenorm=0; int subfpstackuse=0; int rvt=RETURNVALUE_NORMAL; int lsz = compileOpcodes(ctx,r,bufOut ? bufOut + parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, rvt,&rvt, &subfpstackuse, &canHaveDenorm); if (canHaveDenorm && canHaveDenormalOutput) *canHaveDenormalOutput = 1; if (lsz<0) RET_MINUS1_FAIL("call coc for varparm123 failed") if (rvt != RETURNVALUE_NORMAL) RET_MINUS1_FAIL("call coc for varparm123 gave bad type back"); parm_size += lsz; if (bufOut_len < parm_size+GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE) RET_MINUS1_FAIL("call coc for varparm123 size"); if (bufOut) GLUE_STORE_P1_TO_STACK_AT_OFFS(bufOut + parm_size, x*sizeof(void *)); parm_size+=GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE; if (subfpstackuse+local_fpstack_use > *fpStackUsage) *fpStackUsage = subfpstackuse+local_fpstack_use; } else RET_MINUS1_FAIL("zero parameter for varparm123"); } if (bufOut_len < parm_size+GLUE_MOV_PX_DIRECTVALUE_SIZE+GLUE_MOVE_PX_STACKPTR_SIZE) RET_MINUS1_FAIL("insufficient size for varparm p1") if (bufOut) GLUE_MOV_PX_DIRECTVALUE_GEN(bufOut+parm_size, (INT_PTR)n_params,1); parm_size+=GLUE_MOV_PX_DIRECTVALUE_SIZE; if (bufOut) GLUE_MOVE_PX_STACKPTR_GEN(bufOut+parm_size, 0); parm_size+=GLUE_MOVE_PX_STACKPTR_SIZE; } else // not varparm { int pn; #ifdef GLUE_HAS_FXCH int need_fxch=0; #endif int last_nt_parm=-1, last_nt_parm_type; if (op->opcodeType == OPCODETYPE_FUNCX) { // this is not yet supported (calling conventions will need to be sorted, among other things) RET_MINUS1_FAIL("funcx for native functions requires BIF_TAKES_VARPARM or BIF_TAKES_VARPARM_EX") } if (parm0_dv) { if (func == nseel_asm_stack_pop) { func = GLUE_realAddress(nseel_asm_stack_pop_fast,nseel_asm_stack_pop_fast_end,&func_size); if (!func || bufOut_len < func_size) RET_MINUS1_FAIL(func?"failed on popfast size":"failed on popfast addr") if (bufOut) { memcpy(bufOut,func,func_size); NSEEL_PProc_Stack(bufOut,func_size,ctx); } return func_size; } else if (func == nseel_asm_stack_peek) { int f = (int) op->parms.parms[0]->parms.dv.directValue; if (!f) { func = GLUE_realAddress(nseel_asm_stack_peek_top,nseel_asm_stack_peek_top_end,&func_size); if (!func || bufOut_len < func_size) RET_MINUS1_FAIL(func?"failed on peek size":"failed on peek addr") if (bufOut) { memcpy(bufOut,func,func_size); NSEEL_PProc_Stack_PeekTop(bufOut,func_size,ctx); } return func_size; } else { func = GLUE_realAddress(nseel_asm_stack_peek_int,nseel_asm_stack_peek_int_end,&func_size); if (!func || bufOut_len < func_size) RET_MINUS1_FAIL(func?"failed on peekint size":"failed on peekint addr") if (bufOut) { memcpy(bufOut,func,func_size); NSEEL_PProc_Stack_PeekInt(bufOut,func_size,ctx,f*sizeof(EEL_F)); } return func_size; } } } // end of built-in function specific special casing // first pass, calculate any non-trivial parameters for (pn=0; pn < n_params; pn++) { if (!OPCODE_IS_TRIVIAL(op->parms.parms[pn])) { int canHaveDenorm=0; int subfpstackuse=0; int lsz=0; int rvt=RETURNVALUE_NORMAL; int may_need_fppush=-1; if (last_nt_parm>=0) { if (last_nt_parm_type==RETURNVALUE_FPSTACK) { may_need_fppush= parm_size; } else { // push last result if (bufOut_len < parm_size + (int)sizeof(GLUE_PUSH_P1)) RET_MINUS1_FAIL("failed on size, pushp1") if (bufOut) memcpy(bufOut + parm_size, &GLUE_PUSH_P1, sizeof(GLUE_PUSH_P1)); parm_size += sizeof(GLUE_PUSH_P1); } } if (func == nseel_asm_bnot) rvt=RETURNVALUE_BOOL_REVERSED|RETURNVALUE_BOOL; else if (pn == n_params - 1) { if (cfunc_abiinfo&BIF_LASTPARMONSTACK) rvt=RETURNVALUE_FPSTACK; else if (cfunc_abiinfo&BIF_LASTPARM_ASBOOL) rvt=RETURNVALUE_BOOL; else if (func == nseel_asm_assign) rvt=RETURNVALUE_FPSTACK|RETURNVALUE_NORMAL; } else if (pn == n_params -2 && (cfunc_abiinfo&BIF_SECONDLASTPARMST)) { rvt=RETURNVALUE_FPSTACK; } lsz = compileOpcodes(ctx,op->parms.parms[pn],bufOut ? bufOut + parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, rvt,&rvt, &subfpstackuse, &canHaveDenorm); if (lsz<0) RET_MINUS1_FAIL("call coc failed") if (func == nseel_asm_bnot && rvt==RETURNVALUE_BOOL_REVERSED) { // remove bnot, compileOpcodes() used fptobool_rev #ifndef EEL_TARGET_PORTABLE func = nseel_asm_uplus; func_e = nseel_asm_uplus_end; #else func = nseel_asm_bnotnot; func_e = nseel_asm_bnotnot_end; #endif rvt = RETURNVALUE_BOOL; } if (canHaveDenorm && canHaveDenormalOutput) *canHaveDenormalOutput = 1; parm_size += lsz; if (may_need_fppush>=0) { if (local_fpstack_use+subfpstackuse >= (GLUE_MAX_FPSTACK_SIZE-1) || (ctx->optimizeDisableFlags&OPTFLAG_NO_FPSTACK)) { if (bufOut_len < parm_size + (int)sizeof(GLUE_POP_FPSTACK_TOSTACK)) RET_MINUS1_FAIL("failed on size, popfpstacktostack") if (bufOut) { memmove(bufOut + may_need_fppush + sizeof(GLUE_POP_FPSTACK_TOSTACK), bufOut + may_need_fppush, parm_size - may_need_fppush); memcpy(bufOut + may_need_fppush, &GLUE_POP_FPSTACK_TOSTACK, sizeof(GLUE_POP_FPSTACK_TOSTACK)); } parm_size += sizeof(GLUE_POP_FPSTACK_TOSTACK); } else { local_fpstack_use++; } } if (subfpstackuse+local_fpstack_use > *fpStackUsage) *fpStackUsage = subfpstackuse+local_fpstack_use; last_nt_parm = pn; last_nt_parm_type = rvt; if (pn == n_params - 1 && func == nseel_asm_assign) { if (!(ctx->optimizeDisableFlags & OPTFLAG_FULL_DENORMAL_CHECKS) && (!canHaveDenorm || (ctx->optimizeDisableFlags & OPTFLAG_NO_DENORMAL_CHECKS))) { if (rvt == RETURNVALUE_FPSTACK) { cfunc_abiinfo |= BIF_LASTPARMONSTACK; func = nseel_asm_assign_fast_fromfp; func_e = nseel_asm_assign_fast_fromfp_end; } else { func = nseel_asm_assign_fast; func_e = nseel_asm_assign_fast_end; } } else { if (rvt == RETURNVALUE_FPSTACK) { cfunc_abiinfo |= BIF_LASTPARMONSTACK; func = nseel_asm_assign_fromfp; func_e = nseel_asm_assign_fromfp_end; } } } } } pn = last_nt_parm; if (pn >= 0) // if the last thing executed doesn't go to the last parameter, move it there { if ((cfunc_abiinfo&BIF_SECONDLASTPARMST) && pn == n_params-2) { // do nothing, things are in the right place } else if (pn != n_params-1) { // generate mov p1->pX if (bufOut_len < parm_size + GLUE_SET_PX_FROM_P1_SIZE) RET_MINUS1_FAIL("size, pxfromp1") if (bufOut) GLUE_SET_PX_FROM_P1(bufOut + parm_size,n_params - 1 - pn); parm_size += GLUE_SET_PX_FROM_P1_SIZE; } } // pop any pushed parameters while (--pn >= 0) { if (!OPCODE_IS_TRIVIAL(op->parms.parms[pn])) { if ((cfunc_abiinfo&BIF_SECONDLASTPARMST) && pn == n_params-2) { if (!local_fpstack_use) { if (bufOut_len < parm_size + (int)sizeof(GLUE_POP_STACK_TO_FPSTACK)) RET_MINUS1_FAIL("size, popstacktofpstack 2") if (bufOut) memcpy(bufOut+parm_size,GLUE_POP_STACK_TO_FPSTACK,sizeof(GLUE_POP_STACK_TO_FPSTACK)); parm_size += sizeof(GLUE_POP_STACK_TO_FPSTACK); #ifdef GLUE_HAS_FXCH need_fxch = 1; #endif } else { local_fpstack_use--; } } else { if (bufOut_len < parm_size + GLUE_POP_PX_SIZE) RET_MINUS1_FAIL("size, poppx") if (bufOut) GLUE_POP_PX(bufOut + parm_size,n_params - 1 - pn); parm_size += GLUE_POP_PX_SIZE; } } } // finally, set trivial pointers for (pn=0; pn < n_params; pn++) { if (OPCODE_IS_TRIVIAL(op->parms.parms[pn])) { if (pn == n_params-2 && (cfunc_abiinfo&(BIF_SECONDLASTPARMST))) // second to last parameter { int a = compileOpcodes(ctx,op->parms.parms[pn],bufOut ? bufOut+parm_size : NULL,bufOut_len - parm_size,computTableSize,namespacePathToThis, RETURNVALUE_FPSTACK,NULL,NULL,canHaveDenormalOutput); if (a<0) RET_MINUS1_FAIL("coc call here 2") parm_size+=a; #ifdef GLUE_HAS_FXCH need_fxch = 1; #endif } else if (pn == n_params-1) // last parameter, but we should call compileOpcodes to get it in the right format (compileOpcodes can optimize that process if it needs to) { int rvt=0, a; int wantFpStack = func == nseel_asm_assign; #ifdef GLUE_PREFER_NONFP_DV_ASSIGNS // x86-64, and maybe others, prefer to avoid the fp stack for a simple copy if (wantFpStack && (op->parms.parms[pn]->opcodeType != OPCODETYPE_DIRECTVALUE || (op->parms.parms[pn]->parms.dv.directValue != 1.0 && op->parms.parms[pn]->parms.dv.directValue != 0.0))) { wantFpStack=0; } #endif a = compileOpcodes(ctx,op->parms.parms[pn],bufOut ? bufOut+parm_size : NULL,bufOut_len - parm_size,computTableSize,namespacePathToThis, func == nseel_asm_bnot ? (RETURNVALUE_BOOL_REVERSED|RETURNVALUE_BOOL) : (cfunc_abiinfo & BIF_LASTPARMONSTACK) ? RETURNVALUE_FPSTACK : (cfunc_abiinfo & BIF_LASTPARM_ASBOOL) ? RETURNVALUE_BOOL : wantFpStack ? (RETURNVALUE_FPSTACK|RETURNVALUE_NORMAL) : RETURNVALUE_NORMAL, &rvt, NULL,canHaveDenormalOutput); if (a<0) RET_MINUS1_FAIL("coc call here 3") if (func == nseel_asm_bnot && rvt == RETURNVALUE_BOOL_REVERSED) { // remove bnot, compileOpcodes() used fptobool_rev #ifndef EEL_TARGET_PORTABLE func = nseel_asm_uplus; func_e = nseel_asm_uplus_end; #else func = nseel_asm_bnotnot; func_e = nseel_asm_bnotnot_end; #endif rvt = RETURNVALUE_BOOL; } parm_size+=a; #ifdef GLUE_HAS_FXCH need_fxch = 0; #endif if (func == nseel_asm_assign) { if (rvt == RETURNVALUE_FPSTACK) { if (!(ctx->optimizeDisableFlags & OPTFLAG_FULL_DENORMAL_CHECKS)) { func = nseel_asm_assign_fast_fromfp; func_e = nseel_asm_assign_fast_fromfp_end; } else { func = nseel_asm_assign_fromfp; func_e = nseel_asm_assign_fromfp_end; } } else if (!(ctx->optimizeDisableFlags & OPTFLAG_FULL_DENORMAL_CHECKS)) { // assigning a value (from a variable or other non-computer), can use a fast assign (no denormal/result checking) func = nseel_asm_assign_fast; func_e = nseel_asm_assign_fast_end; } } } else { if (bufOut_len < parm_size + GLUE_MOV_PX_DIRECTVALUE_SIZE) RET_MINUS1_FAIL("size, pxdvsz") if (bufOut) { if (generateValueToReg(ctx,op->parms.parms[pn],bufOut + parm_size,n_params - 1 - pn,namespacePathToThis, 0/*nocaching, function gets pointer*/)<0) RET_MINUS1_FAIL("gvtr") } parm_size += GLUE_MOV_PX_DIRECTVALUE_SIZE; } } } #ifdef GLUE_HAS_FXCH if ((cfunc_abiinfo&(BIF_SECONDLASTPARMST)) && !(cfunc_abiinfo&(BIF_LAZYPARMORDERING))&& ((!!need_fxch)^!!(cfunc_abiinfo&BIF_REVERSEFPORDER)) ) { // emit fxch if (bufOut_len < sizeof(GLUE_FXCH)) RET_MINUS1_FAIL("len,fxch") if (bufOut) { memcpy(bufOut+parm_size,GLUE_FXCH,sizeof(GLUE_FXCH)); } parm_size+=sizeof(GLUE_FXCH); } #endif if (!*canHaveDenormalOutput) { // if add_op or sub_op, and non-denormal input, safe to omit denormal checks if (func == (void*)nseel_asm_add_op) { func = nseel_asm_add_op_fast; func_e = nseel_asm_add_op_fast_end; } else if (func == (void*)nseel_asm_sub_op) { func = nseel_asm_sub_op_fast; func_e = nseel_asm_sub_op_fast_end; } // or if mul/div by a fixed value of >= or <= 1.0 else if (func == (void *)nseel_asm_mul_op && parm1_dv && fabs(op->parms.parms[1]->parms.dv.directValue) >= 1.0) { func = nseel_asm_mul_op_fast; func_e = nseel_asm_mul_op_fast_end; } else if (func == (void *)nseel_asm_div_op && parm1_dv && fabs(op->parms.parms[1]->parms.dv.directValue) <= 1.0) { func = nseel_asm_div_op_fast; func_e = nseel_asm_div_op_fast_end; } } } // not varparm if (cfunc_abiinfo & (BIF_CLEARDENORMAL | BIF_RETURNSBOOL) ) *canHaveDenormalOutput=0; else if (!(cfunc_abiinfo & BIF_WONTMAKEDENORMAL)) *canHaveDenormalOutput=1; func = GLUE_realAddress(func,func_e,&func_size); if (!func) RET_MINUS1_FAIL("failrealladdrfunc") if (bufOut_len < parm_size + func_size) RET_MINUS1_FAIL("funcsz") if (bufOut) { unsigned char *p=bufOut + parm_size; memcpy(p, func, func_size); if (preProc) p=preProc(p,func_size,ctx); if (repl) { if (repl[0]) p=EEL_GLUE_set_immediate(p,(INT_PTR)repl[0]); if (repl[1]) p=EEL_GLUE_set_immediate(p,(INT_PTR)repl[1]); if (repl[2]) p=EEL_GLUE_set_immediate(p,(INT_PTR)repl[2]); if (repl[3]) p=EEL_GLUE_set_immediate(p,(INT_PTR)repl[3]); } } if (restore_stack_amt) { if (bufOut_len < parm_size + func_size + GLUE_MOVE_STACK_SIZE) RET_MINUS1_FAIL("insufficient size for varparm") if (bufOut) GLUE_MOVE_STACK(bufOut + parm_size + func_size, restore_stack_amt); parm_size += GLUE_MOVE_STACK_SIZE; } if (cfunc_abiinfo&BIF_RETURNSONSTACK) *rvMode = RETURNVALUE_FPSTACK; else if (cfunc_abiinfo&BIF_RETURNSBOOL) *rvMode=RETURNVALUE_BOOL; return parm_size + func_size; } static int compileEelFunctionCall(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTableSize, const namespaceInformation *namespacePathToThis, int *rvMode, int *fpStackUse, int *canHaveDenormalOutput) { int func_size=0, parm_size=0; int pn; int last_nt_parm=-1,last_nt_parm_mode=0; void *func_e=NULL; int n_params; opcodeRec *parmptrs[NSEEL_MAX_EELFUNC_PARAMETERS]; int cfp_numparams=-1; int cfp_statesize=0; EEL_F **cfp_ptrs=NULL; int func_raw=0; int do_parms; int x; void *func; for (x=0; x < 3; x ++) parmptrs[x] = op->parms.parms[x]; if (op->opcodeType == OPCODETYPE_FUNCX) { n_params=0; for (x=0;x<3;x++) { opcodeRec *prni=op->parms.parms[x]; while (prni && n_params < NSEEL_MAX_EELFUNC_PARAMETERS) { const int isMP = prni->opcodeType == OPCODETYPE_MOREPARAMS; parmptrs[n_params++] = isMP ? prni->parms.parms[0] : prni; if (!isMP) break; prni = prni->parms.parms[1]; } } } else { n_params = 1 + op->opcodeType - OPCODETYPE_FUNC1; } *fpStackUse = 0; func = nseel_getEELFunctionAddress(ctx, op, &cfp_numparams,&cfp_statesize,&cfp_ptrs, computTableSize, &func_e, &func_raw, !!bufOut,namespacePathToThis,rvMode,fpStackUse,canHaveDenormalOutput, parmptrs, n_params); if (func_raw) func_size = (int) ((char*)func_e - (char*)func); else if (func) func = GLUE_realAddress(func,func_e,&func_size); if (!func) RET_MINUS1_FAIL("eelfuncaddr") *fpStackUse += 1; if (cfp_numparams>0 && n_params != cfp_numparams) { RET_MINUS1_FAIL("eelfuncnp") } // user defined function do_parms = cfp_numparams>0 && cfp_ptrs && cfp_statesize>0; // if function local/parameter state is zero, we need to allocate storage for it if (cfp_statesize>0 && cfp_ptrs && !cfp_ptrs[0]) { EEL_F *pstate = newDataBlock(sizeof(EEL_F)*cfp_statesize,8); if (!pstate) RET_MINUS1_FAIL("eelfuncdb") for (pn=0;pn= 0 && do_parms) { if (last_nt_parm_mode == RETURNVALUE_FPSTACK) { if (bufOut_len < parm_size + (int)sizeof(GLUE_POP_FPSTACK_TOSTACK)) RET_MINUS1_FAIL("eelfunc_size popfpstacktostack") if (bufOut) memcpy(bufOut + parm_size,GLUE_POP_FPSTACK_TOSTACK,sizeof(GLUE_POP_FPSTACK_TOSTACK)); parm_size+=sizeof(GLUE_POP_FPSTACK_TOSTACK); } else { if (bufOut_len < parm_size + (int)sizeof(GLUE_PUSH_P1PTR_AS_VALUE)) RET_MINUS1_FAIL("eelfunc_size pushp1ptrasval") // push if (bufOut) memcpy(bufOut + parm_size,&GLUE_PUSH_P1PTR_AS_VALUE,sizeof(GLUE_PUSH_P1PTR_AS_VALUE)); parm_size+=sizeof(GLUE_PUSH_P1PTR_AS_VALUE); } } last_nt_parm_mode=0; lsz = compileOpcodes(ctx,parmptrs[pn],bufOut ? bufOut + parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, do_parms ? (RETURNVALUE_FPSTACK|RETURNVALUE_NORMAL) : RETURNVALUE_IGNORE,&last_nt_parm_mode,&sUse, &needDenorm); // todo: if needDenorm, denorm convert when copying parameter if (lsz<0) RET_MINUS1_FAIL("eelfunc, coc fail") if (last_nt_parm_mode == RETURNVALUE_FPSTACK) sUse++; if (sUse > *fpStackUse) *fpStackUse=sUse; parm_size += lsz; last_nt_parm = pn; } // pop non-trivial results into place if (last_nt_parm >=0 && do_parms) { while (--pn >= 0) { if (!parmptrs[pn] || OPCODE_IS_TRIVIAL(parmptrs[pn])) continue; // skip and process after if (pn == last_nt_parm) { if (last_nt_parm_mode == RETURNVALUE_FPSTACK) { // pop to memory directly const int cpsize = GLUE_POP_FPSTACK_TO_PTR(NULL,NULL); if (bufOut_len < parm_size + cpsize) RET_MINUS1_FAIL("eelfunc size popfpstacktoptr") if (bufOut) GLUE_POP_FPSTACK_TO_PTR((unsigned char *)bufOut + parm_size,cfp_ptrs[pn]); parm_size += cpsize; } else { // copy direct p1ptr to mem const int cpsize = GLUE_COPY_VALUE_AT_P1_TO_PTR(NULL,NULL); if (bufOut_len < parm_size + cpsize) RET_MINUS1_FAIL("eelfunc size copyvalueatp1toptr") if (bufOut) GLUE_COPY_VALUE_AT_P1_TO_PTR((unsigned char *)bufOut + parm_size,cfp_ptrs[pn]); parm_size += cpsize; } } else { const int popsize = GLUE_POP_VALUE_TO_ADDR(NULL,NULL); if (bufOut_len < parm_size + popsize) RET_MINUS1_FAIL("eelfunc size pop value to addr") if (bufOut) GLUE_POP_VALUE_TO_ADDR((unsigned char *)bufOut + parm_size,cfp_ptrs[pn]); parm_size+=popsize; } } } // finally, set any trivial parameters if (do_parms) { const int cpsize = GLUE_MOV_PX_DIRECTVALUE_SIZE + GLUE_COPY_VALUE_AT_P1_TO_PTR(NULL,NULL); for (pn=0; pn < n_params; pn++) { if (!parmptrs[pn] || !OPCODE_IS_TRIVIAL(parmptrs[pn])) continue; // set trivial values, we already set nontrivials if (bufOut_len < parm_size + cpsize) RET_MINUS1_FAIL("eelfunc size trivial set") if (bufOut) { if (generateValueToReg(ctx,parmptrs[pn],bufOut + parm_size,0,namespacePathToThis, 1)<0) RET_MINUS1_FAIL("eelfunc gvr fail") GLUE_COPY_VALUE_AT_P1_TO_PTR(bufOut + parm_size + GLUE_MOV_PX_DIRECTVALUE_SIZE,cfp_ptrs[pn]); } parm_size += cpsize; } } if (bufOut_len < parm_size + func_size) RET_MINUS1_FAIL("eelfunc size combined") if (bufOut) memcpy(bufOut + parm_size, func, func_size); return parm_size + func_size; // end of EEL function generation } #ifdef DUMP_OPS_DURING_COMPILE void dumpOp(compileContext *ctx, opcodeRec *op, int start); #endif #ifdef EEL_DUMP_OPS void dumpOpcodeTree(compileContext *ctx, FILE *fp, opcodeRec *op, int indent_amt) { const char *fname=""; fprintf(fp,"%*sOP TYPE %d", indent_amt, "", op->opcodeType==OPCODETYPE_DIRECTVALUE_TEMPSTRING ? 10000 : // remap around OPCODETYPE_DIRECTVALUE_TEMPSTRING op->opcodeType > OPCODETYPE_DIRECTVALUE_TEMPSTRING ? op->opcodeType - 1 : op->opcodeType); if ((op->opcodeType == OPCODETYPE_FUNC1 || op->opcodeType == OPCODETYPE_FUNC2 || op->opcodeType == OPCODETYPE_FUNC3 || op->opcodeType == OPCODETYPE_FUNCX)) { if (op->fntype == FUNCTYPE_FUNCTIONTYPEREC) { functionType *fn_ptr = (functionType *)op->fn; fname = fn_ptr->name; } else if (op->fntype == FUNCTYPE_EELFUNC) { fname = op->relname; } if (!fname) fname =""; } switch (op->opcodeType) { case OPCODETYPE_DIRECTVALUE: fprintf(fp," DV=%f\r\n",op->parms.dv.directValue); break; case OPCODETYPE_VALUE_FROM_NAMESPACENAME: // this.* or namespace.* are encoded this way fprintf(fp," NSN=%s(%d)\r\n",op->relname?op->relname : "(null)",op->namespaceidx); break; case OPCODETYPE_VARPTR: { const char *nm = op->relname; if (!nm || !*nm) { int wb; for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) { char **plist=ctx->varTable_Names[wb]; if (!plist) break; if (op->parms.dv.valuePtr >= ctx->varTable_Values[wb] && op->parms.dv.valuePtr < ctx->varTable_Values[wb] + NSEEL_VARS_PER_BLOCK) { nm = plist[op->parms.dv.valuePtr - ctx->varTable_Values[wb]]; break; } } } fprintf(fp," VP=%s\r\n", nm?nm : "(null)"); } break; case OPCODETYPE_VARPTRPTR: fprintf(fp, " VPP?\r\n"); break; case OPCODETYPE_FUNC1: if (op->fntype == FN_NOT) fprintf(fp," FUNC1 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_not"); else if (op->fntype == FN_NOTNOT) fprintf(fp," FUNC1 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_notnot"); else if (op->fntype == FN_MEMORY) fprintf(fp," FUNC1 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_mem"); else if (op->fntype == FN_GMEMORY) fprintf(fp," FUNC1 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_gmem"); else if (op->fntype == FN_WHILE) fprintf(fp," FUNC1 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "while"); else fprintf(fp," FUNC1 %d %s {\r\n",op->fntype, fname); if (op->parms.parms[0]) dumpOpcodeTree(ctx,fp,op->parms.parms[0],indent_amt+2); else fprintf(fp,"%*sINVALID PARM\r\n",indent_amt+2,""); fprintf(fp,"%*s}\r\n", indent_amt, ""); break; case OPCODETYPE_MOREPARAMS: case OPCODETYPE_FUNC2: if (op->opcodeType == OPCODETYPE_MOREPARAMS) fprintf(fp," MOREPARAMS {\r\n"); else { if (op->fntype == FN_POW) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "pow"); else if (op->fntype == FN_MOD) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_mod"); else if (op->fntype == FN_XOR) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_xor"); else if (op->fntype == FN_SHL) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_shl"); else if (op->fntype == FN_SHR) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_shr"); else if (op->fntype == FN_LT) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_below"); else if (op->fntype == FN_GT) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_above"); else if (op->fntype == FN_LTE) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_beleq"); else if (op->fntype == FN_GTE) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_aboeq"); else if (op->fntype == FN_EQ) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_equal"); else if (op->fntype == FN_NE) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_noteq"); else if (op->fntype == FN_EQ_EXACT) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_equal_exact"); else if (op->fntype == FN_NE_EXACT) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_noteq_exact"); else if (op->fntype == FN_LOGICAL_AND) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_and"); else if (op->fntype == FN_LOGICAL_OR) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_or"); else if (op->fntype == FN_ASSIGN) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_set"); else if (op->fntype == FN_ADD_OP) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_addop"); else if (op->fntype == FN_SUB_OP) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_subop"); else if (op->fntype == FN_MUL_OP) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_mulop"); else if (op->fntype == FN_DIV_OP) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_divop"); else if (op->fntype == FN_OR_OP) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_orop"); else if (op->fntype == FN_AND_OP) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_andop"); else if (op->fntype == FN_XOR_OP) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_xorop"); else if (op->fntype == FN_MOD_OP) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_modop"); else if (op->fntype == FN_POW_OP) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_powop"); else if (op->fntype == FN_LOOP) fprintf(fp," FUNC2 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "loop"); else fprintf(fp," FUNC2 %d %s {\r\n",op->fntype, fname); } if (op->parms.parms[0]) dumpOpcodeTree(ctx,fp,op->parms.parms[0],indent_amt+2); else fprintf(fp,"%*sINVALID PARM\r\n",indent_amt+2,""); if (op->parms.parms[1]) dumpOpcodeTree(ctx,fp,op->parms.parms[1],indent_amt+2); else fprintf(fp,"%*sINVALID PARM\r\n",indent_amt+2,""); fprintf(fp,"%*s}\r\n", indent_amt, ""); break; case OPCODETYPE_FUNCX: case OPCODETYPE_FUNC3: if (op->opcodeType == OPCODETYPE_FUNCX) fprintf(fp," FUNCX %d %s {\r\n",op->fntype, fname); else if (op->fntype == FN_IF_ELSE) fprintf(fp," FUNC3 %d %s {\r\n",FUNCTYPE_FUNCTIONTYPEREC, "_if"); else fprintf(fp," FUNC3 %d %s {\r\n",op->fntype, fname); if (op->parms.parms[0]) dumpOpcodeTree(ctx,fp,op->parms.parms[0],indent_amt+2); else fprintf(fp,"%*sINVALID PARM\r\n",indent_amt+2,""); if (op->parms.parms[1]) dumpOpcodeTree(ctx,fp,op->parms.parms[1],indent_amt+2); else fprintf(fp,"%*sINVALID PARM\r\n",indent_amt+2,""); if (op->parms.parms[2]) dumpOpcodeTree(ctx,fp,op->parms.parms[2],indent_amt+2); else fprintf(fp,"%*sINVALID PARM\r\n",indent_amt+2,""); fprintf(fp,"%*s}\r\n", indent_amt, ""); break; } } #endif #ifdef GLUE_MAX_JMPSIZE #define CHECK_SIZE_FORJMP(x,y) if ((x)<0 || (x)>=GLUE_MAX_JMPSIZE) goto y; #define RET_MINUS1_FAIL_FALLBACK(err,j) goto j; #else #define CHECK_SIZE_FORJMP(x,y) #define RET_MINUS1_FAIL_FALLBACK(err,j) RET_MINUS1_FAIL(err) #endif static int compileOpcodesInternal(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTableSize, const namespaceInformation *namespacePathToThis, int *calledRvType, int preferredReturnValues, int *fpStackUse, int *canHaveDenormalOutput) { int rv_offset=0, denormal_force=-1; if (!op) RET_MINUS1_FAIL("coi !op") *fpStackUse=0; for (;;) { // special case: statement delimiting means we can process the left side into place, and iteratively do the second parameter without recursing // also we don't need to save/restore anything to the stack (which the normal 2 parameter function processing does) if (op->opcodeType == OPCODETYPE_FUNC2 && op->fntype == FN_JOIN_STATEMENTS) { int fUse1; int parm_size = compileOpcodes(ctx,op->parms.parms[0],bufOut,bufOut_len, computTableSize, namespacePathToThis, RETURNVALUE_IGNORE, NULL,&fUse1,NULL); if (parm_size < 0) RET_MINUS1_FAIL("coc join fail") op = op->parms.parms[1]; if (!op) RET_MINUS1_FAIL("join got to null") if (fUse1>*fpStackUse) *fpStackUse=fUse1; if (bufOut) bufOut += parm_size; bufOut_len -= parm_size; rv_offset += parm_size; #ifdef DUMP_OPS_DURING_COMPILE if (op->opcodeType != OPCODETYPE_FUNC2 || op->fntype != FN_JOIN_STATEMENTS) dumpOp(ctx,op,0); #endif denormal_force=-1; } // special case: __denormal_likely(), __denormal_unlikely() else if (op->opcodeType == OPCODETYPE_FUNC1 && (op->fntype == FN_DENORMAL_LIKELY || op->fntype == FN_DENORMAL_UNLIKELY)) { denormal_force = op->fntype == FN_DENORMAL_LIKELY; op = op->parms.parms[0]; } else { break; } } if (denormal_force >= 0 && canHaveDenormalOutput) { *canHaveDenormalOutput = denormal_force; canHaveDenormalOutput = &denormal_force; // prevent it from being changed by functions below } // special case: BAND/BOR if (op->opcodeType == OPCODETYPE_FUNC2 && (op->fntype == FN_LOGICAL_AND || op->fntype == FN_LOGICAL_OR)) { int fUse1=0; int parm_size; #ifdef GLUE_MAX_JMPSIZE int parm_size_pre; #endif int retType=RETURNVALUE_IGNORE; if (preferredReturnValues != RETURNVALUE_IGNORE) retType = RETURNVALUE_BOOL; *calledRvType = retType; parm_size = compileOpcodes(ctx,op->parms.parms[0],bufOut,bufOut_len, computTableSize, namespacePathToThis, RETURNVALUE_BOOL, NULL, &fUse1, NULL); if (parm_size < 0) RET_MINUS1_FAIL("loop band/bor coc fail") if (fUse1 > *fpStackUse) *fpStackUse=fUse1; #ifdef GLUE_MAX_JMPSIZE parm_size_pre=parm_size; #endif { int sz2, fUse2=0; unsigned char *destbuf; const int testsz=op->fntype == FN_LOGICAL_OR ? sizeof(GLUE_JMP_IF_P1_NZ) : sizeof(GLUE_JMP_IF_P1_Z); if (bufOut_len < parm_size+testsz) RET_MINUS1_FAIL_FALLBACK("band/bor size fail",doNonInlinedAndOr_) if (bufOut) memcpy(bufOut+parm_size,op->fntype == FN_LOGICAL_OR ? GLUE_JMP_IF_P1_NZ : GLUE_JMP_IF_P1_Z,testsz); parm_size += testsz; destbuf = bufOut + parm_size; sz2= compileOpcodes(ctx,op->parms.parms[1],bufOut?bufOut+parm_size:NULL,bufOut_len-parm_size, computTableSize, namespacePathToThis, retType, NULL,&fUse2, NULL); CHECK_SIZE_FORJMP(sz2,doNonInlinedAndOr_) if (sz2<0) RET_MINUS1_FAIL("band/bor coc fail") parm_size+=sz2; if (bufOut) GLUE_JMP_SET_OFFSET(destbuf, (bufOut + parm_size) - destbuf); if (fUse2 > *fpStackUse) *fpStackUse=fUse2; return rv_offset + parm_size; } #ifdef GLUE_MAX_JMPSIZE if (0) { void *stub; int stubsize; unsigned char *newblock2, *p; // encode as function call doNonInlinedAndOr_: parm_size = parm_size_pre; if (op->fntype == FN_LOGICAL_AND) { stub = GLUE_realAddress(nseel_asm_band,nseel_asm_band_end,&stubsize); } else { stub = GLUE_realAddress(nseel_asm_bor,nseel_asm_bor_end,&stubsize); } if (bufOut_len < parm_size + stubsize) RET_MINUS1_FAIL("band/bor len fail") if (bufOut) { int fUse2=0; newblock2 = compileCodeBlockWithRet(ctx,op->parms.parms[1],computTableSize,namespacePathToThis, retType, NULL, &fUse2, NULL); if (!newblock2) RET_MINUS1_FAIL("band/bor ccbwr fail") if (fUse2 > *fpStackUse) *fpStackUse=fUse2; p = bufOut + parm_size; memcpy(p, stub, stubsize); p=EEL_GLUE_set_immediate(p,(INT_PTR)newblock2); } return rv_offset + parm_size + stubsize; } #endif } if (op->opcodeType == OPCODETYPE_FUNC3 && op->fntype == FN_IF_ELSE) // special case: IF { int fUse1=0; #ifdef GLUE_MAX_JMPSIZE int parm_size_pre; #endif int use_rv = RETURNVALUE_IGNORE; int rvMode=0; int parm_size = compileOpcodes(ctx,op->parms.parms[0],bufOut,bufOut_len, computTableSize, namespacePathToThis, RETURNVALUE_BOOL|RETURNVALUE_BOOL_REVERSED, &rvMode,&fUse1, NULL); if (parm_size < 0) RET_MINUS1_FAIL("if coc fail") if (fUse1 > *fpStackUse) *fpStackUse=fUse1; if (preferredReturnValues & RETURNVALUE_NORMAL) use_rv=RETURNVALUE_NORMAL; else if (preferredReturnValues & RETURNVALUE_FPSTACK) use_rv=RETURNVALUE_FPSTACK; else if (preferredReturnValues & RETURNVALUE_BOOL) use_rv=RETURNVALUE_BOOL; *calledRvType = use_rv; #ifdef GLUE_MAX_JMPSIZE parm_size_pre = parm_size; #endif { int csz,hasSecondHalf; if (rvMode & RETURNVALUE_BOOL_REVERSED) { if (bufOut_len < parm_size + (int)sizeof(GLUE_JMP_IF_P1_NZ)) RET_MINUS1_FAIL_FALLBACK("if size fail",doNonInlineIf_) if (bufOut) memcpy(bufOut+parm_size,GLUE_JMP_IF_P1_NZ,sizeof(GLUE_JMP_IF_P1_NZ)); parm_size += sizeof(GLUE_JMP_IF_P1_NZ); } else { if (bufOut_len < parm_size + (int)sizeof(GLUE_JMP_IF_P1_Z)) RET_MINUS1_FAIL_FALLBACK("if size fail",doNonInlineIf_) if (bufOut) memcpy(bufOut+parm_size,GLUE_JMP_IF_P1_Z,sizeof(GLUE_JMP_IF_P1_Z)); parm_size += sizeof(GLUE_JMP_IF_P1_Z); } csz=compileOpcodes(ctx,op->parms.parms[1],bufOut ? bufOut+parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, use_rv, NULL,&fUse1, canHaveDenormalOutput); if (fUse1 > *fpStackUse) *fpStackUse=fUse1; hasSecondHalf = preferredReturnValues || !OPCODE_IS_TRIVIAL(op->parms.parms[2]); CHECK_SIZE_FORJMP(csz,doNonInlineIf_) if (csz<0) RET_MINUS1_FAIL("if coc fial") if (bufOut) GLUE_JMP_SET_OFFSET(bufOut + parm_size, csz + (hasSecondHalf?sizeof(GLUE_JMP_NC):0)); parm_size+=csz; if (hasSecondHalf) { if (bufOut_len < parm_size + (int)sizeof(GLUE_JMP_NC)) RET_MINUS1_FAIL_FALLBACK("if len fail",doNonInlineIf_) if (bufOut) memcpy(bufOut+parm_size,GLUE_JMP_NC,sizeof(GLUE_JMP_NC)); parm_size+=sizeof(GLUE_JMP_NC); csz=compileOpcodes(ctx,op->parms.parms[2],bufOut ? bufOut+parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, use_rv, NULL, &fUse1, canHaveDenormalOutput); CHECK_SIZE_FORJMP(csz,doNonInlineIf_) if (csz<0) RET_MINUS1_FAIL("if coc 2 fail") // update jump address if (bufOut) GLUE_JMP_SET_OFFSET(bufOut + parm_size,csz); parm_size+=csz; if (fUse1 > *fpStackUse) *fpStackUse=fUse1; } return rv_offset + parm_size; } #ifdef GLUE_MAX_JMPSIZE if (0) { unsigned char *newblock2,*newblock3,*ptr; void *stub; int stubsize; doNonInlineIf_: parm_size = parm_size_pre; stub = GLUE_realAddress(nseel_asm_if,nseel_asm_if_end,&stubsize); if (!stub || bufOut_len < parm_size + stubsize) RET_MINUS1_FAIL(stub ? "if sz fail" : "if addr fail") if (bufOut) { int fUse2=0; newblock2 = compileCodeBlockWithRet(ctx,op->parms.parms[1],computTableSize,namespacePathToThis, use_rv, NULL,&fUse2, canHaveDenormalOutput); if (fUse2 > *fpStackUse) *fpStackUse=fUse2; newblock3 = compileCodeBlockWithRet(ctx,op->parms.parms[2],computTableSize,namespacePathToThis, use_rv, NULL,&fUse2, canHaveDenormalOutput); if (fUse2 > *fpStackUse) *fpStackUse=fUse2; if (!newblock2 || !newblock3) RET_MINUS1_FAIL("if subblock gen fail") ptr = bufOut + parm_size; memcpy(ptr, stub, stubsize); ptr=EEL_GLUE_set_immediate(ptr,(INT_PTR)newblock2); EEL_GLUE_set_immediate(ptr,(INT_PTR)newblock3); } return rv_offset + parm_size + stubsize; } #endif } { // special case: while if (op->opcodeType == OPCODETYPE_FUNC1 && op->fntype == FN_WHILE) { *calledRvType = RETURNVALUE_BOOL; #ifndef GLUE_INLINE_LOOPS // todo: PPC looping support when loop length is small enough { unsigned char *pwr=bufOut; unsigned char *newblock2; int stubsz; void *stubfunc = GLUE_realAddress(nseel_asm_repeatwhile,nseel_asm_repeatwhile_end,&stubsz); if (!stubfunc || bufOut_len < stubsz) RET_MINUS1_FAIL(stubfunc ? "repeatwhile size fail" :"repeatwhile addr fail") if (bufOut) { newblock2=compileCodeBlockWithRet(ctx,op->parms.parms[0],computTableSize,namespacePathToThis, RETURNVALUE_BOOL, NULL, fpStackUse, NULL); if (!newblock2) RET_MINUS1_FAIL("repeatwhile ccbwr fail") memcpy(pwr,stubfunc,stubsz); pwr=EEL_GLUE_set_immediate(pwr,(INT_PTR)newblock2); } return rv_offset+stubsz; } #else { #ifndef GLUE_WHILE_END_NOJUMP unsigned char *jzoutpt; #endif unsigned char *looppt; int parm_size=0,subsz; if (bufOut_len < parm_size + (int)(GLUE_WHILE_SETUP_SIZE + sizeof(GLUE_WHILE_BEGIN))) RET_MINUS1_FAIL("while size fail 1") if (bufOut) memcpy(bufOut + parm_size,GLUE_WHILE_SETUP,GLUE_WHILE_SETUP_SIZE); parm_size+=GLUE_WHILE_SETUP_SIZE; looppt = bufOut + parm_size; if (bufOut) memcpy(bufOut + parm_size,GLUE_WHILE_BEGIN,sizeof(GLUE_WHILE_BEGIN)); parm_size+=sizeof(GLUE_WHILE_BEGIN); subsz = compileOpcodes(ctx,op->parms.parms[0],bufOut ? (bufOut + parm_size) : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, RETURNVALUE_BOOL, NULL,fpStackUse, NULL); if (subsz<0) RET_MINUS1_FAIL("while coc fail") if (bufOut_len < parm_size + (int)(sizeof(GLUE_WHILE_END) + sizeof(GLUE_WHILE_CHECK_RV))) RET_MINUS1_FAIL("which size fial 2") parm_size+=subsz; if (bufOut) memcpy(bufOut + parm_size, GLUE_WHILE_END, sizeof(GLUE_WHILE_END)); parm_size+=sizeof(GLUE_WHILE_END); #ifndef GLUE_WHILE_END_NOJUMP jzoutpt = bufOut + parm_size; #endif if (bufOut) memcpy(bufOut + parm_size, GLUE_WHILE_CHECK_RV, sizeof(GLUE_WHILE_CHECK_RV)); parm_size+=sizeof(GLUE_WHILE_CHECK_RV); if (bufOut) { GLUE_JMP_SET_OFFSET(bufOut + parm_size,(looppt - (bufOut+parm_size)) ); #ifndef GLUE_WHILE_END_NOJUMP GLUE_JMP_SET_OFFSET(jzoutpt, (bufOut + parm_size) - jzoutpt); #endif } return rv_offset+parm_size; } #endif } // special case: loop if (op->opcodeType == OPCODETYPE_FUNC2 && op->fntype == FN_LOOP) { int fUse1; int parm_size = compileOpcodes(ctx,op->parms.parms[0],bufOut,bufOut_len, computTableSize, namespacePathToThis, RETURNVALUE_FPSTACK, NULL,&fUse1, NULL); if (parm_size < 0) RET_MINUS1_FAIL("loop coc fail") *calledRvType = RETURNVALUE_BOOL; if (fUse1 > *fpStackUse) *fpStackUse=fUse1; #ifndef GLUE_INLINE_LOOPS // todo: PPC looping support when loop length is small enough { void *stub; int stubsize; unsigned char *newblock2, *p; stub = GLUE_realAddress(nseel_asm_repeat,nseel_asm_repeat_end,&stubsize); if (bufOut_len < parm_size + stubsize) RET_MINUS1_FAIL("loop size fail") if (bufOut) { newblock2 = compileCodeBlockWithRet(ctx,op->parms.parms[1],computTableSize,namespacePathToThis, RETURNVALUE_IGNORE, NULL,fpStackUse, NULL); p = bufOut + parm_size; memcpy(p, stub, stubsize); p=EEL_GLUE_set_immediate(p,(INT_PTR)newblock2); } return rv_offset + parm_size + stubsize; } #else { int subsz; int fUse2=0; unsigned char *skipptr1,*loopdest; if (bufOut_len < parm_size + (int)(sizeof(GLUE_LOOP_LOADCNT) + GLUE_LOOP_CLAMPCNT_SIZE + GLUE_LOOP_BEGIN_SIZE)) RET_MINUS1_FAIL("loop size fail") // store, convert to int, compare against 1, if less than, skip to end if (bufOut) memcpy(bufOut+parm_size,GLUE_LOOP_LOADCNT,sizeof(GLUE_LOOP_LOADCNT)); parm_size += sizeof(GLUE_LOOP_LOADCNT); skipptr1 = bufOut+parm_size; // compare aginst max loop length, jump to loop start if not above it if (bufOut) memcpy(bufOut+parm_size,GLUE_LOOP_CLAMPCNT,GLUE_LOOP_CLAMPCNT_SIZE); parm_size += GLUE_LOOP_CLAMPCNT_SIZE; // loop code: loopdest = bufOut + parm_size; if (bufOut) memcpy(bufOut+parm_size,GLUE_LOOP_BEGIN,GLUE_LOOP_BEGIN_SIZE); parm_size += GLUE_LOOP_BEGIN_SIZE; subsz = compileOpcodes(ctx,op->parms.parms[1],bufOut ? (bufOut + parm_size) : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, RETURNVALUE_IGNORE, NULL, &fUse2, NULL); if (subsz<0) RET_MINUS1_FAIL("loop coc fail") if (fUse2 > *fpStackUse) *fpStackUse=fUse2; parm_size += subsz; if (bufOut_len < parm_size + (int)sizeof(GLUE_LOOP_END)) RET_MINUS1_FAIL("loop size fail 2") if (bufOut) memcpy(bufOut+parm_size,GLUE_LOOP_END,sizeof(GLUE_LOOP_END)); parm_size += sizeof(GLUE_LOOP_END); if (bufOut) { GLUE_JMP_SET_OFFSET(bufOut + parm_size,loopdest - (bufOut+parm_size)); GLUE_JMP_SET_OFFSET(skipptr1, (bufOut+parm_size) - skipptr1); } return rv_offset + parm_size; } #endif } } switch (op->opcodeType) { case OPCODETYPE_DIRECTVALUE: if (preferredReturnValues == RETURNVALUE_BOOL) { int w = fabs(op->parms.dv.directValue) >= NSEEL_CLOSEFACTOR; int wsz=(w?sizeof(GLUE_SET_P1_NZ):sizeof(GLUE_SET_P1_Z)); *calledRvType = RETURNVALUE_BOOL; if (bufOut_len < wsz) RET_MINUS1_FAIL("direct bool size fail3") if (bufOut) memcpy(bufOut,w?GLUE_SET_P1_NZ:GLUE_SET_P1_Z,wsz); return rv_offset+wsz; } else if (preferredReturnValues & RETURNVALUE_FPSTACK) { #ifdef GLUE_HAS_FLDZ if (op->parms.dv.directValue == 0.0) { *fpStackUse = 1; *calledRvType = RETURNVALUE_FPSTACK; if (bufOut_len < sizeof(GLUE_FLDZ)) RET_MINUS1_FAIL("direct fp fail 1") if (bufOut) memcpy(bufOut,GLUE_FLDZ,sizeof(GLUE_FLDZ)); return rv_offset+sizeof(GLUE_FLDZ); } #endif #ifdef GLUE_HAS_FLD1 if (op->parms.dv.directValue == 1.0) { *fpStackUse = 1; *calledRvType = RETURNVALUE_FPSTACK; if (bufOut_len < sizeof(GLUE_FLD1)) RET_MINUS1_FAIL("direct fp fail 1") if (bufOut) memcpy(bufOut,GLUE_FLD1,sizeof(GLUE_FLD1)); return rv_offset+sizeof(GLUE_FLD1); } #endif } // fall through case OPCODETYPE_DIRECTVALUE_TEMPSTRING: case OPCODETYPE_VALUE_FROM_NAMESPACENAME: case OPCODETYPE_VARPTR: case OPCODETYPE_VARPTRPTR: #ifdef GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE if (OPCODE_IS_TRIVIAL(op)) { if (preferredReturnValues & RETURNVALUE_FPSTACK) { *fpStackUse = 1; if (bufOut_len < GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE) RET_MINUS1_FAIL("direct fp fail 2") if (bufOut) { if (generateValueToReg(ctx,op,bufOut,-1,namespacePathToThis, 1 /*allow caching*/)<0) RET_MINUS1_FAIL("direct fp fail gvr") } *calledRvType = RETURNVALUE_FPSTACK; return rv_offset+GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE; } } #endif if (bufOut_len < GLUE_MOV_PX_DIRECTVALUE_SIZE) { RET_MINUS1_FAIL("direct value fail 1") } if (bufOut) { if (generateValueToReg(ctx,op,bufOut,0,namespacePathToThis, !!(preferredReturnValues&RETURNVALUE_FPSTACK)/*cache if going to the fp stack*/)<0) RET_MINUS1_FAIL("direct value gvr fail3") } return rv_offset + GLUE_MOV_PX_DIRECTVALUE_SIZE; case OPCODETYPE_FUNCX: case OPCODETYPE_FUNC1: case OPCODETYPE_FUNC2: case OPCODETYPE_FUNC3: if (op->fntype == FUNCTYPE_EELFUNC) { int a; a = compileEelFunctionCall(ctx,op,bufOut,bufOut_len,computTableSize,namespacePathToThis, calledRvType,fpStackUse,canHaveDenormalOutput); if (a<0) return a; rv_offset += a; } else { int a; a = compileNativeFunctionCall(ctx,op,bufOut,bufOut_len,computTableSize,namespacePathToThis, calledRvType,fpStackUse,preferredReturnValues,canHaveDenormalOutput); if (a<0)return a; rv_offset += a; } return rv_offset; } RET_MINUS1_FAIL("default opcode fail") } #ifdef DUMP_OPS_DURING_COMPILE FILE *g_debugfp; int g_debugfp_indent; int g_debugfp_histsz=0; void dumpOp(compileContext *ctx, opcodeRec *op, int start) { if (start>=0) { if (g_debugfp) { static opcodeRec **hist; int x; int hit=0; if (!hist) hist = (opcodeRec**) calloc(1024,1024*sizeof(opcodeRec*)); for(x=0;x=100) *(char *)1=0; fprintf(g_debugfp,"%*s{ %p : %d%s: ",g_debugfp_indent," ",op,op->opcodeType, hit ? " -- DUPLICATE" : ""); switch (op->opcodeType) { case OPCODETYPE_DIRECTVALUE: fprintf(g_debugfp,"dv %f",op->parms.dv.directValue); break; case OPCODETYPE_VARPTR: if (op->relname && op->relname[0]) { fprintf(g_debugfp,"var %s",op->relname); } else { int wb; for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) { char **plist=ctx->varTable_Names[wb]; if (!plist) break; if (op->parms.dv.valuePtr >= ctx->varTable_Values[wb] && op->parms.dv.valuePtr < ctx->varTable_Values[wb] + NSEEL_VARS_PER_BLOCK) { fprintf(g_debugfp,"var %s",plist[op->parms.dv.valuePtr - ctx->varTable_Values[wb]]); break; } } } break; case OPCODETYPE_FUNC1: case OPCODETYPE_FUNC2: case OPCODETYPE_FUNC3: case OPCODETYPE_FUNCX: if (op->fntype == FUNCTYPE_FUNCTIONTYPEREC) { functionType *p=(functionType*)op->fn; fprintf(g_debugfp,"func %d: %s",p->nParams&0xff,p->name); } else fprintf(g_debugfp,"sf %d",op->fntype); break; } fprintf(g_debugfp,"\n"); g_debugfp_indent+=2; } } else { if (g_debugfp) { g_debugfp_indent-=2; fprintf(g_debugfp,"%*s}%p\n",g_debugfp_indent," ",op); } } } #endif int compileOpcodes(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTableSize, const namespaceInformation *namespacePathToThis, int supportedReturnValues, int *rvType, int *fpStackUse, int *canHaveDenormalOutput) { int code_returns=RETURNVALUE_NORMAL; int fpsu=0; int codesz; int denorm=0; #ifdef DUMP_OPS_DURING_COMPILE dumpOp(ctx,op,1); #endif codesz = compileOpcodesInternal(ctx,op,bufOut,bufOut_len,computTableSize,namespacePathToThis,&code_returns, supportedReturnValues,&fpsu,&denorm); if (denorm && canHaveDenormalOutput) *canHaveDenormalOutput=1; #ifdef DUMP_OPS_DURING_COMPILE dumpOp(ctx,op,-1); #endif #ifdef EEL_DUMP_OPS // dump opcode trees for verification, after optimizing if (g_eel_dump_fp2) { fprintf(g_eel_dump_fp2,"-- compileOpcodes generated %d bytes of code!\r\n",codesz); } #endif if (codesz < 0) return codesz; /* { char buf[512]; sprintf(buf,"opcode %d %d (%s): fpu use: %d\n",op->opcodeType,op->fntype, op->opcodeType >= OPCODETYPE_FUNC1 && op->fntype == FUNCTYPE_FUNCTIONTYPEREC ? ( ((functionType *)op->fn)->name ) : "", fpsu); OutputDebugString(buf); } */ if (fpStackUse) *fpStackUse=fpsu; if (bufOut) bufOut += codesz; bufOut_len -= codesz; if (code_returns == RETURNVALUE_BOOL && !(supportedReturnValues & RETURNVALUE_BOOL) && supportedReturnValues) { int stubsize; void *stub = GLUE_realAddress(nseel_asm_booltofp,nseel_asm_booltofp_end,&stubsize); if (!stub || bufOut_len < stubsize) RET_MINUS1_FAIL(stub?"booltofp size":"booltfp addr") if (bufOut) { memcpy(bufOut,stub,stubsize); bufOut += stubsize; } codesz+=stubsize; bufOut_len -= stubsize; code_returns = RETURNVALUE_FPSTACK; } // default processing of code_returns to meet return value requirements if (supportedReturnValues & code_returns) { if (rvType) *rvType = code_returns; return codesz; } if (rvType) *rvType = RETURNVALUE_IGNORE; if (code_returns == RETURNVALUE_NORMAL) { if (supportedReturnValues & (RETURNVALUE_FPSTACK|RETURNVALUE_BOOL)) { if (bufOut_len < GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE) RET_MINUS1_FAIL("pushvalatpxtofpstack,size") if (bufOut) { GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(bufOut,0); // always fld qword [eax] but we might change that later bufOut += GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE; } codesz += GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE; bufOut_len -= GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE; if (supportedReturnValues & RETURNVALUE_BOOL) { code_returns = RETURNVALUE_FPSTACK; } else { if (rvType) *rvType = RETURNVALUE_FPSTACK; } } } if (code_returns == RETURNVALUE_FPSTACK) { if (supportedReturnValues & (RETURNVALUE_BOOL|RETURNVALUE_BOOL_REVERSED)) { int stubsize; void *stub; if (supportedReturnValues & RETURNVALUE_BOOL_REVERSED) { if (rvType) *rvType = RETURNVALUE_BOOL_REVERSED; stub = GLUE_realAddress(nseel_asm_fptobool_rev,nseel_asm_fptobool_rev_end,&stubsize); } else { if (rvType) *rvType = RETURNVALUE_BOOL; stub = GLUE_realAddress(nseel_asm_fptobool,nseel_asm_fptobool_end,&stubsize); } if (!stub || bufOut_len < stubsize) RET_MINUS1_FAIL(stub?"fptobool size":"fptobool addr") if (bufOut) { memcpy(bufOut,stub,stubsize); bufOut += stubsize; } codesz+=stubsize; bufOut_len -= stubsize; } else if (supportedReturnValues & RETURNVALUE_NORMAL) { if (computTableSize) (*computTableSize) ++; if (bufOut_len < GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE) RET_MINUS1_FAIL("popfpstacktowtptopxsize") // generate fp-pop to temp space if (bufOut) GLUE_POP_FPSTACK_TO_WTP_TO_PX(bufOut,0); codesz+=GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE; if (rvType) *rvType = RETURNVALUE_NORMAL; } else { // toss return value that will be ignored if (bufOut_len < GLUE_POP_FPSTACK_SIZE) RET_MINUS1_FAIL("popfpstack size") if (bufOut) memcpy(bufOut,GLUE_POP_FPSTACK,GLUE_POP_FPSTACK_SIZE); codesz+=GLUE_POP_FPSTACK_SIZE; } } return codesz; } #if 0 static void movestringover(char *str, int amount) { char tmp[1024+8]; int l=(int)strlen(str); l=wdl_min(1024-amount-1,l); memcpy(tmp,str,l+1); while (l >= 0 && tmp[l]!='\n') l--; l++; tmp[l]=0;//ensure we null terminate memcpy(str+amount,tmp,l+1); } #endif //------------------------------------------------------------------------------ NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX _ctx, const char *_expression, int lineoffs) { return NSEEL_code_compile_ex(_ctx,_expression,lineoffs,0); } typedef struct topLevelCodeSegmentRec { struct topLevelCodeSegmentRec *_next; void *code; int codesz; int tmptable_use; } topLevelCodeSegmentRec; NSEEL_CODEHANDLE NSEEL_code_compile_ex(NSEEL_VMCTX _ctx, const char *_expression, int lineoffs, int compile_flags) { compileContext *ctx = (compileContext *)_ctx; const char *endptr; const char *_expression_end; codeHandleType *handle; topLevelCodeSegmentRec *startpts_tail=NULL; topLevelCodeSegmentRec *startpts=NULL; _codeHandleFunctionRec *oldCommonFunctionList; int curtabptr_sz=0; void *curtabptr=NULL; int had_err=0; if (!ctx) return 0; ctx->directValueCache=0; ctx->optimizeDisableFlags=0; ctx->gotEndOfInput=0; if (compile_flags & NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS_RESET) { ctx->functions_common=NULL; // reset common function list } else { // reset common compiled function code, forcing a recompile if shared _codeHandleFunctionRec *a = ctx->functions_common; while (a) { _codeHandleFunctionRec *b = a->derivedCopies; if (a->localstorage) { // force local storage actual values to be reallocated if used again memset(a->localstorage,0,sizeof(EEL_F *) * a->localstorage_size); } a->startptr = NULL; // force this copy to be recompiled while (b) { b->startptr = NULL; // force derived copies to get recompiled // no need to reset b->localstorage, since it points to a->localstorage b=b->derivedCopies; } a=a->next; } } ctx->last_error_string[0]=0; if (!_expression || !*_expression) return 0; _expression_end = _expression + strlen(_expression); oldCommonFunctionList = ctx->functions_common; ctx->isGeneratingCommonFunction=0; ctx->isSharedFunctions = !!(compile_flags & NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS); ctx->functions_local = NULL; freeBlocks(&ctx->tmpblocks_head); // free blocks freeBlocks(&ctx->blocks_head); // free blocks freeBlocks(&ctx->blocks_head_data); // free blocks memset(ctx->l_stats,0,sizeof(ctx->l_stats)); handle = (codeHandleType*)newDataBlock(sizeof(codeHandleType),8); if (!handle) { return 0; } memset(handle,0,sizeof(codeHandleType)); ctx->l_stats[0] += (int)(_expression_end - _expression); ctx->tmpCodeHandle = handle; endptr=_expression; while (*endptr) { int computTableTop = 0; int startptr_size=0; void *startptr=NULL; opcodeRec *start_opcode=NULL; const char *expr=endptr; int function_numparms=0; char is_fname[NSEEL_MAX_VARIABLE_NAMELEN+1]; is_fname[0]=0; memset(ctx->function_localTable_Size,0,sizeof(ctx->function_localTable_Size)); memset(ctx->function_localTable_Names,0,sizeof(ctx->function_localTable_Names)); ctx->function_localTable_ValuePtrs=0; ctx->function_usesNamespaces=0; ctx->function_curName=NULL; ctx->function_globalFlag=0; ctx->errVar=0; // single out top level segment { int had_something = 0, pcnt=0, pcnt2=0; int state=0; for (;;) { int l; const char *p=nseel_simple_tokenizer(&endptr,_expression_end,&l,&state); if (!p) { if (pcnt || pcnt2) ctx->gotEndOfInput|=4; break; } if (*p == ';') { if (had_something && !pcnt && !pcnt2) break; } else if (*p == '/' && l > 1 && (p[1] == '/' || p[1] == '*')) { if (l > 19 && !strnicmp(p,"//#eel-no-optimize:",19)) ctx->optimizeDisableFlags = atoi(p+19); } else { if (!had_something) { expr = p; had_something = 1; } if (*p == '(') pcnt++; else if (*p == ')') { if (--pcnt<0) pcnt=0; } else if (*p == '[') pcnt2++; else if (*p == ']') { if (--pcnt2<0) pcnt2=0; } } } if (!*expr || !had_something) break; } // parse { int tmplen,funcname_len; const char *p = expr; const char *tok1 = nseel_simple_tokenizer(&p,endptr,&tmplen,NULL); const char *funcname = nseel_simple_tokenizer(&p,endptr,&funcname_len,NULL); if (tok1 && funcname && tmplen == 8 && !strnicmp(tok1,"function",8) && (isalpha(funcname[0]) || funcname[0] == '_')) { int had_parms_locals=0; if (funcname_len > sizeof(is_fname)-1) funcname_len=sizeof(is_fname)-1; memcpy(is_fname, funcname, funcname_len); is_fname[funcname_len]=0; ctx->function_curName = is_fname; // only assigned for the duration of the loop, cleared later //-V507 while (NULL != (tok1 = nseel_simple_tokenizer(&p,endptr,&tmplen,NULL))) { int is_parms = 0, localTableContext = 0; int maxcnt=0; const char *sp_save; if (tok1[0] == '(') { if (had_parms_locals) { expr = p-1; // begin compilation at this code! break; } is_parms = 1; } else { if (tmplen == 5 && !strnicmp(tok1,"local",tmplen)) localTableContext=0; else if (tmplen == 6 && !strnicmp(tok1,"static",tmplen)) localTableContext=0; else if (tmplen == 8 && !strnicmp(tok1,"instance",tmplen)) localTableContext=1; else if ((tmplen == 7 && !strnicmp(tok1,"globals",tmplen)) || (tmplen == 6 && !strnicmp(tok1,"global",tmplen))) { ctx->function_globalFlag = 1; localTableContext=2; } else break; // unknown token! tok1 = nseel_simple_tokenizer(&p,endptr,&tmplen,NULL); if (!tok1 || tok1[0] != '(') break; } had_parms_locals = 1; sp_save=p; while (NULL != (tok1 = nseel_simple_tokenizer(&p,endptr,&tmplen,NULL))) { if (tok1[0] == ')') break; if (*tok1 == '#' && localTableContext!=1 && localTableContext!=2) { ctx->errVar = (int) (tok1 - _expression); lstrcpyn_safe(ctx->last_error_string,"#string can only be in instance() or globals()",sizeof(ctx->last_error_string)); goto had_error; } if (isalpha(*tok1) || *tok1 == '_' || *tok1 == '#') { maxcnt++; if (p < endptr && *p == '*') { if (!is_parms && localTableContext!=2) { ctx->errVar = (int) (p - _expression); lstrcpyn_safe(ctx->last_error_string,"namespace* can only be used in parameters or globals()",sizeof(ctx->last_error_string)); goto had_error; } p++; } } else if (*tok1 != ',') { ctx->errVar = (int)(tok1 - _expression); lstrcpyn_safe(ctx->last_error_string,"unknown character in function parameters",sizeof(ctx->last_error_string)); goto had_error; } } if (tok1 && maxcnt > 0) { char **ot = ctx->function_localTable_Names[localTableContext]; const int osz = ctx->function_localTable_Size[localTableContext]; maxcnt += osz; ctx->function_localTable_Names[localTableContext] = (char **)newTmpBlock(ctx,sizeof(char *) * maxcnt); if (ctx->function_localTable_Names[localTableContext]) { int i=osz; if (osz && ot) memcpy(ctx->function_localTable_Names[localTableContext],ot,sizeof(char *) * osz); p=sp_save; while (NULL != (tok1 = nseel_simple_tokenizer(&p,endptr,&tmplen,NULL))) { if (tok1[0] == ')') break; if (isalpha(*tok1) || *tok1 == '_' || *tok1 == '#') { char *newstr; int l = tmplen; if (*p == '*') // xyz* for namespace { p++; l++; } if (l > NSEEL_MAX_VARIABLE_NAMELEN) l = NSEEL_MAX_VARIABLE_NAMELEN; newstr = newTmpBlock(ctx,l+1); if (newstr) { memcpy(newstr,tok1,l); newstr[l]=0; ctx->function_localTable_Names[localTableContext][i++] = newstr; } } } ctx->function_localTable_Size[localTableContext]=i; if (is_parms) function_numparms = i; } } } } } if (ctx->function_localTable_Size[0]>0) { ctx->function_localTable_ValuePtrs = ctx->isSharedFunctions ? newDataBlock(ctx->function_localTable_Size[0] * sizeof(EEL_F *),8) : newTmpBlock(ctx,ctx->function_localTable_Size[0] * sizeof(EEL_F *)); if (!ctx->function_localTable_ValuePtrs) { ctx->function_localTable_Size[0]=0; function_numparms=0; } else { memset(ctx->function_localTable_ValuePtrs,0,sizeof(EEL_F *) * ctx->function_localTable_Size[0]); // force values to be allocated } } { int nseelparse(compileContext* context); void nseelrestart (void *input_file ,void *yyscanner ); ctx->rdbuf_start = _expression; #ifdef NSEEL_SUPER_MINIMAL_LEXER ctx->rdbuf = expr; ctx->rdbuf_end = endptr; if (!nseelparse(ctx) && !ctx->errVar) { start_opcode = ctx->result; } #else nseelrestart(NULL,ctx->scanner); ctx->rdbuf = expr; ctx->rdbuf_end = endptr; if (!nseelparse(ctx) && !ctx->errVar) { start_opcode = ctx->result; } if (ctx->errVar) { const char *p=expr; ctx->errVar += expr-_expression; } #endif ctx->rdbuf = NULL; } if (start_opcode) { int rvMode=0, fUse=0; #ifdef LOG_OPT char buf[512]; int sd=0; sprintf(buf,"pre opt sz=%d (tsackDepth=%d)\n",compileOpcodes(ctx,start_opcode,NULL,1024*1024*256,NULL, NULL,RETURNVALUE_IGNORE,NULL,&sd,NULL),sd); #ifdef _WIN32 OutputDebugString(buf); #else printf("%s\n",buf); #endif #endif #ifdef EEL_DUMP_OPS // dump opcode trees for verification, before optimizing if (g_eel_dump_fp) { fprintf(g_eel_dump_fp,"-- opcode chunk --\r\n"); dumpOpcodeTree(ctx,g_eel_dump_fp,start_opcode,2); } #endif if (!(ctx->optimizeDisableFlags&OPTFLAG_NO_OPTIMIZE)) optimizeOpcodes(ctx,start_opcode,is_fname[0] ? 1 : 0); #ifdef LOG_OPT sprintf(buf,"post opt sz=%d, stack depth=%d\n",compileOpcodes(ctx,start_opcode,NULL,1024*1024*256,NULL,NULL, RETURNVALUE_IGNORE,NULL,&sd,NULL),sd); #ifdef _WIN32 OutputDebugString(buf); #else printf("%s\n",buf); #endif #endif #ifdef EEL_DUMP_OPS // dump opcode trees for verification, after optimizing if (g_eel_dump_fp2) { fprintf(g_eel_dump_fp2,"-- POST-OPTIMIZED opcode chunk --\r\n"); dumpOpcodeTree(ctx,g_eel_dump_fp2,start_opcode,2); } #endif #ifdef DUMP_OPS_DURING_COMPILE g_debugfp_indent=0; g_debugfp_histsz=0; g_debugfp = fopen("C:/temp/foo.txt","w"); #endif startptr_size = compileOpcodes(ctx,start_opcode,NULL,1024*1024*256,NULL, NULL, is_fname[0] ? (RETURNVALUE_NORMAL|RETURNVALUE_FPSTACK) : RETURNVALUE_IGNORE, &rvMode, &fUse, NULL); // if not a function, force return value as address (avoid having to pop it ourselves // if a function, allow the code to decide how return values are generated #ifdef DUMP_OPS_DURING_COMPILE if (g_debugfp) fclose(g_debugfp); g_debugfp=0; #endif if (is_fname[0]) { _codeHandleFunctionRec *fr = ctx->isSharedFunctions ? newDataBlock(sizeof(_codeHandleFunctionRec),8) : newTmpBlock(ctx,sizeof(_codeHandleFunctionRec)); if (fr) { memset(fr,0,sizeof(_codeHandleFunctionRec)); fr->startptr_size = startptr_size; fr->opcodes = start_opcode; fr->rvMode = rvMode; fr->fpStackUsage=fUse; fr->tmpspace_req = computTableTop; if (ctx->function_localTable_Size[0] > 0 && ctx->function_localTable_ValuePtrs) { if (ctx->function_localTable_Names[0]) { int i; for(i=0;ifunction_localTable_Names[0][i]; if (nptr && *nptr && nptr[strlen(nptr)-1] == '*') { fr->parameterAsNamespaceMask |= ((unsigned int)1)<num_params=function_numparms; fr->localstorage = ctx->function_localTable_ValuePtrs; fr->localstorage_size = ctx->function_localTable_Size[0]; } fr->usesNamespaces = ctx->function_usesNamespaces; fr->isCommonFunction = ctx->isSharedFunctions; lstrcpyn_safe(fr->fname,is_fname,sizeof(fr->fname)); if (ctx->isSharedFunctions) { fr->next = ctx->functions_common; ctx->functions_common = fr; } else { fr->next = ctx->functions_local; ctx->functions_local = fr; } } continue; } if (!startptr_size) continue; // optimized away if (startptr_size>0) { startptr = newTmpBlock(ctx,startptr_size); if (startptr) { startptr_size=compileOpcodes(ctx,start_opcode,(unsigned char*)startptr,startptr_size,&computTableTop, NULL, RETURNVALUE_IGNORE, NULL,NULL, NULL); if (startptr_size<=0) startptr = NULL; } } } if (!startptr) { had_error: #ifdef NSEEL_EEL1_COMPAT_MODE continue; #else //if (!ctx->last_error_string[0]) { int byteoffs = ctx->errVar; int linenumber; char cur_err[sizeof(ctx->last_error_string)]; lstrcpyn_safe(cur_err,ctx->last_error_string,sizeof(cur_err)); if (cur_err[0]) lstrcatn(cur_err,": ",sizeof(cur_err)); else lstrcpyn_safe(cur_err,"syntax error: ",sizeof(cur_err)); if (_expression + byteoffs >= _expression_end) { if (ctx->gotEndOfInput&4) byteoffs = (int)(expr-_expression); else byteoffs=(int)(_expression_end-_expression); } if (byteoffs < 0) byteoffs=0; linenumber=findLineNumber(_expression,byteoffs)+1; if (ctx->gotEndOfInput&4) { snprintf(ctx->last_error_string,sizeof(ctx->last_error_string),"%d: %smissing ) or ]",linenumber+lineoffs,cur_err); } else { const char *p = _expression + byteoffs; int x=0, right_amt_nospace=0, left_amt_nospace=0; while (x < 32 && p-x > _expression && p[-x] != '\r' && p[-x] != '\n') { if (!isspace(p[-x])) left_amt_nospace=x; x++; } x=0; while (x < 60 && p[x] && p[x] != '\r' && p[x] != '\n') { if (!isspace(p[x])) right_amt_nospace=x; x++; } if (right_amt_nospace<1) right_amt_nospace=1; // display left_amt >>>> right_amt_nospace if (left_amt_nospace > 0) snprintf(ctx->last_error_string,sizeof(ctx->last_error_string),"%d: %s'%.*s %.*s'",linenumber+lineoffs,cur_err, left_amt_nospace,p-left_amt_nospace, right_amt_nospace,p); else snprintf(ctx->last_error_string,sizeof(ctx->last_error_string),"%d: %s'%.*s'",linenumber+lineoffs,cur_err,right_amt_nospace,p); } } startpts=NULL; startpts_tail=NULL; had_err=1; break; #endif } if (!is_fname[0]) // redundant check (if is_fname[0] is set and we succeeded, it should continue) // but we'll be on the safe side { topLevelCodeSegmentRec *p = newTmpBlock(ctx,sizeof(topLevelCodeSegmentRec)); p->_next=0; p->code = startptr; p->codesz = startptr_size; p->tmptable_use = computTableTop; if (!startpts_tail) startpts_tail=startpts=p; else { startpts_tail->_next=p; startpts_tail=p; } if (curtabptr_sz < computTableTop) { curtabptr_sz=computTableTop; } } } memset(ctx->function_localTable_Size,0,sizeof(ctx->function_localTable_Size)); memset(ctx->function_localTable_Names,0,sizeof(ctx->function_localTable_Names)); ctx->function_localTable_ValuePtrs=0; ctx->function_usesNamespaces=0; ctx->function_curName=NULL; ctx->function_globalFlag=0; ctx->tmpCodeHandle = NULL; if (handle->want_stack) { if (!handle->stack) startpts=NULL; } if (startpts) { curtabptr_sz += 2; // many functions use the worktable for temporary storage of up to 2 EEL_F's handle->workTable_size = curtabptr_sz; handle->workTable = curtabptr = newDataBlock((curtabptr_sz+MIN_COMPUTABLE_SIZE + COMPUTABLE_EXTRA_SPACE) * sizeof(EEL_F),32); #ifdef EEL_VALIDATE_WORKTABLE_USE if (curtabptr) memset(curtabptr,0x3a,(curtabptr_sz+MIN_COMPUTABLE_SIZE + COMPUTABLE_EXTRA_SPACE) * sizeof(EEL_F)); #endif if (!curtabptr) startpts=NULL; } if (startpts || (!had_err && (compile_flags & NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS))) { unsigned char *writeptr; topLevelCodeSegmentRec *p=startpts; int size=sizeof(GLUE_RET)+GLUE_FUNC_ENTER_SIZE+GLUE_FUNC_LEAVE_SIZE; // for ret at end :) int wtpos=0; // now we build one big code segment out of our list of them, inserting a mov esi, computable before each item as necessary while (p) { if (wtpos <= 0) { wtpos=MIN_COMPUTABLE_SIZE; size += GLUE_RESET_WTP(NULL,0); } size+=p->codesz; wtpos -= p->tmptable_use; p=p->_next; } handle->code = newCodeBlock(size,32); if (handle->code) { writeptr=(unsigned char *)handle->code; #if GLUE_FUNC_ENTER_SIZE > 0 memcpy(writeptr,&GLUE_FUNC_ENTER,GLUE_FUNC_ENTER_SIZE); writeptr += GLUE_FUNC_ENTER_SIZE; #endif p=startpts; wtpos=0; while (p) { if (wtpos <= 0) { wtpos=MIN_COMPUTABLE_SIZE; writeptr+=GLUE_RESET_WTP(writeptr,curtabptr); } memcpy(writeptr,(char*)p->code,p->codesz); writeptr += p->codesz; wtpos -= p->tmptable_use; p=p->_next; } #if GLUE_FUNC_LEAVE_SIZE > 0 memcpy(writeptr,&GLUE_FUNC_LEAVE,GLUE_FUNC_LEAVE_SIZE); writeptr += GLUE_FUNC_LEAVE_SIZE; #endif memcpy(writeptr,&GLUE_RET,sizeof(GLUE_RET)); writeptr += sizeof(GLUE_RET); ctx->l_stats[1]=size; handle->code_size = (int) (writeptr - (unsigned char *)handle->code); #ifdef __arm__ __clear_cache(handle->code,writeptr); #endif } handle->blocks = ctx->blocks_head; handle->blocks_data = ctx->blocks_head_data; ctx->blocks_head=0; ctx->blocks_head_data=0; } else { // failed compiling, or failed calloc() handle=NULL; // return NULL (after resetting blocks_head) } ctx->directValueCache=0; ctx->functions_local = NULL; ctx->isGeneratingCommonFunction=0; ctx->isSharedFunctions=0; freeBlocks(&ctx->tmpblocks_head); // free blocks freeBlocks(&ctx->blocks_head); // free blocks of code (will be nonzero only on error) freeBlocks(&ctx->blocks_head_data); // free blocks of data (will be nonzero only on error) if (handle) { handle->ramPtr = ctx->ram_state.blocks; memcpy(handle->code_stats,ctx->l_stats,sizeof(ctx->l_stats)); nseel_evallib_stats[0]+=ctx->l_stats[0]; nseel_evallib_stats[1]+=ctx->l_stats[1]; nseel_evallib_stats[2]+=ctx->l_stats[2]; nseel_evallib_stats[3]+=ctx->l_stats[3]; nseel_evallib_stats[4]++; } else { ctx->functions_common = oldCommonFunctionList; // failed compiling, remove any added common functions from the list // remove any derived copies of functions due to error, since we may have added some that have been freed while (oldCommonFunctionList) { oldCommonFunctionList->derivedCopies=NULL; oldCommonFunctionList=oldCommonFunctionList->next; } } memset(ctx->l_stats,0,sizeof(ctx->l_stats)); return (NSEEL_CODEHANDLE)handle; } //------------------------------------------------------------------------------ void NSEEL_code_execute(NSEEL_CODEHANDLE code) { #ifndef GLUE_TABPTR_IGNORED INT_PTR tabptr; #endif INT_PTR codeptr; codeHandleType *h = (codeHandleType *)code; if (!h || !h->code) return; codeptr = (INT_PTR) h->code; #if 0 { unsigned int *p=(unsigned int *)codeptr; while (*p != GLUE_RET[0]) { printf("instr:%04X:%04X\n",*p>>16,*p&0xffff); p++; } } #endif #ifndef GLUE_TABPTR_IGNORED tabptr=(INT_PTR)h->workTable; #endif //printf("calling code!\n"); GLUE_CALL_CODE(tabptr,codeptr,(INT_PTR)h->ramPtr); } int NSEEL_code_geterror_flag(NSEEL_VMCTX ctx) { compileContext *c=(compileContext *)ctx; if (c) return (c->gotEndOfInput ? 1 : 0); return 0; } char *NSEEL_code_getcodeerror(NSEEL_VMCTX ctx) { compileContext *c=(compileContext *)ctx; if (ctx && c->last_error_string[0]) return c->last_error_string; return 0; } //------------------------------------------------------------------------------ void NSEEL_code_free(NSEEL_CODEHANDLE code) { codeHandleType *h = (codeHandleType *)code; if (h != NULL) { #ifdef EEL_VALIDATE_WORKTABLE_USE if (h->workTable) { char *p = ((char*)h->workTable) + h->workTable_size*sizeof(EEL_F); int x; for(x=COMPUTABLE_EXTRA_SPACE*sizeof(EEL_F) - 1;x >= 0; x --) if (p[x] != 0x3a) { char buf[512]; snprintf(buf,sizeof(buf),"worktable overrun at byte %d (wts=%d), value = %f\n",x,h->workTable_size, *(EEL_F*)(p+(x&~(sizeof(EEL_F)-1)))); #ifdef _WIN32 OutputDebugString(buf); #else printf("%s",buf); #endif break; } } #endif nseel_evallib_stats[0]-=h->code_stats[0]; nseel_evallib_stats[1]-=h->code_stats[1]; nseel_evallib_stats[2]-=h->code_stats[2]; nseel_evallib_stats[3]-=h->code_stats[3]; nseel_evallib_stats[4]--; #if defined(__ppc__) && defined(__APPLE__) { FILE *fp = fopen("/var/db/receipts/com.apple.pkg.Rosetta.plist","r"); if (fp) { fclose(fp); // on PPC, but rosetta installed, do not free h->blocks, as rosetta won't detect changes to these pages } else { freeBlocks(&h->blocks); } } #else freeBlocks(&h->blocks); #endif freeBlocks(&h->blocks_data); } } //------------------------------------------------------------------------------ static void NSEEL_VM_freevars(NSEEL_VMCTX _ctx) { if (_ctx) { compileContext *ctx=(compileContext *)_ctx; free(ctx->varTable_Values); free(ctx->varTable_Names); ctx->varTable_Values=0; ctx->varTable_Names=0; ctx->varTable_numBlocks=0; } } NSEEL_VMCTX NSEEL_VM_alloc() // return a handle { compileContext *ctx=calloc(1,sizeof(compileContext)); #ifdef NSEEL_SUPER_MINIMAL_LEXER if (ctx) ctx->scanner = ctx; #else if (ctx) { int nseellex_init(void ** ptr_yy_globals); void nseelset_extra(void *user_defined , void *yyscanner); if (nseellex_init(&ctx->scanner)) { free(ctx); return NULL; } nseelset_extra(ctx,ctx->scanner); } #endif if (ctx) { ctx->ram_state.maxblocks = NSEEL_RAM_BLOCKS_DEFAULTMAX; ctx->ram_state.closefact = NSEEL_CLOSEFACTOR; } return ctx; } int NSEEL_VM_setramsize(NSEEL_VMCTX _ctx, int maxent) { compileContext *ctx = (compileContext *)_ctx; if (!ctx) return 0; if (maxent > 0) { maxent = (maxent + NSEEL_RAM_ITEMSPERBLOCK - 1)/NSEEL_RAM_ITEMSPERBLOCK; if (maxent > NSEEL_RAM_BLOCKS) maxent = NSEEL_RAM_BLOCKS; ctx->ram_state.maxblocks = maxent; } return ctx->ram_state.maxblocks * NSEEL_RAM_ITEMSPERBLOCK; } void NSEEL_VM_SetFunctionValidator(NSEEL_VMCTX _ctx, const char * (*validateFunc)(const char *fn_name, void *user), void *user) { if (_ctx) { compileContext *ctx = (compileContext *)_ctx; ctx->func_check = validateFunc; ctx->func_check_user = user; } } void NSEEL_VM_SetFunctionTable(NSEEL_VMCTX _ctx, eel_function_table *tab) { if (_ctx) { compileContext *ctx = (compileContext *)_ctx; ctx->registered_func_tab = tab; } } void NSEEL_VM_free(NSEEL_VMCTX _ctx) // free when done with a VM and ALL of its code have been freed, as well { if (_ctx) { compileContext *ctx=(compileContext *)_ctx; NSEEL_VM_freevars(_ctx); NSEEL_VM_freeRAM(_ctx); freeBlocks(&ctx->pblocks); // these should be 0 normally but just in case freeBlocks(&ctx->tmpblocks_head); // free blocks freeBlocks(&ctx->blocks_head); // free blocks freeBlocks(&ctx->blocks_head_data); // free blocks #ifndef NSEEL_SUPER_MINIMAL_LEXER if (ctx->scanner) { int nseellex_destroy(void *yyscanner); nseellex_destroy(ctx->scanner); } #endif ctx->scanner=0; if (ctx->has_used_global_vars) { nseel_globalVarItem *p = NULL; NSEEL_HOSTSTUB_EnterMutex(); if (--nseel_vms_referencing_globallist_cnt == 0) { // clear and free globals p = nseel_globalreg_list; nseel_globalreg_list=0; } NSEEL_HOSTSTUB_LeaveMutex(); while (p) { nseel_globalVarItem *op = p; p=p->_next; free(op); } } free(ctx); } } int *NSEEL_code_getstats(NSEEL_CODEHANDLE code) { codeHandleType *h = (codeHandleType *)code; if (h) { return h->code_stats; } return 0; } void NSEEL_VM_SetStringFunc(NSEEL_VMCTX ctx, EEL_F (*onString)(void *caller_this, struct eelStringSegmentRec *list), EEL_F (*onNamedString)(void *caller_this, const char *name)) { if (ctx) { compileContext *c=(compileContext*)ctx; c->onString = onString; c->onNamedString = onNamedString; } } void NSEEL_VM_SetCustomFuncThis(NSEEL_VMCTX ctx, void *thisptr) { if (ctx) { compileContext *c=(compileContext*)ctx; c->caller_this=thisptr; } } void *NSEEL_PProc_RAM(void *data, int data_size, compileContext *ctx) { if (data_size>0) data=EEL_GLUE_set_immediate(data, (INT_PTR)ctx->ram_state.blocks); return data; } void *NSEEL_PProc_THIS(void *data, int data_size, compileContext *ctx) { if (data_size>0) data=EEL_GLUE_set_immediate(data, (INT_PTR)ctx->caller_this); return data; } void NSEEL_VM_remove_unused_vars(NSEEL_VMCTX _ctx) { compileContext *ctx = (compileContext *)_ctx; int wb; if (ctx) for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) { int ti; char **plist=ctx->varTable_Names[wb]; if (!plist) break; for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) { if (plist[ti]) { varNameHdr *v = ((varNameHdr*)plist[ti])-1; if (!v->refcnt && !v->isreg) { plist[ti]=NULL; } } } } } void NSEEL_VM_remove_all_nonreg_vars(NSEEL_VMCTX _ctx) { compileContext *ctx = (compileContext *)_ctx; int wb; if (ctx) for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) { int ti; char **plist=ctx->varTable_Names[wb]; if (!plist) break; for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) { if (plist[ti]) { varNameHdr *v = ((varNameHdr*)plist[ti])-1; if (!v->isreg) { plist[ti]=NULL; } } } } } void NSEEL_VM_clear_var_refcnts(NSEEL_VMCTX _ctx) { compileContext *ctx = (compileContext *)_ctx; int wb; if (ctx) for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) { int ti; char **plist=ctx->varTable_Names[wb]; if (!plist) break; for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) { if (plist[ti]) { varNameHdr *v = ((varNameHdr*)plist[ti])-1; v->refcnt=0; } } } } #ifdef NSEEL_EEL1_COMPAT_MODE static EEL_F __nseel_global_regs[100]; double *NSEEL_getglobalregs() { return __nseel_global_regs; } #endif EEL_F *get_global_var(compileContext *ctx, const char *gv, int addIfNotPresent) { nseel_globalVarItem *p; #ifdef NSEEL_EEL1_COMPAT_MODE if (!strnicmp(gv,"reg",3) && gv[3]>='0' && gv[3] <= '9' && gv[4] >= '0' && gv[4] <= '9' && !gv[5]) { return __nseel_global_regs + atoi(gv+3); } #endif NSEEL_HOSTSTUB_EnterMutex(); if (!ctx->has_used_global_vars) { ctx->has_used_global_vars++; nseel_vms_referencing_globallist_cnt++; } p = nseel_globalreg_list; while (p) { if (!stricmp(p->name,gv)) break; p=p->_next; } if (!p && addIfNotPresent) { size_t gvl = strlen(gv); p = (nseel_globalVarItem*)malloc(sizeof(nseel_globalVarItem) + gvl); if (p) { p->data=0.0; strcpy(p->name,gv); p->_next = nseel_globalreg_list; nseel_globalreg_list=p; } } NSEEL_HOSTSTUB_LeaveMutex(); return p ? &p->data : NULL; } EEL_F *nseel_int_register_var(compileContext *ctx, const char *name, int isReg, const char **namePtrOut) { int match_wb = -1, match_ti=-1; int wb; int ti=0; if (!strnicmp(name,"_global.",8) && name[8]) { EEL_F *a=get_global_var(ctx,name+8,isReg >= 0); if (a) return a; } for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) { char **plist=ctx->varTable_Names[wb]; if (!plist) return NULL; // error! for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) { if (!plist[ti]) { if (match_wb < 0) { match_wb=wb; match_ti=ti; } } else if (!strnicmp(plist[ti],name,NSEEL_MAX_VARIABLE_NAMELEN)) { varNameHdr *v = ((varNameHdr*)plist[ti])-1; if (isReg < 0) { EEL_F *p; return (ctx->varTable_Values && NULL != (p = ctx->varTable_Values[wb])) ? p + ti : NULL; } v->refcnt++; if (isReg) v->isreg=isReg; if (namePtrOut) *namePtrOut = plist[ti]; break; } } if (ti < NSEEL_VARS_PER_BLOCK) break; } if (isReg < 0) return NULL; if (wb == ctx->varTable_numBlocks && match_wb >=0 && match_ti >= 0) { wb = match_wb; ti = match_ti; } if (wb == ctx->varTable_numBlocks) { ti=0; // add new block if (!(ctx->varTable_numBlocks&(NSEEL_VARS_MALLOC_CHUNKSIZE-1)) || !ctx->varTable_Values || !ctx->varTable_Names ) { void *nv = realloc(ctx->varTable_Values,(ctx->varTable_numBlocks+NSEEL_VARS_MALLOC_CHUNKSIZE) * sizeof(EEL_F *)); if (!nv) return NULL; ctx->varTable_Values = (EEL_F **)nv; nv = realloc(ctx->varTable_Names,(ctx->varTable_numBlocks+NSEEL_VARS_MALLOC_CHUNKSIZE) * sizeof(char **)); if (!nv) return NULL; ctx->varTable_Names = (char ***)nv; } ctx->varTable_numBlocks++; ctx->varTable_Values[wb] = (EEL_F *)newCtxDataBlock(sizeof(EEL_F)*NSEEL_VARS_PER_BLOCK,8); ctx->varTable_Names[wb] = (char **)newCtxDataBlock(sizeof(char *)*NSEEL_VARS_PER_BLOCK,1); if (ctx->varTable_Values[wb]) { memset(ctx->varTable_Values[wb],0,sizeof(EEL_F)*NSEEL_VARS_PER_BLOCK); } if (ctx->varTable_Names[wb]) { memset(ctx->varTable_Names[wb],0,sizeof(char *)*NSEEL_VARS_PER_BLOCK); } } if (!ctx->varTable_Names[wb] || !ctx->varTable_Values[wb]) return NULL; if (!ctx->varTable_Names[wb][ti]) { size_t l = strlen(name); char *b; varNameHdr *vh; if (l > NSEEL_MAX_VARIABLE_NAMELEN) l = NSEEL_MAX_VARIABLE_NAMELEN; b=newCtxDataBlock( (int) (sizeof(varNameHdr) + l+1),1); if (!b) return NULL; // malloc fail vh=(varNameHdr *)b; vh->refcnt=1; vh->isreg=isReg; b+=sizeof(varNameHdr); memcpy(b,name,l); b[l] = 0; ctx->varTable_Names[wb][ti] = b; ctx->varTable_Values[wb][ti]=0.0; if (namePtrOut) *namePtrOut = b; } return ctx->varTable_Values[wb] + ti; } //------------------------------------------------------------------------------ void NSEEL_VM_enumallvars(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F *val, void *ctx), void *userctx) { compileContext *tctx = (compileContext *) ctx; int wb; if (!tctx) return; for (wb = 0; wb < tctx->varTable_numBlocks; wb ++) { int ti; char **plist=tctx->varTable_Names[wb]; if (!plist) break; for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) { if (plist[ti] && !func(plist[ti],tctx->varTable_Values[wb] + ti,userctx)) break; } if (ti < NSEEL_VARS_PER_BLOCK) break; } } //------------------------------------------------------------------------------ EEL_F *NSEEL_VM_regvar(NSEEL_VMCTX _ctx, const char *var) { compileContext *ctx = (compileContext *)_ctx; if (!ctx) return 0; if (!strnicmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4])) { EEL_F *a=get_global_var(ctx,var,1); if (a) return a; } return nseel_int_register_var(ctx,var,1,NULL); } EEL_F *NSEEL_VM_getvar(NSEEL_VMCTX _ctx, const char *var) { compileContext *ctx = (compileContext *)_ctx; if (!ctx) return 0; if (!strnicmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4])) { EEL_F *a=get_global_var(ctx,var,0); if (a) return a; } return nseel_int_register_var(ctx,var,-1,NULL); } int NSEEL_VM_get_var_refcnt(NSEEL_VMCTX _ctx, const char *name) { compileContext *ctx = (compileContext *)_ctx; int wb; if (!ctx) return -1; for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) { int ti; if (!ctx->varTable_Values[wb] || !ctx->varTable_Names[wb]) break; for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) { if (ctx->varTable_Names[wb][ti] && !stricmp(ctx->varTable_Names[wb][ti],name)) { varNameHdr *h = ((varNameHdr *)ctx->varTable_Names[wb][ti])-1; return h->refcnt; } } } return -1; } opcodeRec *nseel_createFunctionByName(compileContext *ctx, const char *name, int np, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3) { int i; for (i=0;nseel_getFunctionFromTableEx(ctx,i);i++) { functionType *f=nseel_getFunctionFromTableEx(ctx,i); if ((f->nParams&FUNCTIONTYPE_PARAMETERCOUNTMASK) == np && !stricmp(f->name, name)) { opcodeRec *o=newOpCode(ctx,NULL, np==3?OPCODETYPE_FUNC3:np==2?OPCODETYPE_FUNC2:OPCODETYPE_FUNC1); if (o) { o->fntype = FUNCTYPE_FUNCTIONTYPEREC; o->fn = f; o->parms.parms[0]=code1; o->parms.parms[1]=code2; o->parms.parms[2]=code3; } return o; } } return NULL; } //------------------------------------------------------------------------------ opcodeRec *nseel_translate(compileContext *ctx, const char *tmp, size_t tmplen) // tmplen 0 = null term { // this depends on the string being nul terminated eventually, tmplen is used more as a hint than anything else if ((tmp[0] == '0' || tmp[0] == '$') && toupper(tmp[1])=='X') { char *p; return nseel_createCompiledValue(ctx,(EEL_F)strtoul(tmp+2,&p,16)); } else if (tmp[0] == '$') { if (tmp[1] == '~') { char *p=(char*)tmp+2; unsigned int v=strtoul(tmp+2,&p,10); if (v>53) v=53; return nseel_createCompiledValue(ctx,(EEL_F)((((WDL_INT64)1) << v) - 1)); } else if (!tmplen ? !stricmp(tmp,"$E") : (tmplen == 2 && !strnicmp(tmp,"$E",2))) return nseel_createCompiledValue(ctx,(EEL_F)2.71828183); else if (!tmplen ? !stricmp(tmp, "$PI") : (tmplen == 3 && !strnicmp(tmp, "$PI", 3))) return nseel_createCompiledValue(ctx,(EEL_F)3.141592653589793); else if (!tmplen ? !stricmp(tmp, "$PHI") : (tmplen == 4 && !strnicmp(tmp, "$PHI", 4))) return nseel_createCompiledValue(ctx,(EEL_F)1.61803399); else if ((!tmplen || tmplen == 4) && tmp[1] == '\'' && tmp[2] && tmp[3] == '\'') return nseel_createCompiledValue(ctx,(EEL_F)tmp[2]); else return NULL; } else if (tmp[0] == '\'') { char b[64]; int x,sz; unsigned int rv=0; if (!tmplen) // nul terminated tmplen, calculate a workable length { // faster than strlen(tmp) if tmp is large, we'll never need more than ~18 chars anyway while (tmplen < 32 && tmp[tmplen]) tmplen++; } sz = tmplen > 0 ? nseel_filter_escaped_string(b,sizeof(b),tmp+1, tmplen - 1, '\'') : 0; if (sz > 4) { if (ctx->last_error_string[0]) lstrcatn(ctx->last_error_string, ", ", sizeof(ctx->last_error_string)); snprintf_append(ctx->last_error_string,sizeof(ctx->last_error_string),"multi-byte character '%.5s...' too long",b); return NULL; // do not allow 'xyzxy', limit to 4 bytes } for (x=0;x sizeof(buf)-1) tmplen = sizeof(buf)-1; memcpy(buf,tmp,tmplen); buf[tmplen]=0; if (ctx->onNamedString) { if (tmplen>0 && buf[1]&&ctx->function_curName) { int err=0; opcodeRec *r = nseel_resolve_named_symbol(ctx,nseel_createCompiledValuePtr(ctx,NULL,buf),-1, &err); if (r) { if (r->opcodeType!=OPCODETYPE_VALUE_FROM_NAMESPACENAME) { r->opcodeType = OPCODETYPE_DIRECTVALUE; r->parms.dv.directValue = ctx->onNamedString(ctx->caller_this,buf+1); r->parms.dv.valuePtr=NULL; } return r; } if (err) return NULL; } // if not namespaced symbol, return directly if (!buf[1]) { opcodeRec *r=newOpCode(ctx,NULL,OPCODETYPE_DIRECTVALUE_TEMPSTRING); if (r) r->parms.dv.directValue = -10000.0; return r; } return nseel_createCompiledValue(ctx,ctx->onNamedString(ctx->caller_this,buf+1)); } } return nseel_createCompiledValue(ctx,(EEL_F)atof(tmp)); } jsusfx-0.4.0/src/WDL/eel2/nseel-eval.c000066400000000000000000000261561353477307700173320ustar00rootroot00000000000000/* Expression Evaluator Library (NS-EEL) v2 Copyright (C) 2004-2013 Cockos Incorporated Copyright (C) 1999-2003 Nullsoft, Inc. nseel-eval.c This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #include #include #include "ns-eel-int.h" #include "../wdlcstring.h" static const char *nseel_skip_space_and_comments(const char *p, const char *endptr) { for (;;) { while (p < endptr && isspace(p[0])) p++; if (p >= endptr-1 || *p != '/') return p; if (p[1]=='/') { while (p < endptr && *p != '\r' && *p != '\n') p++; } else if (p[1] == '*') { p+=2; while (p < endptr-1 && (p[0] != '*' || p[1] != '/')) p++; p+=2; if (p>=endptr) return endptr; } else return p; } } // removes any escaped characters, also will convert pairs delim_char into single delim_chars int nseel_filter_escaped_string(char *outbuf, int outbuf_sz, const char *rdptr, size_t rdptr_size, char delim_char) { int outpos = 0; const char *rdptr_end = rdptr + rdptr_size; while (rdptr < rdptr_end && outpos < outbuf_sz-1) { char thisc=*rdptr; if (thisc == '\\' && rdptr < rdptr_end-1) { const char nc = rdptr[1]; if (nc == 'r' || nc == 'R') { thisc = '\r'; } else if (nc == 'n' || nc == 'N') { thisc = '\n'; } else if (nc == 't' || nc == 'T') { thisc = '\t'; } else if (nc == 'b' || nc == 'B') { thisc = '\b'; } else if ((nc >= '0' && nc <= '9') || nc == 'x' || nc == 'X') { unsigned char c=0; char base_shift = 3; char num_top = '7'; rdptr++; // skip backslash if (nc > '9') // implies xX { base_shift = 4; num_top = '9'; rdptr ++; // skip x } while (rdptr < rdptr_end) { char tc=*rdptr; if (tc >= '0' && tc <= num_top) { c = (c<= 'a' && tc <= 'f') { c = (c<= 'A' && tc <= 'F') { c = (c<str_len; } else if (list->str_len > 1) { if (pos >= bufout_sz) break; pos += nseel_filter_escaped_string(bufOut + pos, bufout_sz-pos, list->str_start+1, list->str_len-1, list->str_start[0]); } list = list->_next; } return pos; } // state can be NULL, it will be set if finished with unterminated thing: 1 for multiline comment, ' or " for string const char *nseel_simple_tokenizer(const char **ptr, const char *endptr, int *lenOut, int *state) { const char *p = *ptr; const char *rv = p; char delim; if (state) // if state set, returns comments as tokens { if (*state == 1) goto in_comment; #ifndef NSEEL_EEL1_COMPAT_MODE if (*state == '\'' || *state == '\"') { delim = (char)*state; goto in_string; } #endif // skip any whitespace while (p < endptr && isspace(p[0])) p++; } else { // state not passed, skip comments (do not return them as tokens) p = nseel_skip_space_and_comments(p,endptr); } if (p >= endptr) { *ptr = endptr; *lenOut = 0; return NULL; } rv=p; if (*p == '$' && p+3 < endptr && p[1] == '\'' && p[3] == '\'') { p+=4; } else if (state && *p == '/' && p < endptr-1 && (p[1] == '/' || p[1] == '*')) { if (p[1] == '/') { while (p < endptr && *p != '\r' && *p != '\n') p++; // advance to end of line } else { if (state) *state=1; p+=2; in_comment: while (p < endptr) { const char c = *p++; if (c == '*' && p < endptr && *p == '/') { p++; if (state) *state=0; break; } } } } else if (isalnum(*p) || *p == '_' || *p == '#' || *p == '$') { if (*p == '$' && p < endptr-1 && p[1] == '~') p++; p++; while (p < endptr && (isalnum(*p) || *p == '_' || *p == '.')) p++; } #ifndef NSEEL_EEL1_COMPAT_MODE else if (*p == '\'' || *p == '\"') { delim = *p++; if (state) *state=delim; in_string: while (p < endptr) { const char c = *p++; if (p < endptr && c == '\\') p++; // skip escaped characters else if (c == delim) { if (state) *state=0; break; } } } #endif else { p++; } *ptr = p; *lenOut = (int) (p - rv); return p>rv ? rv : NULL; } #ifdef NSEEL_SUPER_MINIMAL_LEXER int nseellex(opcodeRec **output, YYLTYPE * yylloc_param, compileContext *scctx) { int rv=0,toklen=0; const char *rdptr = scctx->rdbuf; const char *endptr = scctx->rdbuf_end; const char *tok = nseel_simple_tokenizer(&rdptr,endptr,&toklen,NULL); *output = 0; if (tok) { rv = tok[0]; if (rv == '$') { if (rdptr != tok+1) { *output = nseel_translate(scctx,tok,rdptr-tok); if (*output) rv=VALUE; } } #ifndef NSEEL_EEL1_COMPAT_MODE else if (rv == '#' && scctx->onNamedString) { *output = nseel_translate(scctx,tok,rdptr-tok); if (*output) rv=STRING_IDENTIFIER; } else if (rv == '\'') { if (toklen > 1 && tok[toklen-1] == '\'') { *output = nseel_translate(scctx, tok, toklen); if (*output) rv = VALUE; } else scctx->gotEndOfInput|=8; } else if (rv == '\"' && scctx->onString) { if (toklen > 1 && tok[toklen-1] == '\"') { *output = (opcodeRec *)nseel_createStringSegmentRec(scctx,tok,toklen); if (*output) rv = STRING_LITERAL; } else scctx->gotEndOfInput|=16; } #endif else if (isalpha(rv) || rv == '_') { // toklen already valid char buf[NSEEL_MAX_VARIABLE_NAMELEN*2]; if (toklen > sizeof(buf) - 1) toklen=sizeof(buf) - 1; memcpy(buf,tok,toklen); buf[toklen]=0; *output = nseel_createCompiledValuePtr(scctx, NULL, buf); if (*output) rv = IDENTIFIER; } else if ((rv >= '0' && rv <= '9') || (rv == '.' && (rdptr < endptr && rdptr[0] >= '0' && rdptr[0] <= '9'))) { if (rv == '0' && rdptr < endptr && (rdptr[0] == 'x' || rdptr[0] == 'X')) { rdptr++; while (rdptr < endptr && (rv=rdptr[0]) && ((rv>='0' && rv<='9') || (rv>='a' && rv<='f') || (rv>='A' && rv<='F'))) rdptr++; } else { int pcnt=rv == '.'; while (rdptr < endptr && (rv=rdptr[0]) && ((rv>='0' && rv<='9') || (rv == '.' && !pcnt++))) rdptr++; } *output = nseel_translate(scctx,tok,rdptr-tok); if (*output) rv=VALUE; } else if (rv == '<') { const char nc=*rdptr; if (nc == '<') { rdptr++; rv=TOKEN_SHL; } else if (nc == '=') { rdptr++; rv=TOKEN_LTE; } } else if (rv == '>') { const char nc=*rdptr; if (nc == '>') { rdptr++; rv=TOKEN_SHR; } else if (nc == '=') { rdptr++; rv=TOKEN_GTE; } } else if (rv == '&' && *rdptr == '&') { rdptr++; rv = TOKEN_LOGICAL_AND; } else if (rv == '|' && *rdptr == '|') { rdptr++; rv = TOKEN_LOGICAL_OR; } else if (*rdptr == '=') { switch (rv) { case '+': rv=TOKEN_ADD_OP; rdptr++; break; case '-': rv=TOKEN_SUB_OP; rdptr++; break; case '%': rv=TOKEN_MOD_OP; rdptr++; break; case '|': rv=TOKEN_OR_OP; rdptr++; break; case '&': rv=TOKEN_AND_OP; rdptr++; break; case '~': rv=TOKEN_XOR_OP; rdptr++; break; case '/': rv=TOKEN_DIV_OP; rdptr++; break; case '*': rv=TOKEN_MUL_OP; rdptr++; break; case '^': rv=TOKEN_POW_OP; rdptr++; break; case '!': rdptr++; if (rdptr < endptr && *rdptr == '=') { rdptr++; rv=TOKEN_NE_EXACT; } else rv=TOKEN_NE; break; case '=': rdptr++; if (rdptr < endptr && *rdptr == '=') { rdptr++; rv=TOKEN_EQ_EXACT; } else rv=TOKEN_EQ; break; } } } scctx->rdbuf = rdptr; yylloc_param->first_column = (int)(tok - scctx->rdbuf_start); return rv; } void nseelerror(YYLTYPE *pos,compileContext *ctx, const char *str) { ctx->errVar=pos->first_column>0?pos->first_column:(int)(ctx->rdbuf_end - ctx->rdbuf_start); } #else int nseel_gets(compileContext *ctx, char *buf, size_t sz) { int n=0; const char *endptr = ctx->rdbuf_end; const char *rdptr = ctx->rdbuf; if (!rdptr) return 0; while (n < sz && rdptr < endptr) buf[n++] = *rdptr++; ctx->rdbuf=rdptr; return n; } //#define EEL_TRACE_LEX #ifdef EEL_TRACE_LEX #define nseellex nseellex2 #endif #include "lex.nseel.c" #ifdef EEL_TRACE_LEX #undef nseellex int nseellex(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) { int a=nseellex2(yylval_param,yylloc_param,yyscanner); char buf[512]; sprintf(buf,"tok: %c (%d)\n",a,a); OutputDebugString(buf); return a; } #endif//EEL_TRACE_LEX void nseelerror(YYLTYPE *pos,compileContext *ctx, const char *str) { ctx->errVar=pos->first_column>0?pos->first_column:(int)(ctx->rdbuf_end - ctx->rdbuf_start); } #endif // !NSEEL_SUPER_MINIMAL_LEXER jsusfx-0.4.0/src/WDL/eel2/nseel-lextab.c000066400000000000000000000000211353477307700176410ustar00rootroot00000000000000// no longer usedjsusfx-0.4.0/src/WDL/eel2/nseel-ram.c000066400000000000000000000302651353477307700171560ustar00rootroot00000000000000/* Expression Evaluator Library (NS-EEL) v2 Copyright (C) 2004-2013 Cockos Incorporated Copyright (C) 1999-2003 Nullsoft, Inc. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #include "ns-eel.h" #include "ns-eel-int.h" #include #include #include #include #ifdef _WIN32 #include #ifdef _MSC_VER #define inline __inline #endif #endif unsigned int NSEEL_RAM_limitmem=0; unsigned int NSEEL_RAM_memused=0; int NSEEL_RAM_memused_errors=0; int NSEEL_VM_wantfreeRAM(NSEEL_VMCTX ctx) { if (ctx) { compileContext *c=(compileContext*)ctx; if (c->ram_state.needfree) return 1; } return 0; } void NSEEL_VM_freeRAMIfCodeRequested(NSEEL_VMCTX ctx) // check to see if our free flag was set { if (ctx) { compileContext *c=(compileContext*)ctx; if (c->ram_state.needfree) { NSEEL_HOSTSTUB_EnterMutex(); { INT_PTR startpos=((INT_PTR)c->ram_state.needfree)-1; EEL_F **blocks = c->ram_state.blocks; INT_PTR pos=0; int x; for (x = 0; x < NSEEL_RAM_BLOCKS; x ++) { if (pos >= startpos) { if (blocks[x]) { if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK) NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; else NSEEL_RAM_memused_errors++; free(blocks[x]); blocks[x]=0; } } pos+=NSEEL_RAM_ITEMSPERBLOCK; } c->ram_state.needfree=0; } NSEEL_HOSTSTUB_LeaveMutex(); } } } EEL_F nseel_ramalloc_onfail; EEL_F * volatile nseel_gmembuf_default; EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAllocGMEM(EEL_F ***blocks, unsigned int w) { if (blocks) { EEL_F **pblocks=*blocks; if (w < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) { const unsigned int whichblock = w/NSEEL_RAM_ITEMSPERBLOCK; EEL_F *p=NULL; if (!pblocks || !(p=pblocks[whichblock])) { NSEEL_HOSTSTUB_EnterMutex(); if (!(pblocks=*blocks)) pblocks = *blocks = (EEL_F **)calloc(sizeof(EEL_F *),NSEEL_RAM_BLOCKS); else p = pblocks[whichblock]; if (!p && pblocks) { const int msize=sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; if (!NSEEL_RAM_limitmem || NSEEL_RAM_memused+msize < NSEEL_RAM_limitmem) { p=pblocks[whichblock]=(EEL_F *)calloc(sizeof(EEL_F),NSEEL_RAM_ITEMSPERBLOCK); if (p) NSEEL_RAM_memused+=msize; } } NSEEL_HOSTSTUB_LeaveMutex(); } if (p) return p + (w&(NSEEL_RAM_ITEMSPERBLOCK-1)); } return &nseel_ramalloc_onfail; } if (!nseel_gmembuf_default) { NSEEL_HOSTSTUB_EnterMutex(); if (!nseel_gmembuf_default) nseel_gmembuf_default=(EEL_F*)calloc(sizeof(EEL_F),NSEEL_SHARED_GRAM_SIZE); NSEEL_HOSTSTUB_LeaveMutex(); if (!nseel_gmembuf_default) return &nseel_ramalloc_onfail; } return nseel_gmembuf_default+(((unsigned int)w)&((NSEEL_SHARED_GRAM_SIZE)-1)); } EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAlloc(EEL_F **pblocks, unsigned int w) { // fprintf(stderr,"got request at %d, %d\n",w/NSEEL_RAM_ITEMSPERBLOCK, w&(NSEEL_RAM_ITEMSPERBLOCK-1)); if (w < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) { unsigned int whichblock = w/NSEEL_RAM_ITEMSPERBLOCK; EEL_F *p=pblocks[whichblock]; if (!p && whichblock < ((unsigned int *)pblocks)[-3]) // pblocks -1/-2 are closefact, -3 is maxblocks { NSEEL_HOSTSTUB_EnterMutex(); if (!(p=pblocks[whichblock])) { const int msize=sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; if (!NSEEL_RAM_limitmem || NSEEL_RAM_memused+msize < NSEEL_RAM_limitmem) { p=pblocks[whichblock]=(EEL_F *)calloc(sizeof(EEL_F),NSEEL_RAM_ITEMSPERBLOCK); if (p) NSEEL_RAM_memused+=msize; } } NSEEL_HOSTSTUB_LeaveMutex(); } if (p) return p + (w&(NSEEL_RAM_ITEMSPERBLOCK-1)); } // fprintf(stderr,"ret 0\n"); return &nseel_ramalloc_onfail; } EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemFree(void *blocks, EEL_F *which) { // blocks points to ram_state.blocks, so back it up past closefact and maxblocks to needfree int *flag = (int *)((char *)blocks - sizeof(double) - 2*sizeof(int)); int d=(int)(*which); if (d < 0) d=0; if (d < flag[1]*NSEEL_RAM_ITEMSPERBLOCK) flag[0]=1+d; return which; } EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemTop(void *blocks, EEL_F *which) { // blocks points to ram_state.blocks, so back it up past closefact to maxblocks const int *flag = (int *)((char *)blocks - sizeof(double) - sizeof(int)); *which = flag[0]*NSEEL_RAM_ITEMSPERBLOCK; return which; } EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemCpy(EEL_F **blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr) { const int mem_size=NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK; int dest_offs = (int)(*dest + 0.0001); int src_offs = (int)(*src + 0.0001); int len = (int)(*lenptr + 0.0001); int want_mmove=0; // trim to front if (src_offs<0) { len += src_offs; dest_offs -= src_offs; src_offs=0; } if (dest_offs<0) { len += dest_offs; src_offs -= dest_offs; dest_offs=0; } if (src_offs + len > mem_size) len = mem_size-src_offs; if (dest_offs + len > mem_size) len = mem_size-dest_offs; if (src_offs == dest_offs || len < 1) return dest; if (src_offs < dest_offs && src_offs+len > dest_offs) { // if src_offs < dest_offs and overlapping, must copy right to left if ((dest_offs - src_offs) < NSEEL_RAM_ITEMSPERBLOCK) want_mmove = 1; src_offs += len; dest_offs += len; while (len > 0) { const int maxdlen=((dest_offs-1)&(NSEEL_RAM_ITEMSPERBLOCK-1)) + 1; const int maxslen=((src_offs-1)&(NSEEL_RAM_ITEMSPERBLOCK-1)) + 1; int copy_len = len; EEL_F *srcptr,*destptr; if (copy_len > maxdlen) copy_len=maxdlen; if (copy_len > maxslen) copy_len=maxslen; srcptr = __NSEEL_RAMAlloc(blocks,src_offs - copy_len); destptr = __NSEEL_RAMAlloc(blocks,dest_offs - copy_len); if (srcptr==&nseel_ramalloc_onfail || destptr==&nseel_ramalloc_onfail) break; if (want_mmove) memmove(destptr,srcptr,sizeof(EEL_F)*copy_len); else memcpy(destptr,srcptr,sizeof(EEL_F)*copy_len); src_offs-=copy_len; dest_offs-=copy_len; len-=copy_len; } return dest; } if (dest_offs < src_offs && dest_offs+len > src_offs) { // if dest_offs < src_offs and overlapping, and less than NSEEL_RAM_ITEMSPERBLOCK apart, use memmove() if ((src_offs-dest_offs) < NSEEL_RAM_ITEMSPERBLOCK) want_mmove = 1; } while (len > 0) { const int maxdlen=NSEEL_RAM_ITEMSPERBLOCK - (dest_offs&(NSEEL_RAM_ITEMSPERBLOCK-1)); const int maxslen=NSEEL_RAM_ITEMSPERBLOCK - (src_offs&(NSEEL_RAM_ITEMSPERBLOCK-1)); int copy_len = len; EEL_F *srcptr,*destptr; if (copy_len > maxdlen) copy_len=maxdlen; if (copy_len > maxslen) copy_len=maxslen; srcptr = __NSEEL_RAMAlloc(blocks,src_offs); destptr = __NSEEL_RAMAlloc(blocks,dest_offs); if (srcptr==&nseel_ramalloc_onfail || destptr==&nseel_ramalloc_onfail) break; if (want_mmove) memmove(destptr,srcptr,sizeof(EEL_F)*copy_len); else memcpy(destptr,srcptr,sizeof(EEL_F)*copy_len); src_offs+=copy_len; dest_offs+=copy_len; len-=copy_len; } return dest; } EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemSet(EEL_F **blocks,EEL_F *dest, EEL_F *v, EEL_F *lenptr) { int offs = (int)(*dest + 0.0001); int len = (int)(*lenptr + 0.0001); EEL_F t; if (offs<0) { len += offs; offs=0; } if (offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) return dest; if (offs+len > NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) len = NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - offs; if (len < 1) return dest; t=*v; // set value // int lastBlock=-1; while (len > 0) { int lcnt; EEL_F *ptr=__NSEEL_RAMAlloc(blocks,offs); if (ptr==&nseel_ramalloc_onfail) break; lcnt=NSEEL_RAM_ITEMSPERBLOCK-(offs&(NSEEL_RAM_ITEMSPERBLOCK-1)); if (lcnt > len) lcnt=len; len -= lcnt; offs += lcnt; while (lcnt--) { *ptr++=t; } } return dest; } static inline int __getset_values(EEL_F **blocks, int isset, int len, EEL_F **parms) { int offs, lout=0; unsigned int pageidx, sub_offs; if (--len < 1) return 0; offs = (int)(parms++[0][0] + 0.0001); if (offs<=0) { len += offs; parms -= offs; offs=0; pageidx=sub_offs=0; if (len<1) return 0; } else { sub_offs = ((unsigned int)offs) & (NSEEL_RAM_ITEMSPERBLOCK-1); pageidx = ((unsigned int)offs)>>NSEEL_RAM_ITEMSPERBLOCK_LOG2; if (pageidx>=NSEEL_RAM_BLOCKS) return 0; } for (;;) { int lcnt=NSEEL_RAM_ITEMSPERBLOCK-sub_offs; EEL_F *ptr=blocks[pageidx]; if (!ptr) { ptr = __NSEEL_RAMAlloc(blocks,offs + lout); if (ptr==&nseel_ramalloc_onfail) return lout; } else { ptr += sub_offs; } if (lcnt >= len) { // this page satisfies the request (normal behavior) lout += len; if (isset) while (len--) *ptr++=parms++[0][0]; else while (len--) parms++[0][0] = *ptr++; return lout; } // crossing a page boundary len -= lcnt; lout += lcnt; if (isset) while (lcnt--) *ptr++=parms++[0][0]; else while (lcnt--) parms++[0][0] = *ptr++; if (len <= 0 || ++pageidx >= NSEEL_RAM_BLOCKS) return lout; sub_offs=0; } } EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_Mem_SetValues(EEL_F **blocks, INT_PTR np, EEL_F **parms) { return __getset_values(blocks,1,(int)np,parms); } EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_Mem_GetValues(EEL_F **blocks, INT_PTR np, EEL_F **parms) { return __getset_values(blocks,0,(int)np,parms); } void NSEEL_VM_SetGRAM(NSEEL_VMCTX ctx, void **gram) { if (ctx) { compileContext *c=(compileContext*)ctx; c->gram_blocks = gram; } } void NSEEL_VM_freeRAM(NSEEL_VMCTX ctx) { if (ctx) { int x; compileContext *c=(compileContext*)ctx; EEL_F **blocks = c->ram_state.blocks; for (x = 0; x < NSEEL_RAM_BLOCKS; x ++) { if (blocks[x]) { if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK) NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; else NSEEL_RAM_memused_errors++; free(blocks[x]); blocks[x]=0; } } c->ram_state.needfree=0; // no need to free anymore } } void NSEEL_VM_FreeGRAM(void **ufd) { if (ufd[0]) { EEL_F **blocks = (EEL_F **)ufd[0]; int x; for (x = 0; x < NSEEL_RAM_BLOCKS; x ++) { if (blocks[x]) { if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK) NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; else NSEEL_RAM_memused_errors++; } free(blocks[x]); blocks[x]=0; } free(blocks); ufd[0]=0; } } EEL_F *NSEEL_VM_getramptr(NSEEL_VMCTX ctx, unsigned int offs, int *validCount) { EEL_F *d=__NSEEL_RAMAlloc(ctx ? ((compileContext*)ctx)->ram_state.blocks : 0,offs); if (!d || d == &nseel_ramalloc_onfail) return NULL; if (validCount) *validCount = NSEEL_RAM_ITEMSPERBLOCK - (offs%NSEEL_RAM_ITEMSPERBLOCK); return d; } EEL_F *NSEEL_VM_getramptr_noalloc(NSEEL_VMCTX ctx, unsigned int offs, int *validCount) { EEL_F *d; compileContext *cc = (compileContext *)ctx; if (!cc || offs >= NSEEL_RAM_ITEMSPERBLOCK*NSEEL_RAM_BLOCKS || NULL == (d = cc->ram_state.blocks[offs/NSEEL_RAM_ITEMSPERBLOCK]) ) { if (validCount) *validCount = 0; return NULL; } offs %= NSEEL_RAM_ITEMSPERBLOCK; if (validCount) *validCount = NSEEL_RAM_ITEMSPERBLOCK - offs; return d + offs; } jsusfx-0.4.0/src/WDL/eel2/nseel-yylex.c000066400000000000000000000023751353477307700175520ustar00rootroot00000000000000/* Expression Evaluator Library (NS-EEL) Copyright (C) 2004-2013 Cockos Incorporated Copyright (C) 1999-2003 Nullsoft, Inc. nseel-yylex.c This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #include "ns-eel-int.h" # define YYMALLOC malloc # define YYFREE free int nseellex(void * yylval_param,void * yylloc_param ,void *yyscanner); void nseelerror(void *pos,compileContext *ctx, const char *str); #include #include #include "y.tab.c" jsusfx-0.4.0/src/WDL/eel2/y.tab.c000066400000000000000000001746771353477307700163300ustar00rootroot00000000000000/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Using locations. */ #define YYLSP_NEEDED 1 /* Substitute the variable and function names. */ #define yyparse nseelparse #define yylex nseellex #define yyerror nseelerror #define yylval nseellval #define yychar nseelchar #define yydebug nseeldebug #define yynerrs nseelnerrs #define yylloc nseellloc /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { VALUE = 258, IDENTIFIER = 259, TOKEN_SHL = 260, TOKEN_SHR = 261, TOKEN_LTE = 262, TOKEN_GTE = 263, TOKEN_EQ = 264, TOKEN_EQ_EXACT = 265, TOKEN_NE = 266, TOKEN_NE_EXACT = 267, TOKEN_LOGICAL_AND = 268, TOKEN_LOGICAL_OR = 269, TOKEN_ADD_OP = 270, TOKEN_SUB_OP = 271, TOKEN_MOD_OP = 272, TOKEN_OR_OP = 273, TOKEN_AND_OP = 274, TOKEN_XOR_OP = 275, TOKEN_DIV_OP = 276, TOKEN_MUL_OP = 277, TOKEN_POW_OP = 278, STRING_LITERAL = 279, STRING_IDENTIFIER = 280 }; #endif /* Tokens. */ #define VALUE 258 #define IDENTIFIER 259 #define TOKEN_SHL 260 #define TOKEN_SHR 261 #define TOKEN_LTE 262 #define TOKEN_GTE 263 #define TOKEN_EQ 264 #define TOKEN_EQ_EXACT 265 #define TOKEN_NE 266 #define TOKEN_NE_EXACT 267 #define TOKEN_LOGICAL_AND 268 #define TOKEN_LOGICAL_OR 269 #define TOKEN_ADD_OP 270 #define TOKEN_SUB_OP 271 #define TOKEN_MOD_OP 272 #define TOKEN_OR_OP 273 #define TOKEN_AND_OP 274 #define TOKEN_XOR_OP 275 #define TOKEN_DIV_OP 276 #define TOKEN_MUL_OP 277 #define TOKEN_POW_OP 278 #define STRING_LITERAL 279 #define STRING_IDENTIFIER 280 /* Copy the first part of user declarations. */ #line 13 "eel2.y" #ifdef _WIN32 #include #endif #include #include #include #include #include "y.tab.h" #include "ns-eel-int.h" #define scanner context->scanner #define YY_(x) ("") /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED typedef struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; } YYLTYPE; # define yyltype YYLTYPE /* obsolescent; will be withdrawn */ # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 193 "y.tab.c" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; YYLTYPE yyls; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + 2 * YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 68 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 141 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 47 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 19 /* YYNRULES -- Number of rules. */ #define YYNRULES 73 /* YYNRULES -- Number of states. */ #define YYNSTATES 127 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 280 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 34, 2, 2, 2, 36, 39, 2, 27, 28, 38, 32, 26, 33, 2, 37, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 46, 42, 31, 43, 44, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 29, 2, 30, 35, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 40, 2, 41, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint16 yyprhs[] = { 0, 0, 3, 5, 9, 11, 14, 16, 20, 28, 33, 37, 44, 53, 57, 62, 64, 66, 68, 70, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 122, 125, 128, 131, 133, 137, 139, 143, 147, 151, 153, 157, 159, 163, 165, 169, 171, 175, 177, 181, 185, 189, 191, 195, 199, 203, 207, 211, 215, 219, 223, 225, 229, 233, 235, 241, 246, 250, 252, 256, 259 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 65, 0, -1, 64, -1, 64, 26, 48, -1, 24, -1, 24, 49, -1, 4, -1, 27, 64, 28, -1, 4, 27, 64, 28, 27, 64, 28, -1, 4, 27, 64, 28, -1, 4, 27, 28, -1, 4, 27, 64, 26, 64, 28, -1, 4, 27, 64, 26, 64, 26, 48, 28, -1, 51, 29, 30, -1, 51, 29, 64, 30, -1, 3, -1, 25, -1, 49, -1, 50, -1, 51, -1, 50, 31, 63, -1, 50, 15, 63, -1, 50, 16, 63, -1, 50, 17, 63, -1, 50, 18, 63, -1, 50, 19, 63, -1, 50, 20, 63, -1, 50, 21, 63, -1, 50, 22, 63, -1, 50, 23, 63, -1, 25, 31, 63, -1, 25, 15, 63, -1, 52, -1, 32, 53, -1, 33, 53, -1, 34, 53, -1, 53, -1, 54, 35, 53, -1, 54, -1, 55, 36, 54, -1, 55, 5, 54, -1, 55, 6, 54, -1, 55, -1, 56, 37, 55, -1, 56, -1, 57, 38, 56, -1, 57, -1, 58, 33, 57, -1, 58, -1, 59, 32, 58, -1, 59, -1, 60, 39, 59, -1, 60, 40, 59, -1, 60, 41, 59, -1, 60, -1, 61, 42, 60, -1, 61, 43, 60, -1, 61, 7, 60, -1, 61, 8, 60, -1, 61, 9, 60, -1, 61, 10, 60, -1, 61, 11, 60, -1, 61, 12, 60, -1, 61, -1, 62, 13, 61, -1, 62, 14, 61, -1, 62, -1, 62, 44, 63, 45, 63, -1, 62, 44, 45, 63, -1, 62, 44, 63, -1, 63, -1, 64, 46, 63, -1, 64, 46, -1, 64, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 40, 40, 41, 48, 49, 57, 67, 71, 83, 93, 103, 114, 126, 130, 137, 138, 139, 143, 148, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185, 189, 193, 200, 201, 205, 209, 216, 217, 224, 225, 229, 233, 240, 241, 249, 250, 258, 259, 266, 267, 274, 275, 279, 283, 290, 291, 295, 299, 303, 307, 311, 315, 319, 326, 327, 331, 338, 339, 343, 347, 355, 356, 360, 368 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "VALUE", "IDENTIFIER", "TOKEN_SHL", "TOKEN_SHR", "TOKEN_LTE", "TOKEN_GTE", "TOKEN_EQ", "TOKEN_EQ_EXACT", "TOKEN_NE", "TOKEN_NE_EXACT", "TOKEN_LOGICAL_AND", "TOKEN_LOGICAL_OR", "TOKEN_ADD_OP", "TOKEN_SUB_OP", "TOKEN_MOD_OP", "TOKEN_OR_OP", "TOKEN_AND_OP", "TOKEN_XOR_OP", "TOKEN_DIV_OP", "TOKEN_MUL_OP", "TOKEN_POW_OP", "STRING_LITERAL", "STRING_IDENTIFIER", "','", "'('", "')'", "'['", "']'", "'='", "'+'", "'-'", "'!'", "'^'", "'%'", "'/'", "'*'", "'&'", "'|'", "'~'", "'<'", "'>'", "'?'", "':'", "';'", "$accept", "more_params", "string", "assignable_value", "rvalue", "assignment", "unary_expr", "pow_expr", "mod_expr", "div_expr", "mul_expr", "sub_expr", "add_expr", "andor_expr", "cmp_expr", "logical_and_or_expr", "if_else_expr", "expression", "program", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 44, 40, 41, 91, 93, 61, 43, 45, 33, 94, 37, 47, 42, 38, 124, 126, 60, 62, 63, 58, 59 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 47, 48, 48, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 55, 55, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, 62, 62, 63, 63, 63, 63, 64, 64, 64, 65 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 1, 3, 1, 2, 1, 3, 7, 4, 3, 6, 8, 3, 4, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 2, 2, 2, 1, 3, 1, 3, 3, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 1, 5, 4, 3, 1, 3, 2, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 15, 6, 4, 16, 0, 0, 0, 0, 17, 18, 19, 32, 36, 38, 42, 44, 46, 48, 50, 54, 63, 66, 70, 73, 0, 0, 5, 0, 0, 0, 33, 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 1, 10, 0, 31, 30, 7, 21, 22, 23, 24, 25, 26, 27, 28, 29, 20, 13, 0, 37, 40, 41, 39, 43, 45, 47, 49, 51, 52, 53, 57, 58, 59, 60, 61, 62, 55, 56, 64, 65, 0, 69, 71, 0, 9, 14, 68, 0, 0, 0, 67, 0, 11, 0, 0, 2, 8, 12, 0, 3 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 121, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 122, 25 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -38 static const yytype_int8 yypact[] = { 70, -38, -21, 12, -11, 70, 70, 70, 70, -38, 102, 6, -38, -38, 50, 19, 4, 8, 14, 25, 51, 22, 40, -38, 47, 96, 34, -38, 70, 70, 43, -38, -38, -38, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 45, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 18, 70, -38, -38, 55, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, 30, -38, 50, 50, 50, 19, 4, 8, 14, 25, 25, 25, 51, 51, 51, 51, 51, 51, 51, 51, 22, 22, 70, 53, -38, 70, 72, -38, -38, 70, 60, 70, -38, 70, -38, 54, 77, -23, -38, -38, 70, -38 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -38, -10, 111, -38, -38, -38, 11, 61, 79, 76, 80, 75, 58, 78, -37, -38, -27, 0, -38 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { 24, 71, 72, 125, 28, 30, 26, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 31, 32, 33, 29, 1, 2, 67, 46, 47, 70, 105, 106, 56, 57, 58, 59, 60, 61, 44, 3, 1, 2, 108, 109, 49, 3, 4, 85, 5, 50, 51, 1, 2, 6, 7, 8, 64, 65, 48, 86, 52, 3, 4, 112, 5, 69, 107, 62, 63, 6, 7, 8, 3, 4, 73, 5, 1, 2, 84, 67, 6, 7, 8, 113, 110, 123, 111, 66, 45, 118, 117, 119, 67, 53, 54, 55, 67, 3, 4, 68, 5, 114, 116, 67, 67, 6, 7, 8, 124, 67, 87, 88, 89, 115, 94, 95, 96, 27, 126, 120, 34, 35, 36, 37, 38, 39, 40, 41, 42, 91, 93, 90, 0, 0, 92, 0, 43, 97, 98, 99, 100, 101, 102, 103, 104 }; static const yytype_int8 yycheck[] = { 0, 28, 29, 26, 15, 5, 27, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 6, 7, 8, 31, 3, 4, 46, 5, 6, 26, 64, 65, 7, 8, 9, 10, 11, 12, 29, 24, 3, 4, 66, 67, 37, 24, 25, 44, 27, 38, 33, 3, 4, 32, 33, 34, 13, 14, 36, 45, 32, 24, 25, 30, 27, 28, 45, 42, 43, 32, 33, 34, 24, 25, 28, 27, 3, 4, 30, 46, 32, 33, 34, 107, 26, 28, 28, 44, 35, 26, 114, 28, 46, 39, 40, 41, 46, 24, 25, 0, 27, 45, 27, 46, 46, 32, 33, 34, 28, 46, 46, 47, 48, 110, 53, 54, 55, 3, 125, 116, 15, 16, 17, 18, 19, 20, 21, 22, 23, 50, 52, 49, -1, -1, 51, -1, 31, 56, 57, 58, 59, 60, 61, 62, 63 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 3, 4, 24, 25, 27, 32, 33, 34, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 27, 49, 15, 31, 64, 53, 53, 53, 15, 16, 17, 18, 19, 20, 21, 22, 23, 31, 29, 35, 5, 6, 36, 37, 38, 33, 32, 39, 40, 41, 7, 8, 9, 10, 11, 12, 42, 43, 13, 14, 44, 46, 0, 28, 64, 63, 63, 28, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 30, 64, 53, 54, 54, 54, 55, 56, 57, 58, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 45, 63, 63, 26, 28, 30, 63, 45, 64, 27, 63, 26, 28, 64, 48, 64, 28, 28, 26, 48 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (&yylloc, context, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, &yylloc, scanner) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, Location, context); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, compileContext* context) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; YYLTYPE const * const yylocationp; compileContext* context; #endif { if (!yyvaluep) return; YYUSE (yylocationp); YYUSE (context); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, compileContext* context) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, context) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; YYLTYPE const * const yylocationp; compileContext* context; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); YY_LOCATION_PRINT (yyoutput, *yylocationp); YYFPRINTF (yyoutput, ": "); yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, compileContext* context) #else static void yy_reduce_print (yyvsp, yylsp, yyrule, context) YYSTYPE *yyvsp; YYLTYPE *yylsp; int yyrule; compileContext* context; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , &(yylsp[(yyi + 1) - (yynrhs)]) , context); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, yylsp, Rule, context); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, compileContext* context) #else static void yydestruct (yymsg, yytype, yyvaluep, yylocationp, context) const char *yymsg; int yytype; YYSTYPE *yyvaluep; YYLTYPE *yylocationp; compileContext* context; #endif { YYUSE (yyvaluep); YYUSE (yylocationp); YYUSE (context); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { case 3: /* "VALUE" */ #line 8 "eel2.y" { #define yydestruct(a,b,c,d,e) }; #line 1222 "y.tab.c" break; default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (compileContext* context); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (compileContext* context) #else int yyparse (context) compileContext* context; #endif #endif { /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /* Location data for the look-ahead symbol. */ YYLTYPE yylloc; int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; /* The location stack. */ YYLTYPE yylsa[YYINITDEPTH]; YYLTYPE *yyls = yylsa; YYLTYPE *yylsp; /* The locations where the error started and ended. */ YYLTYPE yyerror_range[2]; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; YYLTYPE yyloc; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; yylsp = yyls; #if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL /* Initialize the default location before parsing starts. */ yylloc.first_line = yylloc.last_line = 1; yylloc.first_column = yylloc.last_column = 0; #endif goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; YYLTYPE *yyls1 = yyls; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yyls1, yysize * sizeof (*yylsp), &yystacksize); yyls = yyls1; yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); YYSTACK_RELOCATE (yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; yylsp = yyls + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; *++yylsp = yylloc; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; /* Default location. */ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); YY_REDUCE_PRINT (yyn); switch (yyn) { case 3: #line 42 "eel2.y" { (yyval) = nseel_createMoreParametersOpcode(context,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 5: #line 50 "eel2.y" { ((struct eelStringSegmentRec *)(yyvsp[(1) - (2)]))->_next = (struct eelStringSegmentRec *)(yyvsp[(2) - (2)]); (yyval) = (yyvsp[(1) - (2)]); } break; case 6: #line 58 "eel2.y" { if (!((yyval) = nseel_resolve_named_symbol(context, (yyvsp[(1) - (1)]), -1, NULL))) /* convert from purely named to namespace-relative, etc */ { yyerror(&yyloc, context, ""); YYERROR; } } break; case 7: #line 68 "eel2.y" { (yyval) = (yyvsp[(2) - (3)]); } break; case 8: #line 72 "eel2.y" { int err; if (!((yyval) = nseel_setCompiledFunctionCallParameters(context,(yyvsp[(1) - (7)]), (yyvsp[(3) - (7)]), 0, 0, (yyvsp[(6) - (7)]), &err))) { if (err == -1) yyerror(&yylsp[-2], context, ""); else if (err == 0) yyerror(&yylsp[-6], context, ""); else yyerror(&yylsp[-3], context, ""); // parameter count wrong YYERROR; } } break; case 9: #line 84 "eel2.y" { int err; if (!((yyval) = nseel_setCompiledFunctionCallParameters(context,(yyvsp[(1) - (4)]), (yyvsp[(3) - (4)]), 0, 0, 0, &err))) { if (err == 0) yyerror(&yylsp[-3], context, ""); else yyerror(&yylsp[0], context, ""); // parameter count wrong YYERROR; } } break; case 10: #line 94 "eel2.y" { int err; if (!((yyval) = nseel_setCompiledFunctionCallParameters(context,(yyvsp[(1) - (3)]), nseel_createCompiledValue(context,0.0), 0, 0, 0,&err))) { if (err == 0) yyerror(&yylsp[-2], context, ""); // function not found else yyerror(&yylsp[0], context, ""); // parameter count wrong YYERROR; } } break; case 11: #line 104 "eel2.y" { int err; if (!((yyval) = nseel_setCompiledFunctionCallParameters(context,(yyvsp[(1) - (6)]), (yyvsp[(3) - (6)]), (yyvsp[(5) - (6)]), 0, 0,&err))) { if (err == 0) yyerror(&yylsp[-5], context, ""); else if (err == 2) yyerror(&yylsp[0], context, ""); // needs more than 2 parameters else yyerror(&yylsp[-2], context, ""); // less than 2 YYERROR; } } break; case 12: #line 115 "eel2.y" { int err; if (!((yyval) = nseel_setCompiledFunctionCallParameters(context,(yyvsp[(1) - (8)]), (yyvsp[(3) - (8)]), (yyvsp[(5) - (8)]), (yyvsp[(7) - (8)]), 0, &err))) { if (err == 0) yyerror(&yylsp[-7], context, ""); else if (err==2) yyerror(&yylsp[0], context, ""); // needs more parameters else if (err==4) yyerror(&yylsp[-4], context, ""); // needs single parameter else yyerror(&yylsp[-2], context, ""); // less parm YYERROR; } } break; case 13: #line 127 "eel2.y" { (yyval) = nseel_createMemoryAccess(context,(yyvsp[(1) - (3)]),0); } break; case 14: #line 131 "eel2.y" { (yyval) = nseel_createMemoryAccess(context,(yyvsp[(1) - (4)]),(yyvsp[(3) - (4)])); } break; case 17: #line 140 "eel2.y" { (yyval) = nseel_eelMakeOpcodeFromStringSegments(context,(struct eelStringSegmentRec *)(yyvsp[(1) - (1)])); } break; case 20: #line 150 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_ASSIGN,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 21: #line 154 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_ADD_OP,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 22: #line 158 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_SUB_OP,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 23: #line 162 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_MOD_OP,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 24: #line 166 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_OR_OP,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 25: #line 170 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_AND_OP,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 26: #line 174 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_XOR_OP,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 27: #line 178 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_DIV_OP,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 28: #line 182 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_MUL_OP,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 29: #line 186 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_POW_OP,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 30: #line 190 "eel2.y" { (yyval) = nseel_createFunctionByName(context,"strcpy",2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),NULL); } break; case 31: #line 194 "eel2.y" { (yyval) = nseel_createFunctionByName(context,"strcat",2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),NULL); } break; case 33: #line 202 "eel2.y" { (yyval) = (yyvsp[(2) - (2)]); } break; case 34: #line 206 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_UMINUS,1,(yyvsp[(2) - (2)]),0); } break; case 35: #line 210 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_NOT,1,(yyvsp[(2) - (2)]),0); } break; case 37: #line 218 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_POW,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 39: #line 226 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_MOD,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 40: #line 230 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_SHL,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 41: #line 234 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_SHR,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 43: #line 242 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_DIVIDE,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 45: #line 251 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_MULTIPLY,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 47: #line 260 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_SUB,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 49: #line 268 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_ADD,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 51: #line 276 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_AND,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 52: #line 280 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_OR,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 53: #line 284 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_XOR,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 55: #line 292 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_LT,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 56: #line 296 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_GT,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 57: #line 300 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_LTE,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 58: #line 304 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_GTE,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 59: #line 308 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_EQ,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 60: #line 312 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_EQ_EXACT,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 61: #line 316 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_NE,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 62: #line 320 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_NE_EXACT,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 64: #line 328 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_LOGICAL_AND,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 65: #line 332 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_LOGICAL_OR,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 67: #line 340 "eel2.y" { (yyval) = nseel_createIfElse(context, (yyvsp[(1) - (5)]), (yyvsp[(3) - (5)]), (yyvsp[(5) - (5)])); } break; case 68: #line 344 "eel2.y" { (yyval) = nseel_createIfElse(context, (yyvsp[(1) - (4)]), 0, (yyvsp[(4) - (4)])); } break; case 69: #line 348 "eel2.y" { (yyval) = nseel_createIfElse(context, (yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), 0); } break; case 71: #line 357 "eel2.y" { (yyval) = nseel_createSimpleCompiledFunction(context,FN_JOIN_STATEMENTS,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); } break; case 72: #line 361 "eel2.y" { (yyval) = (yyvsp[(1) - (2)]); } break; case 73: #line 369 "eel2.y" { if ((yylsp[(1) - (1)]).first_line) { } context->result = (yyvsp[(1) - (1)]); } break; /* Line 1267 of yacc.c. */ #line 1965 "y.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; *++yylsp = yyloc; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (&yylloc, context, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (&yylloc, context, yymsg); } else { yyerror (&yylloc, context, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } yyerror_range[0] = yylloc; if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, &yylloc, context); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; yyerror_range[0] = yylsp[1-yylen]; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yyerror_range[0] = *yylsp; yydestruct ("Error: popping", yystos[yystate], yyvsp, yylsp, context); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; yyerror_range[1] = yylloc; /* Using YYLLOC is tempting, but would change the location of the look-ahead. YYLOC is available though. */ YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); *++yylsp = yyloc; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (&yylloc, context, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc, context); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, yylsp, context); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 376 "eel2.y" jsusfx-0.4.0/src/WDL/eel2/y.tab.h000066400000000000000000000066121353477307700163140ustar00rootroot00000000000000/* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { VALUE = 258, IDENTIFIER = 259, TOKEN_SHL = 260, TOKEN_SHR = 261, TOKEN_LTE = 262, TOKEN_GTE = 263, TOKEN_EQ = 264, TOKEN_EQ_EXACT = 265, TOKEN_NE = 266, TOKEN_NE_EXACT = 267, TOKEN_LOGICAL_AND = 268, TOKEN_LOGICAL_OR = 269, TOKEN_ADD_OP = 270, TOKEN_SUB_OP = 271, TOKEN_MOD_OP = 272, TOKEN_OR_OP = 273, TOKEN_AND_OP = 274, TOKEN_XOR_OP = 275, TOKEN_DIV_OP = 276, TOKEN_MUL_OP = 277, TOKEN_POW_OP = 278, STRING_LITERAL = 279, STRING_IDENTIFIER = 280 }; #endif /* Tokens. */ #define VALUE 258 #define IDENTIFIER 259 #define TOKEN_SHL 260 #define TOKEN_SHR 261 #define TOKEN_LTE 262 #define TOKEN_GTE 263 #define TOKEN_EQ 264 #define TOKEN_EQ_EXACT 265 #define TOKEN_NE 266 #define TOKEN_NE_EXACT 267 #define TOKEN_LOGICAL_AND 268 #define TOKEN_LOGICAL_OR 269 #define TOKEN_ADD_OP 270 #define TOKEN_SUB_OP 271 #define TOKEN_MOD_OP 272 #define TOKEN_OR_OP 273 #define TOKEN_AND_OP 274 #define TOKEN_XOR_OP 275 #define TOKEN_DIV_OP 276 #define TOKEN_MUL_OP 277 #define TOKEN_POW_OP 278 #define STRING_LITERAL 279 #define STRING_IDENTIFIER 280 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED typedef struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; } YYLTYPE; # define yyltype YYLTYPE /* obsolescent; will be withdrawn */ # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif jsusfx-0.4.0/src/WDL/fft.c000066400000000000000000000527711353477307700152310ustar00rootroot00000000000000/* WDL - fft.cpp Copyright (C) 2006 and later Cockos Incorporated Copyright 1999 D. J. Bernstein This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. This file implements the WDL FFT library. These routines are based on the DJBFFT library, which are Copyright 1999 D. J. Bernstein, djb@pobox.com The DJB FFT web page is: http://cr.yp.to/djbfft.html */ // this is based on djbfft #include #include "fft.h" #define FFT_MAXBITLEN 15 #ifdef _MSC_VER #define inline __inline #endif #define PI 3.1415926535897932384626433832795 static WDL_FFT_COMPLEX d16[3]; static WDL_FFT_COMPLEX d32[7]; static WDL_FFT_COMPLEX d64[15]; static WDL_FFT_COMPLEX d128[31]; static WDL_FFT_COMPLEX d256[63]; static WDL_FFT_COMPLEX d512[127]; static WDL_FFT_COMPLEX d1024[127]; static WDL_FFT_COMPLEX d2048[255]; static WDL_FFT_COMPLEX d4096[511]; static WDL_FFT_COMPLEX d8192[1023]; static WDL_FFT_COMPLEX d16384[2047]; static WDL_FFT_COMPLEX d32768[4095]; #define sqrthalf (d16[1].re) #define VOL *(volatile WDL_FFT_REAL *)& #define TRANSFORM(a0,a1,a2,a3,wre,wim) { \ t6 = a2.re; \ t1 = a0.re - t6; \ t6 += a0.re; \ a0.re = t6; \ t3 = a3.im; \ t4 = a1.im - t3; \ t8 = t1 - t4; \ t1 += t4; \ t3 += a1.im; \ a1.im = t3; \ t5 = wre; \ t7 = t8 * t5; \ t4 = t1 * t5; \ t8 *= wim; \ t2 = a3.re; \ t3 = a1.re - t2; \ t2 += a1.re; \ a1.re = t2; \ t1 *= wim; \ t6 = a2.im; \ t2 = a0.im - t6; \ t6 += a0.im; \ a0.im = t6; \ t6 = t2 + t3; \ t2 -= t3; \ t3 = t6 * wim; \ t7 -= t3; \ a2.re = t7; \ t6 *= t5; \ t6 += t8; \ a2.im = t6; \ t5 *= t2; \ t5 -= t1; \ a3.im = t5; \ t2 *= wim; \ t4 += t2; \ a3.re = t4; \ } #define TRANSFORMHALF(a0,a1,a2,a3) { \ t1 = a2.re; \ t5 = a0.re - t1; \ t1 += a0.re; \ a0.re = t1; \ t4 = a3.im; \ t8 = a1.im - t4; \ t1 = t5 - t8; \ t5 += t8; \ t4 += a1.im; \ a1.im = t4; \ t3 = a3.re; \ t7 = a1.re - t3; \ t3 += a1.re; \ a1.re = t3; \ t8 = a2.im; \ t6 = a0.im - t8; \ t2 = t6 + t7; \ t6 -= t7; \ t8 += a0.im; \ a0.im = t8; \ t4 = t6 + t5; \ t3 = sqrthalf; \ t4 *= t3; \ a3.re = t4; \ t6 -= t5; \ t6 *= t3; \ a3.im = t6; \ t7 = t1 - t2; \ t7 *= t3; \ a2.re = t7; \ t2 += t1; \ t2 *= t3; \ a2.im = t2; \ } #define TRANSFORMZERO(a0,a1,a2,a3) { \ t5 = a2.re; \ t1 = a0.re - t5; \ t5 += a0.re; \ a0.re = t5; \ t8 = a3.im; \ t4 = a1.im - t8; \ t7 = a3.re; \ t6 = t1 - t4; \ a2.re = t6; \ t1 += t4; \ a3.re = t1; \ t8 += a1.im; \ a1.im = t8; \ t3 = a1.re - t7; \ t7 += a1.re; \ a1.re = t7; \ t6 = a2.im; \ t2 = a0.im - t6; \ t7 = t2 + t3; \ a2.im = t7; \ t2 -= t3; \ a3.im = t2; \ t6 += a0.im; \ a0.im = t6; \ } #define UNTRANSFORM(a0,a1,a2,a3,wre,wim) { \ t6 = VOL wre; \ t1 = VOL a2.re; \ t1 *= t6; \ t8 = VOL wim; \ t3 = VOL a2.im; \ t3 *= t8; \ t2 = VOL a2.im; \ t4 = VOL a2.re; \ t5 = VOL a3.re; \ t5 *= t6; \ t7 = VOL a3.im; \ t1 += t3; \ t7 *= t8; \ t5 -= t7; \ t3 = t5 + t1; \ t5 -= t1; \ t2 *= t6; \ t6 *= a3.im; \ t4 *= t8; \ t2 -= t4; \ t8 *= a3.re; \ t6 += t8; \ t1 = a0.re - t3; \ t3 += a0.re; \ a0.re = t3; \ t7 = a1.im - t5; \ t5 += a1.im; \ a1.im = t5; \ t4 = t2 - t6; \ t6 += t2; \ t8 = a1.re - t4; \ t4 += a1.re; \ a1.re = t4; \ t2 = a0.im - t6; \ t6 += a0.im; \ a0.im = t6; \ a2.re = t1; \ a3.im = t7; \ a3.re = t8; \ a2.im = t2; \ } #define UNTRANSFORMHALF(a0,a1,a2,a3) { \ t6 = sqrthalf; \ t1 = a2.re; \ t2 = a2.im - t1; \ t2 *= t6; \ t1 += a2.im; \ t1 *= t6; \ t4 = a3.im; \ t3 = a3.re - t4; \ t3 *= t6; \ t4 += a3.re; \ t4 *= t6; \ t8 = t3 - t1; \ t7 = t2 - t4; \ t1 += t3; \ t2 += t4; \ t4 = a1.im - t8; \ a3.im = t4; \ t8 += a1.im; \ a1.im = t8; \ t3 = a1.re - t7; \ a3.re = t3; \ t7 += a1.re; \ a1.re = t7; \ t5 = a0.re - t1; \ a2.re = t5; \ t1 += a0.re; \ a0.re = t1; \ t6 = a0.im - t2; \ a2.im = t6; \ t2 += a0.im; \ a0.im = t2; \ } #define UNTRANSFORMZERO(a0,a1,a2,a3) { \ t2 = a3.im; \ t3 = a2.im - t2; \ t2 += a2.im; \ t1 = a2.re; \ t4 = a3.re - t1; \ t1 += a3.re; \ t5 = a0.re - t1; \ a2.re = t5; \ t6 = a0.im - t2; \ a2.im = t6; \ t7 = a1.re - t3; \ a3.re = t7; \ t8 = a1.im - t4; \ a3.im = t8; \ t1 += a0.re; \ a0.re = t1; \ t2 += a0.im; \ a0.im = t2; \ t3 += a1.re; \ a1.re = t3; \ t4 += a1.im; \ a1.im = t4; \ } static void c2(register WDL_FFT_COMPLEX *a) { register WDL_FFT_REAL t1; t1 = a[1].re; a[1].re = a[0].re - t1; a[0].re += t1; t1 = a[1].im; a[1].im = a[0].im - t1; a[0].im += t1; } static inline void c4(register WDL_FFT_COMPLEX *a) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; t5 = a[2].re; t1 = a[0].re - t5; t7 = a[3].re; t5 += a[0].re; t3 = a[1].re - t7; t7 += a[1].re; t8 = t5 + t7; a[0].re = t8; t5 -= t7; a[1].re = t5; t6 = a[2].im; t2 = a[0].im - t6; t6 += a[0].im; t5 = a[3].im; a[2].im = t2 + t3; t2 -= t3; a[3].im = t2; t4 = a[1].im - t5; a[3].re = t1 + t4; t1 -= t4; a[2].re = t1; t5 += a[1].im; a[0].im = t6 + t5; t6 -= t5; a[1].im = t6; } static void c8(register WDL_FFT_COMPLEX *a) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; t7 = a[4].im; t4 = a[0].im - t7; t7 += a[0].im; a[0].im = t7; t8 = a[6].re; t5 = a[2].re - t8; t8 += a[2].re; a[2].re = t8; t7 = a[6].im; a[6].im = t4 - t5; t4 += t5; a[4].im = t4; t6 = a[2].im - t7; t7 += a[2].im; a[2].im = t7; t8 = a[4].re; t3 = a[0].re - t8; t8 += a[0].re; a[0].re = t8; a[4].re = t3 - t6; t3 += t6; a[6].re = t3; t7 = a[5].re; t3 = a[1].re - t7; t7 += a[1].re; a[1].re = t7; t8 = a[7].im; t6 = a[3].im - t8; t8 += a[3].im; a[3].im = t8; t1 = t3 - t6; t3 += t6; t7 = a[5].im; t4 = a[1].im - t7; t7 += a[1].im; a[1].im = t7; t8 = a[7].re; t5 = a[3].re - t8; t8 += a[3].re; a[3].re = t8; t2 = t4 - t5; t4 += t5; t6 = t1 - t4; t8 = sqrthalf; t6 *= t8; a[5].re = a[4].re - t6; t1 += t4; t1 *= t8; a[5].im = a[4].im - t1; t6 += a[4].re; a[4].re = t6; t1 += a[4].im; a[4].im = t1; t5 = t2 - t3; t5 *= t8; a[7].im = a[6].im - t5; t2 += t3; t2 *= t8; a[7].re = a[6].re - t2; t2 += a[6].re; a[6].re = t2; t5 += a[6].im; a[6].im = t5; c4(a); } static void c16(register WDL_FFT_COMPLEX *a) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; TRANSFORMZERO(a[0],a[4],a[8],a[12]); TRANSFORM(a[1],a[5],a[9],a[13],d16[0].re,d16[0].im); TRANSFORMHALF(a[2],a[6],a[10],a[14]); TRANSFORM(a[3],a[7],a[11],a[15],d16[0].im,d16[0].re); c4(a + 8); c4(a + 12); c8(a); } /* a[0...8n-1], w[0...2n-2]; n >= 2 */ static void cpass(register WDL_FFT_COMPLEX *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; register WDL_FFT_COMPLEX *a1; register WDL_FFT_COMPLEX *a2; register WDL_FFT_COMPLEX *a3; a2 = a + 4 * n; a1 = a + 2 * n; a3 = a2 + 2 * n; --n; TRANSFORMZERO(a[0],a1[0],a2[0],a3[0]); TRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].re,w[0].im); for (;;) { TRANSFORM(a[2],a1[2],a2[2],a3[2],w[1].re,w[1].im); TRANSFORM(a[3],a1[3],a2[3],a3[3],w[2].re,w[2].im); if (!--n) break; a += 2; a1 += 2; a2 += 2; a3 += 2; w += 2; } } static void c32(register WDL_FFT_COMPLEX *a) { cpass(a,d32,4); c8(a + 16); c8(a + 24); c16(a); } static void c64(register WDL_FFT_COMPLEX *a) { cpass(a,d64,8); c16(a + 32); c16(a + 48); c32(a); } static void c128(register WDL_FFT_COMPLEX *a) { cpass(a,d128,16); c32(a + 64); c32(a + 96); c64(a); } static void c256(register WDL_FFT_COMPLEX *a) { cpass(a,d256,32); c64(a + 128); c64(a + 192); c128(a); } static void c512(register WDL_FFT_COMPLEX *a) { cpass(a,d512,64); c128(a + 384); c128(a + 256); c256(a); } /* a[0...8n-1], w[0...n-2]; n even, n >= 4 */ static void cpassbig(register WDL_FFT_COMPLEX *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; register WDL_FFT_COMPLEX *a1; register WDL_FFT_COMPLEX *a2; register WDL_FFT_COMPLEX *a3; register unsigned int k; a2 = a + 4 * n; a1 = a + 2 * n; a3 = a2 + 2 * n; k = n - 2; TRANSFORMZERO(a[0],a1[0],a2[0],a3[0]); TRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].re,w[0].im); a += 2; a1 += 2; a2 += 2; a3 += 2; do { TRANSFORM(a[0],a1[0],a2[0],a3[0],w[1].re,w[1].im); TRANSFORM(a[1],a1[1],a2[1],a3[1],w[2].re,w[2].im); a += 2; a1 += 2; a2 += 2; a3 += 2; w += 2; } while (k -= 2); TRANSFORMHALF(a[0],a1[0],a2[0],a3[0]); TRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].im,w[0].re); a += 2; a1 += 2; a2 += 2; a3 += 2; k = n - 2; do { TRANSFORM(a[0],a1[0],a2[0],a3[0],w[-1].im,w[-1].re); TRANSFORM(a[1],a1[1],a2[1],a3[1],w[-2].im,w[-2].re); a += 2; a1 += 2; a2 += 2; a3 += 2; w -= 2; } while (k -= 2); } static void c1024(register WDL_FFT_COMPLEX *a) { cpassbig(a,d1024,128); c256(a + 768); c256(a + 512); c512(a); } static void c2048(register WDL_FFT_COMPLEX *a) { cpassbig(a,d2048,256); c512(a + 1536); c512(a + 1024); c1024(a); } static void c4096(register WDL_FFT_COMPLEX *a) { cpassbig(a,d4096,512); c1024(a + 3072); c1024(a + 2048); c2048(a); } static void c8192(register WDL_FFT_COMPLEX *a) { cpassbig(a,d8192,1024); c2048(a + 6144); c2048(a + 4096); c4096(a); } static void c16384(register WDL_FFT_COMPLEX *a) { cpassbig(a,d16384,2048); c4096(a + 8192 + 4096); c4096(a + 8192); c8192(a); } static void c32768(register WDL_FFT_COMPLEX *a) { cpassbig(a,d32768,4096); c8192(a + 16384 + 8192); c8192(a + 16384); c16384(a); } /* n even, n > 0 */ void WDL_fft_complexmul(WDL_FFT_COMPLEX *a,WDL_FFT_COMPLEX *b,int n) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; if (n<2 || (n&1)) return; do { t1 = a[0].re * b[0].re; t2 = a[0].im * b[0].im; t3 = a[0].im * b[0].re; t4 = a[0].re * b[0].im; t5 = a[1].re * b[1].re; t6 = a[1].im * b[1].im; t7 = a[1].im * b[1].re; t8 = a[1].re * b[1].im; t1 -= t2; t3 += t4; t5 -= t6; t7 += t8; a[0].re = t1; a[1].re = t5; a[0].im = t3; a[1].im = t7; a += 2; b += 2; } while (n -= 2); } void WDL_fft_complexmul2(WDL_FFT_COMPLEX *c, WDL_FFT_COMPLEX *a, WDL_FFT_COMPLEX *b, int n) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; if (n<2 || (n&1)) return; do { t1 = a[0].re * b[0].re; t2 = a[0].im * b[0].im; t3 = a[0].im * b[0].re; t4 = a[0].re * b[0].im; t5 = a[1].re * b[1].re; t6 = a[1].im * b[1].im; t7 = a[1].im * b[1].re; t8 = a[1].re * b[1].im; t1 -= t2; t3 += t4; t5 -= t6; t7 += t8; c[0].re = t1; c[1].re = t5; c[0].im = t3; c[1].im = t7; a += 2; b += 2; c += 2; } while (n -= 2); } void WDL_fft_complexmul3(WDL_FFT_COMPLEX *c, WDL_FFT_COMPLEX *a, WDL_FFT_COMPLEX *b, int n) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; if (n<2 || (n&1)) return; do { t1 = a[0].re * b[0].re; t2 = a[0].im * b[0].im; t3 = a[0].im * b[0].re; t4 = a[0].re * b[0].im; t5 = a[1].re * b[1].re; t6 = a[1].im * b[1].im; t7 = a[1].im * b[1].re; t8 = a[1].re * b[1].im; t1 -= t2; t3 += t4; t5 -= t6; t7 += t8; c[0].re += t1; c[1].re += t5; c[0].im += t3; c[1].im += t7; a += 2; b += 2; c += 2; } while (n -= 2); } static inline void u4(register WDL_FFT_COMPLEX *a) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; t1 = VOL a[1].re; t3 = a[0].re - t1; t6 = VOL a[2].re; t1 += a[0].re; t8 = a[3].re - t6; t6 += a[3].re; a[0].re = t1 + t6; t1 -= t6; a[2].re = t1; t2 = VOL a[1].im; t4 = a[0].im - t2; t2 += a[0].im; t5 = VOL a[3].im; a[1].im = t4 + t8; t4 -= t8; a[3].im = t4; t7 = a[2].im - t5; t5 += a[2].im; a[1].re = t3 + t7; t3 -= t7; a[3].re = t3; a[0].im = t2 + t5; t2 -= t5; a[2].im = t2; } static void u8(register WDL_FFT_COMPLEX *a) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; u4(a); t1 = a[5].re; a[5].re = a[4].re - t1; t1 += a[4].re; t3 = a[7].re; a[7].re = a[6].re - t3; t3 += a[6].re; t8 = t3 - t1; t1 += t3; t6 = a[2].im - t8; t8 += a[2].im; a[2].im = t8; t5 = a[0].re - t1; a[4].re = t5; t1 += a[0].re; a[0].re = t1; t2 = a[5].im; a[5].im = a[4].im - t2; t2 += a[4].im; t4 = a[7].im; a[7].im = a[6].im - t4; t4 += a[6].im; a[6].im = t6; t7 = t2 - t4; t2 += t4; t3 = a[2].re - t7; a[6].re = t3; t7 += a[2].re; a[2].re = t7; t6 = a[0].im - t2; a[4].im = t6; t2 += a[0].im; a[0].im = t2; t6 = sqrthalf; t1 = a[5].re; t2 = a[5].im - t1; t2 *= t6; t1 += a[5].im; t1 *= t6; t4 = a[7].im; t3 = a[7].re - t4; t3 *= t6; t4 += a[7].re; t4 *= t6; t8 = t3 - t1; t1 += t3; t7 = t2 - t4; t2 += t4; t4 = a[3].im - t8; a[7].im = t4; t5 = a[1].re - t1; a[5].re = t5; t3 = a[3].re - t7; a[7].re = t3; t6 = a[1].im - t2; a[5].im = t6; t8 += a[3].im; a[3].im = t8; t1 += a[1].re; a[1].re = t1; t7 += a[3].re; a[3].re = t7; t2 += a[1].im; a[1].im = t2; } static void u16(register WDL_FFT_COMPLEX *a) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; u8(a); u4(a + 8); u4(a + 12); UNTRANSFORMZERO(a[0],a[4],a[8],a[12]); UNTRANSFORMHALF(a[2],a[6],a[10],a[14]); UNTRANSFORM(a[1],a[5],a[9],a[13],d16[0].re,d16[0].im); UNTRANSFORM(a[3],a[7],a[11],a[15],d16[0].im,d16[0].re); } /* a[0...8n-1], w[0...2n-2] */ static void upass(register WDL_FFT_COMPLEX *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; register WDL_FFT_COMPLEX *a1; register WDL_FFT_COMPLEX *a2; register WDL_FFT_COMPLEX *a3; a2 = a + 4 * n; a1 = a + 2 * n; a3 = a2 + 2 * n; n -= 1; UNTRANSFORMZERO(a[0],a1[0],a2[0],a3[0]); UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].re,w[0].im); for (;;) { UNTRANSFORM(a[2],a1[2],a2[2],a3[2],w[1].re,w[1].im); UNTRANSFORM(a[3],a1[3],a2[3],a3[3],w[2].re,w[2].im); if (!--n) break; a += 2; a1 += 2; a2 += 2; a3 += 2; w += 2; } } static void u32(register WDL_FFT_COMPLEX *a) { u16(a); u8(a + 16); u8(a + 24); upass(a,d32,4); } static void u64(register WDL_FFT_COMPLEX *a) { u32(a); u16(a + 32); u16(a + 48); upass(a,d64,8); } static void u128(register WDL_FFT_COMPLEX *a) { u64(a); u32(a + 64); u32(a + 96); upass(a,d128,16); } static void u256(register WDL_FFT_COMPLEX *a) { u128(a); u64(a + 128); u64(a + 192); upass(a,d256,32); } static void u512(register WDL_FFT_COMPLEX *a) { u256(a); u128(a + 256); u128(a + 384); upass(a,d512,64); } /* a[0...8n-1], w[0...n-2]; n even, n >= 4 */ static void upassbig(register WDL_FFT_COMPLEX *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) { register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; register WDL_FFT_COMPLEX *a1; register WDL_FFT_COMPLEX *a2; register WDL_FFT_COMPLEX *a3; register unsigned int k; a2 = a + 4 * n; a1 = a + 2 * n; a3 = a2 + 2 * n; k = n - 2; UNTRANSFORMZERO(a[0],a1[0],a2[0],a3[0]); UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].re,w[0].im); a += 2; a1 += 2; a2 += 2; a3 += 2; do { UNTRANSFORM(a[0],a1[0],a2[0],a3[0],w[1].re,w[1].im); UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[2].re,w[2].im); a += 2; a1 += 2; a2 += 2; a3 += 2; w += 2; } while (k -= 2); UNTRANSFORMHALF(a[0],a1[0],a2[0],a3[0]); UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].im,w[0].re); a += 2; a1 += 2; a2 += 2; a3 += 2; k = n - 2; do { UNTRANSFORM(a[0],a1[0],a2[0],a3[0],w[-1].im,w[-1].re); UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[-2].im,w[-2].re); a += 2; a1 += 2; a2 += 2; a3 += 2; w -= 2; } while (k -= 2); } static void u1024(register WDL_FFT_COMPLEX *a) { u512(a); u256(a + 512); u256(a + 768); upassbig(a,d1024,128); } static void u2048(register WDL_FFT_COMPLEX *a) { u1024(a); u512(a + 1024); u512(a + 1536); upassbig(a,d2048,256); } static void u4096(register WDL_FFT_COMPLEX *a) { u2048(a); u1024(a + 2048); u1024(a + 3072); upassbig(a,d4096,512); } static void u8192(register WDL_FFT_COMPLEX *a) { u4096(a); u2048(a + 4096); u2048(a + 6144); upassbig(a,d8192,1024); } static void u16384(register WDL_FFT_COMPLEX *a) { u8192(a); u4096(a + 8192); u4096(a + 8192 + 4096); upassbig(a,d16384,2048); } static void u32768(register WDL_FFT_COMPLEX *a) { u16384(a); u8192(a + 16384); u8192(a + 16384 + 8192 ); upassbig(a,d32768,4096); } static void __fft_gen(WDL_FFT_COMPLEX *buf, const WDL_FFT_COMPLEX *buf2, int sz, int isfull) { int x; double div=PI*0.25/(sz+1); if (isfull) div*=2.0; for (x = 0; x < sz; x ++) { if (!(x & 1) || !buf2) { buf[x].re = (WDL_FFT_REAL) cos((x+1)*div); buf[x].im = (WDL_FFT_REAL) sin((x+1)*div); } else { buf[x].re = buf2[x >> 1].re; buf[x].im = buf2[x >> 1].im; } } } #ifndef WDL_FFT_NO_PERMUTE static unsigned int fftfreq_c(unsigned int i,unsigned int n) { unsigned int m; if (n <= 2) return i; m = n >> 1; if (i < m) return fftfreq_c(i,m) << 1; i -= m; m >>= 1; if (i < m) return (fftfreq_c(i,m) << 2) + 1; i -= m; return ((fftfreq_c(i,m) << 2) - 1) & (n - 1); } static int _idxperm[2<> 1, quart = half >> 1, eighth = quart >> 1; const int *permute = WDL_fft_permute_tab(half); unsigned int i, j; WDL_FFT_COMPLEX *p, *q, tw, sum, diff; WDL_FFT_REAL tw1, tw2; if (!isInverse) { WDL_fft((WDL_FFT_COMPLEX*)buf, half, isInverse); r2(buf); } else { v2(buf); } /* Source: http://www.katjaas.nl/realFFT/realFFT2.html */ for (i = 1; i < quart; ++i) { p = (WDL_FFT_COMPLEX*)buf + permute[i]; q = (WDL_FFT_COMPLEX*)buf + permute[half - i]; /* tw.re = cos(2*PI * i / len); tw.im = sin(2*PI * i / len); */ if (i < eighth) { j = i - 1; tw.re = d[j].re; tw.im = d[j].im; } else if (i > eighth) { j = quart - i - 1; tw.re = d[j].im; tw.im = d[j].re; } else { tw.re = tw.im = sqrthalf; } if (!isInverse) tw.re = -tw.re; sum.re = p->re + q->re; sum.im = p->im + q->im; diff.re = p->re - q->re; diff.im = p->im - q->im; tw1 = tw.re * sum.im + tw.im * diff.re; tw2 = tw.im * sum.im - tw.re * diff.re; p->re = sum.re - tw1; p->im = diff.im - tw2; q->re = sum.re + tw1; q->im = -(diff.im + tw2); } p = (WDL_FFT_COMPLEX*)buf + permute[i]; p->re *= 2; p->im *= -2; if (isInverse) WDL_fft((WDL_FFT_COMPLEX*)buf, half, isInverse); } void WDL_real_fft(WDL_FFT_REAL* buf, int len, int isInverse) { switch (len) { case 2: if (!isInverse) r2(buf); else v2(buf); break; case 4: case 8: two_for_one(buf, 0, len, isInverse); break; #define TMP(x) case x: two_for_one(buf, d##x, len, isInverse); break; TMP(16) TMP(32) TMP(64) TMP(128) TMP(256) TMP(512) TMP(1024) TMP(2048) TMP(4096) TMP(8192) TMP(16384) TMP(32768) #undef TMP } } jsusfx-0.4.0/src/WDL/fft.h000066400000000000000000000046411353477307700152270ustar00rootroot00000000000000/* WDL - fft.h Copyright (C) 2006 and later Cockos Incorporated This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. This file defines the interface to the WDL FFT library. These routines are based on the DJBFFT library, which are Copyright 1999 D. J. Bernstein, djb@pobox.com The DJB FFT web page is: http://cr.yp.to/djbfft.html */ #ifndef _WDL_FFT_H_ #define _WDL_FFT_H_ #ifdef __cplusplus extern "C" { #endif #ifndef WDL_FFT_REALSIZE #define WDL_FFT_REALSIZE 4 #endif #if WDL_FFT_REALSIZE == 4 typedef float WDL_FFT_REAL; #elif WDL_FFT_REALSIZE == 8 typedef double WDL_FFT_REAL; #else #error invalid FFT item size #endif typedef struct { WDL_FFT_REAL re; WDL_FFT_REAL im; } WDL_FFT_COMPLEX; extern void WDL_fft_init(); extern void WDL_fft_complexmul(WDL_FFT_COMPLEX *dest, WDL_FFT_COMPLEX *src, int len); extern void WDL_fft_complexmul2(WDL_FFT_COMPLEX *dest, WDL_FFT_COMPLEX *src, WDL_FFT_COMPLEX *src2, int len); extern void WDL_fft_complexmul3(WDL_FFT_COMPLEX *destAdd, WDL_FFT_COMPLEX *src, WDL_FFT_COMPLEX *src2, int len); /* Expects WDL_FFT_COMPLEX input[0..len-1] scaled by 1.0/len, returns WDL_FFT_COMPLEX output[0..len-1] order by WDL_fft_permute(len). */ extern void WDL_fft(WDL_FFT_COMPLEX *, int len, int isInverse); /* Expects WDL_FFT_REAL input[0..len-1] scaled by 0.5/len, returns WDL_FFT_COMPLEX output[0..len/2-1], for len >= 4 order by WDL_fft_permute(len/2). Note that output[len/2].re is stored in output[0].im. */ extern void WDL_real_fft(WDL_FFT_REAL *, int len, int isInverse); extern int WDL_fft_permute(int fftsize, int idx); extern int *WDL_fft_permute_tab(int fftsize); #ifdef __cplusplus }; #endif #endifjsusfx-0.4.0/src/WDL/heapbuf.h000066400000000000000000000246071353477307700160660ustar00rootroot00000000000000/* WDL - heapbuf.h Copyright (C) 2005 and later Cockos Incorporated This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ /* This file provides the interface and implementation for WDL_HeapBuf, a simple malloc() wrapper for resizeable blocks. Also in this file is WDL_TypedBuf which is a templated version WDL_HeapBuf that manages type and type-size. */ #ifndef _WDL_HEAPBUF_H_ #define _WDL_HEAPBUF_H_ #ifndef WDL_HEAPBUF_IMPL_ONLY #ifdef WDL_HEAPBUF_TRACE #include #define WDL_HEAPBUF_TRACEPARM(x) ,(x) #else #define WDL_HEAPBUF_TRACEPARM(x) #endif #include "wdltypes.h" class WDL_HeapBuf { public: // interface #ifdef WDL_HEAPBUF_INTF_ONLY void *Resize(int newsize, bool resizedown=true); void CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig=false); #endif void *Get() const { return m_size?m_buf:NULL; } // returns NULL if size is 0 void *GetFast() const { return m_buf; } // returns last buffer if size is 0 int GetSize() const { return m_size; } void *GetAligned(int align) const { return (void *)(((UINT_PTR)Get() + (align-1)) & ~(UINT_PTR)(align-1)); } void SetGranul(int granul) { m_granul = granul; } int GetGranul() const { return m_granul; } void *ResizeOK(int newsize, bool resizedown = true) { void *p=Resize(newsize, resizedown); return GetSize() == newsize ? p : NULL; } WDL_HeapBuf(const WDL_HeapBuf &cp) { m_buf=0; CopyFrom(&cp,true); } WDL_HeapBuf &operator=(const WDL_HeapBuf &cp) { CopyFrom(&cp,false); return *this; } #ifndef WDL_HEAPBUF_TRACE explicit WDL_HeapBuf(int granul=4096) : m_buf(NULL), m_alloc(0), m_size(0), m_granul(granul) { } ~WDL_HeapBuf() { free(m_buf); } #else explicit WDL_HeapBuf(int granul=4096, const char *tracetype="WDL_HeapBuf" ) : m_buf(NULL), m_alloc(0), m_size(0), m_granul(granul) { m_tracetype = tracetype; char tmp[512]; wsprintf(tmp,"WDL_HeapBuf: created type: %s granul=%d\n",tracetype,granul); OutputDebugString(tmp); } ~WDL_HeapBuf() { char tmp[512]; wsprintf(tmp,"WDL_HeapBuf: destroying type: %s (alloc=%d, size=%d)\n",m_tracetype,m_alloc,m_size); OutputDebugString(tmp); free(m_buf); } #endif #endif // !WDL_HEAPBUF_IMPL_ONLY // implementation bits #ifndef WDL_HEAPBUF_INTF_ONLY #ifdef WDL_HEAPBUF_IMPL_ONLY void *WDL_HeapBuf::Resize(int newsize, bool resizedown) #else void *Resize(int newsize, bool resizedown=true) #endif { if (newsize<0) newsize=0; #ifdef DEBUG_TIGHT_ALLOC // horribly slow, do not use for release builds if (newsize == m_size) return m_buf; int a = newsize; if (a > m_size) a=m_size; void *newbuf = newsize ? malloc(newsize) : 0; if (!newbuf && newsize) { #ifdef WDL_HEAPBUF_ONMALLOCFAIL WDL_HEAPBUF_ONMALLOCFAIL(newsize) #endif return m_buf; } if (newbuf&&m_buf) memcpy(newbuf,m_buf,a); m_size=m_alloc=newsize; free(m_buf); return m_buf=newbuf; #endif if (newsize!=m_size || (resizedown && newsize < m_alloc/2)) { int resizedown_under = 0; if (resizedown && newsize < m_size) { // shrinking buffer: only shrink if allocation decreases to min(alloc/2, alloc-granul*4) or 0 resizedown_under = m_alloc - (m_granul<<2); if (resizedown_under > m_alloc/2) resizedown_under = m_alloc/2; if (resizedown_under < 1) resizedown_under=1; } if (newsize > m_alloc || newsize < resizedown_under) { int granul=newsize/2; int newalloc; if (granul < m_granul) granul=m_granul; if (newsize<1) newalloc=0; else if (m_granul<4096) newalloc=newsize+granul; else { granul &= ~4095; if (granul< 4096) granul=4096; else if (granul>4*1024*1024) granul=4*1024*1024; newalloc = ((newsize + granul + 96)&~4095)-96; } if (newalloc != m_alloc) { #ifdef WDL_HEAPBUF_TRACE char tmp[512]; wsprintf(tmp,"WDL_HeapBuf: type %s realloc(%d) from %d\n",m_tracetype,newalloc,m_alloc); OutputDebugString(tmp); #endif if (newalloc <= 0) { free(m_buf); m_buf=0; m_alloc=0; m_size=0; return 0; } void *nbuf=realloc(m_buf,newalloc); if (!nbuf) { if (!(nbuf=malloc(newalloc))) { #ifdef WDL_HEAPBUF_ONMALLOCFAIL WDL_HEAPBUF_ONMALLOCFAIL(newalloc); #endif return m_size?m_buf:0; // failed, do not resize } if (m_buf) { int sz=newsize0) memcpy(nbuf,m_buf,sz); free(m_buf); } } m_buf=nbuf; m_alloc=newalloc; } // alloc size change } // need size up or down m_size=newsize; } // size change return m_size?m_buf:0; } #ifdef WDL_HEAPBUF_IMPL_ONLY void WDL_HeapBuf::CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig) #else void CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig=false) #endif { if (exactCopyOfConfig) // copy all settings { free(m_buf); #ifdef WDL_HEAPBUF_TRACE m_tracetype = hb->m_tracetype; #endif m_granul = hb->m_granul; m_size=m_alloc=0; m_buf=hb->m_buf && hb->m_alloc>0 ? malloc(m_alloc = hb->m_alloc) : NULL; #ifdef WDL_HEAPBUF_ONMALLOCFAIL if (!m_buf && m_alloc) { WDL_HEAPBUF_ONMALLOCFAIL(m_alloc) } ; #endif if (m_buf) memcpy(m_buf,hb->m_buf,m_size = hb->m_size); else m_alloc=0; } else // copy just the data + size { const int newsz=hb->GetSize(); Resize(newsz,true); if (GetSize()!=newsz) Resize(0); else memcpy(Get(),hb->Get(),newsz); } } #endif // ! WDL_HEAPBUF_INTF_ONLY #ifndef WDL_HEAPBUF_IMPL_ONLY private: void *m_buf; int m_alloc; int m_size; int m_granul; #if defined(_WIN64) || defined(__LP64__) public: int ___pad; // keep size 8 byte aligned #endif #ifdef WDL_HEAPBUF_TRACE const char *m_tracetype; #endif }; template class WDL_TypedBuf { public: PTRTYPE *Get() const { return (PTRTYPE *) m_hb.Get(); } PTRTYPE *GetFast() const { return (PTRTYPE *) m_hb.GetFast(); } int GetSize() const { return m_hb.GetSize()/(unsigned int)sizeof(PTRTYPE); } PTRTYPE *Resize(int newsize, bool resizedown = true) { return (PTRTYPE *)m_hb.Resize(newsize*sizeof(PTRTYPE),resizedown); } PTRTYPE *ResizeOK(int newsize, bool resizedown = true) { return (PTRTYPE *)m_hb.ResizeOK(newsize*sizeof(PTRTYPE), resizedown); } PTRTYPE *GetAligned(int align) const { return (PTRTYPE *) m_hb.GetAligned(align); } PTRTYPE *Add(PTRTYPE val) { const int sz=GetSize(); PTRTYPE* p=ResizeOK(sz+1,false); if (p) { p[sz]=val; return p+sz; } return NULL; } PTRTYPE *Add(const PTRTYPE *buf, int bufsz) { if (bufsz>0) { const int sz=GetSize(); PTRTYPE* p=ResizeOK(sz+bufsz,false); if (p) { p+=sz; if (buf) memcpy(p,buf,bufsz*sizeof(PTRTYPE)); else memset(p,0,bufsz*sizeof(PTRTYPE)); return p; } } return NULL; } PTRTYPE *Set(const PTRTYPE *buf, int bufsz) { if (bufsz>=0) { PTRTYPE* p=ResizeOK(bufsz,false); if (p) { if (buf) memcpy(p,buf,bufsz*sizeof(PTRTYPE)); else memset(p,0,bufsz*sizeof(PTRTYPE)); return p; } } return NULL; } PTRTYPE* Insert(PTRTYPE val, int idx) { const int sz=GetSize(); if (idx >= 0 && idx <= sz) { PTRTYPE* p=ResizeOK(sz+1,false); if (p) { memmove(p+idx+1, p+idx, (sz-idx)*sizeof(PTRTYPE)); p[idx]=val; return p+idx; } } return NULL; } void Delete(int idx) { PTRTYPE* p=Get(); const int sz=GetSize(); if (idx >= 0 && idx < sz) { memmove(p+idx, p+idx+1, (sz-idx-1)*sizeof(PTRTYPE)); Resize(sz-1,false); } } void SetGranul(int gran) { m_hb.SetGranul(gran); } int Find(PTRTYPE val) const { const PTRTYPE* p=Get(); const int sz=GetSize(); int i; for (i=0; i < sz; ++i) if (p[i] == val) return i; return -1; } #ifndef WDL_HEAPBUF_TRACE explicit WDL_TypedBuf(int granul=4096) : m_hb(granul) { } #else explicit WDL_TypedBuf(int granul=4096, const char *tracetype="WDL_TypedBuf") : m_hb(granul WDL_HEAPBUF_TRACEPARM(tracetype)) { } #endif ~WDL_TypedBuf() { } WDL_HeapBuf *GetHeapBuf() { return &m_hb; } const WDL_HeapBuf *GetHeapBuf() const { return &m_hb; } private: WDL_HeapBuf m_hb; }; #endif // ! WDL_HEAPBUF_IMPL_ONLY #endif // _WDL_HEAPBUF_H_ jsusfx-0.4.0/src/WDL/mutex.h000066400000000000000000000140541353477307700156110ustar00rootroot00000000000000/* WDL - mutex.h Copyright (C) 2005 and later, Cockos Incorporated This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ /* This file provides a simple class that abstracts a mutex or critical section object. On Windows it uses CRITICAL_SECTION, on everything else it uses pthread's mutex library. It simulates the Critical Section behavior on non-Windows, as well (meaning a thread can safely Enter the mutex multiple times, provided it Leaves the same number of times) */ #ifndef _WDL_MUTEX_H_ #define _WDL_MUTEX_H_ #ifdef _WIN32 #include #else #include // define this if you wish to use carbon critical sections on OS X // #define WDL_MAC_USE_CARBON_CRITSEC #ifdef WDL_MAC_USE_CARBON_CRITSEC #include #else #include #endif #endif #include "wdltypes.h" #include "wdlatomic.h" // TO SUPPORT try #undef _DEBUG #ifdef _DEBUG #include #endif class WDL_Mutex { public: WDL_Mutex() { #ifdef _DEBUG _debug_cnt=0; #endif #ifdef _WIN32 InitializeCriticalSection(&m_cs); #elif defined( WDL_MAC_USE_CARBON_CRITSEC) MPCreateCriticalRegion(&m_cr); #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) && !defined(__linux__) const pthread_mutex_t tmp = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; m_mutex = tmp; #else pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE); #ifdef __linux__ // todo: macos too? pthread_mutexattr_setprotocol(&attr,PTHREAD_PRIO_INHERIT); #endif pthread_mutex_init(&m_mutex,&attr); pthread_mutexattr_destroy(&attr); #endif } ~WDL_Mutex() { #ifdef _WIN32 DeleteCriticalSection(&m_cs); #elif defined(WDL_MAC_USE_CARBON_CRITSEC) MPDeleteCriticalRegion(m_cr); #else pthread_mutex_destroy(&m_mutex); #endif } void Enter() { #ifdef _DEBUG const int new_debug_cnt = wdl_atomic_incr(&_debug_cnt); assert(new_debug_cnt > 0); #endif #ifdef _WIN32 EnterCriticalSection(&m_cs); #elif defined(WDL_MAC_USE_CARBON_CRITSEC) MPEnterCriticalRegion(m_cr,kDurationForever); #else pthread_mutex_lock(&m_mutex); #endif } bool TryEnter() { #ifdef _WIN32 return ! TryEnterCriticalSection(&m_cs); #else return pthread_mutex_trylock(&m_mutex); #endif } void Leave() { #ifdef _DEBUG const int new_debug_cnt = wdl_atomic_decr(&_debug_cnt); assert(new_debug_cnt >= 0); #endif #ifdef _WIN32 LeaveCriticalSection(&m_cs); #elif defined(WDL_MAC_USE_CARBON_CRITSEC) MPExitCriticalRegion(m_cr); #else pthread_mutex_unlock(&m_mutex); #endif } #ifdef _DEBUG volatile int _debug_cnt; #endif private: #ifdef _WIN32 CRITICAL_SECTION m_cs; #elif defined(WDL_MAC_USE_CARBON_CRITSEC) MPCriticalRegionID m_cr; #else pthread_mutex_t m_mutex; #endif // prevent callers from copying mutexes accidentally WDL_Mutex(const WDL_Mutex &cp) { #ifdef _DEBUG assert(sizeof(WDL_Mutex) == 0); #endif } WDL_Mutex &operator=(const WDL_Mutex &cp) { #ifdef _DEBUG assert(sizeof(WDL_Mutex) == 0); #endif return *this; } } WDL_FIXALIGN; class WDL_MutexLock { public: WDL_MutexLock(WDL_Mutex *m) : m_m(m) { if (m) m->Enter(); } ~WDL_MutexLock() { if (m_m) m_m->Leave(); } private: WDL_Mutex *m_m; } WDL_FIXALIGN; class WDL_SharedMutex { public: WDL_SharedMutex() { m_sharedcnt=0; } ~WDL_SharedMutex() { } void LockExclusive() // note: the calling thread must NOT have any shared locks, or deadlock WILL occur { m_mutex.Enter(); #ifdef _WIN32 while (m_sharedcnt>0) Sleep(1); #else while (m_sharedcnt>0) usleep(100); #endif } void UnlockExclusive() { m_mutex.Leave(); } void LockShared() { m_mutex.Enter(); wdl_atomic_incr(&m_sharedcnt); m_mutex.Leave(); } void UnlockShared() { wdl_atomic_decr(&m_sharedcnt); } void SharedToExclusive() // assumes a SINGLE shared lock by this thread! { m_mutex.Enter(); #ifdef _WIN32 while (m_sharedcnt>1) Sleep(1); #else while (m_sharedcnt>1) usleep(100); #endif UnlockShared(); } void ExclusiveToShared() // assumes exclusive locked returns with shared locked { // already have exclusive lock wdl_atomic_incr(&m_sharedcnt); m_mutex.Leave(); } private: WDL_Mutex m_mutex; volatile int m_sharedcnt; // prevent callers from copying accidentally WDL_SharedMutex(const WDL_SharedMutex &cp) { #ifdef _DEBUG assert(sizeof(WDL_SharedMutex) == 0); #endif } WDL_SharedMutex &operator=(const WDL_SharedMutex &cp) { #ifdef _DEBUG assert(sizeof(WDL_SharedMutex) == 0); #endif return *this; } } WDL_FIXALIGN; class WDL_MutexLockShared { public: WDL_MutexLockShared(WDL_SharedMutex *m) : m_m(m) { if (m) m->LockShared(); } ~WDL_MutexLockShared() { if (m_m) m_m->UnlockShared(); } private: WDL_SharedMutex *m_m; } WDL_FIXALIGN; class WDL_MutexLockExclusive { public: WDL_MutexLockExclusive(WDL_SharedMutex *m) : m_m(m) { if (m) m->LockExclusive(); } ~WDL_MutexLockExclusive() { if (m_m) m_m->UnlockExclusive(); } private: WDL_SharedMutex *m_m; } WDL_FIXALIGN; #endif jsusfx-0.4.0/src/WDL/ptrlist.h000066400000000000000000000161371353477307700161540ustar00rootroot00000000000000/* WDL - ptrlist.h Copyright (C) 2005 and later, Cockos Incorporated This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ /* This file provides a simple templated class for a list of pointers. By default this list doesn't free any of the pointers, but you can call Empty(true) or Delete(x,true) to delete the pointer, or you can use Empty(true,free) etc to call free (or any other function). Note: on certain compilers, instantiating with WDL_PtrList bla; will give a warning, since the template will create code for "delete (void *)x;" which isn't technically valid. Oh well. */ #ifndef _WDL_PTRLIST_H_ #define _WDL_PTRLIST_H_ #include "heapbuf.h" template class WDL_PtrList { public: explicit WDL_PtrList(int defgran=4096) : m_hb(defgran WDL_HEAPBUF_TRACEPARM("WDL_PtrList")) { } ~WDL_PtrList() { } PTRTYPE **GetList() const { return (PTRTYPE**)m_hb.Get(); } PTRTYPE *Get(INT_PTR index) const { PTRTYPE **list = (PTRTYPE**)m_hb.Get(); if (list && (UINT_PTR)index < (UINT_PTR)(m_hb.GetSize()/sizeof(PTRTYPE *))) return list[index]; return NULL; } int GetSize(void) const { return m_hb.GetSize()/(unsigned int)sizeof(PTRTYPE *); } int Find(const PTRTYPE *p) const { if (p) { PTRTYPE **list=(PTRTYPE **)m_hb.Get(); int x; const int n = GetSize(); for (x = 0; x < n; x ++) if (list[x] == p) return x; } return -1; } int FindR(const PTRTYPE *p) const { if (p) { PTRTYPE **list=(PTRTYPE **)m_hb.Get(); int x = GetSize(); while (--x >= 0) if (list[x] == p) return x; } return -1; } PTRTYPE *Add(PTRTYPE *item) { const int s=GetSize(); PTRTYPE **list=(PTRTYPE **)m_hb.ResizeOK((s+1)*(unsigned int)sizeof(PTRTYPE*),false); if (list) { list[s]=item; return item; } return NULL; } PTRTYPE *Set(int index, PTRTYPE *item) { PTRTYPE **list=(PTRTYPE **)m_hb.Get(); if (list && index >= 0 && index < GetSize()) return list[index]=item; return NULL; } PTRTYPE *Insert(int index, PTRTYPE *item) { int s=GetSize(); PTRTYPE **list = (PTRTYPE **)m_hb.ResizeOK((s+1)*(unsigned int)sizeof(PTRTYPE*),false); if (!list) return item; if (index<0) index=0; int x; for (x = s; x > index; x --) list[x]=list[x-1]; return (list[x] = item); } int FindSorted(const PTRTYPE *p, int (*compar)(const PTRTYPE **a, const PTRTYPE **b)) const { bool m; int i = LowerBound(p,&m,compar); return m ? i : -1; } PTRTYPE *InsertSorted(PTRTYPE *item, int (*compar)(const PTRTYPE **a, const PTRTYPE **b)) { bool m; return Insert(LowerBound(item,&m,compar),item); } void Delete(int index) { PTRTYPE **list=GetList(); int size=GetSize(); if (list && index >= 0 && index < size) { if (index < --size) memmove(list+index,list+index+1,(unsigned int)sizeof(PTRTYPE *)*(size-index)); m_hb.Resize(size * (unsigned int)sizeof(PTRTYPE*),false); } } void Delete(int index, bool wantDelete, void (*delfunc)(void *)=NULL) { PTRTYPE **list=GetList(); int size=GetSize(); if (list && index >= 0 && index < size) { if (wantDelete) { if (delfunc) delfunc(Get(index)); else delete Get(index); } if (index < --size) memmove(list+index,list+index+1,(unsigned int)sizeof(PTRTYPE *)*(size-index)); m_hb.Resize(size * (unsigned int)sizeof(PTRTYPE*),false); } } void Delete(int index, void (*delfunc)(PTRTYPE *)) { PTRTYPE **list=GetList(); int size=GetSize(); if (list && index >= 0 && index < size) { if (delfunc) delfunc(Get(index)); if (index < --size) memmove(list+index,list+index+1,(unsigned int)sizeof(PTRTYPE *)*(size-index)); m_hb.Resize(size * (unsigned int)sizeof(PTRTYPE*),false); } } void DeletePtr(const PTRTYPE *p) { Delete(Find(p)); } void DeletePtr(const PTRTYPE *p, bool wantDelete, void (*delfunc)(void *)=NULL) { Delete(Find(p),wantDelete,delfunc); } void DeletePtr(const PTRTYPE *p, void (*delfunc)(PTRTYPE *)) { Delete(Find(p),delfunc); } void Empty() { m_hb.Resize(0,false); } void Empty(bool wantDelete, void (*delfunc)(void *)=NULL) { if (wantDelete) { int x; for (x = GetSize()-1; x >= 0; x --) { PTRTYPE* p = Get(x); if (p) { if (delfunc) delfunc(p); else delete p; } m_hb.Resize(x*(unsigned int)sizeof(PTRTYPE *),false); } } m_hb.Resize(0,false); } void Empty(void (*delfunc)(PTRTYPE *)) { int x; for (x = GetSize()-1; x >= 0; x --) { PTRTYPE* p = Get(x); if (delfunc && p) delfunc(p); m_hb.Resize(x*(unsigned int)sizeof(PTRTYPE *),false); } } void EmptySafe(bool wantDelete=false,void (*delfunc)(void *)=NULL) { if (!wantDelete) Empty(); else { WDL_PtrList tmp; int x; for(x=0;x 0) a = b+1; else if (cmp < 0) c = b; else { *ismatch = true; return b; } } *ismatch = false; return a; } void Compact() { m_hb.Resize(m_hb.GetSize(),true); } private: WDL_HeapBuf m_hb; }; template class WDL_PtrList_DeleteOnDestroy : public WDL_PtrList { public: explicit WDL_PtrList_DeleteOnDestroy(void (*delfunc)(void *)=NULL, int defgran=4096) : WDL_PtrList(defgran), m_delfunc(delfunc) { } ~WDL_PtrList_DeleteOnDestroy() { WDL_PtrList::EmptySafe(true,m_delfunc); } private: void (*m_delfunc)(void *); }; #endif jsusfx-0.4.0/src/WDL/wdlatomic.h000066400000000000000000000027051353477307700164320ustar00rootroot00000000000000#ifndef _WDL_ATOMIC_H_ #define _WDL_ATOMIC_H_ #ifdef _WIN32 static int wdl_atomic_incr(int *v) { return (int) InterlockedIncrement((LONG *)v); } static int wdl_atomic_decr(int *v) { return (int) InterlockedDecrement((LONG *)v); } static int wdl_atomic_incr(volatile int *v) { return (int) InterlockedIncrement((LONG *)v); } static int wdl_atomic_decr(volatile int *v) { return (int) InterlockedDecrement((LONG *)v); } #elif (!defined(__APPLE__) || !defined(__ppc__)) && (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)))) static int wdl_atomic_incr(int *v) { return __sync_add_and_fetch(v,1); } static int wdl_atomic_decr(int *v) { return __sync_add_and_fetch(v,~0); } static int wdl_atomic_incr(volatile int *v) { return __sync_add_and_fetch(v,1); } static int wdl_atomic_decr(volatile int *v) { return __sync_add_and_fetch(v,~0); } #elif defined(__APPLE__) // used by GCC < 4.2 on OSX #include static int wdl_atomic_incr(int *v) { return (int) OSAtomicIncrement32Barrier((int32_t*)v); } static int wdl_atomic_decr(int *v) { return (int) OSAtomicDecrement32Barrier((int32_t*)v); } static int wdl_atomic_incr(volatile int *v) { return (int) OSAtomicIncrement32Barrier((int32_t*)v); } static int wdl_atomic_decr(volatile int *v) { return (int) OSAtomicDecrement32Barrier((int32_t*)v); } #else // unsupported! #pragma message("Need win32 or apple or gcc 4.2+ for wdlatomic.h, doh") #endif #endif jsusfx-0.4.0/src/WDL/wdlcstring.h000066400000000000000000000204001353477307700166170ustar00rootroot00000000000000/* WDL - wdlcstring.h Copyright (C) 2005 and later, Cockos Incorporated This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ /* C string manipulation utilities -- [v]snprintf for Win32, also snprintf_append, lstrcatn, etc */ #ifndef _WDL_CSTRING_H_ #define _WDL_CSTRING_H_ #include #include #include #include "wdltypes.h" #ifdef _WDL_CSTRING_IMPL_ONLY_ #ifdef _WDL_CSTRING_IF_ONLY_ #undef _WDL_CSTRING_IF_ONLY_ #endif #define _WDL_CSTRING_PREFIX #else #define _WDL_CSTRING_PREFIX static WDL_STATICFUNC_UNUSED #endif #if defined(_WIN32) && defined(_MSC_VER) // provide snprintf()/vsnprintf() for win32 -- note that these have no way of knowing // what the amount written was, code should(must) be written to not depend on this. #ifdef snprintf #undef snprintf #endif #define snprintf WDL_snprintf #ifdef vsnprintf #undef vsnprintf #endif #define vsnprintf WDL_vsnprintf #endif // win32 snprintf/vsnprintf // use wdlcstring.h's lstrcpyn_safe rather than the real lstrcpyn. #ifdef _WIN32 #ifdef lstrcpyn #undef lstrcpyn #endif #define lstrcpyn lstrcpyn_safe #endif #ifdef __cplusplus extern "C" { #endif #ifdef _WDL_CSTRING_IF_ONLY_ void lstrcpyn_safe(char *o, const char *in, INT_PTR count); void lstrcatn(char *o, const char *in, INT_PTR count); void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, INT_PTR count, const char *format, ...); void vsnprintf_append(char *o, INT_PTR count, const char *format, va_list va); const char *WDL_get_filepart(const char *str); // returns whole string if no dir chars const char *WDL_get_fileext(const char *str); // returns ".ext" or end of string "" if no extension char *WDL_remove_fileext(char *str); // returns pointer to "ext" if ".ext" was removed (zero-d dot), or NULL char WDL_remove_filepart(char *str); // returns dir character that was zeroed, or 0 if new string is empty int WDL_remove_trailing_dirchars(char *str); // returns trailing dirchar count removed, will not convert "/" into "" size_t WDL_remove_trailing_crlf(char *str); // returns new length #if defined(_WIN32) && defined(_MSC_VER) void WDL_vsnprintf(char *o, size_t count, const char *format, va_list args); void WDL_VARARG_WARN(printf,3,4) WDL_snprintf(char *o, size_t count, const char *format, ...); #endif int WDL_strcmp_logical(const char *s1, const char *s2, int case_sensitive); #else #if defined(_WIN32) && defined(_MSC_VER) _WDL_CSTRING_PREFIX void WDL_vsnprintf(char *o, size_t count, const char *format, va_list args) { if (count>0) { int rv; o[0]=0; rv=_vsnprintf(o,count,format,args); // returns -1 if over, and does not null terminate, ugh if (rv < 0 || rv>=(int)count-1) o[count-1]=0; } } _WDL_CSTRING_PREFIX void WDL_VARARG_WARN(printf,3,4) WDL_snprintf(char *o, size_t count, const char *format, ...) { if (count>0) { int rv; va_list va; va_start(va,format); o[0]=0; rv=_vsnprintf(o,count,format,va); // returns -1 if over, and does not null terminate, ugh va_end(va); if (rv < 0 || rv>=(int)count-1) o[count-1]=0; } } #endif _WDL_CSTRING_PREFIX void lstrcpyn_safe(char *o, const char *in, INT_PTR count) { if (count>0) { while (--count>0 && *in) *o++ = *in++; *o=0; } } _WDL_CSTRING_PREFIX void lstrcatn(char *o, const char *in, INT_PTR count) { if (count>0) { while (*o) { if (--count < 1) return; o++; } while (--count>0 && *in) *o++ = *in++; *o=0; } } _WDL_CSTRING_PREFIX const char *WDL_get_filepart(const char *str) // returns whole string if no dir chars { const char *p = str; while (*p) p++; while (p >= str && !WDL_IS_DIRCHAR(*p)) --p; return p + 1; } _WDL_CSTRING_PREFIX const char *WDL_get_fileext(const char *str) // returns ".ext" or end of string "" if no extension { const char *p=str, *ep; while (*p) p++; ep = p; while (p >= str && !WDL_IS_DIRCHAR(*p)) { if (*p == '.') return p; --p; } return ep; } _WDL_CSTRING_PREFIX char *WDL_remove_fileext(char *str) // returns pointer to "ext" if ".ext" was removed (zero-d dot), or NULL { char *p=str; while (*p) p++; while (p >= str && !WDL_IS_DIRCHAR(*p)) { if (*p == '.') { *p = 0; return p+1; } --p; } return NULL; } _WDL_CSTRING_PREFIX char WDL_remove_filepart(char *str) // returns dir character that was zeroed, or 0 if new string is empty { char *p=str; while (*p) p++; while (p >= str) { char c = *p; if (WDL_IS_DIRCHAR(c)) { *p = 0; return c; } --p; } str[0] = 0; return 0; } _WDL_CSTRING_PREFIX int WDL_remove_trailing_dirchars(char *str) // returns trailing dirchar count removed { int cnt = 0; char *p=str; while (*p) p++; while (p > str+1 && WDL_IS_DIRCHAR(p[-1])) { cnt++; p--; } *p = 0; return cnt; } _WDL_CSTRING_PREFIX size_t WDL_remove_trailing_crlf(char *str) // returns new length { char *p=str; while (*p) p++; while (p > str && (p[-1] == '\r' || p[-1] == '\n')) p--; *p = 0; return p-str; } _WDL_CSTRING_PREFIX void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, INT_PTR count, const char *format, ...) { if (count>0) { va_list va; while (*o) { if (--count < 1) return; o++; } va_start(va,format); vsnprintf(o,count,format,va); va_end(va); } } _WDL_CSTRING_PREFIX void vsnprintf_append(char *o, INT_PTR count, const char *format, va_list va) { if (count>0) { while (*o) { if (--count < 1) return; o++; } vsnprintf(o,count,format,va); } } _WDL_CSTRING_PREFIX int WDL_strcmp_logical(const char *s1, const char *s2, int case_sensitive) { // also exists as WDL_LogicalSortStringKeyedArray::_cmpstr() char lastNonZeroChar=0; // last matching character, updated if not 0. this allows us to track whether // we are inside of a number with the same leading digits for (;;) { char c1=*s1++, c2=*s2++; if (!c1) return c1-c2; if (c1!=c2) { if (c1 >= '0' && c1 <= '9' && c2 >= '0' && c2 <= '9') { int lzdiff=0, cnt=0; if (lastNonZeroChar < '1' || lastNonZeroChar > '9') { while (c1 == '0') { c1=*s1++; lzdiff--; } while (c2 == '0') { c2=*s2++; lzdiff++; } // lzdiff = lz2-lz1, more leading 0s = earlier in list } for (;;) { if (c1 >= '0' && c1 <= '9') { if (c2 < '0' || c2 > '9') return 1; c1=s1[cnt]; c2=s2[cnt++]; } else { if (c2 >= '0' && c2 <= '9') return -1; break; } } s1--; s2--; while (cnt--) { const int d = *s1++ - *s2++; if (d) return d; } if (lzdiff) return lzdiff; } else { if (!case_sensitive) { if (c1>='a' && c1<='z') c1+='A'-'a'; if (c2>='a' && c2<='z') c2+='A'-'a'; } if (c1 != c2) return c1-c2; } } else if (c1 != '0') lastNonZeroChar=c1; } } #endif #ifdef __cplusplus }; #endif #undef _WDL_CSTRING_PREFIX #endif jsusfx-0.4.0/src/WDL/wdlstring.h000066400000000000000000000320141353477307700164600ustar00rootroot00000000000000/* WDL - wdlstring.h Copyright (C) 2005 and later, Cockos Incorporated This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ /* This file provides a simple class for variable-length string manipulation. It provides only the simplest features, and does not do anything confusing like operator overloading. It uses a WDL_HeapBuf for internal storage. Actually: there are WDL_String and WDL_FastString -- the latter's Get() returns const char, and tracks the length of the string, which is often faster. Because of this, you are not permitted to directly modify the buffer returned by Get(). */ #ifndef _WDL_STRING_H_ #define _WDL_STRING_H_ #include "heapbuf.h" #include #include #ifndef WDL_STRING_IMPL_ONLY class WDL_String { public: #ifdef WDL_STRING_INTF_ONLY void Set(const char *str, int maxlen=0); void Set(const WDL_String *str, int maxlen=0); void Append(const char *str, int maxlen=0); void Append(const WDL_String *str, int maxlen=0); void DeleteSub(int position, int len); void Insert(const char *str, int position, int maxlen=0); void Insert(const WDL_String *str, int position, int maxlen=0); bool SetLen(int length, bool resizeDown=false); // returns true on success void Ellipsize(int minlen, int maxlen); const char *get_filepart() const; // returns whole string if no dir chars const char *get_fileext() const; // returns ".ext" or end of string "" if no extension bool remove_fileext(); // returns true if extension was removed char remove_filepart(bool keepTrailingSlash=false); // returns dir character used, or zero if string emptied int remove_trailing_dirchars(); // returns trailing dirchar count removed, will not convert "/" into "" void SetAppendFormattedArgs(bool append, int maxlen, const char* fmt, va_list arglist); void WDL_VARARG_WARN(printf,3,4) SetFormatted(int maxlen, const char *fmt, ...); void WDL_VARARG_WARN(printf,3,4) AppendFormatted(int maxlen, const char *fmt, ...); #endif const char *Get() const { return m_hb.GetSize()?(char*)m_hb.Get():""; } #ifdef WDL_STRING_FASTSUB_DEFINED int GetLength() const { int a = m_hb.GetSize(); return a>0?a-1:0; } // for binary-safe manipulations void SetRaw(const char *str, int len) { __doSet(0,str,len,0); } void AppendRaw(const char *str, int len) { __doSet(GetLength(),str,len,0); } void InsertRaw(const char *str, int position, int ilen) { const int srclen = GetLength(); if (position<0) position=0; else if (position>srclen) position=srclen; if (ilen>0) __doSet(position,str,ilen,srclen-position); } #else char *Get() { if (m_hb.GetSize()) return (char *)m_hb.Get(); static char c; c=0; return &c; // don't return "", in case it gets written to. } int GetLength() const { return m_hb.GetSize()?(int)strlen((const char*)m_hb.Get()):0; } #endif explicit WDL_String(int hbgran) : m_hb(hbgran WDL_HEAPBUF_TRACEPARM("WDL_String(4)")) { } explicit WDL_String(const char *initial=NULL, int initial_len=0) : m_hb(128 WDL_HEAPBUF_TRACEPARM("WDL_String")) { if (initial) Set(initial,initial_len); } WDL_String(const WDL_String &s) : m_hb(128 WDL_HEAPBUF_TRACEPARM("WDL_String(2)")) { Set(&s); } WDL_String(const WDL_String *s) : m_hb(128 WDL_HEAPBUF_TRACEPARM("WDL_String(3)")) { if (s && s != this) Set(s); } ~WDL_String() { } #endif // ! WDL_STRING_IMPL_ONLY #ifndef WDL_STRING_INTF_ONLY #ifdef WDL_STRING_IMPL_ONLY #define WDL_STRING_FUNCPREFIX WDL_String:: #define WDL_STRING_DEFPARM(x) #else #define WDL_STRING_FUNCPREFIX #define WDL_STRING_DEFPARM(x) =(x) #endif void WDL_STRING_FUNCPREFIX Set(const char *str, int maxlen WDL_STRING_DEFPARM(0)) { int s=0; if (str) { if (maxlen>0) while (s < maxlen && str[s]) s++; else s=(int)strlen(str); } __doSet(0,str,s,0); } void WDL_STRING_FUNCPREFIX Set(const WDL_String *str, int maxlen WDL_STRING_DEFPARM(0)) { #ifdef WDL_STRING_FASTSUB_DEFINED int s = str ? str->GetLength() : 0; if (maxlen>0 && maxlenGet():NULL,s,0); #else Set(str?str->Get():NULL, maxlen); // might be faster: "partial" strlen #endif } void WDL_STRING_FUNCPREFIX Append(const char *str, int maxlen WDL_STRING_DEFPARM(0)) { int s=0; if (str) { if (maxlen>0) while (s < maxlen && str[s]) s++; else s=(int)strlen(str); } __doSet(GetLength(),str,s,0); } void WDL_STRING_FUNCPREFIX Append(const WDL_String *str, int maxlen WDL_STRING_DEFPARM(0)) { #ifdef WDL_STRING_FASTSUB_DEFINED int s = str ? str->GetLength() : 0; if (maxlen>0 && maxlenGet():NULL,s,0); #else Append(str?str->Get():NULL, maxlen); // might be faster: "partial" strlen #endif } void WDL_STRING_FUNCPREFIX DeleteSub(int position, int len) { int l=m_hb.GetSize()-1; char *p=(char *)m_hb.Get(); if (l<0 || !*p || position < 0 || position >= l) return; if (position+len > l) len=l-position; if (len>0) { memmove(p+position,p+position+len,l-position-len+1); m_hb.Resize(l+1-len,false); } } void WDL_STRING_FUNCPREFIX Insert(const char *str, int position, int maxlen WDL_STRING_DEFPARM(0)) { int ilen=0; if (str) { if (maxlen>0) while (ilen < maxlen && str[ilen]) ilen++; else ilen=(int)strlen(str); } const int srclen = GetLength(); if (position<0) position=0; else if (position>srclen) position=srclen; if (ilen>0) __doSet(position,str,ilen,srclen-position); } void WDL_STRING_FUNCPREFIX Insert(const WDL_String *str, int position, int maxlen WDL_STRING_DEFPARM(0)) { #ifdef WDL_STRING_FASTSUB_DEFINED int ilen = str ? str->GetLength() : 0; if (maxlen>0 && maxlen0 ? m_hb.GetSize()-1 : 0; if (position<0) position=0; else if (position>srclen) position=srclen; if (ilen>0) __doSet(position,str->Get(),ilen,srclen-position); #else Insert(str?str->Get():NULL, position, maxlen); // might be faster: "partial" strlen #endif } bool WDL_STRING_FUNCPREFIX SetLen(int length, bool resizeDown WDL_STRING_DEFPARM(false)) { #ifdef WDL_STRING_FASTSUB_DEFINED int osz = m_hb.GetSize()-1; if (osz<0)osz=0; #endif if (length < 0) length=0; char *b=(char*)m_hb.ResizeOK(length+1,resizeDown); if (b) { #ifdef WDL_STRING_FASTSUB_DEFINED const int fill = length-osz; if (fill > 0) memset(b+osz,' ',fill); #endif b[length]=0; return true; } return false; } void WDL_STRING_FUNCPREFIX SetAppendFormattedArgs(bool append, int maxlen, const char* fmt, va_list arglist) { int offs = append ? GetLength() : 0; char *b= (char*) m_hb.ResizeOK(offs+maxlen+1,false); if (!b) return; b+=offs; #ifdef _WIN32 int written = _vsnprintf(b, maxlen+1, fmt, arglist); if (written < 0 || written>=maxlen) b[written=b[0]?maxlen:0]=0; #else int written = vsnprintf(b, maxlen+1, fmt, arglist); if (written > maxlen) written=maxlen; #endif m_hb.Resize(offs + written + 1,false); } void WDL_VARARG_WARN(printf,3,4) WDL_STRING_FUNCPREFIX SetFormatted(int maxlen, const char *fmt, ...) { va_list arglist; va_start(arglist, fmt); SetAppendFormattedArgs(false,maxlen,fmt,arglist); va_end(arglist); } void WDL_VARARG_WARN(printf,3,4) WDL_STRING_FUNCPREFIX AppendFormatted(int maxlen, const char *fmt, ...) { va_list arglist; va_start(arglist, fmt); SetAppendFormattedArgs(true,maxlen,fmt,arglist); va_end(arglist); } void WDL_STRING_FUNCPREFIX Ellipsize(int minlen, int maxlen) { if (maxlen >= 4 && m_hb.GetSize() && GetLength() > maxlen) { if (minlen<0) minlen=0; char *b = (char *)m_hb.Get(); int i; for (i = maxlen-4; i >= minlen; --i) { if (b[i] == ' ') { memcpy(b+i, "...",4); m_hb.Resize(i+4,false); break; } } if (i < minlen && maxlen >= 4) { memcpy(b+maxlen-4, "...",4); m_hb.Resize(maxlen,false); } } } const char * WDL_STRING_FUNCPREFIX get_filepart() const // returns whole string if no dir chars { const char *s = Get(); const char *p = s + GetLength() - 1; while (p >= s && !WDL_IS_DIRCHAR(*p)) --p; return p + 1; } const char * WDL_STRING_FUNCPREFIX get_fileext() const // returns ".ext" or end of string "" if no extension { const char *s = Get(); const char *endp = s + GetLength(); const char *p = endp - 1; while (p >= s && !WDL_IS_DIRCHAR(*p)) { if (*p == '.') return p; --p; } return endp; } bool WDL_STRING_FUNCPREFIX remove_fileext() // returns true if extension was removed { const char *str = Get(); int pos = GetLength() - 1; while (pos >= 0) { char c = str[pos]; if (WDL_IS_DIRCHAR(c)) break; if (c == '.') { SetLen(pos); return true; } --pos; } return false; } char WDL_STRING_FUNCPREFIX remove_filepart(bool keepTrailingSlash WDL_STRING_DEFPARM(false)) // returns directory character used, or 0 if string emptied { char rv=0; const char *str = Get(); int pos = GetLength() - 1; while (pos > 0) { char c = str[pos]; if (WDL_IS_DIRCHAR(c)) { rv=c; if (keepTrailingSlash) ++pos; break; } --pos; } SetLen(pos); return rv; } int WDL_STRING_FUNCPREFIX remove_trailing_dirchars() // returns trailing dirchar count removed { int cnt = 0; const char *str = Get(); const int l = GetLength()-1; while (cnt < l) { char c = str[l - cnt]; if (!WDL_IS_DIRCHAR(c)) break; ++cnt; } if (cnt > 0) SetLen(l + 1 - cnt); return cnt; } #ifndef WDL_STRING_IMPL_ONLY private: #endif void WDL_STRING_FUNCPREFIX __doSet(int offs, const char *str, int len, int trailkeep) { // if non-empty, or (empty and allocated and Set() rather than append/insert), then allow update, otherwise do nothing if (len==0 && !trailkeep && !offs) { #ifdef WDL_STRING_FREE_ON_CLEAR m_hb.Resize(0,true); #else char *p = (char *)m_hb.Resize(1,false); if (p) *p=0; #endif } else if (len>0 && offs >= 0) { const int oldsz = m_hb.GetSize(); const int newsz=offs+len+trailkeep+1; const int growamt = newsz-oldsz; if (growamt > 0) { const char *oldb = (const char *)m_hb.Get(); const char *newb = (const char *)m_hb.Resize(newsz,false); // resize up if necessary // in case str overlaps with input, keep it valid if (str && newb != oldb && str >= oldb && str < oldb+oldsz) str = newb + (str - oldb); } if (m_hb.GetSize() >= newsz) { char *newbuf = (char *)m_hb.Get(); if (trailkeep>0) memmove(newbuf+offs+len,newbuf+offs,trailkeep); if (str) memmove(newbuf+offs,str,len); newbuf[newsz-1]=0; // resize down if necessary if (growamt < 0) m_hb.Resize(newsz,false); } } } #undef WDL_STRING_FUNCPREFIX #undef WDL_STRING_DEFPARM #endif // ! WDL_STRING_INTF_ONLY #ifndef WDL_STRING_IMPL_ONLY private: #ifdef WDL_STRING_INTF_ONLY void __doSet(int offs, const char *str, int len, int trailkeep); #endif WDL_HeapBuf m_hb; }; #endif #ifndef WDL_STRING_FASTSUB_DEFINED #undef _WDL_STRING_H_ #define WDL_STRING_FASTSUB_DEFINED #define WDL_String WDL_FastString #include "wdlstring.h" #undef WDL_STRING_FASTSUB_DEFINED #undef WDL_String #endif #endif jsusfx-0.4.0/src/WDL/wdltypes.h000066400000000000000000000101571353477307700163220ustar00rootroot00000000000000#ifndef _WDLTYPES_ #define _WDLTYPES_ #ifdef _MSC_VER typedef __int64 WDL_INT64; typedef unsigned __int64 WDL_UINT64; #else typedef long long WDL_INT64; typedef unsigned long long WDL_UINT64; #endif #ifdef _MSC_VER #define WDL_UINT64_CONST(x) (x##ui64) #define WDL_INT64_CONST(x) (x##i64) #else #define WDL_UINT64_CONST(x) (x##ULL) #define WDL_INT64_CONST(x) (x##LL) #endif #if !defined(_MSC_VER) || _MSC_VER > 1200 #define WDL_DLGRET INT_PTR CALLBACK #else #define WDL_DLGRET BOOL CALLBACK #endif #ifdef _WIN32 #include #else #include typedef intptr_t INT_PTR; typedef uintptr_t UINT_PTR; #endif #if defined(__ppc__) || !defined(__cplusplus) typedef char WDL_bool; #else typedef bool WDL_bool; #endif #ifndef GWLP_USERDATA #define GWLP_USERDATA GWL_USERDATA #define GWLP_WNDPROC GWL_WNDPROC #define GWLP_HINSTANCE GWL_HINSTANCE #define GWLP_HWNDPARENT GWL_HWNDPARENT #define DWLP_USER DWL_USER #define DWLP_DLGPROC DWL_DLGPROC #define DWLP_MSGRESULT DWL_MSGRESULT #define SetWindowLongPtr(a,b,c) SetWindowLong(a,b,c) #define GetWindowLongPtr(a,b) GetWindowLong(a,b) #define SetWindowLongPtrW(a,b,c) SetWindowLongW(a,b,c) #define GetWindowLongPtrW(a,b) GetWindowLongW(a,b) #define SetWindowLongPtrA(a,b,c) SetWindowLongA(a,b,c) #define GetWindowLongPtrA(a,b) GetWindowLongA(a,b) #define GCLP_WNDPROC GCL_WNDPROC #define GCLP_HICON GCL_HICON #define GCLP_HICONSM GCL_HICONSM #define SetClassLongPtr(a,b,c) SetClassLong(a,b,c) #define GetClassLongPtr(a,b) GetClassLong(a,b) #endif #ifdef __GNUC__ // for structures that contain doubles, or doubles in structures that are after stuff of questionable alignment (for OSX/linux) #define WDL_FIXALIGN __attribute__ ((aligned (8))) // usage: void func(int a, const char *fmt, ...) WDL_VARARG_WARN(printf,2,3); // note: if member function, this pointer is counted as well, so as member function that would be 3,4 #define WDL_VARARG_WARN(x,n,s) __attribute__ ((format (x,n,s))) #define WDL_STATICFUNC_UNUSED __attribute__((unused)) #else #define WDL_FIXALIGN #define WDL_VARARG_WARN(x,n,s) #define WDL_STATICFUNC_UNUSED #endif #ifndef WDL_WANT_NEW_EXCEPTIONS #if defined(__cplusplus) #include #define WDL_NEW (std::nothrow) #endif #else #define WDL_NEW #endif #if !defined(max) && defined(WDL_DEFINE_MINMAX) #define max(x,y) ((x)<(y)?(y):(x)) #define min(x,y) ((x)<(y)?(x):(y)) #endif #ifndef wdl_max #define wdl_max(x,y) ((x)<(y)?(y):(x)) #define wdl_min(x,y) ((x)<(y)?(x):(y)) #define wdl_abs(x) ((x)<0 ? -(x) : (x)) #endif #ifndef _WIN32 #ifndef strnicmp #define strnicmp(x,y,z) strncasecmp(x,y,z) #endif #ifndef stricmp #define stricmp(x,y) strcasecmp(x,y) #endif #endif #ifdef WDL_BACKSLASHES_ARE_ORDINARY #define WDL_IS_DIRCHAR(x) ((x) == '/') #else // for multi-platform applications it seems better to treat backslashes as directory separators even if it // isn't supported by the underying system (for resolving filenames, etc) #ifdef _WIN32 #define WDL_IS_DIRCHAR(x) ((x) == '\\' || (x) == '/') #else #define WDL_IS_DIRCHAR(x) ((x) == '/' || (x) == '\\') #endif #endif #if defined(_WIN32) && !defined(WDL_BACKSLASHES_ARE_ORDINARY) #define WDL_DIRCHAR '\\' #define WDL_DIRCHAR_STR "\\" #else #define WDL_DIRCHAR '/' #define WDL_DIRCHAR_STR "/" #endif #if defined(_WIN32) || defined(__APPLE__) // on __APPLE__ we should ideally check the filesystem for case-sensitivity, assuming a case-insensitive-only match #define wdl_filename_cmp(x,y) stricmp(x,y) #define wdl_filename_cmpn(x,y,n) strnicmp(x,y,n) #else #define wdl_filename_cmp(x,y) strcmp(x,y) #define wdl_filename_cmpn(x,y,n) strncmp(x,y,n) #endif #if defined(__GNUC__) || defined(__INTEL_COMPILER) #define WDL_likely(x) (__builtin_expect(!!(x),1)) #define WDL_unlikely(x) (__builtin_expect(!!(x),0)) #else #define WDL_likely(x) (!!(x)) #define WDL_unlikely(x) (!!(x)) #endif #if defined(_DEBUG) || defined(DEBUG) #include #define WDL_ASSERT(x) assert(x) #define WDL_NORMALLY(x) (assert(x),1) #define WDL_NOT_NORMALLY(x) (assert(!(x)),0) #else #define WDL_ASSERT(x) #define WDL_NORMALLY(x) WDL_likely(x) #define WDL_NOT_NORMALLY(x) WDL_unlikely(x) #endif #endif jsusfx-0.4.0/src/jsusfx.cpp000066400000000000000000000745621353477307700157100ustar00rootroot00000000000000/* * Copyright 2014-2015 Pascal Gauthier * Copyright 2018 Pascal Gauthier, Marcel Smit * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * *distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "jsusfx.h" #include "jsusfx_file.h" #include "jsusfx_gfx.h" #include "jsusfx_serialize.h" #include #ifndef WIN32 #include #endif #include "WDL/ptrlist.h" #include "WDL/assocarray.h" #define REAPER_GET_INTERFACE(opaque) ((opaque) ? ((JsusFx*)opaque) : nullptr) #define AUTOVAR(name) name = NSEEL_VM_regvar(m_vm, #name); *name = 0 #define AUTOVARV(name,value) name = NSEEL_VM_regvar(m_vm, #name); *name = value #define EEL_STRING_GET_CONTEXT_POINTER(opaque) (((JsusFx *)opaque)->m_string_context) #ifdef EEL_STRING_STDOUT_WRITE #ifndef EELSCRIPT_NO_STDIO #define EEL_STRING_STDOUT_WRITE(x,len) { fwrite(x,len,1,stdout); fflush(stdout); } #endif #endif #include "WDL/eel2/eel_strings.h" #include "WDL/eel2/eel_misc.h" #include "WDL/eel2/eel_fft.h" #include "WDL/eel2/eel_mdct.h" #include // to check if files exist // Reaper API static EEL_F * NSEEL_CGEN_CALL _reaper_slider(void *opaque, EEL_F *n) { JsusFx *ctx = REAPER_GET_INTERFACE(opaque); const int index = *n; if (index >= 0 && index < ctx->kMaxSliders) return ctx->sliders[index].owner; else { ctx->dummyValue = 0; return &ctx->dummyValue; } } static EEL_F * NSEEL_CGEN_CALL _reaper_spl(void *opaque, EEL_F *n) { JsusFx *ctx = REAPER_GET_INTERFACE(opaque); const int index = *n; if (index >= 0 && index < ctx->numValidInputChannels) return ctx->spl[index]; else { ctx->dummyValue = 0; return &ctx->dummyValue; } } static EEL_F NSEEL_CGEN_CALL _midirecv(void *opaque, INT_PTR np, EEL_F **parms) { JsusFx *ctx = REAPER_GET_INTERFACE(opaque); while (ctx->midiSize > 0) { // peek the message type const uint8_t b = ctx->midi[0]; if ((b & 0xf0) == 0xf0) { // 0xf0 = system exclusive message // consume the byte ctx->midi++; ctx->midiSize--; // skip until we find a 0xf7 byte for (;;) { // end of data stream? if (ctx->midiSize == 0) break; // consume the byte const uint8_t b = ctx->midi[0]; ctx->midi++; ctx->midiSize--; // end of system exclusive message? if (b == 0xf7) break; } } else if (b & 0x80) { // status byte const uint8_t event = b & 0xf0; //const uint8_t channel = b & 0x0f; // consume the byte ctx->midi++; ctx->midiSize--; // data bytes if (ctx->midiSize >= 2) { *parms[0] = 0; *parms[1] = event; if (np >= 4) { *parms[2] = ctx->midi[0]; *parms[3] = ctx->midi[1]; } else { *parms[2] = ctx->midi[0] + ctx->midi[1] * 256; } ctx->midi += 2; ctx->midiSize -= 2; return 1; } else { ctx->midiSize = 0; return 0; } } else { // data byte without a preceeding status byte? something is wrong here ctx->midiSize--; // decrement this otherwise it is an infinite loop ctx->displayMsg("Inconsistent midi stream %x\n", b); } } return 0; } static EEL_F NSEEL_CGEN_CALL _midisend(void *opaque, INT_PTR np, EEL_F **parms) { JsusFx *ctx = REAPER_GET_INTERFACE(opaque); if (ctx->midiSendBufferSize + 3 > ctx->midiSendBufferCapacity) { return 0; } else if (np == 3) { const int offset = (int)*parms[0]; (void)offset; // sample offset into current block. not used const uint8_t msg1 = (uint8_t)*parms[1]; const uint16_t msg23 = (uint16_t)*parms[2]; const uint8_t msg2 = (msg23 >> 0) & 0xff; const uint8_t msg3 = (msg23 >> 8) & 0xff; //printf("midi send. cmd=%x, msg2=%d, msg3=%x\n", msg1, msg2, msg3); ctx->midiSendBuffer[ctx->midiSendBufferSize++] = msg1; ctx->midiSendBuffer[ctx->midiSendBufferSize++] = msg2; ctx->midiSendBuffer[ctx->midiSendBufferSize++] = msg3; return msg1; } else if (np == 4) { const int offset = (int)*parms[0]; (void)offset; // sample offset into current block. not used const uint8_t msg1 = (uint8_t)*parms[1]; const uint8_t msg2 = (uint8_t)*parms[2]; const uint8_t msg3 = (uint8_t)*parms[3]; ctx->midiSendBuffer[ctx->midiSendBufferSize++] = msg1; ctx->midiSendBuffer[ctx->midiSendBufferSize++] = msg2; ctx->midiSendBuffer[ctx->midiSendBufferSize++] = msg3; return msg1; } else { return 0; } } static EEL_F NSEEL_CGEN_CALL _midisend_buf(void *opaque, INT_PTR np, EEL_F **parms) { JsusFx *ctx = REAPER_GET_INTERFACE(opaque); if (np == 3) { const int offset = (int)*parms[0]; (void)offset; // sample offset into current block. not used void *buf = (void*)parms[1]; const int len = (int)*parms[2]; // note : should we auto-detect SysEx messages? Reaper does it, but it seems like a bad idea.. // auto-detection would automagically determine the message's length here by parsing the message stream if (len < 0 || ctx->midiSendBufferSize + len > ctx->midiSendBufferCapacity) { return 0; } else { memcpy(&ctx->midiSendBuffer[ctx->midiSendBufferSize], buf, len); ctx->midiSendBufferSize += len; return len; } } else { return 0; } } // todo : remove __stub static EEL_F NSEEL_CGEN_CALL __stub(void *opaque, INT_PTR np, EEL_F **parms) { return 0.0; } // struct JsusFx_Section { WDL_String code; int lineOffset; JsusFx_Section() { lineOffset = 0; } }; struct JsusFx_Sections { JsusFx_Section init; JsusFx_Section slider; JsusFx_Section block; JsusFx_Section sample; JsusFx_Section gfx; JsusFx_Section serialize; }; // static const char *skipWhite(const char *text) { while ( *text && isspace(*text) ) text++; return text; } static const char *nextToken(const char *text) { while ( *text && *text != ',' && *text != '=' && *text != '<' && *text != '>' && *text != '{' && *text != '}' ) text++; return text; } bool JsusFx_Slider::config(JsusFx &fx, const int index, const char *param, const int lnumber) { char buffer[2048]; strncpy(buffer, param, 2048); def = min = max = inc = 0; exists = false; enumNames.clear(); isEnum = false; bool hasName = false; const char *tmp = strchr(buffer, '>'); if ( tmp != NULL ) { tmp++; while (*tmp == ' ') tmp++; strncpy(desc, tmp, 64); tmp = 0; } else { desc[0] = 0; } tmp = buffer; if ( isalpha(*tmp) ) { // extended syntax of format "slider1:variable_name=5<0,10,1>slider description" const char *begin = tmp; while ( *tmp && *tmp != '=' ) tmp++; if ( *tmp != '=' ) { fx.displayError("Expected '=' at end of slider name %d", lnumber); return false; } const char *end = tmp; int len = end - begin; if ( len > JsusFx_Slider::kMaxName ) { fx.displayError("Slider name too long %d", lnumber); return false; } for ( int i = 0; i < len; ++i ) name[i] = begin[i]; name[len] = 0; hasName = true; tmp++; } if ( !sscanf(tmp, "%f", &def) ) return false; tmp = nextToken(tmp); if ( *tmp != '<' ) { fx.displayError("slider info is missing"); return false; } else { tmp++; if ( !sscanf(tmp, "%f", &min) ) { fx.displayError("failed to read min value"); return false; } tmp = nextToken(tmp); if ( *tmp != ',' ) { fx.displayError("max value is missing"); return false; } else { tmp++; if ( !sscanf(tmp, "%f", &max) ) { fx.displayError("failed to read max value"); return false; } tmp = nextToken(tmp); if ( *tmp == ',') { tmp++; tmp = skipWhite(tmp); if ( !sscanf(tmp, "%f", &inc) ) { //log("failed to read increment value"); //return false; inc = 0; } tmp = nextToken(tmp); if ( *tmp == '{' ) { isEnum = true; inc = 1; tmp++; while ( true ) { const char *end = nextToken(tmp); const std::string name(tmp, end); enumNames.push_back(name); tmp = end; if ( *tmp == 0 ) { fx.displayError("enum value list not properly terminated"); return false; } if ( *tmp == '}' ) { break; } tmp++; } tmp++; } } } } if (hasName == false) { sprintf(name, "slider%d", index); } owner = NSEEL_VM_regvar(fx.m_vm, name); *owner = def; exists = true; return true; } // JsusFxPathLibrary_Basic::JsusFxPathLibrary_Basic(const char * _dataRoot) { if ( _dataRoot != nullptr ) dataRoot = _dataRoot; } void JsusFxPathLibrary_Basic::addSearchPath(const std::string & path) { if ( path.empty() ) return; // make sure it ends with '/' or '\\' if ( path.back() == '/' || path.back() == '\\' ) searchPaths.push_back(path); else searchPaths.push_back(path + "/"); } bool JsusFxPathLibrary_Basic::fileExists(const std::string &filename) { std::ifstream is(filename); return is.is_open(); } bool JsusFxPathLibrary_Basic::resolveImportPath(const std::string &importPath, const std::string &parentPath, std::string &resolvedPath) { const size_t pos = parentPath.rfind('/'); if ( pos != std::string::npos ) resolvedPath = parentPath.substr(0, pos + 1); if ( fileExists(resolvedPath + importPath) ) { resolvedPath = resolvedPath + importPath; return true; } for ( std::string & searchPath : searchPaths ) { if ( fileExists(resolvedPath + searchPath + importPath) ) { resolvedPath = resolvedPath + searchPath + importPath; return true; } } return false; } bool JsusFxPathLibrary_Basic::resolveDataPath(const std::string &importPath, std::string &resolvedPath) { if ( !dataRoot.empty() ) resolvedPath = dataRoot + "/" + importPath; else resolvedPath = importPath; return fileExists(resolvedPath); } std::istream* JsusFxPathLibrary_Basic::open(const std::string &path) { std::ifstream *stream = new std::ifstream(path); if ( stream->is_open() == false ) { delete stream; stream = nullptr; } return stream; } void JsusFxPathLibrary_Basic::close(std::istream *&stream) { delete stream; stream = nullptr; } // JsusFx::JsusFx(JsusFxPathLibrary &_pathLibrary) : pathLibrary(_pathLibrary) { m_vm = NSEEL_VM_alloc(); codeInit = codeSlider = codeBlock = codeSample = codeGfx = codeSerialize = NULL; NSEEL_VM_SetCustomFuncThis(m_vm,this); m_string_context = new eel_string_context_state(); eel_string_initvm(m_vm); computeSlider = false; srate = 0; pathLibrary = _pathLibrary; fileAPI = nullptr; midi = nullptr; midiSize = 0; midiSendBuffer = nullptr; midiSendBufferCapacity = 0; midiSendBufferSize = 0; gfx = nullptr; gfx_w = 0; gfx_h = 0; serializer = nullptr; for (int i = 0; i < kMaxSamples; ++i) { char name[16]; sprintf(name, "spl%d", i); spl[i] = NSEEL_VM_regvar(m_vm, name); *spl[i] = 0; } numInputs = 0; numOutputs = 0; numValidInputChannels = 0; AUTOVAR(srate); AUTOVARV(num_ch, 2); AUTOVAR(samplesblock); AUTOVAR(trigger); // transport state. use setTransportValues to set these AUTOVARV(tempo, 120); // playback tempo in beats per minute AUTOVARV(play_state, 1); // playback state. see the PlaybackState enum for details AUTOVAR(play_position); // current playback position in seconds AUTOVAR(beat_position); // current playback position in beats (beats = quarternotes in /4 time signatures) AUTOVARV(ts_num, 0); // time signature nominator. i.e. 3 if using 3/4 time AUTOVARV(ts_denom, 4); // time signature denominator. i.e. 4 if using 3/4 time AUTOVAR(ext_noinit); AUTOVAR(ext_nodenorm); // set to 1 to disable noise added to signals to avoid denormals from popping up // midi bus support AUTOVAR(ext_midi_bus); // when set to 1, support for midi buses is enabled. otherwise, only bus 0 is active and others will pass through AUTOVAR(midi_bus); // Reaper API NSEEL_addfunc_varparm("slider_automate",1,NSEEL_PProc_THIS,&__stub); // todo : implement slider_automate. add Reaper api interface? NSEEL_addfunc_varparm("slider_next_chg",2,NSEEL_PProc_THIS,&__stub); // todo : implement slider_next_chg. add Reaper api interface? NSEEL_addfunc_varparm("sliderchange",1,NSEEL_PProc_THIS,&__stub); // todo : implement sliderchange. add Reaper api interface? NSEEL_addfunc_retptr("slider",1,NSEEL_PProc_THIS,&_reaper_slider); NSEEL_addfunc_retptr("spl",1,NSEEL_PProc_THIS,&_reaper_spl); NSEEL_addfunc_varparm("midirecv",3,NSEEL_PProc_THIS,&_midirecv); NSEEL_addfunc_varparm("midisend",3,NSEEL_PProc_THIS,&_midisend); NSEEL_addfunc_varparm("midisend_buf",3,NSEEL_PProc_THIS,&_midisend_buf); } JsusFx::~JsusFx() { releaseCode(); if (m_vm) NSEEL_VM_free(m_vm); delete m_string_context; } bool JsusFx::compileSection(int state, const char *code, int line_offset) { if ( code[0] == 0 ) return true; char errorMsg[4096]; //printf("section code:\n"); //printf("%s", code); switch(state) { case 0: codeInit = NSEEL_code_compile_ex(m_vm, code, line_offset, NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS); if ( codeInit == NULL ) { snprintf(errorMsg, 4096, "@init line %s", NSEEL_code_getcodeerror(m_vm)); displayError(errorMsg); return false; } break; case 1: codeSlider = NSEEL_code_compile_ex(m_vm, code, line_offset, NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS); if ( codeSlider == NULL ) { snprintf(errorMsg, 4096, "@slider line %s", NSEEL_code_getcodeerror(m_vm)); displayError(errorMsg); return false; } break; case 2: codeBlock = NSEEL_code_compile_ex(m_vm, code, line_offset, NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS); if ( codeBlock == NULL ) { snprintf(errorMsg, 4096, "@block line %s", NSEEL_code_getcodeerror(m_vm)); displayError(errorMsg); return false; } break; case 3: codeSample = NSEEL_code_compile_ex(m_vm, code, line_offset, NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS); if ( codeSample == NULL ) { snprintf(errorMsg, 4096, "@sample line %s", NSEEL_code_getcodeerror(m_vm)); displayError(errorMsg); return false; } break; case 4: codeGfx = NSEEL_code_compile_ex(m_vm, code, line_offset, NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS); if ( codeGfx == NULL ) { snprintf(errorMsg, 4096, "@gfx line %s", NSEEL_code_getcodeerror(m_vm)); displayError(errorMsg); return false; } break; case 5: codeSerialize = NSEEL_code_compile_ex(m_vm, code, line_offset, NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS); if ( codeSerialize == NULL ) { snprintf(errorMsg, 4096, "@serialize line %s", NSEEL_code_getcodeerror(m_vm)); displayError(errorMsg); return false; } break; default: //printf("unknown block"); break; } m_string_context->update_named_vars(m_vm); return true; } bool JsusFx::processImport(JsusFxPathLibrary &pathLibrary, const std::string &path, const std::string &importPath, JsusFx_Sections §ions, const int compileFlags) { bool result = true; //displayMsg("Importing %s", path.c_str()); std::string resolvedPath; if ( ! pathLibrary.resolveImportPath(importPath, path, resolvedPath) ) { displayError("Failed to resolve import file path %s", importPath.c_str()); return false; } std::istream *is = pathLibrary.open(resolvedPath); if ( is != nullptr ) { result &= readSections(pathLibrary, resolvedPath, *is, sections, compileFlags); } else { displayError("Failed to open imported file %s", importPath.c_str()); result &= false; } pathLibrary.close(is); return result; } static char *trim(char *line, bool trimStart, bool trimEnd) { if (trimStart) { while (*line && isspace(*line)) line++; } if (trimEnd) { char *last = line; while (last[0] && last[1]) last++; for (char *b = last; isspace(*b) && b >= line; b--) *b = 0; } return line; } bool JsusFx::readHeader(JsusFxPathLibrary &pathLibrary, const std::string &path, std::istream &input) { char line[4096]; for(int lnumber = 1; ! input.eof(); lnumber++) { input.getline(line, sizeof(line), '\n'); if ( line[0] == '@' ) break; if ( ! strnicmp(line, "slider", 6) ) { int target = 0; if ( ! sscanf(line, "slider%d:", &target) ) continue; if ( target < 0 || target >= kMaxSliders ) continue; JsusFx_Slider &slider = sliders[target]; char *p = line+7; while ( *p && *p != ':' ) p++; if ( *p != ':' ) continue; p++; if ( ! slider.config(*this, target, p, lnumber) ) { displayError("Incomplete slider @line %d (%s)", lnumber, line); return false; } trim(slider.desc, false, true); continue; } else if ( ! strncmp(line, "desc:", 5) ) { char *src = line+5; src = trim(src, true, true); strncpy(desc, src, 64); continue; } else if ( ! strncmp(line, "in_pin:", 7) ) { numInputs++; } else if ( ! strncmp(line, "out_pin:", 8) ) { numOutputs++; } } return true; } bool JsusFx::readSections(JsusFxPathLibrary &pathLibrary, const std::string &path, std::istream &input, JsusFx_Sections §ions, const int compileFlags) { WDL_String * code = nullptr; char line[4096]; // are we reading the header or sections? bool isHeader = true; for(int lnumber = 1; ! input.eof(); lnumber++) { input.getline(line, sizeof(line), '\n'); const int l = input.gcount(); if ( line[0] == '@' ) { char *b = line + 1; b = trim(b, false, true); // we've begun reading sections now isHeader = false; JsusFx_Section *section = nullptr; if ( ! strnicmp(b, "init", 4) ) section = §ions.init; else if ( ! strnicmp(b, "slider", 6) ) section = §ions.slider; else if ( ! strnicmp(b, "block", 5) ) section = §ions.block; else if ( ! strnicmp(b, "sample", 6) ) section = §ions.sample; else if ( ! strnicmp(b, "gfx", 3) && (compileFlags & kCompileFlag_CompileGraphicsSection) != 0 ) { if ( sscanf(b+3, "%d %d", &gfx_w, &gfx_h) != 2 ) { gfx_w = 0; gfx_h = 0; } section = §ions.gfx; } else if ( ! strnicmp(b, "serialize", 9) && (compileFlags & kCompileFlag_CompileSerializeSection) != 0 ) section = §ions.serialize; if ( section != nullptr ) { code = §ion->code; section->lineOffset = lnumber; } else { code = nullptr; } continue; } if ( code != nullptr ) { //int l = strlen(line); if ( l > 0 && line[l-1] == '\r' ) line[l-1] = 0; if ( line[0] != 0 ) { code->Append(line); } code->Append("\n"); continue; } if (isHeader) { if ( ! strnicmp(line, "slider", 6) ) { int target = 0; if ( ! sscanf(line, "slider%d:", &target) ) continue; if ( target < 0 || target >= kMaxSliders ) continue; JsusFx_Slider &slider = sliders[target]; char *p = line+7; while ( *p && *p != ':' ) p++; if ( *p != ':' ) continue; p++; if ( ! slider.config(*this, target, p, lnumber) ) { displayError("Incomplete slider @line %d (%s)", lnumber, line); return false; } trim(slider.desc, false, true); continue; } else if ( ! strncmp(line, "desc:", 5) ) { char *src = line+5; src = trim(src, true, true); strncpy(desc, src, 64); continue; } else if ( ! strnicmp(line, "filename:", 9) ) { // filename:0,filename.wav char *src = line+8; src = trim(src, true, false); if ( *src != ':' ) return false; src++; src = trim(src, true, false); int index; if ( sscanf(src, "%d", &index) != 1 ) return false; while ( isdigit(*src) ) src++; src = trim(src, true, false); if ( *src != ',' ) return false; src++; src = trim(src, true, true); std::string resolvedPath; if ( pathLibrary.resolveImportPath(src, path, resolvedPath) ) { if ( ! handleFile(index, resolvedPath.c_str() ) ) { return false; } } } else if ( ! strncmp(line, "import ", 7) ) { char *src = line+7; src = trim(src, true, true); if (*src) { processImport(pathLibrary, path, src, sections, compileFlags); } continue; } else if ( ! strncmp(line, "in_pin:", 7) ) { if ( ! strncmp(line+7, "none", 4) ) { numInputs = -1; } else { if ( numInputs != -1 ) numInputs++; } } else if ( ! strncmp(line, "out_pin:", 8) ) { if ( ! strncmp(line+8, "none", 4) ) { numOutputs = -1; } else { if ( numOutputs != -1 ) numOutputs++; } } } } return true; } bool JsusFx::compileSections(JsusFx_Sections §ions, const int compileFlags) { bool result = true; // 0 init // 1 slider // 2 block // 3 sample // 4 gfx // 5 serialize if (sections.init.code.GetLength() != 0) result &= compileSection(0, sections.init.code.Get(), sections.init.lineOffset); if (sections.slider.code.GetLength() != 0) result &= compileSection(1, sections.slider.code.Get(), sections.slider.lineOffset); if (sections.block.code.GetLength() != 0) result &= compileSection(2, sections.block.code.Get(), sections.block.lineOffset); if (sections.sample.code.GetLength() != 0) result &= compileSection(3, sections.sample.code.Get(), sections.sample.lineOffset); if (sections.gfx.code.GetLength() != 0 && (compileFlags & kCompileFlag_CompileGraphicsSection) != 0) result &= compileSection(4, sections.gfx.code.Get(), sections.gfx.lineOffset); if (sections.serialize.code.GetLength() != 0 && (compileFlags & kCompileFlag_CompileSerializeSection) != 0) result &= compileSection(5, sections.serialize.code.Get(), sections.serialize.lineOffset); if (result == false) releaseCode(); return result; } bool JsusFx::compile(JsusFxPathLibrary &pathLibrary, const std::string &path, const int compileFlags) { releaseCode(); std::string resolvedPath; if ( ! pathLibrary.resolveImportPath(path, "", resolvedPath) ) { displayError("Failed to open %s", path.c_str()); return false; } std::istream *input = pathLibrary.open(resolvedPath); if ( input == nullptr ) { displayError("Failed to open %s", resolvedPath.c_str()); return false; } // read code for the various sections inside the jsusfx script JsusFx_Sections sections; if ( ! readSections(pathLibrary, resolvedPath, *input, sections, compileFlags) ) return false; pathLibrary.close(input); // compile the sections if ( ! compileSections(sections, compileFlags) ) { releaseCode(); return false; } computeSlider = 1; // in_pin and out_pin is optional, we default it to 2 in / 2 out if nothing is specified. // if you really want no in or out, specify in_pin:none/out_pin:none if ( numInputs == 0 ) numInputs = 2; else if ( numInputs == -1 ) numInputs = 0; if ( numOutputs == 0 ) numOutputs = 2; else if ( numOutputs == -1 ) numOutputs = 0; return true; } bool JsusFx::readHeader(JsusFxPathLibrary &pathLibrary, const std::string &path) { std::string resolvedPath; if ( ! pathLibrary.resolveImportPath(path, "", resolvedPath) ) { displayError("Failed to open %s", path.c_str()); return false; } std::istream *input = pathLibrary.open(resolvedPath); if ( input == nullptr ) { displayError("Failed to open %s", resolvedPath.c_str()); return false; } if ( ! readHeader(pathLibrary, resolvedPath, *input) ) return false; pathLibrary.close(input); return true; } void JsusFx::prepare(int sampleRate, int blockSize) { *srate = (double) sampleRate; *samplesblock = blockSize; NSEEL_code_execute(codeInit); } void JsusFx::moveSlider(int idx, float value, int normalizeSlider) { if ( idx < 0 || idx >= kMaxSliders || !sliders[idx].exists ) return; if ( normalizeSlider != 0 ) { float steps = sliders[idx].max - sliders[idx].min; value = (value * steps) / normalizeSlider; value += sliders[idx].min; } if ( sliders[idx].inc != 0 ) { int tmp = roundf(value / sliders[idx].inc); value = sliders[idx].inc * tmp; } computeSlider |= sliders[idx].setValue(value); } void JsusFx::setMidi(const void * _midi, int numBytes) { midi = (uint8_t*)_midi; midiSize = numBytes; } void JsusFx::setMidiSendBuffer(void * buffer, int numBytes) { midiSendBuffer = (uint8_t*)buffer; midiSendBufferCapacity = numBytes; midiSendBufferSize = 0; } void JsusFx::setTransportValues( const double in_tempo, const PlaybackState in_playbackState, const double in_playbackPositionInSeconds, const double in_beatPosition, const int in_timeSignatureNumerator, const int in_timeSignatureDenumerator) { *tempo = in_tempo; *play_state = in_playbackState; *play_position = in_playbackPositionInSeconds; *beat_position = in_beatPosition; *ts_num = in_timeSignatureNumerator; *ts_denom = in_timeSignatureDenumerator; } bool JsusFx::process(const float **input, float **output, int size, int numInputChannels, int numOutputChannels) { if ( codeSample == NULL ) return false; if ( computeSlider ) { NSEEL_code_execute(codeSlider); computeSlider = false; } numValidInputChannels = numInputChannels; *samplesblock = size; *num_ch = numValidInputChannels; NSEEL_code_execute(codeBlock); for(int i=0;ibeginDraw(); NSEEL_code_execute(codeGfx); if ( gfx != nullptr ) gfx->endDraw(); } bool JsusFx::serialize(JsusFxSerializer & _serializer, const bool write) { serializer = &_serializer; serializer->begin(*this, write); { if (codeSerialize != nullptr) NSEEL_code_execute(codeSerialize); if (write == false) { if (codeSlider != nullptr) NSEEL_code_execute(codeSlider); computeSlider = false; } } serializer->end(); serializer = nullptr; return true; } const char * JsusFx::getString(const int index, WDL_FastString ** fs) { void * opaque = this; return EEL_STRING_GET_FOR_INDEX(index, fs); } bool JsusFx::handleFile(int index, const char *filename) { if (index < 0 || index >= kMaxFileInfos) { displayError("file index out of bounds %d:%s", index, filename); return false; } if (fileInfos[index].isValid()) { displayMsg("file already exists %d:%s", index, filename); fileInfos[index] = JsusFx_FileInfo(); } // if (fileInfos[index].init(filename)) { const char *ext = nullptr; for (const char *p = filename; *p; ++p) if (*p == '.') ext = p + 1; if (ext != nullptr && (stricmp(ext, "png") == 0 || stricmp(ext, "jpg") == 0)) { if (gfx != nullptr) { gfx->gfx_loadimg(*this, index, index); } } return true; } else { displayError("failed to find file %d:%s", index, filename); return false; } } void JsusFx::releaseCode() { desc[0] = 0; if ( codeInit ) NSEEL_code_free(codeInit); if ( codeSlider ) NSEEL_code_free(codeSlider); if ( codeBlock ) NSEEL_code_free(codeBlock); if ( codeSample ) NSEEL_code_free(codeSample); if ( codeGfx ) NSEEL_code_free(codeGfx); codeInit = codeSlider = codeBlock = codeSample = codeGfx = codeSerialize = NULL; NSEEL_code_compile_ex(m_vm, nullptr, 0, NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS_RESET); numInputs = 0; numOutputs = 0; for(int i=0;i= 0 && target < JsusFx::kMaxSliders ) { if ( ! fx->sliders[target].exists ) { return 1; } else { fx->displayMsg("%s --> %f (%s)", name, *val, fx->sliders[target].desc); return 1; } } } fx->displayMsg("%s --> %f", name, *val); return 1; } void JsusFx::dumpvars() { NSEEL_VM_enumallvars(m_vm, dumpvarsCallback, this); } #ifndef JSUSFX_OWNSCRIPTMUTEXT // todo : implement mutex interface ? void NSEEL_HOSTSTUB_EnterMutex() { } void NSEEL_HOSTSTUB_LeaveMutex() { } #endif jsusfx-0.4.0/src/jsusfx.h000066400000000000000000000164101353477307700153410ustar00rootroot00000000000000/* * Copyright 2014-2015 Pascal Gauthier * Copyright 2018 Pascal Gauthier, Marcel Smit * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * *distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include "WDL/eel2/ns-eel.h" #include "WDL/eel2/ns-eel-int.h" #ifndef nullptr #define nullptr NULL #endif class eel_string_context_state; class JsusFx; struct JsusFxFileAPI; struct JsusFxGfx; struct JsusFxPathLibrary; struct JsusFxSerializer; struct JsusFx_FileInfo; class JsusFx_Slider; struct JsusFx_Sections; class WDL_FastString; // class JsusFx_Slider { public: static const int kMaxName = 63; float def, min, max, inc; char name[kMaxName + 1]; char desc[64]; EEL_F *owner; bool exists; std::vector enumNames; bool isEnum; JsusFx_Slider() { def = min = max = inc = 0; name[0] = 0; desc[0] = 0; exists = false; owner = nullptr; isEnum = false; } bool config(JsusFx &fx, const int index, const char *param, const int lnumber); /** * Return true if the value has changed */ bool setValue(float v) { if ( min < max ) { if ( v < min ) { v = min; } else if ( v > max ) { v = max; } } else { if ( v < max ) { v = max; } else if ( v > min ) { v = min; } } if ( v == *owner ) return false; *owner = v; return true; } float getValue() const { return *owner; } }; struct JsusFx_FileInfo { std::string filename; bool isValid() const { return !filename.empty(); } bool init(const char *_filename) { filename = _filename; return isValid(); } }; struct JsusFxPathLibrary { virtual ~JsusFxPathLibrary() { } virtual bool resolveImportPath(const std::string &importPath, const std::string &parentPath, std::string &resolvedPath) { return false; } virtual bool resolveDataPath(const std::string &importPath, std::string &resolvedPath) { return false; } virtual std::istream* open(const std::string &path) { return nullptr; } virtual void close(std::istream *&stream) { } }; struct JsusFxPathLibrary_Basic : JsusFxPathLibrary { std::string dataRoot; std::vector searchPaths; JsusFxPathLibrary_Basic(const char * _dataRoot); void addSearchPath(const std::string & path); static bool fileExists(const std::string &filename); virtual bool resolveImportPath(const std::string &importPath, const std::string &parentPath, std::string &resolvedPath) override; virtual bool resolveDataPath(const std::string &importPath, std::string &resolvedPath) override; virtual std::istream* open(const std::string &path) override; virtual void close(std::istream *&stream) override; }; class JsusFx { protected: NSEEL_CODEHANDLE codeInit, codeSlider, codeBlock, codeSample, codeGfx, codeSerialize; bool computeSlider; void releaseCode(); bool compileSection(int state, const char *code, int line_offset); bool processImport(JsusFxPathLibrary &pathLibrary, const std::string ¤tPath, const std::string &importPath, JsusFx_Sections §ions, const int compileFlags); bool readHeader(JsusFxPathLibrary &pathLibrary, const std::string ¤tPath, std::istream &input); bool readSections(JsusFxPathLibrary &pathLibrary, const std::string ¤tPath, std::istream &input, JsusFx_Sections §ions, const int compileFlags); bool compileSections(JsusFx_Sections §ions, const int compileFlags); public: static const int kMaxSamples = 64; // Theoretically, it is 64 slider, but starting @ 1, we are simply allowing slider0 to exists static const int kMaxSliders = 65; static const int kMaxFileInfos = 128; enum CompileFlags { kCompileFlag_CompileGraphicsSection = 1 << 0, kCompileFlag_CompileSerializeSection = 1 << 1 }; enum PlaybackState // see 'play_state' at https://www.reaper.fm/sdk/js/vars.php#js_specialvars { kPlaybackState_Error = 0, kPlaybackState_Playing = 1, kPlaybackState_Paused = 2, kPlaybackState_Recording = 5, kPlaybackState_RecordingPaused = 6 }; NSEEL_VMCTX m_vm; JsusFx_Slider sliders[kMaxSliders]; char desc[64]; EEL_F *tempo, *play_state, *play_position, *beat_position, *ts_num, *ts_denom; EEL_F *ext_noinit, *ext_nodenorm, *pdc_delay, *pdc_bot_cd, *pdc_top_ch; EEL_F *srate, *num_ch, *samplesblock; EEL_F *spl[kMaxSamples], *trigger; EEL_F *ext_midi_bus, *midi_bus; EEL_F dummyValue; int numInputs; int numOutputs; int numValidInputChannels; JsusFxPathLibrary &pathLibrary; JsusFxFileAPI *fileAPI; JsusFx_FileInfo fileInfos[kMaxFileInfos]; // midi receive buffer. pointer is incremented and the size decremented by the appropriate number of bytes whenever midirecv is called from within the script uint8_t *midi; int midiSize; // midi send buffer. the pointer and capacity stay the same. size is incremented by the number of bytes written by midisend or midisend_buf uint8_t * midiSendBuffer; int midiSendBufferCapacity; int midiSendBufferSize; JsusFxGfx *gfx; int gfx_w; int gfx_h; JsusFxSerializer *serializer; JsusFx(JsusFxPathLibrary &pathLibrary); virtual ~JsusFx(); bool compile(JsusFxPathLibrary &pathLibrary, const std::string &path, const int compileFlags); bool readHeader(JsusFxPathLibrary &pathLibrary, const std::string &path); void prepare(int sampleRate, int blockSize); // move slider, normalizeSlider is used to normalize the value to a constant (0 means no normalization) void moveSlider(int idx, float value, int normalizeSlider = 0); void setMidi(const void * midi, int numBytes); void setMidiSendBuffer(void * buffer, int maxBytes); void setTransportValues( const double tempo, const PlaybackState playbackState, const double playbackPositionInSeconds, const double beatPosition, const int timeSignatureNumerator, const int timeSignatureDenumerator); bool process(const float **input, float **output, int size, int numInputChannels, int numOutputChannels); bool process64(const double **input, double **output, int size, int numInputChannels, int numOutputChannels); void draw(); bool serialize(JsusFxSerializer & serializer, const bool write); const char * getString(int index, WDL_FastString ** fs); bool hasGraphicsSection() const { return codeGfx != nullptr; } bool hasSerializeSection() const { return codeSerialize != nullptr; } bool handleFile(int index, const char *filename); virtual void displayMsg(const char *fmt, ...) = 0; virtual void displayError(const char *fmt, ...) = 0; void dumpvars(); static void init(); // ============================================================== eel_string_context_state *m_string_context; }; jsusfx-0.4.0/src/jsusfx_file.cpp000066400000000000000000000275641353477307700167070ustar00rootroot00000000000000/* * Copyright 2018 Pascal Gauthier, Marcel Smit * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * *distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "jsusfx.h" #include "jsusfx_file.h" #include "jsusfx_serialize.h" #include "riff.h" #include #define EEL_FILE_GET_INTERFACE(opaque) ((opaque) ? (((JsusFx*)opaque)->fileAPI) : nullptr) #define REAPER_GET_INTERFACE(opaque) (*(JsusFx*)opaque) static EEL_F NSEEL_CGEN_CALL _file_open(void *opaque, EEL_F *_index) { JsusFxFileAPI *fileAPI = EEL_FILE_GET_INTERFACE(opaque); JsusFx &jsusFx = REAPER_GET_INTERFACE(opaque); const int index = *_index; WDL_FastString * fs = nullptr; const char * filename = jsusFx.getString(index, &fs); if (filename == nullptr) return -1; const int handle = fileAPI->file_open(jsusFx, filename); // file handle zero is used as the special serialization file assert(handle != 0); return handle; } static EEL_F NSEEL_CGEN_CALL _file_close(void *opaque, EEL_F *_handle) { JsusFxFileAPI *fileAPI = EEL_FILE_GET_INTERFACE(opaque); JsusFx &jsusFx = REAPER_GET_INTERFACE(opaque); const int handle = *_handle; // file handle zero is used as the special serialization file assert(handle != 0); if (fileAPI->file_close(jsusFx, handle)) return 0; else return -1; } static EEL_F NSEEL_CGEN_CALL _file_avail(void *opaque, EEL_F *_handle) { JsusFxFileAPI *fileAPI = EEL_FILE_GET_INTERFACE(opaque); JsusFx &jsusFx = REAPER_GET_INTERFACE(opaque); const int handle = *_handle; if (handle == 0) { if (jsusFx.serializer == nullptr) return 0; else return jsusFx.serializer->file_avail(); } else { return fileAPI->file_avail(jsusFx, handle); } } static EEL_F NSEEL_CGEN_CALL _file_riff(void *opaque, EEL_F *_handle, EEL_F *_numChannels, EEL_F *_sampleRate) { JsusFxFileAPI *fileAPI = EEL_FILE_GET_INTERFACE(opaque); JsusFx &jsusFx = REAPER_GET_INTERFACE(opaque); const int handle = *_handle; // file handle zero is used as the special serialization file assert(handle != 0); int numChannels; int sampleRate; if (fileAPI->file_riff(jsusFx, handle, numChannels, sampleRate) == false) { *_numChannels = 0; *_sampleRate = 0; return -1; } *_numChannels = numChannels; *_sampleRate = sampleRate; return 0; } static EEL_F NSEEL_CGEN_CALL _file_text(void *opaque, EEL_F *_handle) { JsusFxFileAPI *fileAPI = EEL_FILE_GET_INTERFACE(opaque); JsusFx &jsusFx = REAPER_GET_INTERFACE(opaque); const int handle = *_handle; // file handle zero is used as the special serialization file assert(handle != 0); if (fileAPI->file_text(jsusFx, handle) == false) return -1; return 1; } static EEL_F NSEEL_CGEN_CALL _file_mem(void *opaque, EEL_F *_handle, EEL_F *_destOffset, EEL_F *_numValues) { JsusFxFileAPI *fileAPI = EEL_FILE_GET_INTERFACE(opaque); JsusFx &jsusFx = REAPER_GET_INTERFACE(opaque); const int handle = *_handle; const int destOffset = (int)(*_destOffset + 0.001); EEL_F * dest = NSEEL_VM_getramptr(jsusFx.m_vm, destOffset, nullptr); if (dest == nullptr) return 0; const int numValues = (int)*_numValues; if (handle == 0) { if (jsusFx.serializer == nullptr) return 0; else return jsusFx.serializer->file_mem(dest, numValues); } else { return fileAPI->file_mem(jsusFx, handle, dest, numValues); } } static EEL_F NSEEL_CGEN_CALL _file_var(void *opaque, EEL_F *_handle, EEL_F *dest) { JsusFxFileAPI *fileAPI = EEL_FILE_GET_INTERFACE(opaque); JsusFx &jsusFx = REAPER_GET_INTERFACE(opaque); const int handle = *_handle; if (handle == 0) { if (jsusFx.serializer == nullptr) return 0; else return jsusFx.serializer->file_var(*dest); } else { if (fileAPI->file_var(jsusFx, handle, *dest) == false) return 0; else return 1; } } void JsusFxFileAPI::init(NSEEL_VMCTX vm) { NSEEL_addfunc_retval("file_open",1,NSEEL_PProc_THIS,&_file_open); NSEEL_addfunc_retval("file_close",1,NSEEL_PProc_THIS,&_file_close); NSEEL_addfunc_retval("file_avail",1,NSEEL_PProc_THIS,&_file_avail); NSEEL_addfunc_retval("file_riff",3,NSEEL_PProc_THIS,&_file_riff); NSEEL_addfunc_retval("file_text",1,NSEEL_PProc_THIS,&_file_text); NSEEL_addfunc_retval("file_mem",3,NSEEL_PProc_THIS,&_file_mem); NSEEL_addfunc_retval("file_var",2,NSEEL_PProc_THIS,&_file_var); } // JsusFxFileAPI_Basic::JsusFxFileAPI_Basic() { memset(files, 0, sizeof(files)); } int JsusFxFileAPI_Basic::file_open(JsusFx & jsusFx, const char * filename) { std::string resolvedPath; if (jsusFx.pathLibrary.resolveDataPath(filename, resolvedPath) == false) { jsusFx.displayError("failed to resolve data path"); return -1; } for (int i = 1; i < kMaxFileHandles; ++i) { if (files[i] == nullptr) { files[i] = new JsusFx_File(); if (files[i]->open(jsusFx, resolvedPath.c_str()) == false) { jsusFx.displayError("failed to open file: %s", resolvedPath.c_str()); delete files[i]; files[i] = nullptr; return -1; } else { return i; } } } jsusFx.displayError("failed to find a free file handle"); return -1; } bool JsusFxFileAPI_Basic::file_close(JsusFx & jsusFx, const int index) { if (index < 0 || index >= kMaxFileHandles) { jsusFx.displayError("invalid file handle"); return false; } if (files[index] == nullptr) { jsusFx.displayError("file not opened"); return false; } files[index]->close(jsusFx); delete files[index]; files[index] = nullptr; return true; } int JsusFxFileAPI_Basic::file_avail(JsusFx & jsusFx, const int index) { if (index < 0 || index >= kMaxFileHandles) { jsusFx.displayError("invalid file handle"); return 0; } if (files[index] == nullptr) { jsusFx.displayError("file not opened"); return 0; } return files[index]->avail(); } bool JsusFxFileAPI_Basic::file_riff(JsusFx & jsusFx, const int index, int & numChannels, int & sampleRate) { if (index < 0 || index >= kMaxFileHandles) { jsusFx.displayError("invalid file handle"); return false; } if (files[index] == nullptr) { jsusFx.displayError("file not opened"); return false; } if (files[index]->riff(numChannels, sampleRate) == false) { jsusFx.displayError("failed to parse RIFF"); return false; } return true; } bool JsusFxFileAPI_Basic::file_text(JsusFx & jsusFx, const int index) { if (index < 0 || index >= kMaxFileHandles) { jsusFx.displayError("invalid file handle"); return false; } if (files[index] == nullptr) { jsusFx.displayError("file not opened"); return false; } if (files[index]->text() == false) { jsusFx.displayError("failed to parse text"); return false; } return true; } int JsusFxFileAPI_Basic::file_mem(JsusFx & jsusFx, const int index, EEL_F * dest, const int numValues) { if (index < 0 || index >= kMaxFileHandles) { jsusFx.displayError("invalid file handle"); return 0; } if (files[index] == nullptr) { jsusFx.displayError("file not opened"); return 0; } if (files[index]->mem(numValues, dest) == false) { jsusFx.displayError("failed to read data"); return 0; } else return numValues; } bool JsusFxFileAPI_Basic::file_var(JsusFx & jsusFx, const int index, EEL_F & dest) { if (index < 0 || index >= kMaxFileHandles) { jsusFx.displayError("invalid file handle"); return 0; } if (files[index] == nullptr) { jsusFx.displayError("file not opened"); return 0; } if (files[index]->var(dest) == false) { jsusFx.displayError("failed to read value"); return 0; } else return 1; } // JsusFx_File::JsusFx_File() : stream(nullptr) , mode(kMode_None) , soundData(nullptr) , readPosition(0) , vars() { } JsusFx_File::~JsusFx_File() { assert(stream == nullptr); } bool JsusFx_File::open(JsusFx & jsusFx, const char * filename) { // open the stream stream = jsusFx.pathLibrary.open(filename); if (stream == nullptr) { jsusFx.displayError("failed to open file: %s", filename); return false; } else { return true; } } void JsusFx_File::close(JsusFx & jsusFx) { vars.clear(); delete soundData; soundData = nullptr; jsusFx.pathLibrary.close(stream); } bool JsusFx_File::riff(int & numChannels, int & sampleRate) { assert(mode == kMode_None); numChannels = 0; sampleRate = 0; // reset read state mode = kMode_None; readPosition = 0; // load RIFF file bool success = true; success &= stream != nullptr; int size = 0;; if (success) { try { stream->seekg(0, std::ios_base::end); success &= stream->fail() == false; size = stream->tellg(); success &= size != -1; stream->seekg(0, std::ios_base::beg); success &= stream->fail() == false; } catch (std::exception & e) { (void)e; success &= false; } } success &= size > 0; uint8_t * bytes = nullptr; if (success) { bytes = new uint8_t[size]; try { stream->read((char*)bytes, size); success &= stream->fail() == false; } catch (std::exception & e) { (void)e; success &= false; } } if (success) { soundData = loadRIFF(bytes, size); } if (bytes != nullptr) { delete [] bytes; bytes = nullptr; } if (soundData == nullptr || (soundData->channelSize != 2 && soundData->channelSize != 4)) { if (soundData != nullptr) { delete soundData; soundData = nullptr; } return false; } else { mode = kMode_Sound; numChannels = soundData->channelCount; sampleRate = soundData->sampleRate; return true; } } bool JsusFx_File::text() { assert(mode == kMode_None); // reset read state mode = kMode_None; readPosition = 0; // load text file try { if (stream == nullptr) { return false; } while (!stream->eof()) { char line[2048]; stream->getline(line, sizeof(line), '\n'); // a poor way of skipping comments. assume / is the start of // and strip anything that come after it char * pos = strchr(line, '/'); if (pos != nullptr) *pos = 0; const char * p = line; for (;;) { // skip trailing white space while (*p && isspace(*p)) p++; // reached end of the line ? if (*p == 0) break; // parse the value double var; if (sscanf(p, "%lf", &var) == 1) vars.push_back(var); // skip the value while (*p && !isspace(*p)) p++; } } mode = kMode_Text; return true; } catch (std::exception & e) { (void)e; return false; } } int JsusFx_File::avail() const { if (mode == kMode_None) return 0; else if (mode == kMode_Text) return readPosition == vars.size() ? 0 : 1; else if (mode == kMode_Sound) return soundData->sampleCount * soundData->channelCount - readPosition; else return 0; } bool JsusFx_File::mem(const int numValues, EEL_F * dest) { if (mode == kMode_None) return false; else if (mode == kMode_Text) return false; else if (mode == kMode_Sound) { if (numValues > avail()) return false; for (int i = 0; i < numValues; ++i) { if (soundData->channelSize == 2) { const short * values = (short*)soundData->sampleData; dest[i] = values[readPosition] / float(1 << 15); } else if (soundData->channelSize == 4) { const float * values = (float*)soundData->sampleData; dest[i] = values[readPosition]; } else { assert(false); } readPosition++; } return true; } else return false; } bool JsusFx_File::var(EEL_F & value) { if (mode == kMode_None) return false; else if (mode == kMode_Text) { if (avail() < 1) return false; value = vars[readPosition]; readPosition++; return true; } else if (mode == kMode_Sound) return false; else return false; } jsusfx-0.4.0/src/jsusfx_file.h000066400000000000000000000074421353477307700163450ustar00rootroot00000000000000/* * Copyright 2018 Pascal Gauthier, Marcel Smit * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * *distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "WDL/eel2/ns-eel.h" #include #include class JsusFx; struct JsusFxFileAPI; struct JsusFxFileAPI_Basic; struct JsusFx_File; struct RIFFSoundData; struct JsusFxFileAPI { virtual ~JsusFxFileAPI() { } void init(NSEEL_VMCTX vm); virtual int file_open(JsusFx & jsusFx, const char * filename) { return -1; } virtual bool file_close(JsusFx & jsusFx, const int handle) { return false; } virtual int file_avail(JsusFx & jsusFx, const int handle) { return 0; } virtual bool file_riff(JsusFx & jsusFx, const int handle, int & numChannels, int & sampleRate) { return false; } virtual bool file_text(JsusFx & jsusFx, const int handle) { return false; } virtual int file_mem(JsusFx & jsusFx, const int handle, EEL_F * result, const int numValues) { return 0; } virtual bool file_var(JsusFx & jsusFx, const int handle, EEL_F & result) { return false; } }; /* JsusFxFileAPI_Basic provides a basic File API implementation which uses JsusFx_File for reading and the JsusFxPathLibrary to resolve and open files */ struct JsusFxFileAPI_Basic : JsusFxFileAPI { static const int kMaxFileHandles = 16; JsusFx_File * files[kMaxFileHandles]; JsusFxFileAPI_Basic(); virtual int file_open(JsusFx & jsusFx, const char * filename) override; virtual bool file_close(JsusFx & jsusFx, const int index) override; virtual int file_avail(JsusFx & jsusFx, const int index) override; virtual bool file_riff(JsusFx & jsusFx, const int index, int & numChannels, int & sampleRate) override; virtual bool file_text(JsusFx & jsusFx, const int index) override; virtual int file_mem(JsusFx & jsusFx, const int index, EEL_F * dest, const int numValues) override; virtual bool file_var(JsusFx & jsusFx, const int index, EEL_F & dest) override; }; /* JsusFx_File is used to implement the File API. it provides functionality to read RIFF sound data, text files and raw data files according to how these functions should behave according to Reaper's documentation. documentation for the exact operation of these functions isn't available, so a best effort attempt has been made to implement them // example usage loading a sound file: JsusFx_File file; if (file.open(jsusFx, "sound.wav")) { int numChannels; int sampleRate; if (file.riff(numChannels, sampleRate)) { const int numSamples = file.avail(); EEL_F * samples = new EEL_F[numSamples]; if (file.mem(numSamples, samples)) { printf("successfully loaded some sound samples!\n"); } } file.close(); } // example usage loading values from a text file: JsusFx_File file; if (file.open(jsusFx, "kernelValues.txt")) { if (file.text()) { while (file.avail()) { EEL_F value; if (file.var(value)) { printf("%.2f\n", value); } } } file.close(); } */ struct JsusFx_File { enum Mode { kMode_None, kMode_Text, kMode_Sound }; std::istream * stream; Mode mode; RIFFSoundData * soundData; int readPosition; std::vector vars; JsusFx_File(); ~JsusFx_File(); bool open(JsusFx & jsusFx, const char * _filename); void close(JsusFx & jsusFx); bool riff(int & numChannels, int & sampleRate); bool text(); int avail() const; bool mem(const int numValues, EEL_F * dest); bool var(EEL_F & value); }; jsusfx-0.4.0/src/jsusfx_gfx.cpp000066400000000000000000000307711353477307700165460ustar00rootroot00000000000000/* * Copyright 2018 Pascal Gauthier, Marcel Smit * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * *distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "jsusfx.h" #include "jsusfx_gfx.h" #include "WDL/eel2/ns-eel-int.h" #define EEL_GFX_GET_INTERFACE(opaque) ((opaque) ? (((JsusFx*)opaque)->gfx) : nullptr) #define REAPER_GET_INTERFACE(opaque) (*(JsusFx*)opaque) static EEL_F * NSEEL_CGEN_CALL _gfx_lineto(void *opaque, EEL_F *xpos, EEL_F *ypos, EEL_F *useaa) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_lineto(*xpos, *ypos, *useaa); return xpos; } static EEL_F * NSEEL_CGEN_CALL _gfx_lineto2(void *opaque, EEL_F *xpos, EEL_F *ypos) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_lineto(*xpos, *ypos, 1.0f); return xpos; } static EEL_F * NSEEL_CGEN_CALL _gfx_rectto(void *opaque, EEL_F *xpos, EEL_F *ypos) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_rectto(*xpos, *ypos); return xpos; } static EEL_F NSEEL_CGEN_CALL _gfx_line(void *opaque, INT_PTR np, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_line((int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_rect(void *opaque, INT_PTR np, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_rect((int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_roundrect(void *opaque, INT_PTR np, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_roundrect((int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_arc(void *opaque, INT_PTR np, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_arc((int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_set(void *opaque, INT_PTR np, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_set((int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_gradrect(void *opaque, INT_PTR np, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_grad_or_muladd_rect(0,(int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_muladdrect(void *opaque, INT_PTR np, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_grad_or_muladd_rect(1,(int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_deltablit(void *opaque, INT_PTR np, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_blitext2((int)np,parms,1); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_transformblit(void *opaque, INT_PTR np, EEL_F **parms) { #if 0 // todo JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) { #ifndef EEL_LICE_NO_RAM const int divw = (int) (parms[5][0]+0.5); const int divh = (int) (parms[6][0]+0.5); if (divw < 1 || divh < 1) return 0.0; const int sz = divw*divh*2; #ifdef EEL_LICE_RAMFUNC EEL_F *d = EEL_LICE_RAMFUNC(opaque,7,sz); if (!d) return 0.0; #else EEL_F **blocks = ctx->m_vmref ? ((compileContext*)ctx->m_vmref)->ram_state.blocks : 0; if (!blocks || np < 8) return 0.0; const int addr1= (int) (parms[7][0]+0.5); EEL_F *d=__NSEEL_RAMAlloc(blocks,addr1); if (sz>NSEEL_RAM_ITEMSPERBLOCK) { int x; for(x=NSEEL_RAM_ITEMSPERBLOCK;xgfx_transformblit(parms,divw,divh,d); #endif } #endif return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_circle(void *opaque, INT_PTR np, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); bool aa = true, fill = false; if (np>3) fill = parms[3][0] > 0.5; if (np>4) aa = parms[4][0] > 0.5; if (ctx) ctx->gfx_circle((float)parms[0][0], (float)parms[1][0], (float)parms[2][0], fill, aa); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_triangle(void* opaque, INT_PTR np, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_triangle(parms, np); return 0.0; } static EEL_F * NSEEL_CGEN_CALL _gfx_drawnumber(void *opaque, EEL_F *n, EEL_F *nd) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_drawnumber(*n, *nd); return n; } static EEL_F * NSEEL_CGEN_CALL _gfx_drawchar(void *opaque, EEL_F *n) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_drawchar(*n); return n; } static EEL_F * NSEEL_CGEN_CALL _gfx_measurestr(void *opaque, EEL_F *str, EEL_F *xOut, EEL_F *yOut) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) { EEL_F *p[3]={str,xOut,yOut}; ctx->gfx_drawstr(opaque,p,3,2); } return str; } static EEL_F * NSEEL_CGEN_CALL _gfx_measurechar(void *opaque, EEL_F *str, EEL_F *xOut, EEL_F *yOut) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) { EEL_F *p[3]={str,xOut,yOut}; ctx->gfx_drawstr(opaque,p,3,3); } return str; } static EEL_F * NSEEL_CGEN_CALL _gfx_drawstr(void *opaque, EEL_F *n) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_drawstr(opaque,&n,1,0); return n; } static EEL_F NSEEL_CGEN_CALL _gfx_printf(void *opaque, INT_PTR nparms, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx && nparms>0) { EEL_F v= **parms; ctx->gfx_drawstr(opaque,parms,nparms,1); return v; } return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_showmenu(void* opaque, INT_PTR nparms, EEL_F **parms) { JsusFxGfx* ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) return ctx->gfx_showmenu(parms, (int)nparms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_setcursor(void* opaque, INT_PTR nparms, EEL_F **parms) { JsusFxGfx* ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) return ctx->gfx_setcursor(parms, (int)nparms); return 0.0; } static EEL_F * NSEEL_CGEN_CALL _gfx_setpixel(void *opaque, EEL_F *r, EEL_F *g, EEL_F *b) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_setpixel(*r, *g, *b); return r; } static EEL_F * NSEEL_CGEN_CALL _gfx_getpixel(void *opaque, EEL_F *r, EEL_F *g, EEL_F *b) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_getpixel(r, g, b); return r; } static EEL_F * NSEEL_CGEN_CALL _gfx_blit(void *opaque, EEL_F *img, EEL_F *scale, EEL_F *rotate) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_blit(*img,*scale,*rotate); return img; } static EEL_F NSEEL_CGEN_CALL _gfx_setfont(void *opaque, INT_PTR np, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) return ctx->gfx_setfont((int)np,parms); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_getfont(void *opaque, INT_PTR np, EEL_F **parms) { // todo : implement _gfx_getfont return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_blit2(void *opaque, INT_PTR np, EEL_F **parms) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx && np>=3) { ctx->gfx_blitext2((int)np,parms,0); return *(parms[0]); } return 0.0; } static EEL_F * NSEEL_CGEN_CALL _gfx_blitext(void *opaque, EEL_F *img, EEL_F *coordidx, EEL_F *rotate) { #if 0 // todo JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) { #ifndef EEL_LICE_NO_RAM #ifdef EEL_LICE_RAMFUNC EEL_F *buf = EEL_LICE_RAMFUNC(opaque,1,10); if (!buf) return img; #else EEL_F fc = *coordidx; if (fc < -0.5 || fc >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) return img; int a=(int)fc; if (a<0) return img; EEL_F buf[10]; int x; EEL_F **blocks = ctx->m_vmref ? ((compileContext*)ctx->m_vmref)->ram_state.blocks : 0; if (!blocks) return img; for (x = 0;x < 10; x ++) { EEL_F *d=__NSEEL_RAMAlloc(blocks,a++); if (!d || d==&nseel_ramalloc_onfail) return img; buf[x]=*d; } #endif // read megabuf ctx->gfx_blitext(*img,buf,*rotate); #endif } #endif return img; } static EEL_F * NSEEL_CGEN_CALL _gfx_blurto(void *opaque, EEL_F *x, EEL_F *y) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_blurto(*x,*y); return x; } static EEL_F * NSEEL_CGEN_CALL _gfx_getimgdim(void *opaque, EEL_F *img, EEL_F *w, EEL_F *h) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) ctx->gfx_getimgdim(*img,w,h); return img; } static EEL_F NSEEL_CGEN_CALL _gfx_loadimg(void *opaque, EEL_F *img, EEL_F *fr) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); JsusFx &jsusFx = REAPER_GET_INTERFACE(opaque); if (ctx) return ctx->gfx_loadimg(jsusFx,(int)*img,*fr); return 0.0; } static EEL_F NSEEL_CGEN_CALL _gfx_setimgdim(void *opaque, EEL_F *img, EEL_F *w, EEL_F *h) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) return ctx->gfx_setimgdim((int)*img,w,h); return 0.0; } // static EEL_F NSEEL_CGEN_CALL _gfx_getchar(void *opaque, EEL_F *p) { JsusFxGfx *ctx=EEL_GFX_GET_INTERFACE(opaque); if (ctx) return ctx->gfx_getchar(*p); return 0.0; } // // todo : remove __stub static EEL_F NSEEL_CGEN_CALL __stub(void *opaque, INT_PTR np, EEL_F **parms) { return 0.0; } void JsusFxGfx::init(NSEEL_VMCTX vm) { m_gfx_r = NSEEL_VM_regvar(vm,"gfx_r"); m_gfx_g = NSEEL_VM_regvar(vm,"gfx_g"); m_gfx_b = NSEEL_VM_regvar(vm,"gfx_b"); m_gfx_a = NSEEL_VM_regvar(vm,"gfx_a"); m_gfx_w = NSEEL_VM_regvar(vm,"gfx_w"); m_gfx_h = NSEEL_VM_regvar(vm,"gfx_h"); m_gfx_x = NSEEL_VM_regvar(vm,"gfx_x"); m_gfx_y = NSEEL_VM_regvar(vm,"gfx_y"); m_gfx_mode = NSEEL_VM_regvar(vm,"gfx_mode"); m_gfx_clear = NSEEL_VM_regvar(vm,"gfx_clear"); m_gfx_texth = NSEEL_VM_regvar(vm,"gfx_texth"); m_gfx_dest = NSEEL_VM_regvar(vm,"gfx_dest"); m_mouse_x = NSEEL_VM_regvar(vm,"mouse_x"); m_mouse_y = NSEEL_VM_regvar(vm,"mouse_y"); m_mouse_cap = NSEEL_VM_regvar(vm,"mouse_cap"); m_mouse_wheel = NSEEL_VM_regvar(vm,"mouse_wheel"); // LICE NSEEL_addfunc_retptr("gfx_lineto",3,NSEEL_PProc_THIS,&_gfx_lineto); NSEEL_addfunc_retptr("gfx_lineto",2,NSEEL_PProc_THIS,&_gfx_lineto2); NSEEL_addfunc_retptr("gfx_rectto",2,NSEEL_PProc_THIS,&_gfx_rectto); NSEEL_addfunc_varparm("gfx_rect",4,NSEEL_PProc_THIS,&_gfx_rect); NSEEL_addfunc_varparm("gfx_line",4,NSEEL_PProc_THIS,&_gfx_line); // 5th param is optionally AA NSEEL_addfunc_varparm("gfx_gradrect",8,NSEEL_PProc_THIS,&_gfx_gradrect); NSEEL_addfunc_varparm("gfx_muladdrect",7,NSEEL_PProc_THIS,&_gfx_muladdrect); NSEEL_addfunc_varparm("gfx_deltablit",9,NSEEL_PProc_THIS,&_gfx_deltablit); NSEEL_addfunc_exparms("gfx_transformblit",8,NSEEL_PProc_THIS,&_gfx_transformblit); NSEEL_addfunc_varparm("gfx_circle",3,NSEEL_PProc_THIS,&_gfx_circle); NSEEL_addfunc_varparm("gfx_triangle", 6, NSEEL_PProc_THIS, &_gfx_triangle); NSEEL_addfunc_varparm("gfx_roundrect",5,NSEEL_PProc_THIS,&_gfx_roundrect); NSEEL_addfunc_varparm("gfx_arc",5,NSEEL_PProc_THIS,&_gfx_arc); NSEEL_addfunc_retptr("gfx_blurto",2,NSEEL_PProc_THIS,&_gfx_blurto); NSEEL_addfunc_exparms("gfx_showmenu",1,NSEEL_PProc_THIS,&_gfx_showmenu); NSEEL_addfunc_varparm("gfx_setcursor",1, NSEEL_PProc_THIS, &_gfx_setcursor); NSEEL_addfunc_retptr("gfx_drawnumber",2,NSEEL_PProc_THIS,&_gfx_drawnumber); NSEEL_addfunc_retptr("gfx_drawchar",1,NSEEL_PProc_THIS,&_gfx_drawchar); NSEEL_addfunc_retptr("gfx_drawstr",1,NSEEL_PProc_THIS,&_gfx_drawstr); NSEEL_addfunc_retptr("gfx_measurestr",3,NSEEL_PProc_THIS,&_gfx_measurestr); NSEEL_addfunc_retptr("gfx_measurechar",3,NSEEL_PProc_THIS,&_gfx_measurechar); NSEEL_addfunc_varparm("gfx_printf",1,NSEEL_PProc_THIS,&_gfx_printf); NSEEL_addfunc_retptr("gfx_setpixel",3,NSEEL_PProc_THIS,&_gfx_setpixel); NSEEL_addfunc_retptr("gfx_getpixel",3,NSEEL_PProc_THIS,&_gfx_getpixel); NSEEL_addfunc_retptr("gfx_getimgdim",3,NSEEL_PProc_THIS,&_gfx_getimgdim); NSEEL_addfunc_retval("gfx_setimgdim",3,NSEEL_PProc_THIS,&_gfx_setimgdim); NSEEL_addfunc_retval("gfx_loadimg",2,NSEEL_PProc_THIS,&_gfx_loadimg); NSEEL_addfunc_retptr("gfx_blit",3,NSEEL_PProc_THIS,&_gfx_blit); NSEEL_addfunc_retptr("gfx_blitext",3,NSEEL_PProc_THIS,&_gfx_blitext); NSEEL_addfunc_varparm("gfx_blit",4,NSEEL_PProc_THIS,&_gfx_blit2); NSEEL_addfunc_varparm("gfx_setfont",1,NSEEL_PProc_THIS,&_gfx_setfont); NSEEL_addfunc_varparm("gfx_getfont",1,NSEEL_PProc_THIS,&_gfx_getfont); NSEEL_addfunc_varparm("gfx_set",1,NSEEL_PProc_THIS,&_gfx_set); NSEEL_addfunc_retval("gfx_getchar",1,NSEEL_PProc_THIS,&_gfx_getchar); } jsusfx-0.4.0/src/jsusfx_gfx.h000066400000000000000000000123721353477307700162100ustar00rootroot00000000000000/* * Copyright 2018 Pascal Gauthier, Marcel Smit * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * *distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "WDL/eel2/ns-eel.h" class JsusFx; struct JsusFxGfx { EEL_F *m_gfx_r; EEL_F *m_gfx_g; EEL_F *m_gfx_b; EEL_F *m_gfx_a; EEL_F *m_gfx_w; EEL_F *m_gfx_h; EEL_F *m_gfx_x; EEL_F *m_gfx_y; EEL_F *m_gfx_mode; EEL_F *m_gfx_clear; EEL_F *m_gfx_texth; EEL_F *m_gfx_dest; EEL_F *m_mouse_x; EEL_F *m_mouse_y; EEL_F *m_mouse_cap; EEL_F *m_mouse_wheel; virtual ~JsusFxGfx() { } void init(NSEEL_VMCTX vm); virtual void setup(const int w, const int h) { } virtual void beginDraw() { } virtual void endDraw() { } virtual void gfx_line(int np, EEL_F ** params) { } virtual void gfx_rect(int np, EEL_F ** params) { } virtual void gfx_circle(EEL_F x, EEL_F y, EEL_F radius, bool fill, bool aa) { } virtual void gfx_triangle(EEL_F ** params, int np) { } virtual void gfx_lineto(EEL_F xpos, EEL_F ypos, EEL_F useaa) { } virtual void gfx_rectto(EEL_F xpos, EEL_F ypos) { } virtual void gfx_arc(int np, EEL_F ** params) { } virtual void gfx_set(int np, EEL_F ** params) { } virtual void gfx_roundrect(int np, EEL_F ** params) { } virtual void gfx_grad_or_muladd_rect(int mod, int np, EEL_F ** params) { } virtual void gfx_drawnumber(EEL_F n, int nd) { } virtual void gfx_drawchar(EEL_F n) { } virtual void gfx_drawstr(void * opaque, EEL_F ** parms, int np, int mode) { } // mode=1 for format, 2 for purely measure no format, 3 for measure char virtual void gfx_setpixel(EEL_F r, EEL_F g, EEL_F b) { } virtual void gfx_getpixel(EEL_F * r, EEL_F * g, EEL_F * b) { } virtual EEL_F gfx_loadimg(JsusFx & jsusFx, int img, EEL_F loadFrom) { return 0.f; } virtual void gfx_getimgdim(EEL_F img, EEL_F * w, EEL_F * h) { } virtual EEL_F gfx_setimgdim(int img, EEL_F * w, EEL_F * h) { return 0.f; } virtual EEL_F gfx_setfont(int np, EEL_F ** parms) { return 0.f; } virtual EEL_F gfx_getfont(int np, EEL_F ** parms) { return 0.f; } virtual EEL_F gfx_showmenu(EEL_F ** parms, int nparms) { return 0.f; } virtual EEL_F gfx_setcursor(EEL_F ** parms, int nparms) { return 0.f; } virtual void gfx_blurto(EEL_F x, EEL_F y) { } virtual void gfx_blit(EEL_F img, EEL_F scale, EEL_F rotate) { } virtual void gfx_blitext(EEL_F img, EEL_F * coords, EEL_F angle) { } virtual void gfx_blitext2(int mp, EEL_F ** params, int blitmode) { } // 0=blit, 1=deltablit virtual int gfx_getchar(int p) { return 0; } }; // the logging based GFX implementation below is used to see if the API works, and to see which calls a script is making. it's use doesn't extend beyong this basic debugging facility #define GFXLOG printf("%s called!\n", __FUNCTION__) struct JsusFxGfx_Log : JsusFxGfx { virtual void gfx_line(int np, EEL_F ** params) override { GFXLOG; } virtual void gfx_rect(int np, EEL_F ** params) override { GFXLOG; } virtual void gfx_circle(EEL_F x, EEL_F y, EEL_F radius, bool fill, bool aa) override { GFXLOG; } virtual void gfx_triangle(EEL_F ** params, int np) override { GFXLOG; } virtual void gfx_lineto(EEL_F xpos, EEL_F ypos, EEL_F useaa) override { GFXLOG; } virtual void gfx_rectto(EEL_F xpos, EEL_F ypos) override { GFXLOG; } virtual void gfx_arc(int np, EEL_F ** params) override { GFXLOG; } virtual void gfx_set(int np, EEL_F ** params) override { GFXLOG; } virtual void gfx_roundrect(int np, EEL_F ** params) override { GFXLOG; } virtual void gfx_grad_or_muladd_rect(int mod, int np, EEL_F ** params) override { GFXLOG; } virtual void gfx_drawnumber(EEL_F n, int nd) override { GFXLOG; } virtual void gfx_drawchar(EEL_F n) override { GFXLOG; } virtual void gfx_drawstr(void * opaque, EEL_F ** parms, int np, int mode) override { GFXLOG; } virtual void gfx_setpixel(EEL_F r, EEL_F g, EEL_F b) override { GFXLOG; } virtual void gfx_getpixel(EEL_F * r, EEL_F * g, EEL_F * b) override { GFXLOG; } virtual EEL_F gfx_loadimg(JsusFx & jsusFx, int img, EEL_F loadFrom) override { GFXLOG; return -1.f; } virtual void gfx_getimgdim(EEL_F img, EEL_F * w, EEL_F * h) override { GFXLOG; } virtual EEL_F gfx_setimgdim(int img, EEL_F * w, EEL_F * h) override { GFXLOG; return 0.f; } virtual EEL_F gfx_setfont(int np, EEL_F ** parms) override { GFXLOG; return 0.f; } virtual EEL_F gfx_getfont(int np, EEL_F ** parms) override { GFXLOG; return 0.f; } virtual EEL_F gfx_showmenu(EEL_F ** parms, int nparms) override { GFXLOG; return 0.f; } virtual EEL_F gfx_setcursor(EEL_F ** parms, int nparms) override { GFXLOG; return 0.f; } virtual void gfx_blurto(EEL_F x, EEL_F y) override { GFXLOG; } virtual void gfx_blit(EEL_F img, EEL_F scale, EEL_F rotate) override { GFXLOG; } virtual void gfx_blitext(EEL_F img, EEL_F * coords, EEL_F angle) override { GFXLOG; } virtual void gfx_blitext2(int mp, EEL_F ** params, int blitmode) override { GFXLOG; } }; #undef GFXLOG jsusfx-0.4.0/src/jsusfx_serialize.cpp000066400000000000000000000065221353477307700177460ustar00rootroot00000000000000/* * Copyright 2018 Pascal Gauthier, Marcel Smit * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * *distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "jsusfx.h" #include "jsusfx_serialize.h" void JsusFxSerializationData::addSlider(const int index, const float value) { sliders.resize(sliders.size() + 1); Slider & slider = sliders.back(); slider.index = index; slider.value = value; } void JsusFxSerializationData::addVar(const float value) { vars.push_back(value); } // JsusFxSerializer_Basic::JsusFxSerializer_Basic(JsusFxSerializationData & _serializationData) : JsusFxSerializer() , jsusFx(nullptr) , write(false) , serializationData(_serializationData) , varPosition(0) { } void JsusFxSerializer_Basic::begin(JsusFx & _jsusFx, const bool _write) { jsusFx = &_jsusFx; write = _write; varPosition = 0; if (write) saveSliders(*jsusFx, serializationData); else restoreSliders(*jsusFx, serializationData); } void JsusFxSerializer_Basic::end() { } void JsusFxSerializer_Basic::saveSliders(const JsusFx & jsusFx, JsusFxSerializationData & serializationData) { for (int i = 0; i < jsusFx.kMaxSliders; ++i) { if (jsusFx.sliders[i].exists && jsusFx.sliders[i].getValue() != jsusFx.sliders[i].def) { serializationData.addSlider(i, jsusFx.sliders[i].getValue()); } } } void JsusFxSerializer_Basic::restoreSliders(JsusFx & jsusFx, const JsusFxSerializationData & serializationData) { for (int i = 0; i < JsusFx::kMaxSliders; ++i) { if (jsusFx.sliders[i].exists) jsusFx.sliders[i].setValue(jsusFx.sliders[i].def); } for (int i = 0; i < serializationData.sliders.size(); ++i) { const JsusFxSerializationData::Slider & slider = serializationData.sliders[i]; if (slider.index >= 0 && slider.index < JsusFx::kMaxSliders && jsusFx.sliders[slider.index].exists) { jsusFx.sliders[slider.index].setValue(slider.value); } } } int JsusFxSerializer_Basic::file_avail() const { if (write) return -1; else return varPosition == serializationData.vars.size() ? 0 : 1; } int JsusFxSerializer_Basic::file_var(EEL_F & value) { if (write) { serializationData.vars.push_back(value); return 1; } else { if (varPosition >= 0 && varPosition < serializationData.vars.size()) { value = serializationData.vars[varPosition]; varPosition++; return 1; } else { value = 0.f; return 0; } } } int JsusFxSerializer_Basic::file_mem(EEL_F * values, const int numValues) { if (write) { for (int i = 0; i < numValues; ++i) { serializationData.vars.push_back(values[i]); } return 1; } else { if (numValues < 0) return 0; if (varPosition >= 0 && varPosition + numValues <= serializationData.vars.size()) { for (int i = 0; i < numValues; ++i) { values[i] = serializationData.vars[varPosition]; varPosition++; } return 1; } else { for (int i = 0; i < numValues; ++i) values[i] = 0.f; return 0; } } } jsusfx-0.4.0/src/jsusfx_serialize.h000066400000000000000000000050531353477307700174110ustar00rootroot00000000000000/* * Copyright 2018 Pascal Gauthier, Marcel Smit * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * *distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "WDL/eel2/ns-eel.h" #include class JsusFx; struct JsusFxSerializationData { // note : Reaper will always save/restore values using single precision floating point, so we don't use EEL_F here, // as it may be double or float depending on compile time options struct Slider { int index; float value; }; std::vector sliders; std::vector vars; void addSlider(const int index, const float value); void addVar(const float value); bool operator==(const JsusFxSerializationData & other) const { if (sliders.size() != other.sliders.size()) return false; if (vars.size() != other.vars.size()) return false; for (size_t i = 0; i < sliders.size(); ++i) if (sliders[i].index != other.sliders[i].index || sliders[i].value != other.sliders[i].value) return false; for (size_t i = 0; i < vars.size(); ++i) if (vars[i] != other.vars[i]) return false; return true; } bool operator!=(const JsusFxSerializationData & other) const { return !(*this == other); } }; struct JsusFxSerializer { virtual void begin(JsusFx & _jsusFx, const bool _write) = 0; virtual void end() = 0; virtual int file_avail() const = 0; virtual int file_var(EEL_F & value) = 0; virtual int file_mem(EEL_F * values, const int numValues) = 0; }; struct JsusFxSerializer_Basic : JsusFxSerializer { JsusFx * jsusFx; bool write; JsusFxSerializationData & serializationData; int varPosition; JsusFxSerializer_Basic(JsusFxSerializationData & _serializationData); virtual void begin(JsusFx & _jsusFx, const bool _write) override; virtual void end() override; static void saveSliders(const JsusFx & jsusFx, JsusFxSerializationData & serializationData); static void restoreSliders(JsusFx & jsusFx, const JsusFxSerializationData & serializationData); virtual int file_avail() const override; virtual int file_var(EEL_F & value) override; virtual int file_mem(EEL_F * values, const int numValues) override; }; jsusfx-0.4.0/src/riff.cpp000066400000000000000000000157401353477307700153050ustar00rootroot00000000000000/* Copyright (C) 2018 Marcel Smit marcel303@gmail.com https://www.facebook.com/marcel.smit981 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "riff.h" #include #include #include // #ifndef nullptr #define nullptr NULL #endif // template bool read(const uint8_t *& src, int & srcSize, T & result) { if (srcSize < sizeof(T)) return false; result = *(T*)src; src += sizeof(T); srcSize -= sizeof(T); return true; } bool read(const uint8_t *& src, int & srcSize, void * result, const int numBytes) { if (srcSize < numBytes) return false; memcpy(result, src, numBytes); src += numBytes; srcSize -= numBytes; return true; } bool skip(const uint8_t *& src, int & srcSize, const int numBytes) { if (srcSize < numBytes) return false; src += numBytes; srcSize -= numBytes; return true; } static void logError(const char * format, ...) { } // enum Chunk { kChunk_RIFF, kChunk_WAVE, kChunk_FMT, kChunk_DATA, kChunk_OTHER }; static bool checkId(const char * id, const char * match) { for (int i = 0; i < 4; ++i) if (tolower(id[i]) != tolower(match[i])) return false; return true; } static bool readChunk(const uint8_t *& src, int & srcSize, Chunk & chunk, int32_t & size) { char id[4]; if (!read(src, srcSize, id, 4)) return false; //logDebug("RIFF chunk: %c%c%c%c", id[0], id[1], id[2], id[3]); chunk = kChunk_OTHER; size = 0; if (checkId(id, "WAVE")) { chunk = kChunk_WAVE; return true; } else if (checkId(id, "fmt ")) { chunk = kChunk_FMT; return true; } else { if (checkId(id, "RIFF")) chunk = kChunk_RIFF; else if (checkId(id, "data")) chunk = kChunk_DATA; else if (checkId(id, "LIST") || checkId(id, "FLLR") || checkId(id, "JUNK") || checkId(id, "bext")) chunk = kChunk_OTHER; else { logError("unknown RIFF chunk: %c%c%c%c", id[0], id[1], id[2], id[3]); return false; // unknown } if (!read(src, srcSize, size)) return false; if (size < 0) return false; return true; } } // RIFFSoundData::RIFFSoundData() { memset(this, 0, sizeof(RIFFSoundData)); } RIFFSoundData::~RIFFSoundData() { if (sampleData != 0) { delete [] (char*)sampleData; sampleData = 0; } } RIFFSoundData * loadRIFF(const void * _src, const int _srcSize) { const uint8_t * src = (uint8_t*)_src; int srcSize = _srcSize; bool hasFmt = false; int32_t fmtLength; int16_t fmtCompressionType; // format code is a better name. 1 = PCM/integer, 2 = ADPCM, 3 = float, 7 = u-law int16_t fmtChannelCount; int32_t fmtSampleRate; int32_t fmtByteRate; int16_t fmtBlockAlign; int16_t fmtBitDepth; int16_t fmtExtraLength; uint8_t * bytes = nullptr; int numBytes = 0; bool done = false; do { Chunk chunk; int32_t byteCount; if (!readChunk(src, srcSize, chunk, byteCount)) return 0; if (chunk == kChunk_RIFF || chunk == kChunk_WAVE) { // just process sub chunks } else if (chunk == kChunk_FMT) { bool ok = true; ok &= read(src, srcSize, fmtLength); ok &= read(src, srcSize, fmtCompressionType); ok &= read(src, srcSize, fmtChannelCount); ok &= read(src, srcSize, fmtSampleRate); ok &= read(src, srcSize, fmtByteRate); ok &= read(src, srcSize, fmtBlockAlign); ok &= read(src, srcSize, fmtBitDepth); if (fmtCompressionType != 1) ok &= read(src, srcSize, fmtExtraLength); else fmtExtraLength = 0; if (!ok) { logError("failed to read FMT chunk"); return 0; } if (fmtCompressionType != 1) { logError("only PCM is supported. type: %d", fmtCompressionType); ok = false; } if (fmtChannelCount <= 0) { logError("invalid channel count: %d", fmtChannelCount); ok = false; } if (fmtBitDepth != 8 && fmtBitDepth != 16 && fmtBitDepth != 24 && fmtBitDepth != 32) { logError("bit depth not supported: %d", fmtBitDepth); ok = false; } if (!ok) return 0; hasFmt = true; } else if (chunk == kChunk_DATA) { if (hasFmt == false) return 0; bytes = new uint8_t[byteCount]; if (!read(src, srcSize, bytes, byteCount)) { logError("failed to load WAVE data"); delete [] bytes; return 0; } // convert data if necessary if (fmtBitDepth == 8) { // for 8 bit data the integers are unsigned. convert them to signed here const uint8_t * srcValues = bytes; int8_t * dstValues = (int8_t*)bytes; const int numValues = byteCount; for (int i = 0; i < numValues; ++i) { const int8_t value = int8_t(int(srcValues[i]) - 128); dstValues[i] = value; } } else if (fmtBitDepth == 24) { const int sampleCount = byteCount / 3; float * samplesData = new float[sampleCount]; for (int i = 0; i < sampleCount; ++i) { int32_t value = (bytes[i * 3 + 0] << 8) | (bytes[i * 3 + 1] << 16) | (bytes[i * 3 + 2] << 24); value >>= 8; samplesData[i] = value / float(1 << 23); } delete[] bytes; bytes = nullptr; bytes = (uint8_t*)samplesData; fmtBitDepth = 32; byteCount = byteCount * 4 / 3; } else if (fmtBitDepth == 32) { const int32_t * srcValues = (int32_t*)bytes; float * dstValues = (float*)bytes; const int numValues = byteCount / 4; for (int i = 0; i < numValues; ++i) { dstValues[i] = float(srcValues[i] / double(1 << 31)); } } numBytes = byteCount; done = true; } else if (chunk == kChunk_OTHER) { //logDebug("wave loader: skipping %d bytes of list chunk", size); skip(src, srcSize, byteCount); } } while (!done); if (false) { // suppress unused variables warnings fmtLength = 0; fmtByteRate = 0; fmtBlockAlign = 0; fmtExtraLength = 0; } RIFFSoundData * soundData = new RIFFSoundData(); soundData->channelSize = fmtBitDepth / 8; soundData->channelCount = fmtChannelCount; soundData->sampleCount = numBytes / (fmtBitDepth / 8 * fmtChannelCount); soundData->sampleRate = fmtSampleRate; soundData->sampleData = bytes; return soundData; } jsusfx-0.4.0/src/riff.h000066400000000000000000000026741353477307700147540ustar00rootroot00000000000000/* Copyright (C) 2018 Marcel Smit marcel303@gmail.com https://www.facebook.com/marcel.smit981 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #pragma once struct RIFFSoundData { public: RIFFSoundData(); ~RIFFSoundData(); int channelSize; // 1 or 2 bytes = int8 or int16, 4 bytes = float32 int channelCount; // 1 for mono, 2 for stereo int sampleCount; int sampleRate; void * sampleData; }; RIFFSoundData * loadRIFF(const void * src, const int srcSize); jsusfx-0.4.0/test/000077500000000000000000000000001353477307700140345ustar00rootroot00000000000000jsusfx-0.4.0/test/CMakeLists.txt000066400000000000000000000003161353477307700165740ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.7) project (jsusfx_test) add_subdirectory(../src ../src) set(SOURCE jsusfx_test.cpp) add_executable(jsusfx_test jsusfx_test.cpp) target_link_libraries(jsusfx_test jsusfx) jsusfx-0.4.0/test/jsusfx_test.cpp000066400000000000000000000075201353477307700171250ustar00rootroot00000000000000/** * jsusfx - Opensource Jesuscript FX implementation */ #include #include #include "jsusfx.h" #include #include #define ENABLE_INOUT_TEST 1 #define TEST_FILE 1 #define TEST_GFX 1 #if ENABLE_INOUT_TEST #include #endif #if TEST_FILE #include "jsusfx_file.h" #endif #if TEST_GFX #include "jsusfx_gfx.h" #endif struct JsusFxPathLibraryTest : JsusFxPathLibrary { std::string dataRoot; JsusFxPathLibraryTest(const char * _dataRoot) { dataRoot = _dataRoot; } static bool fileExists(const std::string &filename) { std::ifstream is(filename); return is.is_open(); } virtual bool resolveImportPath(const std::string &importPath, const std::string &parentPath, std::string &resolvedPath) override { const size_t pos = parentPath.rfind('/', '\\'); if (pos != std::string::npos) resolvedPath = parentPath.substr(0, pos + 1); resolvedPath += importPath; return fileExists(resolvedPath); } virtual bool resolveDataPath(const std::string &importPath, std::string &resolvedPath) override { resolvedPath = dataRoot + "/" + importPath; return fileExists(resolvedPath); } virtual std::istream* open(const std::string &path) override { std::ifstream *stream = new std::ifstream(path); if ( stream->is_open() == false ) { delete stream; stream = nullptr; } return stream; } virtual void close(std::istream *&stream) override { delete stream; stream = nullptr; } }; class JsusFxTest : public JsusFx { public: JsusFxTest(JsusFxPathLibrary &pathLibrary) : JsusFx(pathLibrary) { } void displayMsg(const char *fmt, ...) { char output[4096]; va_list argptr; va_start(argptr, fmt); vsnprintf(output, 4095, fmt, argptr); va_end(argptr); printf("%s", output); printf("\n"); } void displayError(const char *fmt, ...) { char output[4096]; va_list argptr; va_start(argptr, fmt); vsnprintf(output, 4095, fmt, argptr); va_end(argptr); printf("%s", output); printf("\n"); } }; void test_script(const char *path) { JsusFxTest *fx; float *in1, *in2; const float *in[2]; float *out[2]; in1 = new float[64]; in2 = new float[64]; in[0] = in1; in[1] = in2; out[0] = new float[64]; out[1] = new float[64]; std::string dataRoot = path; const size_t pos = dataRoot.rfind('/', '\\'); if (pos != std::string::npos) dataRoot = dataRoot.substr(0, pos + 1); printf("data root: %s\n", dataRoot.c_str()); JsusFxPathLibraryTest pathLibrary(dataRoot.c_str()); fx = new JsusFxTest(pathLibrary); #if TEST_FILE JsusFxFileAPI_Basic fileAPI; fx->fileAPI = &fileAPI; fileAPI.init(fx->m_vm); #endif #if TEST_GFX JsusFxGfx_Log gfx; fx->gfx = &gfx; gfx.init(fx->m_vm); #endif printf("compile %d: %s\n", fx->compile(pathLibrary, path, 0), path); printf("desc: %s\n", fx->desc); #if ENABLE_INOUT_TEST for (int i = 0; i < 64; ++i) { in1[i] = sin(i * 2.0 * M_PI / 63.0); in2[i] = cos(i * 2.0 * M_PI / 63.0); } fx->moveSlider(1, 0.5); fx->moveSlider(2, 0.1); #endif fx->prepare(44100, 64); fx->process(in, out, 64, 2, 2); #if ENABLE_INOUT_TEST for (int i = 0; i < 64; ++i) { printf("(%.3f, %.3f) -> (%.3f, %.3f)\n", in[0][i], in[1][i], out[0][i], out[1][i]); } #endif fx->dumpvars(); #if TEST_GFX fx->draw(); #endif delete fx; delete[] in1; delete[] in2; delete[] out[0]; delete[] out[1]; } extern "C" void test_jsfx(); void test_jsfx() { JsusFx::init(); #if TEST_GFX test_script("../scripts/liteon/3bandpeakfilter.jsfx"); #else test_script("../pd/gain.jsfx"); #endif } int main(int argc, char *argv[]) { if (argc >= 2) { const char *path = argv[1]; JsusFx::init(); test_script(path); } else { test_jsfx(); } return 0; }