summaryrefslogtreecommitdiffstats
path: root/gst/goom
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2008-02-23 01:51:37 +0000
committerBastien Nocera <hadess@hadess.net>2008-02-23 01:51:37 +0000
commita7bc7485b1a4d7e1b1a12ff593ca4ccb1d59e466 (patch)
treeffba99ad38c7616d089c5e728c75a6bd5f736c6c /gst/goom
parent7f0745bb7f26c69766bb0c64458c6543588cc4dc (diff)
configure.ac: Add checks for Flex/Yacc/Bison and other furry animals, for the new goom 2k4 based plugin
Original commit message from CVS: 2008-02-23 Bastien Nocera <hadess@hadess.net> * configure.ac: Add checks for Flex/Yacc/Bison and other furry animals, for the new goom 2k4 based plugin * gst/goom/*: Update to use goom 2k4, uses liboil to detect CPU optimisations (not working yet), move the old plugin to... * gst/goom2k1/*: ... here, in case somebody is sick enough Fixes #515073
Diffstat (limited to 'gst/goom')
-rw-r--r--gst/goom/Makefile.am79
-rw-r--r--gst/goom/README3
-rw-r--r--gst/goom/config_param.c141
-rw-r--r--gst/goom/convolve_fx.c342
-rw-r--r--gst/goom/default_scripts.h6
-rw-r--r--gst/goom/drawmethods.c204
-rw-r--r--gst/goom/drawmethods.h9
-rw-r--r--gst/goom/filters.c1284
-rw-r--r--gst/goom/filters.h83
-rw-r--r--gst/goom/filters_mmx.s132
-rw-r--r--gst/goom/flying_stars_fx.c341
-rw-r--r--gst/goom/gfontlib.c260
-rw-r--r--gst/goom/gfontlib.h10
-rw-r--r--gst/goom/gfontrle.c3080
-rw-r--r--gst/goom/gfontrle.h7
-rw-r--r--gst/goom/goom.h30
-rw-r--r--gst/goom/goom_config.h28
-rw-r--r--gst/goom/goom_config_param.h115
-rw-r--r--gst/goom/goom_core.c1103
-rw-r--r--gst/goom/goom_core.h43
-rw-r--r--gst/goom/goom_filters.h52
-rw-r--r--gst/goom/goom_fx.h12
-rw-r--r--gst/goom/goom_graphic.h74
-rw-r--r--gst/goom/goom_plugin_info.h176
-rw-r--r--gst/goom/goom_tools.c32
-rw-r--r--gst/goom/goom_tools.h49
-rw-r--r--gst/goom/goom_typedefs.h11
-rw-r--r--gst/goom/goom_visual_fx.h26
-rw-r--r--gst/goom/goomsl.c1660
-rw-r--r--gst/goom/goomsl.h34
-rw-r--r--gst/goom/goomsl_hash.c153
-rw-r--r--gst/goom/goomsl_hash.h40
-rw-r--r--gst/goom/goomsl_heap.c126
-rw-r--r--gst/goom/goomsl_heap.h29
-rw-r--r--gst/goom/goomsl_lex.l94
-rw-r--r--gst/goom/goomsl_private.h251
-rw-r--r--gst/goom/goomsl_yacc.y1405
-rw-r--r--gst/goom/graphic.c16
-rw-r--r--gst/goom/graphic.h23
-rw-r--r--gst/goom/gstgoom.c11
-rw-r--r--gst/goom/gstgoom.h4
-rw-r--r--gst/goom/ifs.c776
-rw-r--r--gst/goom/ifs.h27
-rw-r--r--gst/goom/lines.c288
-rw-r--r--gst/goom/lines.h83
-rw-r--r--gst/goom/mathtools.c95
-rw-r--r--gst/goom/mathtools.h36
-rw-r--r--gst/goom/mmx.c256
-rw-r--r--gst/goom/mmx.h729
-rw-r--r--gst/goom/motif_goom1.h1026
-rw-r--r--gst/goom/motif_goom2.h1026
-rw-r--r--gst/goom/plugin_info.c222
-rw-r--r--gst/goom/ppc_drawings.h18
-rw-r--r--gst/goom/ppc_drawings.s381
-rw-r--r--gst/goom/ppc_zoom_ultimate.h14
-rw-r--r--gst/goom/ppc_zoom_ultimate.s323
-rw-r--r--gst/goom/sound_tester.c143
-rw-r--r--gst/goom/sound_tester.h11
-rw-r--r--gst/goom/surf3d.c123
-rw-r--r--gst/goom/surf3d.h38
-rw-r--r--gst/goom/surf3d.s484
-rw-r--r--gst/goom/tentacle3d.c333
-rw-r--r--gst/goom/tentacle3d.h8
-rw-r--r--gst/goom/v3d.c20
-rw-r--r--gst/goom/v3d.h65
-rw-r--r--gst/goom/xmmx.c364
-rw-r--r--gst/goom/xmmx.h537
67 files changed, 17885 insertions, 1119 deletions
diff --git a/gst/goom/Makefile.am b/gst/goom/Makefile.am
index 4f4abb76..41e9cb32 100644
--- a/gst/goom/Makefile.am
+++ b/gst/goom/Makefile.am
@@ -1,14 +1,79 @@
plugin_LTLIBRARIES = libgstgoom.la
-GOOM_FILTER_FILES = filters.c
-GOOM_FILTER_CFLAGS = -UMMX -UUSE_ASM
+PPC_FILES=ppc_zoom_ultimate.s ppc_drawings.s ppc_drawings.h ppc_zoom_ultimate.h
+MMX_FILES=mmx.c xmmx.c mmx.h xmmx.h
-noinst_HEADERS = gstgoom.h filters.h goom_core.h goom_tools.h graphic.h lines.h
+if HAVE_CPU_PPC
+ARCH_FILES = $(PPC_FILES)
+endif
+if HAVE_CPU_PPC64
+ARCH_FILES = $(PPC_FILES)
+endif
+if HAVE_CPU_I386
+ARCH_FILES = $(MMX_FILES)
+endif
-libgstgoom_la_SOURCES = gstgoom.c goom_core.c $(GOOM_FILTER_FILES) graphic.c lines.c
+libgstgoom_la_SOURCES = \
+ gstgoom.c gstgoom.h \
+ drawmethods.c drawmethods.h \
+ sound_tester.c sound_tester.h \
+ mathtools.c mathtools.h \
+ goomsl_heap.c goomsl_heap.h \
+ goomsl_hash.c goomsl_hash.h \
+ goomsl.c goomsl_private.h \
+ lines.c lines.h ifs.c ifs.h surf3d.c surf3d.h \
+ tentacle3d.c tentacle3d.h v3d.c v3d.h \
+ gfontrle.c gfontrle.h gfontlib.c gfontlib.h \
+ convolve_fx.c flying_stars_fx.c \
+ goom_fx.h goom_visual_fx.h \
+ motif_goom1.h motif_goom2.h \
+ plugin_info.c goom_plugin_info.h \
+ default_scripts.h goom_tools.c \
+ config_param.c filters.c goom_core.c graphic.c \
+ goom.h goom_typedefs.h goom_graphic.h \
+ goom_config_param.h goom_visual_fx.h goom_filters.h \
+ goom_tools.h goom_tools.h goom_config.h \
+ $(ARCH_FILES)
-libgstgoom_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GOOM_FILTER_CFLAGS)
-libgstgoom_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM)
+ERROR_CFLAGS=
+libgstgoom_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GOOM_FILTER_CFLAGS) $(LIBOIL_CFLAGS)
+libgstgoom_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM) $(LIBOIL_LIBS) libgstgoomconfigparse.la
libgstgoom_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-EXTRA_DIST = filters.c
+EXTRA_DIST = filters.c $(PPC_FILES) $(MMX_FILES)
+
+goomsl_yacc.c goomsl_yacc.h: goomsl_yacc.y
+ $(BISON_PATH) -d $(srcdir)/goomsl_yacc.y -o goomsl_yacc.c && \
+ mv goomsl_yacc.c goomsl_yacc_tmp.c && \
+ echo '#ifdef HAVE_CONFIG_H' > goomsl_yacc_tmp2.c && \
+ echo '#include <config.h>' >> goomsl_yacc_tmp2.c && \
+ echo '#endif' >> goomsl_yacc_tmp2.c && \
+ cat goomsl_yacc_tmp.c >> goomsl_yacc_tmp2.c && \
+ rm goomsl_yacc_tmp.c && \
+ mv goomsl_yacc_tmp2.c goomsl_yacc.c
+
+goomsl_lex.c: goomsl_lex.l goomsl_yacc.h
+ $(FLEX_PATH) -ogoomsl_lex.c $(srcdir)/goomsl_lex.l && \
+ mv goomsl_lex.c goomsl_lex_tmp.c && \
+ echo '#ifdef HAVE_CONFIG_H' > goomsl_lex_tmp2.c && \
+ echo '#include <config.h>' >> goomsl_lex_tmp2.c && \
+ echo '#endif' >> goomsl_lex_tmp2.c && \
+ cat goomsl_lex_tmp.c >> goomsl_lex_tmp2.c && \
+ rm goomsl_lex_tmp.c && \
+ mv goomsl_lex_tmp2.c goomsl_lex.c
+
+# libgstgoomconfigparse.la is library linked into the goom plugin
+noinst_LTLIBRARIES = libgstgoomconfigparse.la
+
+# uncomment these lines to dist the generated sources
+#BUILT_SOURCES = goomsl_yacc.h goomsl_yacc.c goomsl_lex.c
+#libgstgoomconfigparse_la_SOURCES = goomsl_lex.c goomsl_yacc.c goomsl_yacc.h
+
+# uncomment these lines to _NOT_ dist the generated sources
+nodist_libgstgoomconfigparse_la_SOURCES = goomsl_lex.c goomsl_yacc.c
+CLEANFILES=goomsl_yacc.c goomsl_lex.c goomsl_yacc.h
+
+EXTRA_DIST += goomsl_yacc.y goomsl_lex.l
+
+.NOTPARALLEL:
+
diff --git a/gst/goom/README b/gst/goom/README
index f12cf1b5..1b3736a1 100644
--- a/gst/goom/README
+++ b/gst/goom/README
@@ -3,3 +3,6 @@ the Goom homepage found at:
http://ios.free.fr/?page=projet&quoi=1
Like the original library so is the Goom plugin available under the LGPL license
+
+This is based on goom2k4 with changes to plugin_info.c and mmx.h to use liboil for CPU
+detection and GStreamer-specific ifdef's for architecture detection.
diff --git a/gst/goom/config_param.c b/gst/goom/config_param.c
new file mode 100644
index 00000000..4c4cebd9
--- /dev/null
+++ b/gst/goom/config_param.c
@@ -0,0 +1,141 @@
+/*---------------------------------------------------------------------------*/
+/*
+** config_param.c
+** Goom Project
+**
+** Created by Jean-Christophe Hoelt on Sat Jul 19 2003
+** Copyright (c) 2003 iOS. All rights reserved.
+*/
+/*---------------------------------------------------------------------------*/
+
+#include "goom_config_param.h"
+#include <string.h>
+
+/* TODO: Ajouter goom_ devant ces fonctions */
+
+static void
+empty_fct (PluginParam * dummy)
+{
+}
+
+PluginParam
+goom_secure_param ()
+{
+ PluginParam p;
+
+ p.changed = empty_fct;
+ p.change_listener = empty_fct;
+ p.user_data = 0;
+ p.name = p.desc = 0;
+ p.rw = 1;
+ return p;
+}
+
+PluginParam
+goom_secure_f_param (char *name)
+{
+ PluginParam p = secure_param ();
+
+ p.name = name;
+ p.type = PARAM_FLOATVAL;
+ FVAL (p) = 0.5f;
+ FMIN (p) = 0.0f;
+ FMAX (p) = 1.0f;
+ FSTEP (p) = 0.01f;
+ return p;
+}
+
+PluginParam
+goom_secure_f_feedback (char *name)
+{
+ PluginParam p = secure_f_param (name);
+
+ p.rw = 0;
+ return p;
+}
+
+PluginParam
+goom_secure_s_param (char *name)
+{
+ PluginParam p = secure_param ();
+
+ p.name = name;
+ p.type = PARAM_STRVAL;
+ SVAL (p) = 0;
+ return p;
+}
+
+PluginParam
+goom_secure_b_param (char *name, int value)
+{
+ PluginParam p = secure_param ();
+
+ p.name = name;
+ p.type = PARAM_BOOLVAL;
+ BVAL (p) = value;
+ return p;
+}
+
+PluginParam
+goom_secure_i_param (char *name)
+{
+ PluginParam p = secure_param ();
+
+ p.name = name;
+ p.type = PARAM_INTVAL;
+ IVAL (p) = 50;
+ IMIN (p) = 0;
+ IMAX (p) = 100;
+ ISTEP (p) = 1;
+ return p;
+}
+
+PluginParam
+goom_secure_i_feedback (char *name)
+{
+ PluginParam p = secure_i_param (name);
+
+ p.rw = 0;
+ return p;
+}
+
+PluginParameters
+goom_plugin_parameters (const char *name, int nb)
+{
+ PluginParameters p;
+
+ p.name = (char *) name;
+ p.desc = "";
+ p.nbParams = nb;
+ p.params = (PluginParam **) malloc (nb * sizeof (PluginParam *));
+ return p;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void
+goom_set_str_param_value (PluginParam * p, const char *str)
+{
+ int len = strlen (str);
+
+ if (SVAL (*p))
+ SVAL (*p) = (char *) realloc (SVAL (*p), len + 1);
+ else
+ SVAL (*p) = (char *) malloc (len + 1);
+ memcpy (SVAL (*p), str, len + 1);
+}
+
+void
+goom_set_list_param_value (PluginParam * p, const char *str)
+{
+ int len = strlen (str);
+
+#ifdef VERBOSE
+ printf ("%s: %d\n", str, len);
+#endif
+ if (LVAL (*p))
+ LVAL (*p) = (char *) realloc (LVAL (*p), len + 1);
+ else
+ LVAL (*p) = (char *) malloc (len + 1);
+ memcpy (LVAL (*p), str, len + 1);
+}
diff --git a/gst/goom/convolve_fx.c b/gst/goom/convolve_fx.c
new file mode 100644
index 00000000..261c5fa8
--- /dev/null
+++ b/gst/goom/convolve_fx.c
@@ -0,0 +1,342 @@
+#include "goom_fx.h"
+#include "goom_plugin_info.h"
+#include "goomsl.h"
+#include "goom_config.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+//#define CONV_MOTIF_W 32
+//#define CONV_MOTIF_WMASK 0x1f
+
+#define CONV_MOTIF_W 128
+#define CONV_MOTIF_WMASK 0x7f
+
+typedef char Motif[CONV_MOTIF_W][CONV_MOTIF_W];
+
+#include "motif_goom1.h"
+#include "motif_goom2.h"
+
+#define NB_THETA 512
+
+#define MAX 2.0f
+
+typedef struct _CONV_DATA
+{
+ PluginParam light;
+ PluginParam factor_adj_p;
+ PluginParam factor_p;
+ PluginParameters params;
+
+ GoomSL *script;
+
+ /* rotozoom */
+ int theta;
+ float ftheta;
+ int h_sin[NB_THETA];
+ int h_cos[NB_THETA];
+ int h_height;
+ float visibility;
+ Motif conv_motif;
+ int inverse_motif;
+
+} ConvData;
+
+/* init rotozoom tables */
+static void
+compute_tables (VisualFX * _this, PluginInfo * info)
+{
+ ConvData *data = (ConvData *) _this->fx_data;
+ double screen_coef;
+ int i;
+ double h;
+ double radian;
+
+ if (data->h_height == info->screen.height)
+ return;
+
+ screen_coef = 2.0 * 300.0 / (double) info->screen.height;
+ data->h_height = info->screen.height;
+
+ for (i = 0; i < NB_THETA; i++) {
+ radian = 2 * i * M_PI / NB_THETA;
+ h = (0.2 + cos (radian) / 15.0 * sin (radian * 2.0 + 12.123)) * screen_coef;
+ data->h_cos[i] = 0x10000 * (-h * cos (radian) * cos (radian));
+ data->h_sin[i] = 0x10000 * (h * sin (radian + 1.57) * sin (radian));
+ }
+}
+
+static void
+set_motif (ConvData * data, Motif motif)
+{
+ int i, j;
+
+ for (i = 0; i < CONV_MOTIF_W; ++i)
+ for (j = 0; j < CONV_MOTIF_W; ++j)
+ data->conv_motif[i][j] =
+ motif[CONV_MOTIF_W - i - 1][CONV_MOTIF_W - j - 1];
+}
+
+static void
+convolve_init (VisualFX * _this, PluginInfo * info)
+{
+ ConvData *data;
+
+ data = (ConvData *) malloc (sizeof (ConvData));
+ _this->fx_data = (void *) data;
+
+ data->light = secure_f_param ("Screen Brightness");
+ data->light.param.fval.max = 300.0f;
+ data->light.param.fval.step = 1.0f;
+ data->light.param.fval.value = 100.0f;
+
+ data->factor_adj_p = secure_f_param ("Flash Intensity");
+ data->factor_adj_p.param.fval.max = 200.0f;
+ data->factor_adj_p.param.fval.step = 1.0f;
+ data->factor_adj_p.param.fval.value = 70.0f;
+
+ data->factor_p = secure_f_feedback ("Factor");
+
+ data->params = plugin_parameters ("Bright Flash", 5);
+ data->params.params[0] = &data->light;
+ data->params.params[1] = &data->factor_adj_p;
+ data->params.params[2] = 0;
+ data->params.params[3] = &data->factor_p;
+ data->params.params[4] = 0;
+
+ /* init rotozoom tables */
+ compute_tables (_this, info);
+ data->theta = 0;
+ data->ftheta = 0.0;
+ data->visibility = 1.0;
+ set_motif (data, CONV_MOTIF2);
+ data->inverse_motif = 0;
+
+ _this->params = &data->params;
+}
+
+static void
+convolve_free (VisualFX * _this)
+{
+ free (_this->fx_data);
+}
+
+static void
+create_output_with_brightness (VisualFX * _this, Pixel * src, Pixel * dest,
+ PluginInfo * info, int iff)
+{
+ ConvData *data = (ConvData *) _this->fx_data;
+
+ int x, y;
+ int i = 0; //info->screen.height * info->screen.width - 1;
+
+ const int c = data->h_cos[data->theta];
+ const int s = data->h_sin[data->theta];
+
+ const int xi = -(info->screen.width / 2) * c;
+ const int yi = (info->screen.width / 2) * s;
+
+ const int xj = -(info->screen.height / 2) * s;
+ const int yj = -(info->screen.height / 2) * c;
+
+ int xprime = xj;
+ int yprime = yj;
+
+ int ifftab[16];
+
+ if (data->inverse_motif) {
+ int i;
+
+ for (i = 0; i < 16; ++i)
+ ifftab[i] = (double) iff *(1.0 + data->visibility * (15.0 - i) / 15.0);
+ } else {
+ int i;
+
+ for (i = 0; i < 16; ++i)
+ ifftab[i] = (double) iff / (1.0 + data->visibility * (15.0 - i) / 15.0);
+ }
+
+ for (y = info->screen.height; y--;) {
+ int xtex, ytex;
+
+ xtex = xprime + xi + CONV_MOTIF_W * 0x10000 / 2;
+ xprime += s;
+
+ ytex = yprime + yi + CONV_MOTIF_W * 0x10000 / 2;
+ yprime += c;
+
+#ifdef HAVE_MMX
+ __asm__ __volatile__ ("\n\t pxor %%mm7, %%mm7" /* mm7 = 0 */
+ "\n\t movd %[xtex], %%mm2" "\n\t movd %[ytex], %%mm3" "\n\t punpckldq %%mm3, %%mm2" /* mm2 = [ ytex | xtex ] */
+ "\n\t movd %[c], %%mm4" "\n\t movd %[s], %%mm6" "\n\t pxor %%mm5, %%mm5" "\n\t psubd %%mm6, %%mm5" "\n\t punpckldq %%mm5, %%mm4" /* mm4 = [ -s | c ] */
+ "\n\t movd %[motif], %%mm6" /* mm6 = motif */
+ ::[xtex] "g" (xtex),[ytex] "g" (ytex)
+ ,[c] "g" (c),[s] "g" (s)
+ ,[motif] "g" (&data->conv_motif[0][0]));
+
+ for (x = info->screen.width; x--;) {
+ __asm__ __volatile__ ("\n\t movd %[src], %%mm0" /* mm0 = src */
+ "\n\t paddd %%mm4, %%mm2" /* [ ytex | xtex ] += [ -s | s ] */
+ "\n\t movd %%esi, %%mm5" /* save esi into mm5 */
+ "\n\t movq %%mm2, %%mm3" "\n\t psrld $16, %%mm3" /* mm3 = [ (ytex>>16) | (xtex>>16) ] */
+ "\n\t movd %%mm3, %%eax" /* eax = xtex' */
+ "\n\t psrlq $25, %%mm3" "\n\t movd %%mm3, %%ecx" /* ecx = ytex' << 7 */
+ "\n\t andl $127, %%eax" "\n\t andl $16256, %%ecx" "\n\t addl %%ecx, %%eax" "\n\t movd %%mm6, %%esi" /* esi = motif */
+ "\n\t xorl %%ecx, %%ecx" "\n\t movb (%%eax,%%esi), %%cl" "\n\t movl %[ifftab], %%eax" "\n\t movd %%mm5, %%esi" /* restore esi from mm5 */
+ "\n\t movd (%%eax,%%ecx,4), %%mm1" /* mm1 = [0|0|0|iff2] */
+ "\n\t punpcklwd %%mm1, %%mm1"
+ "\n\t punpcklbw %%mm7, %%mm0"
+ "\n\t punpckldq %%mm1, %%mm1"
+ "\n\t psrlw $1, %%mm0"
+ "\n\t psrlw $2, %%mm1"
+ "\n\t pmullw %%mm1, %%mm0"
+ "\n\t psrlw $5, %%mm0"
+ "\n\t packuswb %%mm7, %%mm0"
+ "\n\t movd %%mm0, %[dest]":[dest] "=g" (dest[i].val)
+ :[src] "g" (src[i].val)
+ ,[ifftab] "g" (&ifftab[0])
+ :"eax", "ecx");
+
+ i++;
+ }
+#else
+ for (x = info->screen.width; x--;) {
+
+ int iff2;
+ unsigned int f0, f1, f2, f3;
+
+ xtex += c;
+ ytex -= s;
+
+ iff2 =
+ ifftab[data->
+ conv_motif[(ytex >> 16) & CONV_MOTIF_WMASK][(xtex >> 16) &
+ CONV_MOTIF_WMASK]];
+
+#define sat(a) ((a)>0xFF?0xFF:(a))
+ f0 = src[i].val;
+ f1 = ((f0 >> R_OFFSET) & 0xFF) * iff2 >> 8;
+ f2 = ((f0 >> G_OFFSET) & 0xFF) * iff2 >> 8;
+ f3 = ((f0 >> B_OFFSET) & 0xFF) * iff2 >> 8;
+ dest[i].val =
+ (sat (f1) << R_OFFSET) | (sat (f2) << G_OFFSET) | (sat (f3) <<
+ B_OFFSET);
+/*
+ f0 = (src[i].cop[0] * iff2) >> 8;
+ f1 = (src[i].cop[1] * iff2) >> 8;
+ f2 = (src[i].cop[2] * iff2) >> 8;
+ f3 = (src[i].cop[3] * iff2) >> 8;
+
+ dest[i].cop[0] = (f0 & 0xffffff00) ? 0xff : (unsigned char)f0;
+ dest[i].cop[1] = (f1 & 0xffffff00) ? 0xff : (unsigned char)f1;
+ dest[i].cop[2] = (f2 & 0xffffff00) ? 0xff : (unsigned char)f2;
+ dest[i].cop[3] = (f3 & 0xffffff00) ? 0xff : (unsigned char)f3;
+*/
+ i++;
+ }
+#endif
+ }
+#ifdef HAVE_MMX
+ __asm__ __volatile__ ("\n\t emms");
+#endif
+
+ compute_tables (_this, info);
+}
+
+
+/*#include <stdint.h>
+
+static uint64_t GetTick()
+{
+ uint64_t x;
+ asm volatile ("RDTSC" : "=A" (x));
+ return x;
+}*/
+
+
+static void
+convolve_apply (VisualFX * _this, Pixel * src, Pixel * dest, PluginInfo * info)
+{
+
+ ConvData *data = (ConvData *) _this->fx_data;
+ float ff;
+ int iff;
+
+ ff = (FVAL (data->factor_p) * FVAL (data->factor_adj_p) +
+ FVAL (data->light)) / 100.0f;
+ iff = (unsigned int) (ff * 256);
+
+ {
+ double fcycle = (double) info->cycle;
+ double rotate_param, rotate_coef;
+ float INCREASE_RATE = 1.5;
+ float DECAY_RATE = 0.955;
+
+ if (FVAL (info->sound.last_goom_p) > 0.8)
+ FVAL (data->factor_p) += FVAL (info->sound.goom_power_p) * INCREASE_RATE;
+ FVAL (data->factor_p) *= DECAY_RATE;
+
+ rotate_param = FVAL (info->sound.last_goom_p);
+ if (rotate_param < 0.0)
+ rotate_param = 0.0;
+ rotate_param += FVAL (info->sound.goom_power_p);
+
+ rotate_coef = 4.0 + FVAL (info->sound.goom_power_p) * 6.0;
+ data->ftheta = (data->ftheta + rotate_coef * sin (rotate_param * 6.3));
+ data->theta = ((unsigned int) data->ftheta) % NB_THETA;
+ data->visibility =
+ (cos (fcycle * 0.001 + 1.5) * sin (fcycle * 0.008) +
+ cos (fcycle * 0.011 + 5.0) - 0.8 + info->sound.speedvar) * 1.5;
+ if (data->visibility < 0.0)
+ data->visibility = 0.0;
+ data->factor_p.change_listener (&data->factor_p);
+ }
+
+ if (data->visibility < 0.01) {
+ switch (goom_irand (info->gRandom, 300)) {
+ case 1:
+ set_motif (data, CONV_MOTIF1);
+ data->inverse_motif = 1;
+ break;
+ case 2:
+ set_motif (data, CONV_MOTIF2);
+ data->inverse_motif = 0;
+ break;
+ }
+ }
+
+ if ((ff > 0.98f) && (ff < 1.02f))
+ memcpy (dest, src, info->screen.size * sizeof (Pixel));
+ else
+ create_output_with_brightness (_this, src, dest, info, iff);
+/*
+// Benching suite...
+ {
+ uint64_t before, after;
+ double timed;
+ static double stimed = 10000.0;
+ before = GetTick();
+ data->visibility = 1.0;
+ create_output_with_brightness(_this,src,dest,info,iff);
+ after = GetTick();
+ timed = (double)((after-before) / info->screen.size);
+ if (timed < stimed) {
+ stimed = timed;
+ printf ("CLK = %3.0f CPP\n", stimed);
+ }
+ }
+*/
+}
+
+VisualFX
+convolve_create (void)
+{
+ VisualFX vfx = {
+ init:convolve_init,
+ free:convolve_free,
+ apply:convolve_apply,
+ fx_data:0
+ };
+ return vfx;
+}
diff --git a/gst/goom/default_scripts.h b/gst/goom/default_scripts.h
new file mode 100644
index 00000000..5984d705
--- /dev/null
+++ b/gst/goom/default_scripts.h
@@ -0,0 +1,6 @@
+#ifndef _DEFAULT_SCRIPTS_H
+#define _DEFAULT_SCRIPTS_H
+
+#define GOOM_MAIN_SCRIPT ""
+
+#endif
diff --git a/gst/goom/drawmethods.c b/gst/goom/drawmethods.c
new file mode 100644
index 00000000..929564da
--- /dev/null
+++ b/gst/goom/drawmethods.c
@@ -0,0 +1,204 @@
+#include "drawmethods.h"
+
+#define DRAWMETHOD_PLUS(_out,_backbuf,_col) \
+{\
+ int tra=0,i=0;\
+ unsigned char *bra = (unsigned char*)&(_backbuf);\
+ unsigned char *dra = (unsigned char*)&(_out);\
+ unsigned char *cra = (unsigned char*)&(_col);\
+ for (;i<4;i++) {\
+ tra = *cra;\
+ tra += *bra;\
+ if (tra>255) tra=255;\
+ *dra = tra;\
+ ++dra;++cra;++bra;\
+ }\
+}
+
+#define DRAWMETHOD DRAWMETHOD_PLUS(*p,*p,col)
+
+void
+draw_line (Pixel * data, int x1, int y1, int x2, int y2, int col, int screenx,
+ int screeny)
+{
+ int x, y, dx, dy, yy, xx;
+ Pixel *p;
+
+ if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny)
+ || (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx))
+ return;
+
+ /* clip to top edge
+ if ((y1 < 0) && (y2 < 0))
+ return;
+
+ if (y1 < 0) {
+ x1 += (y1 * (x1 - x2)) / (y2 - y1);
+ y1 = 0;
+ }
+ if (y2 < 0) {
+ x2 += (y2 * (x1 - x2)) / (y2 - y1);
+ y2 = 0;
+ }
+
+ clip to bottom edge
+ if ((y1 >= screeny) && (y2 >= screeny))
+ return;
+ if (y1 >= screeny) {
+ x1 -= ((screeny - y1) * (x1 - x2)) / (y2 - y1);
+ y1 = screeny - 1;
+ }
+ if (y2 >= screeny) {
+ x2 -= ((screeny - y2) * (x1 - x2)) / (y2 - y1);
+ y2 = screeny - 1;
+ }
+ clip to left edge
+ if ((x1 < 0) && (x2 < 0))
+ return;
+ if (x1 < 0) {
+ y1 += (x1 * (y1 - y2)) / (x2 - x1);
+ x1 = 0;
+ }
+ if (x2 < 0) {
+ y2 += (x2 * (y1 - y2)) / (x2 - x1);
+ x2 = 0;
+ }
+ clip to right edge
+ if ((x1 >= screenx) && (x2 >= screenx))
+ return;
+ if (x1 >= screenx) {
+ y1 -= ((screenx - x1) * (y1 - y2)) / (x2 - x1);
+ x1 = screenx - 1;
+ }
+ if (x2 >= screenx) {
+ y2 -= ((screenx - x2) * (y1 - y2)) / (x2 - x1);
+ x2 = screenx - 1;
+ }
+ */
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ if (x1 > x2) {
+ int tmp;
+
+ tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ dx = x2 - x1;
+ dy = y2 - y1;
+ }
+
+ /* vertical line */
+ if (dx == 0) {
+ if (y1 < y2) {
+ p = &(data[(screenx * y1) + x1]);
+ for (y = y1; y <= y2; y++) {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ } else {
+ p = &(data[(screenx * y2) + x1]);
+ for (y = y2; y <= y1; y++) {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ }
+ return;
+ }
+ /* horizontal line */
+ if (dy == 0) {
+ if (x1 < x2) {
+ p = &(data[(screenx * y1) + x1]);
+ for (x = x1; x <= x2; x++) {
+ DRAWMETHOD;
+ p++;
+ }
+ return;
+ } else {
+ p = &(data[(screenx * y1) + x2]);
+ for (x = x2; x <= x1; x++) {
+ DRAWMETHOD;
+ p++;
+ }
+ return;
+ }
+ }
+ /* 1 */
+ /* \ */
+ /* \ */
+ /* 2 */
+ if (y2 > y1) {
+ /* steep */
+ if (dy > dx) {
+ dx = ((dx << 16) / dy);
+ x = x1 << 16;
+ for (y = y1; y <= y2; y++) {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1)) {
+ p++;
+ /* DRAWMETHOD; */
+ }
+ x += dx;
+ }
+ return;
+ }
+ /* shallow */
+ else {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++) {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1)) {
+ p += screeny;
+ /* DRAWMETHOD; */
+ }
+ y += dy;
+ }
+ }
+ }
+ /* 2 */
+ /* / */
+ /* / */
+ /* 1 */
+ else {
+ /* steep */
+ if (-dy > dx) {
+ dx = ((dx << 16) / -dy);
+ x = (x1 + 1) << 16;
+ for (y = y1; y >= y2; y--) {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1)) {
+ p--;
+ /* DRAWMETHOD; */
+ }
+ x += dx;
+ }
+ return;
+ }
+ /* shallow */
+ else {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++) {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1)) {
+ p += screeny;
+ /* DRAWMETHOD; */
+ }
+ y += dy;
+ }
+ return;
+ }
+ }
+}
diff --git a/gst/goom/drawmethods.h b/gst/goom/drawmethods.h
new file mode 100644
index 00000000..76ad6ca0
--- /dev/null
+++ b/gst/goom/drawmethods.h
@@ -0,0 +1,9 @@
+#ifndef _DRAWMETHODS_H
+#define _DRAWMETHODS_H
+
+#include "goom_config.h"
+#include "goom_graphic.h"
+
+void draw_line (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny);
+
+#endif /* _DRAWMETHODS_H */
diff --git a/gst/goom/filters.c b/gst/goom/filters.c
index b898e89c..07e989e7 100644
--- a/gst/goom/filters.c
+++ b/gst/goom/filters.c
@@ -1,606 +1,836 @@
+// --- CHUI EN TRAIN DE SUPPRIMER LES EXTERN RESOLX ET C_RESOLY ---
+
/* filter.c version 0.7
- * contient les filtres applicable a un buffer
- * creation : 01/10/2000
- * -ajout de sinFilter()
- * -ajout de zoomFilter()
- * -copie de zoomFilter() en zoomFilterRGB(), gérant les 3 couleurs
- * -optimisation de sinFilter (utilisant une table de sin)
- * -asm
- * -optimisation de la procedure de génération du buffer de transformation
- * la vitesse est maintenant comprise dans [0..128] au lieu de [0..100]
+* contient les filtres applicable a un buffer
+* creation : 01/10/2000
+* -ajout de sinFilter()
+* -ajout de zoomFilter()
+* -copie de zoomFilter() en zoomFilterRGB(), gerant les 3 couleurs
+* -optimisation de sinFilter (utilisant une table de sin)
+* -asm
+* -optimisation de la procedure de generation du buffer de transformation
+* la vitesse est maintenant comprise dans [0..128] au lieu de [0..100]
*/
-/*#define _DEBUG_PIXEL; */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+/* #define _DEBUG_PIXEL */
-#include "filters.h"
-#include "graphic.h"
-#include "goom_tools.h"
-#include "goom_core.h"
+#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
+#include <inttypes.h>
-#ifdef MMX
-#define USE_ASM
-#endif
-#ifdef POWERPC
-#define USE_ASM
-#endif
+#include "goom_filters.h"
+#include "goom_graphic.h"
+#include "goom_tools.h"
+#include "goom_plugin_info.h"
+#include "goom_fx.h"
+#include "v3d.h"
-#ifdef USE_ASM
-#define EFFECT_DISTORS 4
-#else
-#define EFFECT_DISTORS 10
-#endif
+/* TODO : MOVE THIS AWAY !!! */
+/* jeko: j'ai essayer de le virer, mais si on veut les laisser inline c'est un peu lourdo... */
+static inline void
+setPixelRGB (PluginInfo * goomInfo, Pixel * buffer, Uint x, Uint y, Color c)
+{
+ Pixel i;
+ i.channels.b = c.b;
+ i.channels.g = c.v;
+ i.channels.r = c.r;
+ *(buffer + (x + y * goomInfo->screen.width)) = i;
+}
-#ifdef USE_ASM
+static inline void
+setPixelRGB_ (Pixel * buffer, Uint x, Color c)
+{
+ buffer[x].channels.r = c.r;
+ buffer[x].channels.g = c.v;
+ buffer[x].channels.b = c.b;
+}
-#ifdef MMX
-int mmx_zoom ();
-guint32 mmx_zoom_size;
-#endif /* MMX */
+static inline void
+getPixelRGB (PluginInfo * goomInfo, Pixel * buffer, Uint x, Uint y, Color * c)
+{
+ Pixel i = *(buffer + (x + y * goomInfo->screen.width));
-#ifdef POWERPC
-extern unsigned int useAltivec;
-extern void ppc_zoom (void);
-extern void ppc_zoom_altivec (void);
-unsigned int ppcsize4;
-#endif /* PowerPC */
+ c->b = i.channels.b;
+ c->v = i.channels.g;
+ c->r = i.channels.r;
+}
+static inline void
+getPixelRGB_ (Pixel * buffer, Uint x, Color * c)
+{
+ Pixel i = *(buffer + x);
-unsigned int *coeffs = 0, *freecoeffs = 0;
-guint32 *expix1 = 0; /* pointeur exporte vers p1 */
-guint32 *expix2 = 0; /* pointeur exporte vers p2 */
-guint32 zoom_width;
-#endif /* ASM */
+ c->b = i.channels.b;
+ c->v = i.channels.g;
+ c->r = i.channels.r;
+}
+/* END TODO */
-static int firstTime = 1;
-static int sintable[0xffff];
-ZoomFilterData *
-zoomFilterNew ()
-{
- ZoomFilterData *zf = malloc (sizeof (ZoomFilterData));
-
- zf->vitesse = 128;
- zf->pertedec = 8;
- zf->sqrtperte = 16;
- zf->middleX = 1;
- zf->middleY = 1;
- zf->reverse = 0;
- zf->mode = WAVE_MODE;
- zf->hPlaneEffect = 0;
- zf->vPlaneEffect = 0;
- zf->noisify = 0;
- zf->buffsize = 0;
- zf->res_x = 0;
- zf->res_y = 0;
-
- zf->buffer = NULL;
- zf->firedec = NULL;
-
- zf->wave = 0;
- zf->wavesp = 0;
-
- return zf;
-}
+/* DEPRECATED */
+// retourne x>>s , en testant le signe de x
+//#define ShiftRight(_x,_s) (((_x)<0) ? -(-(_x)>>(_s)) : ((_x)>>(_s)))
+//#define EFFECT_DISTORS 4
+//#define EFFECT_DISTORS_SL 2
+//#define INTERLACE_ADD 9
+//#define INTERLACE_AND 0xf
+/* END DEPRECATED */
-/* retourne x>>s , en testant le signe de x */
-static inline int
-ShiftRight (int x, const unsigned char s)
+#define BUFFPOINTNB 16
+#define BUFFPOINTNBF 16.0f
+#define BUFFPOINTMASK 0xffff
+
+#define sqrtperte 16
+/* faire : a % sqrtperte <=> a & pertemask */
+#define PERTEMASK 0xf
+/* faire : a / sqrtperte <=> a >> PERTEDEC */
+#define PERTEDEC 4
+
+/* pure c version of the zoom filter */
+static void c_zoom (Pixel * expix1, Pixel * expix2, unsigned int prevX,
+ unsigned int prevY, signed int *brutS, signed int *brutD, int buffratio,
+ int precalCoef[BUFFPOINTNB][BUFFPOINTNB]);
+
+/* simple wrapper to give it the same proto than the others */
+void
+zoom_filter_c (int sizeX, int sizeY, Pixel * src, Pixel * dest, int *brutS,
+ int *brutD, int buffratio, int precalCoef[16][16])
{
- if (x < 0)
- return -(-x >> s);
- else
- return x >> s;
+ c_zoom (src, dest, sizeX, sizeY, brutS, brutD, buffratio, precalCoef);
}
-/*
- calculer px et py en fonction de x,y,middleX,middleY et theMode
- px et py indique la nouvelle position (en sqrtperte ieme de pixel)
- (valeur * 16)
-*/
-void
-calculatePXandPY (GoomData * gd, int x, int y, int *px, int *py)
+static void generatePrecalCoef (int precalCoef[BUFFPOINTNB][BUFFPOINTNB]);
+
+
+typedef struct _ZOOM_FILTER_FX_WRAPPER_DATA
{
- ZoomFilterData *zf = gd->zfd;
+
+ PluginParam enabled_bp;
+ PluginParameters params;
+
+ unsigned int *coeffs, *freecoeffs;
+
+ signed int *brutS, *freebrutS; /* source */
+ signed int *brutD, *freebrutD; /* dest */
+ signed int *brutT, *freebrutT; /* temp (en cours de generation) */
+
+ guint32 zoom_width;
+
+ unsigned int prevX, prevY;
+
+ float general_speed;
+ int reverse; /* reverse the speed */
+ char theMode;
+ int waveEffect;
+ int hypercosEffect;
+ int vPlaneEffect;
+ int hPlaneEffect;
+ char noisify;
int middleX, middleY;
- guint32 resoly = zf->res_y;
- int vPlaneEffect = zf->vPlaneEffect;
- int hPlaneEffect = zf->hPlaneEffect;
- int vitesse = zf->vitesse;
- char theMode = zf->mode;
-
- if (theMode == WATER_MODE) {
- int wavesp = zf->wavesp;
- int wave = zf->wave;
- int yy = y + RAND (gd) % 4 + wave / 10;
-
- yy -= RAND (gd) % 4;
- if (yy < 0)
- yy = 0;
- if (yy >= resoly)
- yy = resoly - 1;
-
- *px = (x << 4) + zf->firedec[yy] + (wave / 10);
- *py = (y << 4) + 132 - ((vitesse < 132) ? vitesse : 131);
-
- wavesp += RAND (gd) % 3;
- wavesp -= RAND (gd) % 3;
- if (wave < -10)
- wavesp += 2;
- if (wave > 10)
- wavesp -= 2;
- wave += (wavesp / 10) + RAND (gd) % 3;
- wave -= RAND (gd) % 3;
- if (wavesp > 100)
- wavesp = (wavesp * 9) / 10;
-
- zf->wavesp = wavesp;
- zf->wave = wave;
- } else {
- int dist;
- register int vx, vy;
- int fvitesse = vitesse << 4;
-
- middleX = zf->middleX;
- middleY = zf->middleY;
-
- if (zf->noisify) {
- x += RAND (gd) % zf->noisify;
- x -= RAND (gd) % zf->noisify;
- y += RAND (gd) % zf->noisify;
- y -= RAND (gd) % zf->noisify;
- }
- if (hPlaneEffect)
- vx = ((x - middleX) << 9) + hPlaneEffect * (y - middleY);
- else
- vx = (x - middleX) << 9;
-
- if (vPlaneEffect)
- vy = ((y - middleY) << 9) + vPlaneEffect * (x - middleX);
- else
- vy = (y - middleY) << 9;
-
- switch (theMode) {
- case WAVE_MODE:
- dist =
- ShiftRight (vx, 9) * ShiftRight (vx, 9) + ShiftRight (vy,
- 9) * ShiftRight (vy, 9);
- fvitesse *=
- 1024 +
- ShiftRight (sintable[(unsigned short) (0xffff * dist *
- EFFECT_DISTORS)], 6);
- fvitesse /= 1024;
- break;
- case CRYSTAL_BALL_MODE:
- dist =
- ShiftRight (vx, 9) * ShiftRight (vx, 9) + ShiftRight (vy,
- 9) * ShiftRight (vy, 9);
- fvitesse += (dist * EFFECT_DISTORS >> 10);
- break;
- case AMULETTE_MODE:
- dist =
- ShiftRight (vx, 9) * ShiftRight (vx, 9) + ShiftRight (vy,
- 9) * ShiftRight (vy, 9);
- fvitesse -= (dist * EFFECT_DISTORS >> 4);
- break;
- case SCRUNCH_MODE:
- dist =
- ShiftRight (vx, 9) * ShiftRight (vx, 9) + ShiftRight (vy,
- 9) * ShiftRight (vy, 9);
- fvitesse -= (dist * EFFECT_DISTORS >> 9);
- break;
- }
- if (vx < 0)
- *px = (middleX << 4) - (-(vx * fvitesse) >> 16);
- else
- *px = (middleX << 4) + ((vx * fvitesse) >> 16);
- if (vy < 0)
- *py = (middleY << 4) - (-(vy * fvitesse) >> 16);
- else
- *py = (middleY << 4) + ((vy * fvitesse) >> 16);
- }
-}
+ int mustInitBuffers;
+ int interlace_start;
-/*#define _DEBUG */
+ /** modif by jeko : fixedpoint : buffration = (16:16) (donc 0<=buffration<=2^16) */
+ int buffratio;
+ int *firedec;
-static inline void
-setPixelRGB (Uint * buffer, Uint x, Uint y, Color c,
- guint32 resolx, guint32 resoly)
-{
-/* buffer[ y*WIDTH + x ] = (c.r<<16)|(c.v<<8)|c.b */
-#ifdef _DEBUG_PIXEL
- if (x + y * resolx >= resolx * resoly) {
- fprintf (stderr, "setPixel ERROR : hors du tableau... %i, %i\n", x, y);
- /*exit (1) ; */
- }
-#endif
+ /** modif d'optim by Jeko : precalcul des 4 coefs resultant des 2 pos */
+ int precalCoef[BUFFPOINTNB][BUFFPOINTNB];
-#ifdef USE_DGA
- buffer[y * resolx + x] = (c.b << 16) | (c.v << 8) | c.r;
-#else
- buffer[y * resolx + x] = (c.r << 16) | (c.v << 8) | c.b;
-#endif
-}
+ /** calculatePXandPY statics */
+ int wave;
+ int wavesp;
+} ZoomFilterFXWrapperData;
-static inline void
-setPixelRGB_ (Uint * buffer, Uint x, Color c, guint32 resolx, guint32 resoly)
+
+
+
+static inline v2g
+zoomVector (ZoomFilterFXWrapperData * data, float X, float Y)
{
-#ifdef _DEBUG
- if (x >= resolx * resoly) {
- printf ("setPixel ERROR : hors du tableau... %i >= %i*%i (%i)\n", x, resolx,
- resoly, resolx * resoly);
- exit (1);
+ v2g vecteur;
+ float vx, vy;
+ float sq_dist = X * X + Y * Y;
+
+ /* sx = (X < 0.0f) ? -1.0f : 1.0f;
+ sy = (Y < 0.0f) ? -1.0f : 1.0f;
+ */
+ float coefVitesse = (1.0f + data->general_speed) / 50.0f;
+
+ // Effects
+
+ /* Centralized FX */
+
+ switch (data->theMode) {
+ case CRYSTAL_BALL_MODE:
+ coefVitesse -= (sq_dist - 0.3f) / 15.0f;
+ break;
+ case AMULETTE_MODE:
+ coefVitesse += sq_dist * 3.5f;
+ break;
+ case WAVE_MODE:
+ coefVitesse += sin (sq_dist * 20.0f) / 100.0f;
+ break;
+ case SCRUNCH_MODE:
+ coefVitesse += sq_dist / 10.0f;
+ break;
+ //case HYPERCOS1_MODE:
+ break;
+ //case HYPERCOS2_MODE:
+ break;
+ //case YONLY_MODE:
+ break;
+ case SPEEDWAY_MODE:
+ coefVitesse *= 4.0f * Y;
+ break;
+ default:
+ break;
}
-#endif
-#ifdef USE_DGA
- buffer[x] = (c.b << 16) | (c.v << 8) | c.r;
-#else
- buffer[x] = (c.r << 16) | (c.v << 8) | c.b;
-#endif
-}
+ if (coefVitesse < -2.01f)
+ coefVitesse = -2.01f;
+ if (coefVitesse > 2.01f)
+ coefVitesse = 2.01f;
+ vx = coefVitesse * X;
+ vy = coefVitesse * Y;
+ /* Amulette 2 */
+ // vx = X * tan(dist);
+ // vy = Y * tan(dist);
-static inline void
-getPixelRGB (Uint * buffer, Uint x, Uint y, Color * c,
- guint32 resolx, guint32 resoly)
-{
- register unsigned char *tmp8;
+ /* Rotate */
+ //vx = (X+Y)*0.1;
+ //vy = (Y-X)*0.1;
+
+
+ // Effects adds-on
-#ifdef _DEBUG
- if (x + y * resolx >= resolx * resoly) {
- printf ("getPixel ERROR : hors du tableau... %i, %i\n", x, y);
- exit (1);
+ /* Noise */
+ if (data->noisify) {
+ vx += (((float) random ()) / ((float) RAND_MAX) - 0.5f) / 50.0f;
+ vy += (((float) random ()) / ((float) RAND_MAX) - 0.5f) / 50.0f;
}
-#endif
-
-#ifdef __BIG_ENDIAN__
- c->b = *(unsigned char *) (tmp8 =
- (unsigned char *) (buffer + (x + y * resolx)));
- c->r = *(unsigned char *) (++tmp8);
- c->v = *(unsigned char *) (++tmp8);
- c->b = *(unsigned char *) (++tmp8);
-
-#else
- /* ATTENTION AU PETIT INDIEN */
- c->b = *(unsigned char *) (tmp8 =
- (unsigned char *) (buffer + (x + y * resolx)));
- c->v = *(unsigned char *) (++tmp8);
- c->r = *(unsigned char *) (++tmp8);
-/* *c = (Color) buffer[x+y*WIDTH] ; */
-#endif
+
+ /* Hypercos */
+ if (data->hypercosEffect) {
+ vx += sin (Y * 10.0f) / 120.0f;
+ vy += sin (X * 10.0f) / 120.0f;
+ }
+
+ /* H Plane */
+ if (data->hPlaneEffect)
+ vx += Y * 0.0025f * data->hPlaneEffect;
+
+ /* V Plane */
+ if (data->vPlaneEffect)
+ vy += X * 0.0025f * data->vPlaneEffect;
+
+ /* TODO : Water Mode */
+ // if (data->waveEffect)
+
+ vecteur.x = vx;
+ vecteur.y = vy;
+
+ return vecteur;
}
-static inline void
-getPixelRGB_ (Uint * buffer, Uint x, Color * c, guint32 resolx, guint32 resoly)
+/*
+ * Makes a stripe of a transform buffer (brutT)
+ *
+ * The transform is (in order) :
+ * Translation (-data->middleX, -data->middleY)
+ * Homothetie (Center : 0,0 Coeff : 2/data->prevX)
+ */
+static void
+makeZoomBufferStripe (ZoomFilterFXWrapperData * data, int INTERLACE_INCR)
{
- register unsigned char *tmp8;
+ // Position of the pixel to compute in pixmap coordinates
+ Uint x, y;
-#ifdef _DEBUG
- if (x >= resolx * resoly) {
- printf ("getPixel ERROR : hors du tableau... %i\n", x);
- exit (1);
+ // Where (verticaly) to stop generating the buffer stripe
+ int maxEnd = (data->interlace_start + INTERLACE_INCR);
+
+ // Ratio from pixmap to normalized coordinates
+ float ratio = 2.0f / ((float) data->prevX);
+
+ // Ratio from normalized to virtual pixmap coordinates
+ float inv_ratio = BUFFPOINTNBF / ratio;
+ float min = ratio / BUFFPOINTNBF;
+
+ // Y position of the pixel to compute in normalized coordinates
+ float Y = ((float) (data->interlace_start - data->middleY)) * ratio;
+
+ maxEnd = data->prevY;
+ if (maxEnd > (data->interlace_start + INTERLACE_INCR))
+ maxEnd = (data->interlace_start + INTERLACE_INCR);
+
+ for (y = data->interlace_start;
+ (y < data->prevY) && ((signed int) y < maxEnd); y++) {
+ Uint premul_y_prevX = y * data->prevX * 2;
+ float X = -((float) data->middleX) * ratio;
+
+ for (x = 0; x < data->prevX; x++) {
+ v2g vector = zoomVector (data, X, Y);
+
+ /* Finish and avoid null displacement */
+ if (fabs (vector.x) < min)
+ vector.x = (vector.x < 0.0f) ? -min : min;
+ if (fabs (vector.y) < min)
+ vector.y = (vector.y < 0.0f) ? -min : min;
+
+ data->brutT[premul_y_prevX] =
+ ((int) ((X - vector.x) * inv_ratio) +
+ ((int) (data->middleX * BUFFPOINTNB)));
+ data->brutT[premul_y_prevX + 1] =
+ ((int) ((Y - vector.y) * inv_ratio) +
+ ((int) (data->middleY * BUFFPOINTNB)));
+ premul_y_prevX += 2;
+ X += ratio;
+ }
+ Y += ratio;
}
-#endif
-
-#ifdef __BIG_ENDIAN__
- c->b = *(unsigned char *) (tmp8 = (unsigned char *) (buffer + x));
- c->r = *(unsigned char *) (++tmp8);
- c->v = *(unsigned char *) (++tmp8);
- c->b = *(unsigned char *) (++tmp8);
-
-#else
- /* ATTENTION AU PETIT INDIEN */
- tmp8 = (unsigned char *) (buffer + x);
- c->b = *(unsigned char *) (tmp8++);
- c->v = *(unsigned char *) (tmp8++);
- c->r = *(unsigned char *) (tmp8);
-/* *c = (Color) buffer[x+y*WIDTH] ; */
-#endif
+ data->interlace_start += INTERLACE_INCR;
+ if (y >= data->prevY - 1)
+ data->interlace_start = -1;
}
+
+/*
+ * calculer px et py en fonction de x,y,middleX,middleY et theMode
+ * px et py indique la nouvelle position (en sqrtperte ieme de pixel)
+ * (valeur * 16)
+
+ inline void calculatePXandPY (PluginInfo *goomInfo, ZoomFilterFXWrapperData *data, int x, int y, int *px, int *py)
+ {
+ if (data->theMode == WATER_MODE) {
+ int yy;
+
+ yy = y + goom_irand(goomInfo->gRandom, 4) - goom_irand(goomInfo->gRandom, 4) + data->wave / 10;
+ if (yy < 0)
+ yy = 0;
+ if (yy >= (signed int)goomInfo->screen.height)
+ yy = goomInfo->screen.height - 1;
+
+ *px = (x << 4) + data->firedec[yy] + (data->wave / 10);
+ *py = (y << 4) + 132 - ((data->vitesse < 131) ? data->vitesse : 130);
+
+ data->wavesp += goom_irand(goomInfo->gRandom, 3) - goom_irand(goomInfo->gRandom, 3);
+ if (data->wave < -10)
+ data->wavesp += 2;
+ if (data->wave > 10)
+ data->wavesp -= 2;
+ data->wave += (data->wavesp / 10) + goom_irand(goomInfo->gRandom, 3) - goom_irand(goomInfo->gRandom, 3);
+ if (data->wavesp > 100)
+ data->wavesp = (data->wavesp * 9) / 10;
+ }
+ else {
+ int dist = 0, vx9, vy9;
+ int vx, vy;
+ int ppx, ppy;
+ int fvitesse = data->vitesse << 4;
+
+ if (data->noisify) {
+ x += goom_irand(goomInfo->gRandom, data->noisify) - goom_irand(goomInfo->gRandom, data->noisify);
+ y += goom_irand(goomInfo->gRandom, data->noisify) - goom_irand(goomInfo->gRandom, data->noisify);
+ }
+ vx = (x - data->middleX) << 9;
+ vy = (y - data->middleY) << 9;
+
+ if (data->hPlaneEffect)
+ vx += data->hPlaneEffect * (y - data->middleY);
+
+ if (data->vPlaneEffect)
+ vy += data->vPlaneEffect * (x - data->middleX);
+
+ if (data->waveEffect) {
+ fvitesse *=
+ 1024 +
+ ShiftRight (goomInfo->sintable
+ [(unsigned short) (dist * 0xffff + EFFECT_DISTORS)], 6);
+ fvitesse /= 1024;
+ }
+
+ if (data->hypercosEffect) {
+ vx += ShiftRight (goomInfo->sintable[(-vy + dist) & 0xffff], 1);
+ vy += ShiftRight (goomInfo->sintable[(vx + dist) & 0xffff], 1);
+ }
+
+ vx9 = ShiftRight (vx, 9);
+ vy9 = ShiftRight (vy, 9);
+ dist = vx9 * vx9 + vy9 * vy9;
+
+ switch (data->theMode) {
+ case WAVE_MODE:
+ fvitesse *=
+ 1024 +
+ ShiftRight (goomInfo->sintable
+ [(unsigned short) (dist * 0xffff * EFFECT_DISTORS)], 6);
+ fvitesse>>=10;
+ break;
+ case CRYSTAL_BALL_MODE:
+ fvitesse += (dist >> (10-EFFECT_DISTORS_SL));
+ break;
+ case AMULETTE_MODE:
+ fvitesse -= (dist >> (4 - EFFECT_DISTORS_SL));
+ break;
+ case SCRUNCH_MODE:
+ fvitesse -= (dist >> (10 - EFFECT_DISTORS_SL));
+ break;
+ case HYPERCOS1_MODE:
+ vx = vx + ShiftRight (goomInfo->sintable[(-vy + dist) & 0xffff], 1);
+ vy = vy + ShiftRight (goomInfo->sintable[(vx + dist) & 0xffff], 1);
+ break;
+ case HYPERCOS2_MODE:
+ vx =
+ vx + ShiftRight (goomInfo->sintable[(-ShiftRight (vy, 1) + dist) & 0xffff], 0);
+ vy =
+ vy + ShiftRight (goomInfo->sintable[(ShiftRight (vx, 1) + dist) & 0xffff], 0);
+ fvitesse = 128 << 4;
+ break;
+ case YONLY_MODE:
+ fvitesse *= 1024 + ShiftRight (goomInfo->sintable[vy & 0xffff], 6);
+ fvitesse >>= 10;
+ break;
+ case SPEEDWAY_MODE:
+ fvitesse -= (ShiftRight(vy,10-EFFECT_DISTORS_SL));
+ break;
+ }
+
+ if (fvitesse < -3024)
+ fvitesse = -3024;
+
+ if (vx < 0) // pb avec decalage sur nb negatif
+ ppx = -(-(vx * fvitesse) >> 16);
+ // 16 = 9 + 7 (7 = nb chiffre virgule de vitesse * (v = 128 => immobile)
+ // * * * * * 9 = nb chiffre virgule de vx)
+ else
+ ppx = ((vx * fvitesse) >> 16);
+
+ if (vy < 0)
+ ppy = -(-(vy * fvitesse) >> 16);
+ else
+ ppy = ((vy * fvitesse) >> 16);
+
+ *px = (data->middleX << 4) + ppx;
+ *py = (data->middleY << 4) + ppy;
+ }
+ }
+ */
+
+
+
static void
-zoomFilterSetResolution (GoomData * gd, ZoomFilterData * zf)
+c_zoom (Pixel * expix1, Pixel * expix2, unsigned int prevX, unsigned int prevY,
+ signed int *brutS, signed int *brutD, int buffratio, int precalCoef[16][16])
{
- unsigned short us;
+ int myPos, myPos2;
+ Color couleur;
- if (zf->buffsize >= gd->buffsize) {
- zf->res_x = gd->resolx;
- zf->res_y = gd->resoly;
- zf->middleX = gd->resolx / 2;
- zf->middleY = gd->resoly - 1;
+ unsigned int ax = (prevX - 1) << PERTEDEC, ay = (prevY - 1) << PERTEDEC;
- return;
- }
-#ifndef USE_ASM
- if (zf->buffer)
- free (zf->buffer);
- zf->buffer = 0;
-#else
- if (coeffs)
- free (freecoeffs);
- coeffs = 0;
-#endif
- zf->middleX = gd->resolx / 2;
- zf->middleY = gd->resoly - 1;
- zf->res_x = gd->resolx;
- zf->res_y = gd->resoly;
-
- if (zf->firedec)
- free (zf->firedec);
- zf->firedec = 0;
-
- zf->buffsize = gd->resolx * gd->resoly * sizeof (unsigned int);
-
-#ifdef USE_ASM
- freecoeffs = (unsigned int *)
- malloc (resx * resy * 2 * sizeof (unsigned int) + 128);
- coeffs = (guint32 *) ((1 + ((unsigned int) (freecoeffs)) / 128) * 128);
-
-#else
- zf->buffer = calloc (sizeof (guint32), zf->buffsize * 5);
- zf->pos10 = zf->buffer;
- zf->c[0] = zf->pos10 + zf->buffsize;
- zf->c[1] = zf->c[0] + zf->buffsize;
- zf->c[2] = zf->c[1] + zf->buffsize;
- zf->c[3] = zf->c[2] + zf->buffsize;
-#endif
- zf->firedec = (int *) malloc (zf->res_y * sizeof (int));
-
- if (firstTime) {
- firstTime = 0;
-
- /* generation d'une table de sinus */
- for (us = 0; us < 0xffff; us++) {
- sintable[us] = (int) (1024.0f * sin (us * 2 * 3.31415f / 0xffff));
- }
- }
+ int bufsize = prevX * prevY * 2;
+ int bufwidth = prevX;
- {
- int loopv;
-
- for (loopv = zf->res_y; loopv != 0;) {
- int decc = 0;
- int spdc = 0;
- int accel = 0;
-
- loopv--;
- zf->firedec[loopv] = decc;
- decc += spdc / 10;
- spdc += RAND (gd) % 3;
- spdc -= RAND (gd) % 3;
-
- if (decc > 4)
- spdc -= 1;
- if (decc < -4)
- spdc += 1;
-
- if (spdc > 30)
- spdc = spdc - RAND (gd) % 3 + accel / 10;
- if (spdc < -30)
- spdc = spdc + RAND (gd) % 3 + accel / 10;
-
- if (decc > 8 && spdc > 1)
- spdc -= RAND (gd) % 3 - 2;
-
- if (decc < -8 && spdc < -1)
- spdc += RAND (gd) % 3 + 2;
-
- if (decc > 8 || decc < -8)
- decc = decc * 8 / 9;
-
- accel += RAND (gd) % 2;
- accel -= RAND (gd) % 2;
- if (accel > 20)
- accel -= 2;
- if (accel < -20)
- accel += 2;
+ expix1[0].val = expix1[prevX - 1].val = expix1[prevX * prevY - 1].val =
+ expix1[prevX * prevY - prevX].val = 0;
+
+ for (myPos = 0; myPos < bufsize; myPos += 2) {
+ Color col1, col2, col3, col4;
+ int c1, c2, c3, c4, px, py;
+ int pos;
+ int coeffs;
+
+ int brutSmypos = brutS[myPos];
+
+ myPos2 = myPos + 1;
+
+ px = brutSmypos + (((brutD[myPos] -
+ brutSmypos) * buffratio) >> BUFFPOINTNB);
+ brutSmypos = brutS[myPos2];
+ py = brutSmypos + (((brutD[myPos2] -
+ brutSmypos) * buffratio) >> BUFFPOINTNB);
+
+ if ((py >= ay) || (px >= ax)) {
+ pos = coeffs = 0;
+ } else {
+ pos = ((px >> PERTEDEC) + prevX * (py >> PERTEDEC));
+ /* coef en modulo 15 */
+ coeffs = precalCoef[px & PERTEMASK][py & PERTEMASK];
}
+ getPixelRGB_ (expix1, pos, &col1);
+ getPixelRGB_ (expix1, pos + 1, &col2);
+ getPixelRGB_ (expix1, pos + bufwidth, &col3);
+ getPixelRGB_ (expix1, pos + bufwidth + 1, &col4);
+
+ c1 = coeffs;
+ c2 = (c1 >> 8) & 0xFF;
+ c3 = (c1 >> 16) & 0xFF;
+ c4 = (c1 >> 24) & 0xFF;
+ c1 = c1 & 0xff;
+
+ couleur.r = col1.r * c1 + col2.r * c2 + col3.r * c3 + col4.r * c4;
+ if (couleur.r > 5)
+ couleur.r -= 5;
+ couleur.r >>= 8;
+
+ couleur.v = col1.v * c1 + col2.v * c2 + col3.v * c3 + col4.v * c4;
+ if (couleur.v > 5)
+ couleur.v -= 5;
+ couleur.v >>= 8;
+
+ couleur.b = col1.b * c1 + col2.b * c2 + col3.b * c3 + col4.b * c4;
+ if (couleur.b > 5)
+ couleur.b -= 5;
+ couleur.b >>= 8;
+
+ setPixelRGB_ (expix2, myPos >> 1, couleur);
}
}
-void
-zoomFilterDestroy (ZoomFilterData * zf)
+/** generate the water fx horizontal direction buffer */
+static void
+generateTheWaterFXHorizontalDirectionBuffer (PluginInfo * goomInfo,
+ ZoomFilterFXWrapperData * data)
{
- if (zf) {
- if (zf->firedec)
- free (zf->firedec);
- if (zf->buffer)
- free (zf->buffer);
- free (zf);
+
+ int loopv;
+ int decc = goom_irand (goomInfo->gRandom, 8) - 4;
+ int spdc = goom_irand (goomInfo->gRandom, 8) - 4;
+ int accel = goom_irand (goomInfo->gRandom, 8) - 4;
+
+ for (loopv = data->prevY; loopv != 0;) {
+
+ loopv--;
+ data->firedec[loopv] = decc;
+ decc += spdc / 10;
+ spdc +=
+ goom_irand (goomInfo->gRandom, 3) - goom_irand (goomInfo->gRandom, 3);
+
+ if (decc > 4)
+ spdc -= 1;
+ if (decc < -4)
+ spdc += 1;
+
+ if (spdc > 30)
+ spdc = spdc - goom_irand (goomInfo->gRandom, 3) + accel / 10;
+ if (spdc < -30)
+ spdc = spdc + goom_irand (goomInfo->gRandom, 3) + accel / 10;
+
+ if (decc > 8 && spdc > 1)
+ spdc -= goom_irand (goomInfo->gRandom, 3) - 2;
+
+ if (decc < -8 && spdc < -1)
+ spdc += goom_irand (goomInfo->gRandom, 3) + 2;
+
+ if (decc > 8 || decc < -8)
+ decc = decc * 8 / 9;
+
+ accel +=
+ goom_irand (goomInfo->gRandom, 2) - goom_irand (goomInfo->gRandom, 2);
+ if (accel > 20)
+ accel -= 2;
+ if (accel < -20)
+ accel += 2;
}
}
-/*===============================================================*/
+
+
+/**
+* Main work for the dynamic displacement map.
+ *
+ * Reads data from pix1, write to pix2.
+ *
+ * Useful datas for this FX are stored in ZoomFilterData.
+ *
+ * If you think that this is a strange function name, let me say that a long time ago,
+ * there has been a slow version and a gray-level only one. Then came these function,
+ * fast and workin in RGB colorspace ! nice but it only was applying a zoom to the image.
+ * So that is why you have this name, for the nostalgy of the first days of goom
+ * when it was just a tiny program writen in Turbo Pascal on my i486...
+ */
void
-zoomFilterFastRGB (GoomData * goomdata, ZoomFilterData * zf, int zfd_update)
+zoomFilterFastRGB (PluginInfo * goomInfo, Pixel * pix1, Pixel * pix2,
+ ZoomFilterData * zf, Uint resx, Uint resy, int switchIncr, float switchMult)
{
- guint32 prevX = goomdata->resolx;
- guint32 prevY = goomdata->resoly;
+ Uint x, y;
- guint32 *pix1 = goomdata->p1;
- guint32 *pix2 = goomdata->p2;
- unsigned int *pos10;
- unsigned int **c;
+ ZoomFilterFXWrapperData *data =
+ (ZoomFilterFXWrapperData *) goomInfo->zoomFilter_fx.fx_data;
- Uint x, y;
+ if (!BVAL (data->enabled_bp))
+ return;
-/* static unsigned int prevX = 0, prevY = 0; */
+ /** changement de taille **/
+ if ((data->prevX != resx) || (data->prevY != resy)) {
+ data->prevX = resx;
+ data->prevY = resy;
+
+ if (data->brutS)
+ free (data->freebrutS);
+ data->brutS = 0;
+ if (data->brutD)
+ free (data->freebrutD);
+ data->brutD = 0;
+ if (data->brutT)
+ free (data->freebrutT);
+ data->brutT = 0;
+
+ data->middleX = resx / 2;
+ data->middleY = resy / 2;
+ data->mustInitBuffers = 1;
+ if (data->firedec)
+ free (data->firedec);
+ data->firedec = 0;
+ }
-#ifdef USE_ASM
- expix1 = pix1;
- expix2 = pix2;
-#else
- Color couleur;
- Color col1, col2, col3, col4;
- Uint position;
-#endif
+ if (data->interlace_start != -2)
+ zf = NULL;
- if ((goomdata->resolx != zf->res_x) || (goomdata->resoly != zf->res_y)) {
- zoomFilterSetResolution (goomdata, zf);
+ /** changement de config **/
+ if (zf) {
+ data->reverse = zf->reverse;
+ data->general_speed = (float) (zf->vitesse - 128) / 128.0f;
+ if (data->reverse)
+ data->general_speed = -data->general_speed;
+ data->middleX = zf->middleX;
+ data->middleY = zf->middleY;
+ data->theMode = zf->mode;
+ data->hPlaneEffect = zf->hPlaneEffect;
+ data->vPlaneEffect = zf->vPlaneEffect;
+ data->waveEffect = zf->waveEffect;
+ data->hypercosEffect = zf->hypercosEffect;
+ data->noisify = zf->noisify;
+ data->interlace_start = 0;
}
- pos10 = zf->pos10;
- c = zf->c;
-
- if (zfd_update) {
- guchar sqrtperte = zf->sqrtperte;
- gint start_y = 0;
-
- if (zf->reverse)
- zf->vitesse = 256 - zf->vitesse;
-
- /* generation du buffer */
- for (y = 0; y < zf->res_y; y++) {
- gint y_16 = y << 4;
- gint max_px = (prevX - 1) * sqrtperte;
- gint max_py = (prevY - 1) * sqrtperte;
-
- for (x = 0; x < zf->res_x; x++) {
- gint px, py;
- guchar coefv, coefh;
-
- /* calculer px et py en fonction de */
- /* x,y,middleX,middleY et theMode */
- calculatePXandPY (goomdata, x, y, &px, &py);
-
- if ((px == x << 4) && (py == y_16))
- py += 8;
-
- if ((py < 0) || (px < 0) || (py >= max_py) || (px >= max_px)) {
-#ifdef USE_ASM
- coeffs[(y * prevX + x) * 2] = 0;
- coeffs[(y * prevX + x) * 2 + 1] = 0;
-#else
- pos10[start_y + x] = 0;
- c[0][start_y + x] = 0;
- c[1][start_y + x] = 0;
- c[2][start_y + x] = 0;
- c[3][start_y + x] = 0;
-#endif
- } else {
- int npx10;
- int npy10;
- int pos;
-
- npx10 = (px / sqrtperte);
- npy10 = (py / sqrtperte);
-
-/* if (npx10 >= prevX) fprintf(stderr,"error npx:%d",npx10);
- if (npy10 >= prevY) fprintf(stderr,"error npy:%d",npy10);
-*/
- coefh = px % sqrtperte;
- coefv = py % sqrtperte;
-#ifdef USE_ASM
- pos = (y * prevX + x) * 2;
- coeffs[pos] = (npx10 + prevX * npy10) * 4;
-
- if (!(coefh || coefv))
- coeffs[pos + 1] = (sqrtperte * sqrtperte - 1);
- else
- coeffs[pos + 1] = ((sqrtperte - coefh) * (sqrtperte - coefv));
-
- coeffs[pos + 1] |= (coefh * (sqrtperte - coefv)) << 8;
- coeffs[pos + 1] |= ((sqrtperte - coefh) * coefv) << 16;
- coeffs[pos + 1] |= (coefh * coefv) << 24;
-#else
- pos = start_y + x;
- pos10[pos] = npx10 + prevX * npy10;
-
- if (!(coefh || coefv))
- c[0][pos] = sqrtperte * sqrtperte - 1;
- else
- c[0][pos] = (sqrtperte - coefh) * (sqrtperte - coefv);
-
- c[1][pos] = coefh * (sqrtperte - coefv);
- c[2][pos] = (sqrtperte - coefh) * coefv;
- c[3][pos] = coefh * coefv;
-#endif
- }
- }
- /* Advance start of line index */
- start_y += prevX;
+
+ if (data->mustInitBuffers) {
+
+ data->mustInitBuffers = 0;
+ data->freebrutS =
+ (signed int *) calloc (resx * resy * 2 + 128, sizeof (unsigned int));
+ data->brutS =
+ (gint32 *) ((1 + ((uintptr_t) (data->freebrutS)) / 128) * 128);
+
+ data->freebrutD =
+ (signed int *) calloc (resx * resy * 2 + 128, sizeof (unsigned int));
+ data->brutD =
+ (gint32 *) ((1 + ((uintptr_t) (data->freebrutD)) / 128) * 128);
+
+ data->freebrutT =
+ (signed int *) calloc (resx * resy * 2 + 128, sizeof (unsigned int));
+ data->brutT =
+ (gint32 *) ((1 + ((uintptr_t) (data->freebrutT)) / 128) * 128);
+
+ data->buffratio = 0;
+
+ data->firedec = (int *) malloc (data->prevY * sizeof (int));
+ generateTheWaterFXHorizontalDirectionBuffer (goomInfo, data);
+
+ data->interlace_start = 0;
+ makeZoomBufferStripe (data, resy);
+
+ /* Copy the data from temp to dest and source */
+ memcpy (data->brutS, data->brutT, resx * resy * 2 * sizeof (int));
+ memcpy (data->brutD, data->brutT, resx * resy * 2 * sizeof (int));
+ }
+
+ /* generation du buffer de trans */
+ if (data->interlace_start == -1) {
+
+ /* sauvegarde de l'etat actuel dans la nouvelle source
+ * TODO: write that in MMX (has been done in previous version, but did not follow some new fonctionnalities) */
+ y = data->prevX * data->prevY * 2;
+ for (x = 0; x < y; x += 2) {
+ int brutSmypos = data->brutS[x];
+ int x2 = x + 1;
+
+ data->brutS[x] =
+ brutSmypos + (((data->brutD[x] -
+ brutSmypos) * data->buffratio) >> BUFFPOINTNB);
+ brutSmypos = data->brutS[x2];
+ data->brutS[x2] =
+ brutSmypos + (((data->brutD[x2] -
+ brutSmypos) * data->buffratio) >> BUFFPOINTNB);
}
+ data->buffratio = 0;
}
-#ifdef USE_ASM
-#ifdef MMX
- zoom_width = prevX;
- mmx_zoom_size = prevX * prevY;
- mmx_zoom ();
-#endif
-
-#ifdef POWERPC
- zoom_width = prevX;
- if (useAltivec) {
- ppcsize4 = ((unsigned int) (prevX * prevY)) / 4;
- ppc_zoom_altivec ();
- } else {
- ppcsize4 = ((unsigned int) (prevX * prevY));
- ppc_zoom ();
+
+ if (data->interlace_start == -1) {
+ signed int *tmp;
+
+ tmp = data->brutD;
+ data->brutD = data->brutT;
+ data->brutT = tmp;
+ tmp = data->freebrutD;
+ data->freebrutD = data->freebrutT;
+ data->freebrutT = tmp;
+ data->interlace_start = -2;
+ }
+
+ if (data->interlace_start >= 0) {
+ /* creation de la nouvelle destination */
+ makeZoomBufferStripe (data, resy / 16);
+ }
+
+ if (switchIncr != 0) {
+ data->buffratio += switchIncr;
+ if (data->buffratio > BUFFPOINTMASK)
+ data->buffratio = BUFFPOINTMASK;
+ }
+
+ if (switchMult != 1.0f) {
+ data->buffratio = (int) ((float) BUFFPOINTMASK * (1.0f - switchMult) +
+ (float) data->buffratio * switchMult);
}
-#endif
-#else
- for (position = 0; position < prevX * prevY; position++) {
- getPixelRGB_ (pix1, pos10[position], &col1, goomdata->resolx,
- goomdata->resoly);
- getPixelRGB_ (pix1, pos10[position] + 1, &col2, goomdata->resolx,
- goomdata->resoly);
- getPixelRGB_ (pix1, pos10[position] + prevX, &col3, goomdata->resolx,
- goomdata->resoly);
- getPixelRGB_ (pix1, pos10[position] + prevX + 1, &col4, goomdata->resolx,
- goomdata->resoly);
-
- couleur.r = col1.r * c[0][position]
- + col2.r * c[1][position]
- + col3.r * c[2][position]
- + col4.r * c[3][position];
- couleur.r >>= zf->pertedec;
-
- couleur.v = col1.v * c[0][position]
- + col2.v * c[1][position]
- + col3.v * c[2][position]
- + col4.v * c[3][position];
- couleur.v >>= zf->pertedec;
-
- couleur.b = col1.b * c[0][position]
- + col2.b * c[1][position]
- + col3.b * c[2][position]
- + col4.b * c[3][position];
- couleur.b >>= zf->pertedec;
-
- setPixelRGB_ (pix2, position, couleur, goomdata->resolx, goomdata->resoly);
+
+ data->zoom_width = data->prevX;
+
+ goomInfo->methods.zoom_filter (data->prevX, data->prevY, pix1, pix2,
+ data->brutS, data->brutD, data->buffratio, data->precalCoef);
+}
+
+static void
+generatePrecalCoef (int precalCoef[16][16])
+{
+ int coefh, coefv;
+
+ for (coefh = 0; coefh < 16; coefh++) {
+ for (coefv = 0; coefv < 16; coefv++) {
+
+ int i;
+ int diffcoeffh;
+ int diffcoeffv;
+
+ diffcoeffh = sqrtperte - coefh;
+ diffcoeffv = sqrtperte - coefv;
+
+ if (!(coefh || coefv)) {
+ i = 255;
+ } else {
+ int i1, i2, i3, i4;
+
+ i1 = diffcoeffh * diffcoeffv;
+ i2 = coefh * diffcoeffv;
+ i3 = diffcoeffh * coefv;
+ i4 = coefh * coefv;
+
+ // TODO: faire mieux...
+ if (i1)
+ i1--;
+ if (i2)
+ i2--;
+ if (i3)
+ i3--;
+ if (i4)
+ i4--;
+
+ i = (i1) | (i2 << 8) | (i3 << 16) | (i4 << 24);
+ }
+ precalCoef[coefh][coefv] = i;
+ }
}
-#endif
}
+/* VisualFX Wrapper */
+
+static void
+zoomFilterVisualFXWrapper_init (struct _VISUAL_FX *_this, PluginInfo * info)
+{
+ ZoomFilterFXWrapperData *data =
+ (ZoomFilterFXWrapperData *) malloc (sizeof (ZoomFilterFXWrapperData));
+
+ data->coeffs = 0;
+ data->freecoeffs = 0;
+ data->brutS = 0;
+ data->freebrutS = 0;
+ data->brutD = 0;
+ data->freebrutD = 0;
+ data->brutT = 0;
+ data->freebrutT = 0;
+ data->prevX = 0;
+ data->prevY = 0;
+
+ data->mustInitBuffers = 1;
+ data->interlace_start = -2;
+
+ data->general_speed = 0.0f;
+ data->reverse = 0;
+ data->theMode = AMULETTE_MODE;
+ data->waveEffect = 0;
+ data->hypercosEffect = 0;
+ data->vPlaneEffect = 0;
+ data->hPlaneEffect = 0;
+ data->noisify = 2;
+
+ /** modif by jeko : fixedpoint : buffration = (16:16) (donc 0<=buffration<=2^16) */
+ data->buffratio = 0;
+ data->firedec = 0;
+
+ data->wave = data->wavesp = 0;
+
+ data->enabled_bp = secure_b_param ("Enabled", 1);
+
+ data->params = plugin_parameters ("Zoom Filter", 1);
+ data->params.params[0] = &data->enabled_bp;
+
+ _this->params = &data->params;
+ _this->fx_data = (void *) data;
+
+ /** modif d'optim by Jeko : precalcul des 4 coefs resultant des 2 pos */
+ generatePrecalCoef (data->precalCoef);
+}
+
+static void
+zoomFilterVisualFXWrapper_free (struct _VISUAL_FX *_this)
+{
+ free (_this->fx_data);
+}
+
+static void
+zoomFilterVisualFXWrapper_apply (struct _VISUAL_FX *_this, Pixel * src,
+ Pixel * dest, PluginInfo * info)
+{
+}
+
+VisualFX
+zoomFilterVisualFXWrapper_create (void)
+{
+ VisualFX fx;
+
+ fx.init = zoomFilterVisualFXWrapper_init;
+ fx.free = zoomFilterVisualFXWrapper_free;
+ fx.apply = zoomFilterVisualFXWrapper_apply;
+ return fx;
+}
+
+
+/* TODO : MOVE THIS AWAY */
void
-pointFilter (GoomData * goomdata, Color c,
- float t1, float t2, float t3, float t4, Uint cycle)
+pointFilter (PluginInfo * goomInfo, Pixel * pix1, Color c, float t1, float t2,
+ float t3, float t4, Uint cycle)
{
- Uint *pix1 = goomdata->p1;
- ZoomFilterData *zf = goomdata->zfd;
- Uint x = (Uint) (zf->middleX + (int) (t1 * cos ((float) cycle / t3)));
- Uint y = (Uint) (zf->middleY + (int) (t2 * sin ((float) cycle / t4)));
-
- if ((x > 1) && (y > 1) && (x < goomdata->resolx - 2)
- && (y < goomdata->resoly - 2)) {
- setPixelRGB (pix1, x + 1, y, c, goomdata->resolx, goomdata->resoly);
- setPixelRGB (pix1, x, y + 1, c, goomdata->resolx, goomdata->resoly);
- setPixelRGB (pix1, x + 1, y + 1, WHITE, goomdata->resolx, goomdata->resoly);
- setPixelRGB (pix1, x + 2, y + 1, c, goomdata->resolx, goomdata->resoly);
- setPixelRGB (pix1, x + 1, y + 2, c, goomdata->resolx, goomdata->resoly);
+ Uint x = (Uint) ((int) (goomInfo->screen.width / 2)
+ + (int) (t1 * cos ((float) cycle / t3)));
+ Uint y = (Uint) ((int) (goomInfo->screen.height / 2)
+ + (int) (t2 * sin ((float) cycle / t4)));
+
+ if ((x > 1) && (y > 1) && (x < goomInfo->screen.width - 2)
+ && (y < goomInfo->screen.height - 2)) {
+ setPixelRGB (goomInfo, pix1, x + 1, y, c);
+ setPixelRGB (goomInfo, pix1, x, y + 1, c);
+ setPixelRGB (goomInfo, pix1, x + 1, y + 1, WHITE);
+ setPixelRGB (goomInfo, pix1, x + 2, y + 1, c);
+ setPixelRGB (goomInfo, pix1, x + 1, y + 2, c);
}
}
diff --git a/gst/goom/filters.h b/gst/goom/filters.h
deleted file mode 100644
index 65eb3e25..00000000
--- a/gst/goom/filters.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef FILTERS_H
-#define FILTERS_H
-
-#include <glib.h>
-
-#include "graphic.h"
-#include "goom_core.h"
-
-#define NORMAL_MODE 0
-#define WAVE_MODE 1
-#define CRYSTAL_BALL_MODE 2
-#define SCRUNCH_MODE 3
-#define AMULETTE_MODE 4
-#define WATER_MODE 5
-
-struct ZoomFilterData
-{
- int vitesse;
- unsigned char pertedec;
- unsigned char sqrtperte;
- int middleX;
- int middleY;
- char reverse;
- char mode;
- /** @since June 2001 */
- int hPlaneEffect;
- int vPlaneEffect;
- char noisify;
-
- guint32 res_x;
- guint32 res_y;
- guint32 buffsize;
-
- guint32 *buffer;
- guint32 *pos10;
- guint32 *c[4];
- int *firedec;
-
- int wave;
- int wavesp;
-};
-
-void pointFilter(GoomData *goomdata, Color c,
- float t1, float t2, float t3, float t4,
- guint32 cycle);
-
-/* filtre de zoom :
- le contenu de pix1 est copie dans pix2, avec l'effet appliqué
- midx et midy represente le centre du zoom
-
-void zoomFilter(Uint *pix1, Uint *pix2, Uint middleX, Uint middleY);
-void zoomFilterRGB(Uint *pix1,
-Uint *pix2,
-Uint middleX,
-Uint middleY);
-*/
-
-ZoomFilterData *zoomFilterNew ();
-void zoomFilterDestroy (ZoomFilterData *zf);
-void zoomFilterFastRGB (GoomData *goomdata, ZoomFilterData *zf,
- int zfd_update);
-
-/* filtre sin :
- le contenu de pix1 est copie dans pix2, avec l'effet appliqué
- cycle est la variable de temps.
- mode vaut SIN_MUL ou SIN_ADD
- rate est le pourcentage de l'effet appliqué
- lenght : la longueur d'onde (1..10) [5]
- speed : la vitesse (1..100) [10]
-*/
-/*
-void sinFilter(Uint *pix1,Uint *pix2,
- Uint cycle,
- Uint mode,
- Uint rate,
- char lenght,
- Uint speed);
-*/
-
-#define SIN_MUL 1
-#define SIN_ADD 2
-
-#endif
diff --git a/gst/goom/filters_mmx.s b/gst/goom/filters_mmx.s
index 337de56c..765f1588 100644
--- a/gst/goom/filters_mmx.s
+++ b/gst/goom/filters_mmx.s
@@ -15,49 +15,117 @@
.data
+chaine:
+ .string "pos = %d\n\0"
+ .long 0x0
+
thezero:
.long 0x00000000
.long 0x00000000
-
.text
.globl mmx_zoom ;// name of the function to call by C program
-.extern coeffs ;// the transformation buffer
+/* .extern coeffs ;// the transformation buffer */
.extern expix1,expix2 ;// the source and destination buffer
.extern mmx_zoom_size, zoom_width ;// size of the buffers
+.extern brutS,brutD,buffratio,precalCoef,prevX,prevY
+
+#define PERTEMASK 15
+/* faire : a / sqrtperte <=> a >> PERTEDEC*/
+#define PERTEDEC 4
+
.align 16
mmx_zoom:
-push %ebp
-push %esp
+ pushl %ebp
+ movl %esp,%ebp
+ subl $12,%esp
-;// initialisation du mm7 à zero
-movq (thezero), %mm7
+ movl prevX,%eax
+ decl %eax
+ sarl $4,%eax
+ movl %eax,-4(%ebp)
-movl zoom_width, %eax
-movl $4, %ebx
-mull %ebx
-movl %eax, %ebp
+ movl prevY,%eax
+ decl %eax
+ sarl $4,%eax
+ movl %eax,-8(%ebp)
+
+;// initialisation du mm7 à zero
+ movq (thezero), %mm7
-movl (coeffs), %eax
-movl (expix1), %edx
-movl (expix2), %ebx
-movl $10, %edi
movl mmx_zoom_size, %ecx
+decl %ecx
.while:
;// esi <- nouvelle position
- movl (%eax), %esi
- leal (%edx, %esi), %esi
+ movl brutS, %eax
+ leal (%eax, %ecx, 8),%eax
+
+ movl (%eax),%edx /* = brutS.px (brutSmypos) */
+ movl 4(%eax),%eax /* = brutS.py */
+
+ movl brutD,%ebx
+ leal (%ebx, %ecx, 8),%ebx
+ movl (%ebx),%esi
+ subl %edx, %esi
+ imull buffratio,%esi
+ sarl $16,%esi
+ addl %edx,%esi /* esi = px */
+
+ /* eax contient deja brutS.py = le nouveau brutSmypos*/
+ /* ebx pointe sur brutD[myPos] */
+ movl 4(%ebx),%edi
+ subl %eax,%edi
+ imull buffratio,%edi
+ sarl $16,%edi
+ addl %eax,%edi /* edi = py */
+
+/* pushl %eax
+ pushl %ebx*/
+/* popl %ebx
+ popl %eax*/
+
+ movl %esi,%eax
+ andl $15,%eax /* eax = coefh */
+ movl %edi,%ebx
+ andl $15,%ebx /* ebx = coefv */
+
+ leal 0(,%ebx,4),%ebx
+ sall $6,%eax
+ addl %ebx,%eax
+ movl $precalCoef,%ebx
+/* movd (%eax,%ebx),%mm6*/ /* mm6 = coeffs */
+
+ cmpl -8(%ebp),%edi
+ jge .then1
+ cmpl -4(%ebp),%esi
+ jge .then1
+
+ sarl $4,%esi
+ sarl $4,%edi
+ imull zoom_width,%edi
+ leal (%esi,%edi),%esi
+ jmp .finsi1
+
+.then1:
+ movl $0,%esi
+.finsi1:
+
+ /** apres ce calcul, %esi = pos, %mm6 = coeffs **/
+/* pushl %esi
+ pushl $chaine
+ call printf
+ addl $8,%esp*/
+
+ movl expix1,%eax
;// recuperation des deux premiers pixels dans mm0 et mm1
- movq (%esi), %mm0 /* b1-v1-r1-a1-b2-v2-r2-a2 */
- movq %mm0, %mm1 /* b1-v1-r1-a1-b2-v2-r2-a2 */
+/* movq (%eax,%esi,4), %mm0 /* b1-v1-r1-a1-b2-v2-r2-a2 */
+ movq %mm0, %mm1 /* b1-v1-r1-a1-b2-v2-r2-a2 */
- ;// recuperation des 4 coefficients
- movd 4(%eax), %mm6 /* ??-??-??-??-c4-c3-c2-c1 */
;// depackage du premier pixel
punpcklbw %mm7, %mm0 /* 00-b2-00-v2-00-r2-00-a2 */
@@ -87,8 +155,11 @@ movl mmx_zoom_size, %ecx
punpcklbw %mm7, %mm4 /* 00-c3-00-c3-00-c3-00-c3 */
punpckhbw %mm7, %mm5 /* 00-c4-00-c4-00-c4-00-c4 */
+ /* ajouter la longueur de ligne a esi */
+ addl prevX,%esi
+
;// recuperation des 2 derniers pixels
- movq (%esi,%ebp), %mm1
+/* movq (%eax,%esi,4), %mm1*/
movq %mm1, %mm2
;// depackage des pixels
@@ -108,23 +179,22 @@ movl mmx_zoom_size, %ecx
packuswb %mm7, %mm0
;// passage au suivant
- leal 8(%eax), %eax
- decl %ecx
;// enregistrement du resultat
- movd %mm0, (%ebx)
- leal 4(%ebx), %ebx
+ movl expix2,%eax
+/* movd %mm0,(%eax,%ecx,4)*/
+ decl %ecx
;// test de fin du tantque
cmpl $0, %ecx ;// 400x300
-jz .fin_while
-jmp .while
+ jz .fin_while
+ jmp .while
.fin_while:
-emms
+ emms
-pop %esp
-pop %ebp
+ movl %ebp,%esp
+ popl %ebp
-ret ;//The End
+ ret ;//The End
diff --git a/gst/goom/flying_stars_fx.c b/gst/goom/flying_stars_fx.c
new file mode 100644
index 00000000..c323c7c9
--- /dev/null
+++ b/gst/goom/flying_stars_fx.c
@@ -0,0 +1,341 @@
+#include "goom_fx.h"
+#include "goom_plugin_info.h"
+#include "goom_tools.h"
+
+#include "mathtools.h"
+
+/* TODO:-- FAIRE PROPREMENT... BOAH... */
+#define NCOL 15
+
+/*static const int colval[] = {
+0xfdf6f5,
+0xfae4e4,
+0xf7d1d1,
+0xf3b6b5,
+0xefa2a2,
+0xec9190,
+0xea8282,
+0xe87575,
+0xe46060,
+0xe14b4c,
+0xde3b3b,
+0xdc2d2f,
+0xd92726,
+0xd81619,
+0xd50c09,
+0
+};
+*/
+static const int colval[] = {
+ 0x1416181a,
+ 0x1419181a,
+ 0x141f181a,
+ 0x1426181a,
+ 0x142a181a,
+ 0x142f181a,
+ 0x1436181a,
+ 0x142f1819,
+ 0x14261615,
+ 0x13201411,
+ 0x111a100a,
+ 0x0c180508,
+ 0x08100304,
+ 0x00050101,
+ 0x0
+};
+
+
+/* The different modes of the visual FX.
+ * Put this values on fx_mode */
+#define FIREWORKS_FX 0
+#define RAIN_FX 1
+#define FOUNTAIN_FX 2
+#define LAST_FX 3
+
+typedef struct _FS_STAR
+{
+ float x, y;
+ float vx, vy;
+ float ax, ay;
+ float age, vage;
+} Star;
+
+typedef struct _FS_DATA
+{
+
+ int fx_mode;
+ int nbStars;
+
+ int maxStars;
+ Star *stars;
+
+ float min_age;
+ float max_age;
+
+ PluginParam min_age_p;
+ PluginParam max_age_p;
+ PluginParam nbStars_p;
+ PluginParam nbStars_limit_p;
+ PluginParam fx_mode_p;
+
+ PluginParameters params;
+} FSData;
+
+static void
+fs_init (VisualFX * _this, PluginInfo * info)
+{
+
+ FSData *data;
+
+ data = (FSData *) malloc (sizeof (FSData));
+
+ data->fx_mode = FIREWORKS_FX;
+ data->maxStars = 4096;
+ data->stars = (Star *) malloc (data->maxStars * sizeof (Star));
+ data->nbStars = 0;
+
+ data->max_age_p = secure_i_param ("Fireworks Smallest Bombs");
+ IVAL (data->max_age_p) = 80;
+ IMIN (data->max_age_p) = 0;
+ IMAX (data->max_age_p) = 100;
+ ISTEP (data->max_age_p) = 1;
+
+ data->min_age_p = secure_i_param ("Fireworks Largest Bombs");
+ IVAL (data->min_age_p) = 99;
+ IMIN (data->min_age_p) = 0;
+ IMAX (data->min_age_p) = 100;
+ ISTEP (data->min_age_p) = 1;
+
+ data->nbStars_limit_p = secure_i_param ("Max Number of Particules");
+ IVAL (data->nbStars_limit_p) = 512;
+ IMIN (data->nbStars_limit_p) = 0;
+ IMAX (data->nbStars_limit_p) = data->maxStars;
+ ISTEP (data->nbStars_limit_p) = 64;
+
+ data->fx_mode_p = secure_i_param ("FX Mode");
+ IVAL (data->fx_mode_p) = data->fx_mode;
+ IMIN (data->fx_mode_p) = 1;
+ IMAX (data->fx_mode_p) = 3;
+ ISTEP (data->fx_mode_p) = 1;
+
+ data->nbStars_p = secure_f_feedback ("Number of Particules (% of Max)");
+
+ data->params = plugin_parameters ("Particule System", 7);
+ data->params.params[0] = &data->fx_mode_p;
+ data->params.params[1] = &data->nbStars_limit_p;
+ data->params.params[2] = 0;
+ data->params.params[3] = &data->min_age_p;
+ data->params.params[4] = &data->max_age_p;
+ data->params.params[5] = 0;
+ data->params.params[6] = &data->nbStars_p;
+
+ _this->params = &data->params;
+ _this->fx_data = (void *) data;
+}
+
+static void
+fs_free (VisualFX * _this)
+{
+ free (_this->fx_data);
+}
+
+
+/**
+ * Cree une nouvelle 'bombe', c'est a dire une particule appartenant a une fusee d'artifice.
+ */
+static void
+addABomb (FSData * fs, int mx, int my, float radius, float vage, float gravity,
+ PluginInfo * info)
+{
+
+ int i = fs->nbStars;
+ float ro;
+ int theta;
+
+ if (fs->nbStars >= fs->maxStars)
+ return;
+ fs->nbStars++;
+
+ fs->stars[i].x = mx;
+ fs->stars[i].y = my;
+
+ ro = radius * (float) goom_irand (info->gRandom, 100) / 100.0f;
+ ro *= (float) goom_irand (info->gRandom, 100) / 100.0f + 1.0f;
+ theta = goom_irand (info->gRandom, 256);
+
+ fs->stars[i].vx = ro * cos256[theta];
+ fs->stars[i].vy = -0.2f + ro * sin256[theta];
+
+ fs->stars[i].ax = 0;
+ fs->stars[i].ay = gravity;
+
+ fs->stars[i].age = 0;
+ if (vage < fs->min_age)
+ vage = fs->min_age;
+ fs->stars[i].vage = vage;
+}
+
+
+/**
+ * Met a jour la position et vitesse d'une particule.
+ */
+static void
+updateStar (Star * s)
+{
+ s->x += s->vx;
+ s->y += s->vy;
+ s->vx += s->ax;
+ s->vy += s->ay;
+ s->age += s->vage;
+}
+
+
+/**
+ * Ajoute de nouvelles particules au moment d'un evenement sonore.
+ */
+static void
+fs_sound_event_occured (VisualFX * _this, PluginInfo * info)
+{
+
+ FSData *data = (FSData *) _this->fx_data;
+ int i;
+
+ int max =
+ (int) ((1.0f + info->sound.goomPower) * goom_irand (info->gRandom,
+ 150)) + 100;
+ float radius =
+ (1.0f + info->sound.goomPower) * (float) (goom_irand (info->gRandom,
+ 150) + 50) / 300;
+ int mx;
+ int my;
+ float vage, gravity = 0.02f;
+
+ switch (data->fx_mode) {
+ case FIREWORKS_FX:
+ {
+ double dx, dy;
+
+ do {
+ mx = goom_irand (info->gRandom, info->screen.width);
+ my = goom_irand (info->gRandom, info->screen.height);
+ dx = (mx - info->screen.width / 2);
+ dy = (my - info->screen.height / 2);
+ } while (dx * dx + dy * dy <
+ (info->screen.height / 2) * (info->screen.height / 2));
+ vage = data->max_age * (1.0f - info->sound.goomPower);
+ }
+ break;
+ case RAIN_FX:
+ mx = goom_irand (info->gRandom, info->screen.width);
+ if (mx > info->screen.width / 2)
+ mx = info->screen.width;
+ else
+ mx = 0;
+ my = -(info->screen.height / 3) - goom_irand (info->gRandom,
+ info->screen.width / 3);
+ radius *= 1.5;
+ vage = 0.002f;
+ break;
+ case FOUNTAIN_FX:
+ my = info->screen.height + 2;
+ vage = 0.001f;
+ radius += 1.0f;
+ mx = info->screen.width / 2;
+ gravity = 0.04f;
+ break;
+ default:
+ return;
+ /* my = i R A N D (info->screen.height); vage = 0.01f; */
+ }
+
+ radius *= info->screen.height / 200.0f; /* why 200 ? because the FX was developped on 320x200 */
+ max *= info->screen.height / 200.0f;
+
+ if (info->sound.timeSinceLastBigGoom < 1) {
+ radius *= 1.5;
+ max *= 2;
+ }
+ for (i = 0; i < max; ++i)
+ addABomb (data, mx, my, radius, vage, gravity, info);
+}
+
+
+/**
+ * Main methode of the FX.
+ */
+static void
+fs_apply (VisualFX * _this, Pixel * src, Pixel * dest, PluginInfo * info)
+{
+
+ int i;
+ int col;
+ FSData *data = (FSData *) _this->fx_data;
+
+ /* Get the new parameters values */
+ data->min_age = 1.0f - (float) IVAL (data->min_age_p) / 100.0f;
+ data->max_age = 1.0f - (float) IVAL (data->max_age_p) / 100.0f;
+ FVAL (data->nbStars_p) = (float) data->nbStars / (float) data->maxStars;
+ data->nbStars_p.change_listener (&data->nbStars_p);
+ data->maxStars = IVAL (data->nbStars_limit_p);
+ data->fx_mode = IVAL (data->fx_mode_p);
+
+ /* look for events */
+ if (info->sound.timeSinceLastGoom < 1) {
+ fs_sound_event_occured (_this, info);
+ if (goom_irand (info->gRandom, 20) == 1) {
+ IVAL (data->fx_mode_p) = goom_irand (info->gRandom, (LAST_FX * 3));
+ data->fx_mode_p.change_listener (&data->fx_mode_p);
+ }
+ }
+
+ /* update particules */
+ for (i = 0; i < data->nbStars; ++i) {
+ updateStar (&data->stars[i]);
+
+ /* dead particule */
+ if (data->stars[i].age >= NCOL)
+ continue;
+
+ /* choose the color of the particule */
+ col = colval[(int) data->stars[i].age];
+
+ /* draws the particule */
+ info->methods.draw_line (dest, (int) data->stars[i].x,
+ (int) data->stars[i].y,
+ (int) (data->stars[i].x - data->stars[i].vx * 6),
+ (int) (data->stars[i].y - data->stars[i].vy * 6), col,
+ (int) info->screen.width, (int) info->screen.height);
+ info->methods.draw_line (dest, (int) data->stars[i].x,
+ (int) data->stars[i].y,
+ (int) (data->stars[i].x - data->stars[i].vx * 2),
+ (int) (data->stars[i].y - data->stars[i].vy * 2), col,
+ (int) info->screen.width, (int) info->screen.height);
+ }
+
+ /* look for dead particules */
+ for (i = 0; i < data->nbStars;) {
+
+ if ((data->stars[i].x > info->screen.width + 64)
+ || ((data->stars[i].vy >= 0)
+ && (data->stars[i].y - 16 * data->stars[i].vy >
+ info->screen.height))
+ || (data->stars[i].x < -64)
+ || (data->stars[i].age >= NCOL)) {
+ data->stars[i] = data->stars[data->nbStars - 1];
+ data->nbStars--;
+ } else
+ ++i;
+ }
+}
+
+VisualFX
+flying_star_create (void)
+{
+ VisualFX vfx = {
+ init:fs_init,
+ free:fs_free,
+ apply:fs_apply,
+ fx_data:0
+ };
+ return vfx;
+}
diff --git a/gst/goom/gfontlib.c b/gst/goom/gfontlib.c
new file mode 100644
index 00000000..52d3e545
--- /dev/null
+++ b/gst/goom/gfontlib.c
@@ -0,0 +1,260 @@
+#include "goom_config.h"
+#include "gfontrle.h"
+#include "gfontlib.h"
+#include <string.h>
+#include <stdlib.h>
+
+static Pixel ***font_chars;
+static int *font_width;
+static int *font_height;
+static Pixel ***small_font_chars;
+static int *small_font_width;
+static int *small_font_height;
+
+void
+gfont_load (void)
+{
+ unsigned char *gfont;
+ unsigned int i = 0, j = 0;
+ unsigned int nba = 0;
+ unsigned int current = 32;
+ int *font_pos;
+
+ /* decompress le rle */
+
+
+
+ gfont = malloc (the_font.width * the_font.height * the_font.bytes_per_pixel);
+ while (i < the_font.rle_size) {
+ unsigned char c = the_font.rle_pixel[i++];
+
+ if (c == 0) {
+ unsigned int nb = the_font.rle_pixel[i++];
+
+ while (nb--)
+ gfont[j++] = 0;
+ } else
+ gfont[j++] = c;
+ }
+
+ /* determiner les positions de chaque lettre. */
+
+ font_height = calloc (256, sizeof (int));
+ small_font_height = calloc (256, sizeof (int));
+ font_width = calloc (256, sizeof (int));
+ small_font_width = calloc (256, sizeof (int));
+ font_chars = calloc (256, sizeof (int **));
+ small_font_chars = calloc (256, sizeof (int **));
+ font_pos = calloc (256, sizeof (int));
+
+ for (i = 0; i < the_font.width; i++) {
+ unsigned char a = gfont[i * 4 + 3];
+
+ if (a)
+ nba++;
+ else
+ nba = 0;
+ if (nba == 2) {
+ font_width[current] = i - font_pos[current];
+ small_font_width[current] = font_width[current] / 2;
+ font_pos[++current] = i;
+ font_height[current] = the_font.height - 2;
+ small_font_height[current] = font_height[current] / 2;
+ }
+ }
+ font_pos[current] = 0;
+ font_height[current] = 0;
+ small_font_height[current] = 0;
+
+ /* charger les lettres et convertir au format de la machine */
+
+ for (i = 33; i < current; i++) {
+ int x;
+ int y;
+ font_chars[i] = malloc (font_height[i] * sizeof (int *));
+ small_font_chars[i] = malloc (font_height[i] * sizeof (int *) / 2);
+ for (y = 0; y < font_height[i]; y++) {
+ font_chars[i][y] = malloc (font_width[i] * sizeof (int));
+ for (x = 0; x < font_width[i]; x++) {
+ unsigned int r, g, b, a;
+
+ r = gfont[(y + 2) * (the_font.width * 4) + (x * 4 + font_pos[i] * 4)];
+ g = gfont[(y + 2) * (the_font.width * 4) + (x * 4 + font_pos[i] * 4 +
+ 1)];
+ b = gfont[(y + 2) * (the_font.width * 4) + (x * 4 + font_pos[i] * 4 +
+ 2)];
+ a = gfont[(y + 2) * (the_font.width * 4) + (x * 4 + font_pos[i] * 4 +
+ 3)];
+ font_chars[i][y][x].val =
+ (r << (ROUGE * 8)) | (g << (VERT * 8)) | (b << (BLEU *
+ 8)) | (a << (ALPHA * 8));
+ }
+ }
+ for (y = 0; y < font_height[i] / 2; y++) {
+ small_font_chars[i][y] = malloc (font_width[i] * sizeof (int) / 2);
+ for (x = 0; x < font_width[i] / 2; x++) {
+ unsigned int r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3, r4, g4, b4,
+ a4;
+ r1 = gfont[2 * (y + 1) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4)];
+ g1 = gfont[2 * (y + 1) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 1)];
+ b1 = gfont[2 * (y + 1) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 2)];
+ a1 = gfont[2 * (y + 1) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 3)];
+ r2 = gfont[(2 * y + 3) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 4)];
+ g2 = gfont[(2 * y + 3) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 5)];
+ b2 = gfont[(2 * y + 3) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 6)];
+ a2 = gfont[(2 * y + 3) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 7)];
+ r3 = gfont[(2 * y + 3) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4)];
+ g3 = gfont[(2 * y + 3) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 1)];
+ b3 = gfont[(2 * y + 3) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 2)];
+ a3 = gfont[(2 * y + 3) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 3)];
+ r4 = gfont[2 * (y + 1) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 4)];
+ g4 = gfont[2 * (y + 1) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 5)];
+ b4 = gfont[2 * (y + 1) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 6)];
+ a4 = gfont[2 * (y + 1) * (the_font.width * 4) + (x * 8 +
+ font_pos[i] * 4 + 7)];
+ small_font_chars[i][y][x].val =
+ (((r1 + r2 + r3 + r4) >> 2) << (ROUGE * 8)) | (((g1 + g2 + g3 +
+ g4) >> 2) << (VERT * 8)) | (((b1 + b2 + b3 +
+ b4) >> 2) << (BLEU * 8)) | (((a1 + a2 + a3 +
+ a4) >> 2) << (ALPHA * 8));
+ }
+ }
+ }
+
+ /* definir les lettres restantes */
+
+ for (i = 0; i < 256; i++) {
+ if (font_chars[i] == 0) {
+ font_chars[i] = font_chars[42];
+ small_font_chars[i] = small_font_chars[42];
+ font_width[i] = font_width[42];
+ font_pos[i] = font_pos[42];
+ font_height[i] = font_height[42];
+ small_font_width[i] = small_font_width[42];
+ small_font_height[i] = small_font_height[42];
+ }
+ }
+
+ font_width[32] = (the_font.height / 2) - 1;
+ small_font_width[32] = font_width[32] / 2;
+ font_chars[32] = 0;
+ small_font_chars[32] = 0;
+}
+
+void
+goom_draw_text (Pixel * buf, int resolx, int resoly,
+ int x, int y, const char *str, float charspace, int center)
+{
+ float fx = (float) x;
+ int fin = 0;
+
+ Pixel ***cur_font_chars;
+ int *cur_font_width;
+ int *cur_font_height;
+
+ if (resolx > 320) {
+ /* printf("use big\n"); */
+ cur_font_chars = font_chars;
+ cur_font_width = font_width;
+ cur_font_height = font_height;
+ } else {
+ /* printf ("use small\n"); */
+ cur_font_chars = small_font_chars;
+ cur_font_width = small_font_width;
+ cur_font_height = small_font_height;
+ }
+
+ if (cur_font_chars == NULL)
+ return;
+
+ if (center) {
+ unsigned char *tmp = (unsigned char *) str;
+ float lg = -charspace;
+
+ while (*tmp != '\0')
+ lg += cur_font_width[*(tmp++)] + charspace;
+
+ fx -= lg / 2;
+ }
+
+ while (!fin) {
+ unsigned char c = *str;
+
+ x = (int) fx;
+
+ if (c == '\0')
+ fin = 1;
+ else if (cur_font_chars[c] == 0) {
+ fx += cur_font_width[c] + charspace;
+ } else {
+ int xx, yy;
+ int xmin = x;
+ int xmax = x + cur_font_width[c];
+ int ymin = y - cur_font_height[c];
+ int ymax = y;
+
+ yy = ymin;
+
+ if (xmin < 0)
+ xmin = 0;
+
+ if (xmin >= resolx - 1)
+ return;
+
+ if (xmax >= (int) resolx)
+ xmax = resolx - 1;
+
+ if (yy < 0)
+ yy = 0;
+
+ if (yy <= (int) resoly - 1) {
+ if (ymax >= (int) resoly - 1)
+ ymax = resoly - 1;
+
+ for (; yy < ymax; yy++)
+ for (xx = xmin; xx < xmax; xx++) {
+ Pixel color = cur_font_chars[c][yy - ymin][xx - x];
+ Pixel transparency;
+
+ transparency.val = color.val & A_CHANNEL;
+ if (transparency.val) {
+ if (transparency.val == A_CHANNEL)
+ buf[yy * resolx + xx] = color;
+ else {
+ Pixel back = buf[yy * resolx + xx];
+ unsigned int a1 = color.channels.a;
+ unsigned int a2 = 255 - a1;
+
+ buf[yy * resolx + xx].channels.r =
+ (unsigned char) ((((unsigned int) color.channels.r * a1) +
+ ((unsigned int) back.channels.r * a2)) >> 8);
+ buf[yy * resolx + xx].channels.g =
+ (unsigned char) ((((unsigned int) color.channels.g * a1) +
+ ((unsigned int) back.channels.g * a2)) >> 8);
+ buf[yy * resolx + xx].channels.b =
+ (unsigned char) ((((unsigned int) color.channels.b * a1) +
+ ((unsigned int) back.channels.b * a2)) >> 8);
+ }
+ }
+ }
+ }
+ fx += cur_font_width[c] + charspace;
+ }
+ str++;
+ }
+}
diff --git a/gst/goom/gfontlib.h b/gst/goom/gfontlib.h
new file mode 100644
index 00000000..0520b7da
--- /dev/null
+++ b/gst/goom/gfontlib.h
@@ -0,0 +1,10 @@
+#ifndef _GFONTLIB_H
+#define _GFONTLIB_H
+
+#include "goom_graphic.h"
+
+void gfont_load (void);
+void goom_draw_text (Pixel * buf,int resolx,int resoly, int x, int y,
+ const char *str, float chspace, int center);
+
+#endif
diff --git a/gst/goom/gfontrle.c b/gst/goom/gfontrle.c
new file mode 100644
index 00000000..e57b494d
--- /dev/null
+++ b/gst/goom/gfontrle.c
@@ -0,0 +1,3080 @@
+/* RGBA C-Source image dump (with zRLE compression) */
+
+const struct
+{
+ unsigned int width;
+ unsigned int height;
+ unsigned int bytes_per_pixel;
+ unsigned int rle_size;
+ unsigned char rle_pixel[49725];
+} the_font = {
+ 1277, 21, 4, 49725, {
+121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255,
+ 0, 8, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 36, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 52, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 52, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 52, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 12, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 20, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 20, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 52, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 12, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 36, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 12, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 36, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 12, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 12, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 36, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 36, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 36, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 36, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 36, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 12, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 36, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 52, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 52, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 20, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 36, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 20, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 36, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 36, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 12, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 28, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 12, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 28, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 12, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 52, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 28, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 52, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 44, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 0, 44, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17,
+ 164, 255, 121, 17, 164, 255, 0, 28, 121, 17, 164, 0, 1, 121, 17,
+ 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 12, 121, 17, 164,
+ 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0,
+ 28, 121, 17, 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 121,
+ 17, 164, 255, 121, 17, 164, 255, 121, 17, 164, 255, 0, 56, 121, 17,
+ 164, 0, 1, 121, 17, 164, 255, 121, 17, 164, 255, 13, 4, 17, 0, 1,
+ 13, 4, 17, 0, 1, 13, 4, 17, 0, 1, 16, 5, 22, 0, 13, 16, 5, 22, 0, 1,
+ 14, 4, 19, 0, 1, 16, 5, 22, 0, 41, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1,
+ 16, 5, 22, 0, 57, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0,
+ 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 57, 16, 5, 22,
+ 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 57, 16, 5, 22, 0, 1, 14, 4, 19,
+ 0, 1, 16, 5, 22, 0, 17, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22,
+ 0, 25, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 25, 16, 5,
+ 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 57, 16, 5, 22, 0, 1, 14, 4,
+ 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5,
+ 22, 0, 17, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 41, 16,
+ 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 17, 16, 5, 22, 0, 1, 14,
+ 4, 19, 0, 1, 16, 5, 22, 0, 41, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16,
+ 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49,
+ 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1,
+ 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1,
+ 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0,
+ 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22,
+ 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19,
+ 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22,
+ 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 17, 16, 5,
+ 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 17, 16, 5, 22, 0, 1, 14, 4,
+ 19, 0, 1, 16, 5, 22, 0, 41, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5,
+ 22, 0, 41, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 41, 16,
+ 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14,
+ 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16,
+ 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49,
+ 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1,
+ 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1,
+ 16, 5, 22, 0, 41, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0,
+ 41, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22,
+ 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19,
+ 0, 1, 16, 5, 22, 0, 17, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22,
+ 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5,
+ 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 41, 16, 5, 22, 0, 1, 14, 4,
+ 19, 0, 1, 16, 5, 22, 0, 57, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5,
+ 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16,
+ 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14,
+ 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16,
+ 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49,
+ 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1,
+ 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1,
+ 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0,
+ 57, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22,
+ 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19,
+ 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22,
+ 0, 25, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 41, 16, 5,
+ 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 25, 16, 5, 22, 0, 1, 14, 4,
+ 19, 0, 1, 16, 5, 22, 0, 41, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5,
+ 22, 0, 41, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 17, 16,
+ 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14,
+ 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16,
+ 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49,
+ 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1,
+ 14, 4, 19, 0, 1, 16, 5, 22, 0, 33, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1,
+ 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0,
+ 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 17, 16, 5, 22,
+ 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 33, 16, 5, 22, 0, 1, 14, 4, 19,
+ 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22,
+ 0, 17, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 57, 16, 5,
+ 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4,
+ 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5,
+ 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16,
+ 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14,
+ 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16,
+ 5, 22, 0, 33, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49,
+ 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22, 0, 1,
+ 14, 4, 19, 0, 1, 16, 5, 22, 0, 57, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1,
+ 16, 5, 22, 0, 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0,
+ 49, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 49, 16, 5, 22,
+ 0, 1, 14, 4, 19, 0, 1, 16, 5, 22, 0, 33, 16, 5, 22, 0, 1, 14, 4, 19,
+ 0, 1, 16, 5, 22, 0, 17, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 16, 5, 22,
+ 0, 33, 16, 5, 22, 0, 1, 14, 4, 19, 0, 1, 13, 4, 17, 0, 1, 13, 4, 17,
+ 0, 1, 16, 5, 22, 0, 61, 16, 5, 22, 0, 1, 14, 4, 19, 0, 255, 0, 255,
+ 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
+ 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+ 0, 255, 0, 25, 8, 6, 3, 57, 10, 8, 5, 85, 9, 7, 4, 76, 0, 12, 8, 6,
+ 3, 54, 9, 8, 4, 96, 9, 7, 4, 85, 0, 12, 8, 6, 3, 57, 9, 8, 4, 96, 9,
+ 7, 4, 85, 0, 24, 8, 6, 3, 57, 11, 8, 4, 85, 9, 7, 4, 79, 0, 12, 8,
+ 6, 3, 51, 10, 8, 5, 85, 8, 6, 3, 85, 0, 40, 8, 6, 3, 57, 11, 8, 4,
+ 85, 8, 6, 3, 85, 0, 32, 8, 6, 3, 57, 10, 8, 5, 85, 9, 7, 4, 85, 0,
+ 28, 5, 4, 2, 14, 8, 6, 3, 85, 9, 7, 4, 85, 0, 24, 8, 6, 3, 74, 9, 7,
+ 4, 113, 8, 6, 3, 167, 8, 6, 3, 139, 9, 7, 4, 85, 5, 4, 2, 14, 0, 36,
+ 8, 6, 3, 57, 9, 8, 4, 110, 9, 7, 4, 85, 0, 24, 5, 4, 2, 20, 9, 7, 4,
+ 85, 9, 8, 4, 85, 0, 16, 9, 8, 4, 57, 9, 8, 4, 85, 6, 5, 3, 48, 0,
+ 255, 0, 29, 5, 4, 2, 17, 8, 6, 3, 85, 9, 7, 4, 82, 0, 20, 5, 4, 2,
+ 3, 8, 6, 3, 85, 9, 7, 4, 93, 8, 6, 3, 153, 8, 6, 3, 161, 8, 6, 3,
+ 110, 9, 8, 4, 85, 8, 6, 3, 85, 6, 5, 3, 31, 0, 32, 5, 4, 2, 3, 8, 6,
+ 3, 85, 10, 8, 5, 85, 10, 7, 5, 85, 0, 36, 5, 4, 2, 57, 8, 6, 3, 85,
+ 9, 7, 4, 91, 8, 6, 3, 153, 8, 6, 3, 170, 8, 6, 3, 164, 8, 6, 3, 108,
+ 8, 6, 3, 85, 6, 5, 3, 71, 0, 24, 5, 4, 2, 42, 8, 6, 3, 85, 9, 7, 4,
+ 91, 8, 6, 3, 153, 8, 6, 3, 170, 8, 6, 3, 164, 8, 6, 3, 108, 8, 6, 3,
+ 85, 6, 5, 3, 71, 0, 48, 5, 4, 2, 3, 8, 6, 3, 85, 9, 8, 4, 85, 9, 7,
+ 4, 74, 0, 16, 8, 6, 3, 42, 9, 7, 4, 85, 8, 6, 3, 85, 9, 7, 4, 85, 8,
+ 6, 3, 125, 8, 6, 3, 170, 7, 6, 4, 170, 9, 7, 4, 170, 12, 9, 7, 170,
+ 19, 14, 10, 170, 19, 13, 10, 142, 8, 6, 5, 28, 0, 16, 5, 4, 2, 51,
+ 8, 6, 3, 85, 9, 7, 4, 91, 8, 6, 3, 153, 8, 6, 3, 170, 8, 6, 3, 164,
+ 8, 6, 3, 108, 8, 6, 3, 85, 6, 5, 3, 71, 0, 20, 10, 8, 5, 57, 9, 7,
+ 4, 170, 8, 6, 3, 170, 8, 6, 3, 170, 8, 6, 3, 161, 8, 6, 3, 142, 9,
+ 7, 4, 96, 9, 7, 4, 85, 8, 6, 3, 85, 9, 7, 4, 85, 9, 7, 4, 74, 0, 20,
+ 5, 4, 2, 42, 8, 6, 3, 85, 9, 7, 4, 91, 8, 6, 3, 153, 8, 6, 3, 170,
+ 8, 6, 3, 164, 8, 6, 3, 108, 8, 6, 3, 85, 6, 5, 3, 76, 0, 24, 8, 6,
+ 5, 82, 10, 8, 7, 133, 12, 9, 7, 170, 15, 11, 8, 170, 15, 11, 8, 170,
+ 15, 11, 8, 170, 13, 10, 8, 170, 10, 8, 7, 161, 10, 8, 7, 85, 6, 5,
+ 5, 28, 0, 96, 8, 6, 3, 74, 9, 8, 4, 85, 8, 6, 3, 57, 0, 68, 7, 6, 4,
+ 28, 9, 7, 4, 85, 9, 7, 4, 85, 5, 4, 2, 17, 0, 40, 5, 4, 2, 42, 8, 6,
+ 3, 85, 9, 7, 4, 91, 8, 6, 3, 153, 8, 6, 3, 170, 8, 6, 3, 164, 8, 6,
+ 3, 108, 8, 6, 3, 85, 6, 5, 3, 85, 0, 24, 8, 6, 5, 85, 10, 8, 7, 133,
+ 12, 9, 7, 170, 15, 10, 8, 170, 15, 11, 8, 170, 15, 11, 8, 170, 13,
+ 10, 8, 170, 10, 8, 7, 150, 8, 6, 5, 62, 0, 24, 8, 6, 5, 82, 10, 8,
+ 7, 133, 12, 9, 7, 170, 15, 10, 8, 170, 14, 10, 7, 170, 9, 7, 4, 170,
+ 8, 6, 5, 147, 10, 8, 5, 85, 7, 6, 4, 85, 5, 4, 4, 3, 0, 16, 12, 9,
+ 7, 57, 11, 8, 6, 161, 9, 7, 6, 170, 10, 8, 7, 170, 13, 10, 8, 170,
+ 14, 10, 7, 170, 13, 10, 8, 170, 12, 9, 7, 170, 10, 8, 7, 156, 10, 8,
+ 7, 85, 6, 5, 5, 25, 0, 20, 6, 5, 3, 57, 8, 7, 5, 85, 9, 7, 4, 110,
+ 9, 7, 4, 170, 10, 8, 5, 170, 10, 8, 5, 170, 11, 8, 6, 170, 10, 8, 7,
+ 150, 10, 8, 7, 85, 6, 5, 5, 25, 0, 16, 15, 11, 8, 57, 11, 8, 6, 170,
+ 9, 7, 6, 170, 10, 8, 7, 170, 13, 10, 8, 170, 15, 11, 8, 170, 15, 11,
+ 8, 170, 13, 10, 8, 170, 10, 8, 7, 159, 10, 8, 7, 85, 6, 5, 5, 25, 0,
+ 16, 15, 11, 8, 59, 11, 9, 6, 170, 9, 7, 4, 125, 10, 8, 5, 85, 8, 6,
+ 3, 133, 8, 6, 3, 167, 8, 6, 3, 170, 8, 6, 3, 170, 9, 8, 4, 113, 0,
+ 16, 8, 6, 3, 42, 10, 8, 5, 85, 10, 7, 5, 85, 9, 7, 4, 125, 10, 8, 5,
+ 170, 12, 10, 7, 170, 14, 11, 7, 170, 19, 14, 10, 170, 19, 14, 10,
+ 142, 8, 6, 5, 28, 0, 16, 8, 6, 5, 82, 10, 8, 7, 133, 12, 9, 7, 170,
+ 15, 11, 8, 170, 15, 11, 8, 170, 15, 11, 8, 170, 13, 10, 8, 170, 10,
+ 8, 7, 161, 10, 8, 7, 85, 6, 5, 5, 25, 0, 16, 12, 10, 7, 74, 14, 10,
+ 7, 170, 12, 9, 7, 139, 7, 6, 4, 28, 0, 16, 10, 8, 7, 110, 14, 10, 7,
+ 170, 13, 10, 8, 125, 0, 16, 13, 10, 8, 71, 15, 11, 8, 170, 13, 10,
+ 8, 130, 5, 5, 4, 8, 0, 44, 11, 8, 6, 85, 9, 7, 4, 170, 10, 8, 5, 93,
+ 0, 16, 12, 9, 7, 57, 10, 8, 5, 167, 11, 8, 6, 110, 6, 5, 3, 8, 0,
+ 16, 11, 8, 6, 57, 10, 7, 5, 159, 11, 8, 6, 102, 0, 16, 8, 6, 3, 51,
+ 10, 8, 5, 85, 9, 7, 4, 85, 0, 40, 10, 7, 5, 57, 11, 9, 6, 85, 7, 6,
+ 4, 57, 0, 28, 7, 5, 4, 28, 10, 8, 5, 85, 11, 8, 6, 85, 0, 16, 8, 6,
+ 3, 48, 10, 8, 5, 85, 8, 6, 3, 85, 0, 20, 8, 6, 3, 57, 11, 8, 4, 85,
+ 9, 7, 4, 79, 0, 20, 5, 4, 2, 45, 8, 6, 3, 85, 9, 7, 4, 85, 9, 7, 4,
+ 88, 9, 7, 4, 108, 9, 8, 4, 93, 9, 7, 4, 85, 8, 6, 3, 85, 6, 5, 3,
+ 74, 0, 20, 8, 6, 3, 45, 9, 7, 4, 85, 8, 6, 3, 85, 9, 7, 4, 85, 8, 6,
+ 3, 125, 8, 6, 3, 170, 8, 6, 3, 164, 8, 6, 3, 108, 8, 6, 3, 85, 6, 5,
+ 3, 74, 0, 24, 6, 5, 3, 57, 8, 7, 5, 85, 10, 8, 5, 85, 9, 7, 4, 119,
+ 8, 6, 3, 142, 9, 7, 4, 130, 10, 8, 5, 91, 10, 7, 5, 85, 6, 5, 3, 85,
+ 0, 20, 9, 7, 4, 57, 10, 8, 5, 85, 10, 7, 5, 85, 10, 8, 5, 85, 8, 6,
+ 3, 144, 8, 6, 3, 170, 8, 6, 3, 164, 8, 6, 3, 108, 8, 6, 3, 85, 6, 5,
+ 3, 71, 0, 24, 5, 4, 2, 45, 8, 6, 3, 85, 9, 7, 4, 91, 8, 6, 3, 153,
+ 8, 6, 3, 170, 8, 6, 3, 164, 9, 7, 4, 105, 8, 6, 3, 85, 6, 5, 3, 74,
+ 0, 20, 11, 8, 4, 59, 9, 7, 4, 170, 8, 6, 3, 164, 9, 7, 4, 91, 8, 6,
+ 3, 85, 8, 6, 3, 85, 8, 6, 3, 85, 9, 7, 4, 85, 8, 6, 3, 142, 9, 6, 4,
+ 170, 9, 8, 4, 116, 0, 16, 8, 6, 3, 48, 10, 8, 5, 85, 9, 7, 4, 85, 0,
+ 20, 8, 6, 3, 57, 11, 8, 4, 85, 9, 7, 4, 76, 0, 16, 8, 6, 3, 48, 10,
+ 8, 5, 85, 9, 7, 4, 85, 0, 20, 8, 6, 3, 57, 11, 8, 4, 85, 9, 7, 4,
+ 76, 0, 16, 8, 6, 3, 48, 10, 8, 5, 85, 9, 7, 4, 85, 0, 28, 8, 6, 3,
+ 57, 11, 8, 4, 85, 9, 7, 4, 76, 0, 16, 8, 6, 3, 54, 9, 8, 4, 96, 9,
+ 7, 4, 85, 0, 20, 8, 6, 3, 57, 9, 8, 4, 96, 9, 7, 4, 85, 0, 16, 10,
+ 8, 5, 57, 10, 7, 5, 153, 10, 8, 5, 93, 0, 20, 10, 8, 7, 93, 14, 11,
+ 7, 170, 13, 10, 8, 136, 0, 16, 11, 8, 6, 91, 11, 8, 6, 170, 9, 7, 4,
+ 170, 9, 7, 4, 170, 8, 6, 5, 170, 8, 6, 3, 119, 9, 7, 4, 85, 8, 6, 3,
+ 85, 8, 6, 3, 85, 9, 7, 4, 85, 9, 7, 4, 76, 0, 16, 8, 6, 3, 42, 9, 7,
+ 4, 85, 8, 6, 3, 85, 8, 6, 3, 122, 9, 8, 4, 102, 0, 16, 8, 6, 3, 51,
+ 9, 7, 4, 85, 6, 5, 3, 45, 0, 40, 12, 8, 5, 57, 8, 6, 3, 156, 10, 7,
+ 5, 93, 11, 8, 6, 85, 11, 8, 6, 85, 0, 28, 6, 5, 5, 14, 13, 10, 8,
+ 85, 8, 7, 5, 45, 0, 80, 10, 8, 5, 57, 10, 7, 5, 156, 10, 8, 5, 96,
+ 0, 76, 9, 7, 4, 57, 10, 8, 5, 93, 10, 8, 5, 85, 0, 140, 10, 8, 7,
+ 110, 13, 10, 8, 170, 12, 9, 7, 133, 5, 5, 4, 6, 0, 84, 8, 6, 5, 79,
+ 10, 8, 7, 127, 13, 10, 8, 170, 16, 12, 9, 142, 8, 7, 5, 28, 0, 72,
+ 8, 6, 3, 57, 10, 8, 5, 85, 9, 6, 4, 85, 0, 48, 15, 11, 8, 113, 25,
+ 18, 12, 170, 20, 15, 11, 142, 8, 7, 5, 28, 0, 28, 15, 11, 8, 130,
+ 22, 16, 11, 170, 20, 15, 11, 142, 7, 6, 6, 23, 0, 12, 13, 10, 8, 68,
+ 12, 9, 7, 170, 11, 8, 6, 116, 6, 5, 3, 8, 0, 44, 12, 9, 7, 82, 15,
+ 10, 8, 170, 13, 10, 8, 130, 5, 5, 4, 8, 0, 255, 0, 197, 6, 5, 3, 57,
+ 8, 6, 3, 85, 0, 255, 0, 149, 5, 4, 2, 6, 8, 6, 3, 85, 8, 6, 3, 156,
+ 9, 8, 4, 113, 0, 16, 8, 6, 3, 48, 9, 8, 4, 91, 9, 7, 4, 76, 0, 16,
+ 10, 8, 5, 57, 9, 6, 4, 170, 8, 6, 3, 99, 5, 4, 2, 34, 0, 36, 8, 6,
+ 3, 71, 9, 8, 4, 93, 9, 8, 4, 96, 8, 6, 3, 85, 6, 5, 3, 45, 0, 12, 8,
+ 6, 3, 76, 0, 44, 8, 6, 3, 57, 58, 31, 9, 255, 93, 50, 12, 255, 88,
+ 45, 11, 255, 12, 10, 5, 113, 0, 4, 7, 6, 4, 28, 54, 29, 9, 255, 93,
+ 46, 12, 255, 88, 45, 11, 255, 12, 9, 5, 122, 0, 4, 7, 5, 4, 37, 54,
+ 29, 9, 255, 93, 46, 12, 255, 88, 45, 11, 255, 14, 10, 5, 142, 0, 16,
+ 8, 6, 3, 85, 58, 31, 9, 255, 93, 50, 12, 255, 88, 44, 11, 255, 9, 7,
+ 4, 170, 0, 4, 5, 4, 2, 85, 52, 28, 9, 255, 93, 48, 12, 255, 88, 44,
+ 11, 255, 12, 10, 5, 170, 0, 32, 7, 6, 4, 85, 58, 31, 9, 255, 93, 50,
+ 12, 255, 88, 45, 11, 255, 12, 9, 5, 170, 0, 24, 8, 6, 3, 57, 58, 31,
+ 9, 255, 93, 50, 12, 255, 88, 45, 11, 255, 14, 10, 5, 142, 0, 20, 6,
+ 5, 3, 28, 19, 12, 6, 227, 76, 37, 11, 255, 88, 45, 11, 255, 14, 10,
+ 5, 139, 0, 16, 9, 8, 4, 170, 69, 35, 10, 255, 92, 47, 11, 255, 92,
+ 47, 11, 255, 88, 45, 11, 255, 88, 45, 11, 255, 16, 11, 5, 227, 7, 5,
+ 4, 28, 0, 28, 8, 6, 3, 57, 58, 31, 9, 255, 93, 46, 12, 255, 88, 45,
+ 11, 255, 14, 10, 5, 142, 0, 16, 6, 5, 3, 28, 19, 12, 6, 227, 82, 39,
+ 11, 255, 92, 47, 11, 255, 14, 10, 5, 105, 0, 8, 7, 5, 4, 20, 54, 29,
+ 9, 255, 100, 50, 13, 255, 30, 19, 7, 255, 8, 6, 3, 85, 0, 255, 0,
+ 21, 6, 5, 3, 28, 19, 12, 6, 227, 76, 37, 11, 255, 88, 45, 11, 255,
+ 14, 10, 5, 130, 0, 12, 7, 6, 4, 65, 17, 11, 6, 227, 71, 37, 10, 255,
+ 88, 45, 11, 255, 92, 47, 11, 255, 92, 47, 11, 255, 88, 45, 11, 255,
+ 88, 44, 11, 255, 88, 44, 11, 255, 25, 16, 6, 255, 8, 6, 3, 142, 0,
+ 24, 7, 5, 4, 85, 17, 12, 6, 229, 77, 39, 12, 255, 107, 51, 14, 255,
+ 113, 55, 16, 255, 20, 14, 9, 178, 0, 28, 14, 11, 7, 170, 29, 18, 8,
+ 255, 74, 39, 11, 255, 88, 45, 11, 255, 88, 45, 11, 255, 92, 47, 11,
+ 255, 92, 47, 11, 255, 88, 45, 11, 255, 88, 44, 11, 255, 41, 23, 8,
+ 255, 12, 9, 5, 227, 5, 5, 4, 23, 0, 12, 9, 7, 4, 170, 26, 17, 6,
+ 255, 74, 39, 11, 255, 88, 45, 11, 255, 88, 45, 11, 255, 92, 47, 11,
+ 255, 92, 47, 11, 255, 88, 45, 11, 255, 88, 44, 11, 255, 41, 24, 8,
+ 255, 12, 9, 5, 227, 6, 5, 3, 28, 0, 36, 6, 5, 3, 85, 16, 11, 5, 227,
+ 71, 37, 10, 255, 88, 45, 11, 255, 88, 44, 11, 255, 12, 10, 5, 113,
+ 0, 8, 8, 6, 3, 28, 54, 29, 9, 255, 92, 47, 11, 255, 88, 44, 11, 255,
+ 88, 45, 11, 255, 92, 46, 13, 255, 100, 52, 13, 255, 109, 53, 16,
+ 255, 121, 63, 20, 255, 158, 74, 23, 255, 180, 88, 27, 255, 183, 90,
+ 28, 255, 26, 17, 11, 142, 0, 12, 10, 7, 5, 170, 26, 17, 6, 255, 74,
+ 39, 11, 255, 88, 45, 11, 255, 92, 47, 11, 255, 92, 47, 11, 255, 92,
+ 47, 11, 255, 88, 45, 11, 255, 88, 45, 11, 255, 41, 24, 8, 255, 12,
+ 9, 5, 227, 6, 5, 3, 28, 0, 8, 7, 6, 4, 8, 61, 32, 10, 255, 102, 51,
+ 13, 255, 92, 46, 13, 255, 92, 46, 13, 255, 92, 46, 13, 255, 92, 46,
+ 13, 255, 92, 46, 13, 255, 90, 45, 11, 255, 84, 44, 11, 255, 88, 45,
+ 11, 255, 88, 44, 11, 255, 14, 10, 5, 119, 0, 12, 9, 7, 4, 153, 26,
+ 17, 6, 255, 74, 39, 11, 255, 88, 45, 11, 255, 92, 47, 11, 255, 92,
+ 47, 11, 255, 92, 47, 11, 255, 88, 45, 11, 255, 88, 44, 11, 255, 45,
+ 25, 8, 255, 13, 10, 6, 227, 7, 6, 4, 28, 0, 12, 17, 13, 10, 170, 64,
+ 39, 21, 255, 155, 78, 26, 255, 169, 83, 26, 255, 165, 80, 24, 255,
+ 161, 79, 24, 255, 145, 71, 22, 255, 136, 70, 21, 255, 134, 69, 21,
+ 255, 88, 50, 23, 255, 22, 17, 11, 232, 9, 8, 6, 31, 0, 84, 4, 4, 3,
+ 23, 12, 9, 5, 173, 71, 34, 10, 255, 92, 43, 13, 255, 33, 20, 8, 255,
+ 10, 8, 5, 57, 0, 64, 20, 14, 7, 227, 83, 42, 12, 255, 92, 46, 13,
+ 255, 19, 13, 6, 227, 6, 5, 3, 34, 0, 32, 10, 8, 5, 170, 26, 17, 6,
+ 255, 76, 37, 11, 255, 90, 46, 11, 255, 92, 46, 13, 255, 92, 46, 13,
+ 255, 90, 45, 11, 255, 90, 45, 11, 255, 88, 44, 11, 255, 46, 26, 9,
+ 255, 18, 13, 9, 227, 8, 7, 5, 28, 0, 12, 15, 12, 8, 170, 58, 35, 19,
+ 255, 134, 73, 23, 255, 153, 76, 24, 255, 142, 69, 21, 255, 131, 64,
+ 20, 255, 121, 59, 18, 255, 121, 59, 18, 255, 121, 62, 18, 255, 43,
+ 27, 12, 255, 11, 9, 6, 170, 0, 16, 17, 13, 10, 170, 64, 39, 21, 255,
+ 164, 85, 27, 255, 177, 86, 26, 255, 154, 75, 23, 255, 121, 62, 18,
+ 255, 115, 56, 16, 255, 119, 61, 18, 255, 123, 61, 20, 255, 80, 45,
+ 19, 255, 22, 16, 11, 227, 8, 7, 5, 28, 0, 8, 13, 10, 8, 57, 96, 48,
+ 19, 255, 165, 80, 24, 255, 159, 78, 24, 255, 159, 78, 24, 255, 165,
+ 80, 24, 255, 165, 80, 24, 255, 165, 80, 24, 255, 159, 78, 24, 255,
+ 164, 81, 25, 255, 91, 52, 24, 255, 22, 17, 11, 227, 8, 7, 5, 28, 0,
+ 12, 13, 10, 8, 170, 38, 24, 11, 255, 99, 47, 16, 255, 116, 59, 17,
+ 255, 126, 65, 21, 255, 142, 69, 21, 255, 153, 76, 24, 255, 157, 74,
+ 24, 255, 155, 76, 24, 255, 91, 52, 24, 255, 23, 18, 12, 227, 8, 7,
+ 5, 28, 0, 8, 13, 10, 8, 57, 104, 52, 21, 255, 171, 84, 26, 255, 155,
+ 76, 24, 255, 164, 81, 25, 255, 173, 81, 26, 255, 180, 88, 27, 255,
+ 180, 88, 27, 255, 177, 86, 26, 255, 169, 80, 26, 255, 92, 55, 25,
+ 255, 22, 17, 11, 227, 8, 7, 5, 28, 0, 8, 13, 10, 8, 57, 114, 63, 25,
+ 255, 177, 86, 26, 255, 114, 56, 17, 255, 92, 46, 13, 255, 92, 47,
+ 11, 255, 93, 46, 12, 255, 92, 46, 13, 255, 96, 48, 13, 255, 92, 46,
+ 13, 255, 18, 12, 5, 91, 0, 8, 8, 6, 3, 40, 55, 29, 10, 255, 108, 50,
+ 15, 255, 114, 56, 17, 255, 130, 67, 21, 255, 153, 76, 24, 255, 161,
+ 82, 24, 255, 171, 84, 26, 255, 179, 84, 26, 255, 179, 84, 26, 255,
+ 25, 17, 10, 142, 0, 12, 15, 12, 8, 170, 64, 39, 21, 255, 162, 84,
+ 27, 255, 179, 88, 28, 255, 183, 90, 28, 255, 181, 89, 28, 255, 181,
+ 89, 28, 255, 172, 88, 27, 255, 156, 77, 25, 255, 88, 50, 23, 255,
+ 22, 17, 11, 227, 8, 7, 5, 28, 0, 8, 13, 9, 6, 57, 96, 48, 19, 255,
+ 153, 71, 22, 255, 134, 69, 21, 255, 20, 14, 9, 193, 0, 12, 11, 8, 6,
+ 113, 124, 62, 25, 255, 185, 91, 28, 255, 169, 80, 26, 255, 22, 15,
+ 9, 142, 0, 8, 11, 8, 6, 57, 111, 61, 24, 255, 184, 90, 27, 255, 177,
+ 86, 26, 255, 23, 16, 10, 173, 0, 40, 11, 8, 6, 113, 114, 59, 23,
+ 255, 144, 73, 21, 255, 126, 63, 21, 255, 20, 14, 9, 142, 0, 8, 11,
+ 9, 6, 57, 97, 51, 20, 255, 152, 71, 23, 255, 134, 69, 21, 255, 20,
+ 14, 9, 187, 0, 12, 12, 9, 7, 96, 97, 48, 18, 255, 140, 71, 21, 255,
+ 138, 71, 21, 255, 20, 15, 9, 142, 0, 8, 8, 6, 3, 40, 52, 28, 9, 255,
+ 93, 50, 12, 255, 88, 45, 11, 255, 14, 10, 5, 142, 0, 32, 13, 10, 8,
+ 82, 91, 48, 16, 255, 132, 71, 21, 255, 63, 36, 18, 255, 10, 8, 7,
+ 136, 0, 20, 7, 6, 6, 62, 31, 21, 12, 244, 124, 66, 23, 255, 134, 69,
+ 21, 255, 20, 15, 9, 142, 0, 8, 8, 6, 3, 28, 54, 29, 9, 255, 93, 46,
+ 12, 255, 80, 39, 11, 255, 14, 10, 5, 142, 0, 12, 8, 6, 3, 57, 58,
+ 31, 9, 255, 93, 50, 12, 255, 88, 44, 11, 255, 14, 10, 5, 116, 0, 12,
+ 9, 7, 4, 153, 26, 17, 6, 255, 74, 39, 11, 255, 88, 45, 11, 255, 88,
+ 45, 11, 255, 88, 45, 11, 255, 88, 45, 11, 255, 88, 44, 11, 255, 88,
+ 44, 11, 255, 41, 23, 8, 255, 12, 9, 5, 227, 5, 4, 4, 17, 0, 8, 8, 6,
+ 3, 34, 54, 29, 9, 255, 92, 43, 11, 255, 88, 44, 11, 255, 88, 45, 11,
+ 255, 92, 43, 11, 255, 92, 47, 11, 255, 92, 47, 11, 255, 88, 45, 11,
+ 255, 88, 44, 11, 255, 45, 25, 8, 255, 12, 10, 5, 227, 6, 5, 3, 28,
+ 0, 12, 13, 10, 6, 170, 40, 24, 11, 255, 97, 48, 16, 255, 113, 55,
+ 16, 255, 115, 56, 16, 255, 116, 57, 17, 255, 116, 57, 17, 255, 113,
+ 55, 16, 255, 113, 55, 16, 255, 60, 33, 13, 255, 18, 14, 9, 227, 8,
+ 6, 5, 28, 0, 8, 12, 9, 7, 57, 77, 38, 14, 255, 118, 57, 17, 255,
+ 116, 59, 17, 255, 118, 60, 17, 255, 109, 53, 16, 255, 98, 47, 13,
+ 255, 92, 47, 11, 255, 88, 45, 11, 255, 88, 44, 11, 255, 41, 23, 8,
+ 255, 12, 9, 5, 227, 6, 5, 3, 28, 0, 12, 10, 8, 5, 170, 28, 18, 7,
+ 255, 76, 37, 11, 255, 90, 45, 11, 255, 92, 46, 13, 255, 94, 45, 13,
+ 255, 94, 45, 13, 255, 92, 46, 13, 255, 92, 46, 13, 255, 46, 26, 9,
+ 255, 13, 10, 6, 227, 6, 5, 5, 28, 0, 8, 7, 6, 4, 8, 61, 32, 10, 255,
+ 100, 50, 13, 255, 92, 46, 13, 255, 92, 46, 13, 255, 92, 46, 13, 255,
+ 92, 46, 13, 255, 92, 46, 13, 255, 92, 46, 13, 255, 94, 47, 13, 255,
+ 98, 49, 13, 255, 94, 47, 13, 255, 18, 12, 5, 93, 0, 8, 8, 6, 3, 42,
+ 60, 32, 9, 255, 96, 48, 13, 255, 88, 45, 11, 255, 14, 10, 5, 142, 0,
+ 12, 8, 6, 3, 57, 58, 31, 9, 255, 93, 50, 12, 255, 88, 44, 11, 255,
+ 12, 10, 5, 113, 0, 8, 8, 6, 3, 28, 54, 29, 9, 255, 93, 50, 12, 255,
+ 88, 44, 11, 255, 14, 10, 5, 142, 0, 12, 8, 6, 3, 57, 58, 31, 9, 255,
+ 93, 50, 12, 255, 88, 44, 11, 255, 12, 10, 5, 113, 0, 8, 8, 6, 3, 28,
+ 54, 29, 9, 255, 93, 50, 12, 255, 88, 44, 11, 255, 14, 10, 5, 142, 0,
+ 20, 8, 6, 3, 57, 58, 31, 9, 255, 93, 50, 12, 255, 88, 44, 11, 255,
+ 12, 10, 5, 113, 0, 8, 7, 6, 4, 28, 54, 29, 9, 255, 93, 50, 12, 255,
+ 88, 45, 11, 255, 14, 10, 5, 142, 0, 12, 8, 7, 3, 57, 60, 31, 9, 255,
+ 96, 48, 13, 255, 92, 46, 13, 255, 14, 10, 5, 127, 0, 8, 10, 8, 5,
+ 57, 82, 42, 15, 255, 135, 66, 20, 255, 121, 60, 20, 255, 20, 15, 9,
+ 176, 0, 12, 11, 9, 6, 108, 107, 56, 22, 255, 172, 84, 25, 255, 158,
+ 74, 23, 255, 22, 15, 9, 142, 0, 8, 11, 8, 6, 54, 98, 51, 19, 255,
+ 142, 72, 21, 255, 136, 70, 21, 255, 138, 71, 21, 255, 121, 59, 18,
+ 255, 100, 52, 13, 255, 90, 46, 11, 255, 88, 44, 11, 255, 88, 44, 11,
+ 255, 88, 44, 11, 255, 88, 45, 11, 255, 12, 10, 5, 113, 0, 8, 8, 6,
+ 3, 28, 54, 29, 9, 255, 92, 47, 11, 255, 88, 44, 11, 255, 92, 47, 11,
+ 255, 92, 47, 11, 255, 18, 12, 5, 85, 0, 8, 7, 6, 4, 45, 54, 30, 9,
+ 255, 94, 47, 13, 255, 31, 20, 8, 255, 9, 7, 4, 85, 0, 32, 8, 6, 3,
+ 48, 65, 33, 10, 255, 114, 55, 15, 255, 119, 58, 18, 255, 126, 63,
+ 21, 255, 128, 66, 21, 255, 22, 15, 9, 164, 0, 20, 5, 5, 4, 28, 19,
+ 14, 10, 227, 141, 72, 26, 255, 43, 27, 16, 255, 7, 6, 6, 85, 0, 72,
+ 14, 10, 7, 71, 96, 49, 17, 255, 138, 71, 21, 255, 130, 67, 21, 255,
+ 22, 15, 9, 164, 0, 68, 12, 9, 7, 76, 77, 39, 14, 255, 118, 57, 17,
+ 255, 109, 53, 16, 255, 22, 15, 9, 153, 0, 132, 11, 8, 6, 96, 103,
+ 53, 20, 255, 144, 73, 21, 255, 121, 60, 20, 255, 24, 16, 9, 153, 0,
+ 80, 15, 12, 8, 184, 61, 36, 20, 255, 141, 68, 24, 255, 168, 82, 25,
+ 255, 171, 84, 26, 255, 26, 18, 11, 159, 0, 68, 9, 7, 4, 57, 60, 32,
+ 9, 255, 96, 48, 13, 255, 92, 46, 13, 255, 19, 12, 6, 142, 0, 40, 14,
+ 10, 7, 76, 129, 67, 26, 255, 190, 97, 29, 255, 180, 88, 27, 255, 26,
+ 17, 11, 161, 0, 24, 14, 10, 7, 85, 129, 67, 26, 255, 190, 97, 29,
+ 255, 180, 88, 27, 255, 25, 17, 10, 125, 0, 8, 11, 8, 6, 57, 109, 60,
+ 24, 255, 175, 86, 26, 255, 142, 73, 23, 255, 20, 14, 9, 187, 0, 40,
+ 12, 9, 7, 93, 121, 65, 24, 255, 183, 89, 26, 255, 168, 82, 25, 255,
+ 21, 15, 10, 178, 0, 255, 0, 193, 10, 8, 5, 170, 39, 23, 8, 255, 78,
+ 41, 11, 255, 16, 11, 5, 142, 0, 255, 0, 141, 6, 5, 3, 85, 16, 11, 5,
+ 227, 71, 37, 10, 255, 92, 47, 11, 255, 92, 47, 11, 255, 18, 12, 5,
+ 85, 0, 8, 8, 6, 3, 28, 54, 29, 9, 255, 93, 46, 12, 255, 88, 45, 11,
+ 255, 12, 10, 5, 113, 0, 12, 58, 31, 9, 255, 93, 50, 12, 255, 88, 45,
+ 11, 255, 25, 17, 6, 255, 8, 6, 3, 142, 0, 24, 4, 4, 3, 25, 10, 8, 5,
+ 173, 65, 33, 10, 255, 92, 46, 13, 255, 92, 46, 13, 255, 67, 34, 10,
+ 255, 27, 18, 8, 255, 9, 7, 4, 156, 3, 3, 2, 85, 10, 8, 5, 184, 69,
+ 35, 10, 255, 19, 13, 6, 147, 0, 40, 9, 7, 4, 113, 112, 55, 13, 255,
+ 141, 69, 16, 255, 141, 75, 16, 255, 18, 13, 5, 170, 0, 4, 8, 6, 3,
+ 85, 110, 54, 13, 255, 143, 76, 16, 255, 139, 68, 16, 255, 19, 13, 6,
+ 170, 0, 4, 8, 6, 3, 85, 110, 54, 13, 255, 143, 76, 16, 255, 141, 72,
+ 16, 255, 23, 15, 6, 170, 0, 12, 10, 9, 5, 110, 35, 21, 8, 255, 129,
+ 63, 14, 255, 141, 69, 16, 255, 139, 68, 16, 255, 52, 27, 9, 255, 9,
+ 7, 4, 255, 27, 17, 8, 255, 135, 66, 16, 255, 154, 75, 17, 255, 155,
+ 79, 18, 255, 91, 50, 16, 255, 20, 15, 9, 207, 10, 9, 7, 28, 0, 16,
+ 5, 4, 4, 20, 8, 6, 3, 127, 31, 20, 8, 255, 130, 66, 15, 255, 143,
+ 76, 16, 255, 143, 76, 16, 255, 67, 34, 10, 255, 10, 8, 5, 215, 10,
+ 8, 5, 170, 13, 10, 6, 142, 7, 5, 4, 23, 0, 8, 12, 9, 5, 85, 115, 59,
+ 14, 255, 149, 72, 16, 255, 143, 76, 16, 255, 18, 12, 5, 235, 0, 16,
+ 7, 6, 4, 28, 14, 10, 5, 227, 92, 46, 13, 255, 143, 73, 16, 255, 143,
+ 70, 16, 255, 18, 13, 5, 170, 0, 12, 14, 10, 5, 170, 53, 28, 10, 255,
+ 114, 56, 13, 255, 56, 29, 9, 255, 16, 11, 5, 255, 34, 20, 7, 255,
+ 112, 55, 13, 255, 87, 42, 12, 255, 19, 13, 6, 235, 8, 7, 5, 40, 0,
+ 24, 10, 8, 5, 85, 114, 56, 13, 255, 143, 70, 16, 255, 141, 72, 16,
+ 255, 23, 15, 6, 170, 0, 12, 7, 6, 4, 28, 14, 10, 5, 227, 90, 44, 13,
+ 255, 112, 57, 13, 255, 47, 26, 8, 255, 11, 8, 4, 57, 0, 12, 25, 16,
+ 6, 227, 96, 48, 13, 255, 112, 57, 13, 255, 26, 16, 7, 255, 8, 6, 5,
+ 85, 0, 24, 13, 10, 6, 85, 8, 7, 5, 57, 0, 20, 6, 5, 3, 28, 15, 11,
+ 6, 85, 9, 7, 4, 28, 0, 36, 9, 7, 4, 105, 10, 8, 5, 170, 10, 8, 5,
+ 130, 6, 5, 3, 23, 0, 156, 8, 6, 3, 136, 77, 39, 12, 255, 143, 73,
+ 16, 255, 139, 74, 16, 255, 18, 12, 5, 170, 0, 12, 21, 14, 6, 227,
+ 112, 57, 13, 255, 141, 69, 16, 255, 80, 40, 11, 255, 16, 11, 5, 255,
+ 14, 10, 5, 227, 18, 13, 5, 255, 72, 35, 11, 255, 136, 69, 15, 255,
+ 130, 66, 15, 255, 46, 26, 9, 255, 8, 6, 3, 105, 0, 16, 8, 7, 5, 57,
+ 42, 27, 13, 255, 150, 79, 21, 255, 184, 94, 21, 255, 195, 99, 22,
+ 255, 199, 106, 24, 255, 26, 18, 11, 255, 0, 24, 10, 8, 7, 99, 83,
+ 45, 18, 255, 144, 74, 17, 255, 143, 70, 16, 255, 94, 47, 13, 255,
+ 18, 13, 5, 255, 16, 11, 5, 173, 14, 10, 5, 227, 52, 27, 9, 255, 132,
+ 67, 15, 255, 139, 68, 16, 255, 75, 39, 12, 255, 10, 7, 5, 116, 0, 8,
+ 6, 5, 3, 57, 52, 27, 9, 255, 137, 73, 16, 255, 143, 76, 16, 255, 94,
+ 47, 13, 255, 18, 13, 5, 255, 16, 11, 5, 173, 14, 10, 5, 227, 52, 27,
+ 9, 255, 132, 67, 15, 255, 139, 74, 16, 255, 75, 39, 12, 255, 10, 8,
+ 5, 142, 0, 32, 8, 6, 5, 85, 22, 15, 7, 255, 102, 51, 13, 255, 137,
+ 67, 16, 255, 140, 71, 15, 255, 141, 75, 16, 255, 20, 13, 5, 170, 0,
+ 8, 9, 6, 4, 85, 108, 55, 13, 255, 141, 69, 16, 255, 139, 74, 16,
+ 255, 74, 36, 11, 255, 18, 12, 7, 255, 20, 13, 7, 181, 22, 15, 9,
+ 207, 20, 13, 9, 238, 18, 13, 9, 252, 23, 16, 10, 255, 31, 21, 12,
+ 218, 14, 11, 7, 42, 0, 8, 7, 6, 4, 57, 40, 22, 9, 255, 130, 66, 15,
+ 255, 141, 75, 16, 255, 84, 42, 11, 255, 18, 12, 5, 255, 16, 12, 5,
+ 181, 14, 10, 5, 241, 69, 35, 10, 255, 140, 69, 17, 255, 154, 78, 17,
+ 255, 117, 60, 18, 255, 17, 13, 8, 142, 0, 12, 21, 14, 8, 190, 28,
+ 18, 9, 255, 23, 15, 8, 255, 21, 14, 8, 255, 21, 14, 8, 255, 23, 15,
+ 8, 255, 38, 24, 11, 255, 98, 53, 17, 255, 151, 74, 18, 255, 150, 76,
+ 17, 255, 141, 75, 16, 255, 21, 15, 6, 170, 0, 8, 5, 4, 2, 28, 33,
+ 20, 8, 255, 130, 66, 15, 255, 141, 72, 16, 255, 84, 42, 11, 255, 18,
+ 12, 5, 255, 18, 12, 5, 176, 14, 10, 5, 235, 57, 29, 10, 255, 140,
+ 72, 17, 255, 165, 85, 20, 255, 121, 67, 24, 255, 14, 11, 7, 142, 0,
+ 8, 8, 6, 5, 57, 72, 46, 23, 255, 198, 113, 29, 255, 200, 102, 23,
+ 255, 131, 68, 22, 255, 33, 21, 12, 255, 17, 13, 8, 255, 21, 14, 8,
+ 255, 88, 47, 19, 255, 192, 99, 23, 255, 203, 113, 26, 255, 146, 87,
+ 29, 255, 13, 11, 8, 164, 0, 12, 10, 8, 5, 85, 13, 10, 6, 170, 11, 9,
+ 6, 142, 7, 6, 4, 28, 0, 12, 13, 10, 8, 113, 18, 14, 9, 170, 16, 13,
+ 9, 147, 10, 8, 7, 28, 0, 24, 10, 8, 7, 28, 20, 15, 11, 227, 104, 62,
+ 21, 255, 184, 94, 21, 255, 117, 62, 22, 255, 17, 12, 8, 227, 7, 5,
+ 4, 28, 0, 64, 11, 8, 6, 170, 67, 35, 16, 255, 164, 85, 21, 255, 115,
+ 58, 16, 255, 20, 14, 7, 252, 8, 6, 5, 85, 0, 24, 9, 7, 4, 82, 66,
+ 37, 13, 255, 145, 75, 18, 255, 154, 78, 17, 255, 115, 58, 16, 255,
+ 29, 18, 8, 255, 14, 10, 7, 255, 16, 11, 7, 255, 65, 34, 12, 255,
+ 150, 74, 19, 255, 189, 97, 22, 255, 138, 79, 27, 255, 14, 12, 9,
+ 142, 0, 8, 7, 6, 6, 57, 55, 33, 16, 255, 158, 81, 19, 255, 162, 80,
+ 19, 255, 102, 53, 17, 255, 24, 15, 7, 255, 19, 12, 6, 170, 14, 10,
+ 5, 204, 46, 26, 9, 255, 137, 67, 16, 255, 139, 71, 16, 255, 49, 27,
+ 10, 255, 7, 6, 4, 105, 0, 8, 7, 6, 6, 62, 72, 46, 23, 255, 199, 115,
+ 32, 255, 205, 111, 28, 255, 155, 84, 26, 255, 41, 24, 14, 255, 18,
+ 13, 9, 255, 25, 16, 10, 255, 110, 61, 25, 255, 199, 100, 28, 255,
+ 205, 112, 30, 255, 146, 87, 29, 255, 13, 11, 8, 142, 0, 8, 10, 8, 7,
+ 147, 180, 87, 25, 255, 206, 111, 27, 255, 203, 105, 26, 255, 164,
+ 85, 27, 255, 40, 24, 15, 255, 20, 14, 9, 255, 26, 17, 11, 255, 121,
+ 64, 26, 255, 201, 101, 28, 255, 205, 112, 30, 255, 146, 87, 29, 255,
+ 14, 11, 7, 142, 0, 8, 8, 6, 5, 57, 71, 44, 22, 255, 192, 108, 25,
+ 255, 198, 101, 23, 255, 150, 78, 25, 255, 41, 24, 14, 255, 32, 21,
+ 13, 255, 74, 41, 21, 255, 184, 105, 27, 255, 202, 104, 25, 255, 202,
+ 118, 27, 255, 174, 102, 31, 255, 17, 14, 10, 142, 0, 8, 11, 9, 6,
+ 136, 182, 92, 25, 255, 206, 112, 29, 255, 205, 111, 28, 255, 166,
+ 79, 27, 255, 43, 25, 16, 255, 21, 15, 10, 255, 29, 19, 12, 255, 116,
+ 67, 27, 255, 202, 107, 31, 255, 206, 113, 31, 255, 146, 87, 29, 255,
+ 12, 10, 7, 142, 0, 8, 11, 8, 6, 144, 185, 93, 26, 255, 202, 103, 23,
+ 255, 157, 77, 18, 255, 83, 42, 12, 255, 19, 13, 6, 255, 13, 10, 6,
+ 255, 20, 13, 7, 255, 27, 17, 8, 255, 28, 18, 9, 227, 10, 8, 5, 45,
+ 0, 8, 11, 9, 6, 142, 139, 73, 20, 255, 198, 96, 21, 255, 199, 106,
+ 24, 255, 155, 78, 26, 255, 41, 25, 14, 255, 21, 15, 10, 255, 28, 18,
+ 11, 255, 38, 24, 15, 255, 40, 24, 15, 227, 14, 10, 7, 62, 0, 8, 8,
+ 7, 5, 57, 65, 41, 20, 255, 197, 108, 28, 255, 205, 111, 28, 255,
+ 170, 88, 27, 255, 43, 27, 16, 255, 19, 14, 10, 255, 29, 19, 12, 255,
+ 123, 66, 24, 255, 181, 84, 20, 255, 170, 87, 19, 255, 114, 60, 17,
+ 255, 11, 10, 6, 142, 0, 8, 11, 9, 6, 85, 119, 60, 15, 255, 154, 75,
+ 17, 255, 154, 78, 17, 255, 18, 13, 7, 255, 0, 12, 13, 10, 8, 170,
+ 191, 102, 30, 255, 209, 118, 30, 255, 207, 113, 30, 255, 28, 19, 11,
+ 201, 0, 8, 13, 10, 8, 105, 166, 87, 23, 255, 198, 101, 23, 255, 198,
+ 97, 23, 255, 26, 18, 11, 255, 0, 40, 13, 10, 8, 170, 189, 100, 28,
+ 255, 206, 111, 27, 255, 204, 102, 27, 255, 28, 20, 11, 201, 0, 8,
+ 12, 10, 7, 116, 184, 93, 27, 255, 206, 107, 27, 255, 203, 113, 26,
+ 255, 23, 17, 10, 255, 0, 8, 6, 5, 5, 28, 25, 18, 12, 244, 192, 105,
+ 27, 255, 206, 112, 29, 255, 207, 117, 30, 255, 32, 22, 13, 170, 0,
+ 8, 11, 9, 6, 88, 112, 57, 13, 255, 143, 70, 16, 255, 141, 69, 16,
+ 255, 17, 12, 6, 227, 0, 32, 14, 11, 9, 170, 184, 92, 25, 255, 206,
+ 111, 27, 255, 192, 111, 31, 255, 49, 33, 18, 255, 10, 8, 7, 122, 0,
+ 12, 7, 7, 6, 59, 22, 16, 11, 232, 167, 100, 28, 255, 205, 112, 30,
+ 255, 205, 116, 30, 255, 26, 18, 11, 210, 0, 8, 8, 7, 3, 85, 110, 54,
+ 13, 255, 141, 69, 16, 255, 141, 75, 16, 255, 25, 16, 6, 255, 5, 4,
+ 4, 40, 0, 8, 10, 8, 5, 85, 112, 55, 13, 255, 141, 75, 16, 255, 141,
+ 75, 16, 255, 20, 13, 5, 170, 0, 8, 5, 4, 2, 28, 33, 20, 8, 255, 130,
+ 66, 15, 255, 141, 72, 16, 255, 112, 55, 13, 255, 45, 25, 8, 255, 26,
+ 17, 6, 255, 33, 20, 8, 255, 94, 47, 13, 255, 141, 69, 16, 255, 144,
+ 71, 17, 255, 80, 40, 13, 255, 9, 7, 4, 125, 0, 8, 10, 8, 5, 85, 112,
+ 57, 13, 255, 148, 79, 17, 255, 141, 75, 16, 255, 87, 42, 12, 255,
+ 19, 13, 6, 255, 14, 10, 5, 215, 15, 10, 6, 255, 60, 31, 11, 255,
+ 143, 71, 18, 255, 160, 82, 19, 255, 96, 54, 17, 255, 12, 9, 7, 142,
+ 0, 8, 8, 6, 5, 57, 71, 44, 22, 255, 192, 100, 25, 255, 199, 106, 24,
+ 255, 185, 93, 26, 255, 91, 50, 22, 255, 58, 33, 17, 255, 72, 41, 19,
+ 255, 158, 81, 25, 255, 199, 106, 24, 255, 199, 106, 24, 255, 138,
+ 79, 27, 255, 13, 11, 8, 142, 0, 8, 10, 8, 7, 147, 166, 87, 23, 255,
+ 203, 108, 24, 255, 202, 108, 25, 255, 153, 77, 26, 255, 38, 22, 13,
+ 255, 15, 11, 6, 255, 14, 10, 5, 255, 52, 28, 9, 255, 132, 70, 15,
+ 255, 141, 75, 16, 255, 80, 41, 13, 255, 10, 8, 5, 139, 0, 8, 7, 6,
+ 6, 57, 48, 29, 13, 255, 154, 79, 19, 255, 160, 85, 19, 255, 108, 56,
+ 17, 255, 30, 18, 9, 255, 16, 11, 7, 255, 24, 15, 9, 255, 96, 51, 17,
+ 255, 167, 86, 20, 255, 181, 88, 20, 255, 140, 75, 23, 255, 18, 14,
+ 9, 144, 0, 12, 22, 14, 7, 193, 22, 13, 7, 255, 20, 13, 7, 255, 78,
+ 40, 15, 255, 165, 81, 20, 255, 177, 90, 20, 255, 177, 90, 20, 255,
+ 115, 58, 20, 255, 32, 20, 11, 255, 24, 15, 9, 255, 30, 19, 9, 227,
+ 11, 8, 6, 54, 0, 8, 11, 9, 6, 142, 139, 68, 20, 255, 166, 78, 19,
+ 255, 144, 71, 17, 255, 19, 12, 6, 215, 0, 12, 9, 7, 4, 136, 114, 56,
+ 13, 255, 143, 70, 16, 255, 139, 68, 16, 255, 19, 13, 6, 170, 0, 8,
+ 10, 7, 5, 85, 112, 55, 13, 255, 143, 70, 16, 255, 139, 74, 16, 255,
+ 17, 11, 6, 221, 0, 12, 9, 7, 4, 136, 114, 56, 13, 255, 143, 70, 16,
+ 255, 141, 75, 16, 255, 20, 13, 5, 170, 0, 8, 9, 6, 4, 85, 110, 54,
+ 13, 255, 141, 69, 16, 255, 141, 72, 16, 255, 17, 11, 6, 221, 0, 20,
+ 9, 7, 4, 136, 114, 56, 13, 255, 143, 73, 16, 255, 139, 74, 16, 255,
+ 19, 13, 6, 170, 0, 8, 8, 6, 3, 85, 110, 54, 13, 255, 143, 76, 16,
+ 255, 141, 69, 16, 255, 18, 12, 5, 252, 0, 12, 11, 9, 6, 170, 131,
+ 69, 18, 255, 170, 87, 19, 255, 168, 86, 19, 255, 28, 19, 9, 170, 0,
+ 8, 11, 8, 6, 85, 145, 74, 26, 255, 204, 102, 27, 255, 203, 105, 26,
+ 255, 52, 33, 17, 255, 6, 5, 5, 57, 0, 8, 17, 14, 10, 227, 190, 107,
+ 25, 255, 204, 113, 25, 255, 174, 86, 27, 255, 18, 13, 9, 170, 0, 12,
+ 28, 18, 11, 198, 37, 23, 14, 255, 32, 21, 13, 255, 21, 15, 10, 255,
+ 20, 14, 9, 255, 38, 23, 11, 255, 87, 44, 12, 255, 137, 70, 16, 255,
+ 141, 72, 16, 255, 143, 70, 16, 255, 141, 72, 16, 255, 18, 12, 5,
+ 170, 0, 8, 9, 6, 4, 85, 110, 54, 13, 255, 145, 74, 16, 255, 141, 69,
+ 16, 255, 94, 47, 13, 255, 27, 17, 8, 227, 12, 8, 5, 28, 0, 8, 14,
+ 10, 7, 85, 121, 62, 18, 255, 172, 87, 19, 255, 139, 69, 18, 255, 20,
+ 15, 9, 227, 0, 36, 21, 14, 8, 227, 117, 61, 24, 255, 199, 100, 28,
+ 255, 205, 106, 26, 255, 204, 110, 27, 255, 26, 18, 11, 255, 0, 16,
+ 8, 7, 5, 28, 20, 15, 11, 227, 135, 73, 22, 255, 192, 97, 21, 255,
+ 165, 83, 22, 255, 33, 22, 12, 255, 10, 9, 7, 85, 0, 68, 11, 9, 6,
+ 170, 184, 97, 27, 255, 206, 112, 29, 255, 204, 110, 27, 255, 28, 19,
+ 11, 255, 0, 68, 14, 11, 7, 170, 179, 93, 24, 255, 202, 103, 23, 255,
+ 198, 97, 23, 255, 22, 15, 9, 255, 0, 132, 9, 7, 6, 170, 125, 63, 18,
+ 255, 158, 77, 17, 255, 146, 75, 17, 255, 17, 12, 6, 255, 0, 76, 8,
+ 6, 5, 76, 72, 46, 23, 255, 197, 108, 28, 255, 201, 107, 24, 255,
+ 164, 85, 27, 255, 37, 22, 14, 227, 13, 9, 6, 48, 0, 68, 12, 9, 7,
+ 170, 138, 67, 19, 255, 170, 79, 19, 255, 168, 86, 19, 255, 20, 14,
+ 9, 255, 0, 40, 8, 7, 5, 20, 21, 15, 10, 184, 26, 17, 11, 255, 26,
+ 17, 11, 215, 12, 9, 7, 74, 0, 24, 8, 7, 5, 20, 21, 15, 10, 184, 26,
+ 17, 11, 255, 31, 21, 12, 207, 18, 13, 9, 28, 0, 8, 11, 9, 8, 156,
+ 184, 93, 27, 255, 208, 105, 29, 255, 205, 111, 28, 255, 28, 19, 11,
+ 255, 0, 40, 14, 11, 7, 170, 184, 92, 25, 255, 203, 104, 24, 255,
+ 200, 98, 23, 255, 26, 18, 11, 255, 0, 255, 0, 189, 8, 7, 5, 57, 51,
+ 29, 12, 255, 152, 75, 19, 255, 162, 86, 19, 255, 19, 13, 8, 246, 0,
+ 255, 0, 137, 6, 5, 3, 28, 19, 13, 6, 249, 92, 46, 13, 255, 123, 63,
+ 14, 255, 78, 39, 11, 255, 21, 15, 6, 227, 9, 8, 4, 28, 0, 8, 9, 8,
+ 4, 85, 110, 59, 13, 255, 141, 69, 16, 255, 141, 75, 16, 255, 21, 14,
+ 6, 170, 0, 12, 16, 11, 5, 170, 52, 28, 9, 255, 115, 59, 14, 255,
+ 116, 60, 15, 255, 43, 26, 10, 255, 9, 7, 6, 125, 0, 16, 8, 7, 5, 28,
+ 21, 17, 10, 227, 109, 59, 18, 255, 160, 82, 19, 255, 121, 64, 18,
+ 255, 62, 34, 13, 255, 94, 53, 17, 255, 149, 78, 20, 255, 102, 54,
+ 19, 255, 32, 22, 11, 255, 72, 39, 15, 255, 121, 62, 18, 255, 24, 17,
+ 9, 187, 0, 40, 8, 6, 3, 167, 128, 66, 15, 255, 161, 85, 17, 255,
+ 159, 81, 18, 255, 24, 15, 7, 178, 0, 4, 6, 5, 3, 37, 48, 28, 11,
+ 255, 173, 92, 20, 255, 181, 96, 20, 255, 21, 15, 8, 221, 0, 4, 6, 5,
+ 3, 28, 40, 24, 9, 255, 143, 74, 18, 255, 158, 80, 17, 255, 21, 15,
+ 6, 181, 0, 8, 10, 8, 5, 54, 107, 51, 14, 255, 157, 83, 18, 255, 164,
+ 84, 19, 255, 176, 89, 19, 255, 189, 92, 20, 255, 191, 98, 22, 255,
+ 190, 106, 23, 255, 197, 110, 26, 255, 203, 108, 24, 255, 203, 117,
+ 24, 255, 205, 119, 26, 255, 207, 122, 30, 255, 199, 118, 32, 255,
+ 32, 23, 13, 170, 0, 12, 7, 6, 4, 85, 22, 15, 7, 232, 113, 54, 14,
+ 255, 146, 75, 17, 255, 158, 80, 17, 255, 154, 78, 17, 255, 158, 80,
+ 17, 255, 148, 76, 17, 255, 139, 71, 16, 255, 135, 66, 16, 255, 135,
+ 66, 16, 255, 21, 14, 6, 136, 0, 8, 10, 8, 5, 85, 128, 66, 15, 255,
+ 161, 85, 17, 255, 158, 80, 17, 255, 25, 16, 6, 204, 0, 12, 7, 6, 4,
+ 28, 25, 16, 8, 227, 102, 50, 15, 255, 148, 76, 17, 255, 142, 73, 17,
+ 255, 84, 45, 13, 255, 10, 8, 5, 113, 0, 8, 9, 7, 4, 82, 107, 53, 14,
+ 255, 146, 75, 17, 255, 84, 41, 13, 255, 8, 7, 5, 198, 3, 2, 2, 23,
+ 5, 4, 4, 136, 38, 23, 9, 255, 136, 70, 17, 255, 140, 72, 17, 255,
+ 21, 15, 6, 178, 0, 24, 7, 6, 4, 57, 45, 26, 10, 255, 143, 74, 18,
+ 255, 158, 80, 17, 255, 26, 17, 6, 170, 0, 12, 24, 16, 7, 227, 115,
+ 58, 16, 255, 148, 76, 17, 255, 46, 26, 9, 255, 7, 6, 4, 156, 0, 16,
+ 5, 4, 4, 71, 19, 13, 6, 255, 139, 71, 16, 255, 140, 72, 17, 255, 43,
+ 26, 10, 255, 9, 8, 4, 85, 0, 16, 14, 10, 5, 85, 109, 52, 14, 255,
+ 38, 23, 9, 255, 6, 5, 3, 85, 0, 12, 4, 4, 3, 28, 15, 12, 6, 227,
+ 115, 56, 16, 255, 29, 19, 8, 170, 0, 32, 13, 10, 6, 113, 122, 64,
+ 21, 255, 164, 85, 21, 255, 138, 71, 17, 255, 21, 15, 6, 161, 0, 156,
+ 13, 10, 6, 227, 137, 67, 16, 255, 154, 75, 17, 255, 84, 45, 13, 255,
+ 10, 8, 5, 116, 0, 8, 9, 7, 4, 85, 111, 55, 14, 255, 158, 87, 17,
+ 255, 158, 80, 17, 255, 19, 13, 6, 255, 4, 4, 3, 28, 0, 4, 3, 3, 2,
+ 113, 17, 12, 6, 255, 139, 71, 16, 255, 161, 85, 17, 255, 146, 75,
+ 17, 255, 20, 14, 7, 210, 0, 16, 16, 13, 9, 110, 184, 105, 27, 255,
+ 209, 123, 30, 255, 210, 124, 31, 255, 208, 123, 31, 255, 207, 122,
+ 30, 255, 27, 20, 12, 255, 0, 24, 13, 11, 8, 147, 143, 75, 20, 255,
+ 161, 85, 17, 255, 158, 80, 17, 255, 27, 18, 8, 227, 5, 4, 2, 28, 0,
+ 8, 10, 7, 5, 198, 131, 65, 16, 255, 161, 85, 17, 255, 150, 76, 17,
+ 255, 21, 14, 6, 170, 0, 8, 10, 8, 5, 85, 123, 61, 16, 255, 163, 83,
+ 18, 255, 158, 80, 17, 255, 27, 18, 8, 227, 5, 4, 2, 28, 0, 8, 9, 7,
+ 4, 198, 130, 66, 15, 255, 163, 83, 18, 255, 148, 76, 17, 255, 21,
+ 14, 6, 193, 0, 28, 7, 6, 4, 85, 22, 15, 7, 255, 131, 65, 16, 255,
+ 154, 78, 17, 255, 154, 78, 17, 255, 154, 78, 17, 255, 154, 78, 17,
+ 255, 21, 15, 6, 170, 0, 8, 10, 8, 5, 85, 129, 64, 16, 255, 163, 86,
+ 18, 255, 180, 91, 19, 255, 29, 20, 10, 255, 3, 3, 2, 93, 0, 36, 10,
+ 8, 5, 122, 121, 60, 16, 255, 161, 85, 17, 255, 159, 81, 18, 255, 24,
+ 15, 7, 255, 4, 4, 3, 34, 0, 4, 2, 2, 1, 6, 17, 13, 8, 181, 181, 93,
+ 22, 255, 203, 108, 24, 255, 205, 114, 26, 255, 32, 23, 13, 210, 0,
+ 36, 5, 4, 4, 161, 30, 22, 13, 255, 198, 116, 29, 255, 206, 106, 25,
+ 255, 191, 96, 20, 255, 26, 17, 7, 170, 0, 8, 9, 7, 4, 85, 116, 60,
+ 15, 255, 161, 85, 17, 255, 158, 80, 17, 255, 21, 14, 6, 255, 5, 4,
+ 2, 28, 0, 4, 2, 2, 1, 3, 12, 9, 7, 215, 190, 107, 25, 255, 211, 124,
+ 30, 255, 208, 134, 37, 255, 32, 22, 13, 178, 0, 8, 13, 11, 8, 96,
+ 187, 112, 32, 255, 209, 123, 30, 255, 191, 96, 20, 255, 28, 19, 9,
+ 255, 4, 3, 3, 74, 0, 4, 3, 2, 2, 28, 13, 10, 8, 227, 196, 120, 31,
+ 255, 211, 124, 30, 255, 199, 106, 24, 255, 27, 19, 10, 170, 0, 8,
+ 13, 10, 6, 57, 114, 61, 19, 255, 178, 91, 21, 255, 182, 102, 23,
+ 255, 23, 17, 10, 173, 0, 8, 11, 9, 6, 91, 146, 85, 25, 255, 198,
+ 113, 29, 255, 196, 120, 31, 255, 27, 20, 12, 207, 0, 20, 5, 5, 4,
+ 28, 21, 17, 12, 227, 190, 118, 33, 255, 209, 131, 40, 255, 161, 100,
+ 34, 255, 17, 14, 10, 227, 5, 5, 4, 28, 0, 72, 9, 8, 6, 170, 91, 59,
+ 28, 255, 189, 94, 24, 255, 162, 83, 19, 255, 39, 25, 12, 255, 7, 7,
+ 6, 85, 0, 20, 13, 11, 8, 142, 183, 103, 24, 255, 203, 112, 24, 255,
+ 203, 112, 24, 255, 42, 26, 13, 249, 5, 4, 4, 62, 0, 4, 3, 2, 2, 25,
+ 12, 9, 7, 227, 195, 115, 30, 255, 212, 127, 35, 255, 211, 132, 38,
+ 255, 32, 22, 13, 181, 0, 8, 12, 10, 7, 85, 124, 65, 17, 255, 161,
+ 85, 17, 255, 159, 78, 18, 255, 21, 14, 6, 255, 5, 4, 2, 28, 0, 8, 7,
+ 6, 4, 224, 133, 68, 16, 255, 159, 81, 18, 255, 146, 72, 17, 255, 22,
+ 14, 7, 170, 0, 8, 13, 11, 8, 91, 185, 111, 32, 255, 210, 125, 33,
+ 255, 205, 114, 26, 255, 37, 26, 14, 255, 4, 4, 3, 85, 0, 4, 4, 4, 4,
+ 28, 13, 10, 8, 227, 193, 105, 26, 255, 206, 111, 27, 255, 202, 118,
+ 27, 255, 32, 22, 13, 170, 0, 8, 11, 9, 6, 127, 174, 91, 23, 255,
+ 202, 102, 21, 255, 200, 105, 21, 255, 36, 23, 13, 255, 4, 4, 3, 85,
+ 0, 4, 3, 3, 2, 28, 13, 11, 8, 227, 198, 118, 33, 255, 212, 127, 35,
+ 255, 208, 128, 33, 255, 31, 22, 12, 181, 0, 8, 13, 11, 8, 91, 185,
+ 114, 30, 255, 211, 124, 30, 255, 208, 122, 29, 255, 34, 24, 13, 255,
+ 4, 4, 3, 85, 0, 4, 7, 6, 6, 113, 32, 24, 13, 255, 185, 95, 22, 255,
+ 202, 98, 21, 255, 198, 97, 23, 255, 33, 22, 12, 170, 0, 8, 10, 8, 7,
+ 156, 190, 108, 27, 255, 212, 126, 33, 255, 211, 127, 36, 255, 40,
+ 26, 15, 255, 4, 4, 3, 85, 0, 4, 3, 3, 2, 28, 13, 11, 8, 227, 198,
+ 118, 33, 255, 214, 129, 37, 255, 211, 132, 38, 255, 32, 23, 13, 173,
+ 0, 8, 10, 8, 7, 144, 167, 87, 22, 255, 185, 94, 20, 255, 165, 87,
+ 18, 255, 25, 17, 8, 255, 3, 3, 2, 57, 0, 28, 13, 11, 8, 170, 195,
+ 112, 30, 255, 210, 125, 33, 255, 208, 117, 29, 255, 39, 26, 14, 255,
+ 4, 4, 3, 85, 0, 28, 12, 10, 7, 150, 184, 108, 27, 255, 211, 124, 30,
+ 255, 211, 127, 36, 255, 40, 27, 15, 255, 4, 4, 3, 85, 0, 4, 3, 3, 2,
+ 28, 17, 13, 8, 178, 138, 71, 17, 255, 161, 85, 17, 255, 155, 79, 18,
+ 255, 21, 14, 6, 170, 0, 8, 10, 8, 5, 85, 124, 61, 15, 255, 169, 89,
+ 18, 255, 180, 91, 19, 255, 25, 18, 10, 255, 0, 12, 13, 11, 8, 170,
+ 196, 113, 31, 255, 211, 124, 30, 255, 205, 119, 26, 255, 26, 18, 11,
+ 204, 0, 8, 11, 9, 6, 88, 134, 70, 19, 255, 173, 87, 18, 255, 168,
+ 86, 19, 255, 20, 13, 7, 255, 0, 40, 13, 11, 8, 170, 196, 113, 31,
+ 255, 210, 125, 33, 255, 207, 122, 30, 255, 24, 18, 11, 212, 0, 8,
+ 11, 9, 6, 119, 180, 93, 23, 255, 203, 108, 24, 255, 202, 103, 23,
+ 255, 20, 15, 9, 255, 0, 8, 15, 13, 10, 195, 101, 63, 26, 255, 202,
+ 117, 25, 255, 206, 128, 35, 255, 160, 106, 35, 255, 15, 13, 10, 142,
+ 0, 8, 10, 8, 5, 147, 139, 70, 20, 255, 191, 96, 20, 255, 200, 105,
+ 21, 255, 25, 18, 10, 255, 0, 32, 13, 10, 8, 170, 189, 99, 26, 255,
+ 206, 115, 27, 255, 205, 106, 26, 255, 185, 106, 28, 255, 79, 52, 26,
+ 255, 10, 9, 7, 122, 0, 4, 7, 6, 6, 42, 36, 27, 17, 244, 172, 106,
+ 35, 255, 207, 128, 34, 255, 211, 126, 34, 255, 211, 127, 36, 255,
+ 24, 18, 11, 227, 0, 8, 10, 8, 5, 85, 124, 64, 15, 255, 159, 81, 18,
+ 255, 158, 80, 17, 255, 76, 40, 13, 255, 11, 8, 6, 210, 0, 8, 12, 9,
+ 5, 85, 129, 64, 16, 255, 161, 85, 17, 255, 158, 80, 17, 255, 26, 16,
+ 7, 170, 0, 8, 9, 7, 4, 85, 115, 56, 16, 255, 161, 85, 17, 255, 159,
+ 81, 18, 255, 49, 27, 10, 255, 7, 6, 4, 170, 5, 4, 4, 85, 6, 5, 3,
+ 113, 26, 19, 11, 255, 185, 95, 22, 255, 202, 102, 21, 255, 197, 104,
+ 22, 255, 28, 20, 11, 173, 0, 8, 13, 10, 6, 102, 167, 87, 22, 255,
+ 200, 101, 21, 255, 201, 102, 22, 255, 32, 21, 11, 255, 4, 3, 3, 65,
+ 0, 4, 2, 2, 1, 17, 12, 10, 7, 221, 190, 98, 23, 255, 208, 116, 27,
+ 255, 204, 110, 27, 255, 30, 21, 11, 181, 0, 8, 13, 11, 8, 91, 185,
+ 114, 30, 255, 211, 124, 30, 255, 209, 123, 30, 255, 86, 55, 25, 255,
+ 9, 8, 6, 187, 6, 6, 5, 85, 7, 6, 6, 130, 32, 24, 15, 255, 200, 122,
+ 31, 255, 209, 123, 30, 255, 206, 122, 31, 255, 32, 23, 13, 173, 0,
+ 8, 10, 8, 7, 144, 191, 113, 30, 255, 212, 127, 35, 255, 210, 126,
+ 35, 255, 40, 27, 15, 255, 4, 4, 3, 85, 0, 4, 2, 2, 1, 8, 11, 9, 6,
+ 212, 157, 81, 20, 255, 189, 92, 20, 255, 190, 97, 21, 255, 27, 19,
+ 10, 178, 0, 8, 12, 10, 7, 96, 183, 105, 28, 255, 209, 123, 30, 255,
+ 205, 114, 26, 255, 36, 24, 13, 255, 4, 4, 3, 85, 0, 4, 4, 4, 4, 28,
+ 18, 14, 9, 187, 195, 115, 30, 255, 211, 124, 30, 255, 210, 130, 35,
+ 255, 35, 26, 14, 210, 0, 20, 3, 2, 2, 28, 12, 10, 7, 227, 195, 115,
+ 30, 255, 211, 124, 30, 255, 209, 123, 30, 255, 38, 25, 15, 255, 4,
+ 4, 3, 85, 0, 20, 13, 11, 8, 170, 194, 115, 31, 255, 209, 122, 28,
+ 255, 196, 99, 21, 255, 21, 15, 8, 255, 0, 12, 11, 9, 6, 170, 153,
+ 79, 20, 255, 187, 91, 20, 255, 181, 96, 20, 255, 30, 20, 9, 178, 0,
+ 8, 13, 10, 6, 96, 151, 79, 20, 255, 187, 91, 20, 255, 181, 96, 20,
+ 255, 22, 16, 9, 255, 0, 12, 12, 9, 7, 170, 146, 76, 19, 255, 167,
+ 88, 18, 255, 158, 77, 17, 255, 23, 15, 6, 170, 0, 8, 10, 8, 5, 85,
+ 133, 66, 16, 255, 167, 88, 18, 255, 168, 86, 19, 255, 22, 16, 9,
+ 255, 0, 20, 12, 9, 7, 170, 155, 80, 20, 255, 185, 94, 20, 255, 181,
+ 96, 20, 255, 22, 16, 9, 221, 0, 8, 6, 6, 5, 42, 51, 29, 12, 255,
+ 150, 81, 19, 255, 165, 87, 18, 255, 42, 26, 11, 255, 5, 5, 4, 108,
+ 0, 4, 5, 5, 4, 28, 18, 15, 11, 255, 195, 114, 28, 255, 207, 123, 32,
+ 255, 158, 94, 31, 255, 17, 13, 10, 142, 0, 8, 6, 5, 5, 57, 50, 34,
+ 19, 255, 191, 111, 32, 255, 208, 117, 29, 255, 113, 73, 30, 255, 10,
+ 10, 9, 227, 6, 6, 5, 125, 7, 7, 6, 198, 42, 29, 17, 255, 187, 96,
+ 22, 255, 166, 87, 23, 255, 42, 27, 15, 255, 8, 6, 5, 110, 0, 32, 5,
+ 5, 4, 184, 21, 16, 8, 255, 106, 54, 15, 255, 154, 78, 17, 255, 151,
+ 77, 18, 255, 92, 48, 15, 255, 11, 9, 6, 119, 0, 8, 10, 8, 5, 93,
+ 131, 69, 18, 255, 189, 92, 20, 255, 200, 105, 21, 255, 33, 22, 12,
+ 255, 5, 4, 4, 54, 0, 12, 9, 8, 6, 85, 76, 53, 25, 255, 200, 118, 31,
+ 255, 204, 114, 27, 255, 65, 43, 22, 255, 6, 6, 5, 113, 0, 32, 4, 3,
+ 3, 17, 14, 11, 9, 227, 195, 111, 28, 255, 206, 115, 27, 255, 204,
+ 105, 25, 255, 24, 17, 11, 255, 0, 12, 5, 5, 4, 28, 13, 10, 6, 227,
+ 125, 66, 18, 255, 165, 84, 18, 255, 161, 85, 17, 255, 161, 85, 17,
+ 255, 155, 79, 18, 255, 28, 19, 9, 255, 6, 5, 3, 85, 0, 64, 11, 9, 8,
+ 68, 86, 56, 27, 255, 204, 126, 33, 255, 210, 125, 33, 255, 30, 21,
+ 13, 255, 0, 68, 13, 11, 8, 170, 195, 115, 30, 255, 209, 123, 30,
+ 255, 207, 122, 30, 255, 27, 19, 12, 255, 3, 3, 2, 28, 0, 128, 7, 6,
+ 4, 184, 131, 65, 16, 255, 161, 85, 17, 255, 154, 78, 17, 255, 15,
+ 11, 6, 249, 0, 76, 10, 8, 7, 173, 166, 87, 23, 255, 198, 104, 21,
+ 255, 196, 99, 21, 255, 35, 23, 12, 255, 3, 3, 2, 85, 0, 72, 13, 11,
+ 8, 170, 194, 115, 31, 255, 211, 124, 30, 255, 207, 122, 30, 255, 27,
+ 19, 12, 255, 3, 3, 2, 28, 0, 108, 13, 11, 8, 170, 196, 113, 31, 255,
+ 213, 132, 36, 255, 211, 127, 36, 255, 30, 21, 13, 255, 0, 40, 11, 9,
+ 6, 170, 155, 80, 20, 255, 185, 94, 20, 255, 180, 91, 19, 255, 21,
+ 15, 8, 255, 0, 255, 0, 189, 10, 8, 7, 184, 183, 100, 26, 255, 208,
+ 116, 27, 255, 204, 114, 27, 255, 26, 18, 11, 255, 4, 4, 4, 28, 0,
+ 255, 0, 133, 10, 8, 5, 127, 119, 60, 15, 255, 160, 85, 19, 255, 91,
+ 48, 16, 255, 10, 8, 5, 227, 4, 4, 3, 28, 0, 12, 9, 7, 4, 161, 131,
+ 67, 16, 255, 159, 81, 18, 255, 159, 78, 18, 255, 18, 13, 7, 249, 0,
+ 16, 7, 6, 4, 170, 57, 34, 14, 255, 176, 90, 21, 255, 195, 95, 22,
+ 255, 26, 19, 11, 232, 0, 16, 17, 14, 10, 99, 179, 106, 28, 255, 207,
+ 122, 30, 255, 180, 109, 33, 255, 25, 20, 12, 255, 7, 6, 6, 170, 20,
+ 17, 11, 255, 196, 114, 27, 255, 208, 117, 29, 255, 203, 124, 30,
+ 255, 172, 106, 35, 255, 53, 36, 20, 255, 10, 9, 7, 108, 0, 40, 9, 8,
+ 6, 170, 159, 82, 20, 255, 202, 103, 23, 255, 206, 111, 27, 255, 22,
+ 17, 11, 255, 0, 8, 10, 9, 7, 139, 115, 74, 30, 255, 213, 133, 48,
+ 255, 39, 28, 16, 255, 0, 8, 9, 8, 4, 113, 67, 39, 14, 255, 181, 92,
+ 20, 255, 24, 18, 9, 255, 0, 12, 28, 19, 9, 227, 139, 79, 26, 255,
+ 206, 117, 31, 255, 212, 123, 37, 255, 214, 126, 41, 255, 172, 106,
+ 35, 255, 53, 34, 18, 255, 122, 78, 31, 255, 211, 127, 44, 255, 217,
+ 136, 50, 255, 216, 135, 49, 255, 190, 122, 41, 255, 65, 43, 22, 255,
+ 14, 11, 7, 85, 0, 8, 7, 6, 4, 28, 29, 21, 10, 249, 153, 79, 20, 255,
+ 174, 85, 19, 255, 103, 53, 16, 255, 17, 12, 6, 244, 19, 13, 6, 170,
+ 21, 14, 6, 170, 27, 17, 6, 170, 21, 14, 6, 212, 21, 14, 6, 255, 25,
+ 17, 6, 224, 12, 9, 5, 45, 0, 12, 24, 16, 7, 153, 22, 15, 7, 255, 26,
+ 16, 7, 210, 12, 9, 5, 40, 0, 8, 8, 7, 5, 28, 17, 13, 8, 227, 114,
+ 61, 19, 255, 174, 85, 19, 255, 154, 79, 19, 255, 60, 33, 13, 255,
+ 11, 9, 6, 170, 0, 12, 10, 8, 5, 170, 146, 79, 19, 255, 180, 87, 19,
+ 255, 67, 39, 14, 255, 8, 6, 5, 85, 0, 8, 24, 17, 9, 255, 143, 75,
+ 20, 255, 162, 80, 19, 255, 22, 15, 7, 215, 0, 28, 8, 7, 5, 110, 60,
+ 33, 13, 255, 166, 78, 19, 255, 22, 15, 7, 227, 0, 8, 7, 6, 4, 85,
+ 91, 51, 16, 255, 174, 88, 19, 255, 169, 78, 18, 255, 25, 17, 8, 255,
+ 3, 3, 2, 8, 0, 20, 11, 9, 6, 178, 143, 74, 18, 255, 177, 89, 18,
+ 255, 138, 75, 19, 255, 18, 13, 7, 176, 0, 16, 9, 7, 4, 28, 29, 19,
+ 8, 232, 41, 25, 10, 255, 17, 13, 8, 255, 9, 8, 6, 116, 0, 4, 7, 6,
+ 4, 59, 14, 11, 7, 227, 32, 21, 9, 255, 40, 24, 9, 255, 12, 9, 5,
+ 105, 0, 32, 14, 11, 9, 170, 199, 124, 36, 255, 213, 119, 36, 255,
+ 202, 102, 21, 255, 20, 14, 7, 246, 0, 152, 8, 7, 5, 142, 53, 31, 12,
+ 255, 162, 86, 19, 255, 121, 64, 18, 255, 19, 14, 8, 252, 6, 5, 3,
+ 28, 0, 8, 10, 8, 5, 125, 142, 74, 19, 255, 180, 91, 19, 255, 183,
+ 89, 19, 255, 19, 14, 8, 255, 0, 4, 5, 5, 4, 6, 15, 13, 10, 193, 69,
+ 42, 18, 255, 171, 91, 20, 255, 189, 88, 20, 255, 200, 101, 21, 255,
+ 31, 21, 12, 255, 0, 16, 10, 8, 7, 28, 30, 21, 13, 227, 150, 92, 35,
+ 255, 208, 121, 37, 255, 211, 115, 30, 255, 208, 117, 29, 255, 28,
+ 21, 13, 255, 0, 24, 10, 8, 7, 28, 22, 15, 7, 198, 26, 17, 7, 255,
+ 24, 15, 7, 221, 9, 7, 4, 57, 0, 12, 8, 7, 5, 156, 171, 89, 22, 255,
+ 202, 107, 23, 255, 202, 103, 23, 255, 23, 18, 10, 249, 0, 12, 26,
+ 18, 9, 198, 29, 19, 8, 255, 24, 16, 7, 215, 10, 8, 5, 51, 0, 12, 10,
+ 8, 5, 85, 134, 70, 19, 255, 175, 88, 18, 255, 173, 87, 18, 255, 20,
+ 14, 7, 255, 0, 24, 10, 8, 5, 85, 26, 19, 9, 255, 107, 58, 18, 255,
+ 154, 83, 19, 255, 168, 79, 19, 255, 169, 78, 18, 255, 173, 87, 18,
+ 255, 172, 80, 19, 255, 26, 17, 7, 170, 0, 8, 11, 10, 8, 136, 189,
+ 99, 26, 255, 210, 115, 31, 255, 216, 129, 45, 255, 143, 96, 40, 255,
+ 15, 13, 10, 227, 12, 12, 11, 170, 15, 13, 12, 170, 13, 12, 10, 170,
+ 13, 12, 10, 136, 9, 8, 8, 85, 0, 16, 11, 9, 6, 170, 169, 91, 22,
+ 255, 202, 103, 23, 255, 203, 108, 24, 255, 18, 15, 9, 255, 0, 12, 6,
+ 5, 5, 23, 28, 19, 11, 156, 31, 22, 12, 255, 34, 24, 13, 227, 14, 11,
+ 7, 85, 0, 36, 9, 8, 8, 142, 72, 54, 31, 255, 215, 147, 60, 255, 218,
+ 146, 61, 255, 174, 100, 35, 255, 14, 11, 7, 142, 0, 8, 11, 8, 6,
+ 102, 142, 74, 19, 255, 185, 86, 20, 255, 195, 98, 20, 255, 18, 14,
+ 9, 249, 0, 12, 10, 8, 7, 170, 202, 131, 47, 255, 220, 152, 63, 255,
+ 220, 151, 61, 255, 22, 19, 13, 252, 0, 8, 11, 9, 8, 167, 203, 135,
+ 46, 255, 217, 139, 48, 255, 210, 120, 33, 255, 18, 14, 9, 255, 0,
+ 12, 9, 8, 6, 170, 198, 117, 37, 255, 211, 115, 30, 255, 202, 102,
+ 21, 255, 34, 22, 11, 176, 0, 8, 13, 11, 8, 170, 202, 122, 37, 255,
+ 218, 144, 49, 255, 217, 144, 50, 255, 28, 21, 13, 255, 0, 8, 12, 11,
+ 9, 170, 204, 122, 41, 255, 217, 135, 46, 255, 215, 136, 42, 255, 46,
+ 33, 19, 255, 0, 16, 10, 9, 7, 28, 21, 19, 14, 227, 153, 104, 46,
+ 255, 214, 149, 55, 255, 158, 103, 39, 255, 16, 14, 11, 221, 7, 6, 6,
+ 28, 0, 20, 20, 18, 13, 142, 31, 26, 18, 170, 25, 21, 16, 170, 24,
+ 20, 15, 170, 24, 20, 15, 170, 24, 20, 15, 170, 24, 21, 15, 170, 31,
+ 26, 18, 170, 25, 21, 16, 170, 14, 12, 9, 31, 0, 20, 10, 9, 7, 167,
+ 75, 51, 26, 255, 202, 117, 33, 255, 186, 120, 43, 255, 41, 32, 20,
+ 255, 12, 11, 9, 85, 0, 16, 11, 9, 8, 28, 31, 22, 12, 215, 49, 33,
+ 18, 255, 41, 27, 16, 227, 12, 10, 7, 85, 0, 12, 14, 12, 9, 170, 204,
+ 137, 51, 255, 220, 152, 63, 255, 220, 151, 61, 255, 23, 19, 12, 252,
+ 0, 8, 11, 10, 6, 85, 136, 70, 17, 255, 175, 88, 18, 255, 169, 78,
+ 18, 255, 15, 11, 6, 255, 0, 8, 9, 8, 6, 85, 26, 19, 9, 255, 153, 82,
+ 18, 255, 177, 89, 18, 255, 180, 84, 19, 255, 24, 17, 9, 218, 0, 8,
+ 11, 9, 8, 147, 196, 115, 35, 255, 215, 125, 38, 255, 214, 125, 39,
+ 255, 20, 16, 11, 255, 0, 12, 9, 8, 6, 159, 165, 86, 22, 255, 197,
+ 99, 20, 255, 195, 90, 20, 255, 32, 21, 11, 170, 0, 8, 12, 10, 7, 85,
+ 145, 76, 20, 255, 189, 92, 20, 255, 191, 96, 20, 255, 18, 14, 9,
+ 255, 0, 12, 9, 8, 6, 170, 199, 126, 39, 255, 217, 133, 50, 255, 217,
+ 144, 50, 255, 23, 18, 12, 252, 0, 8, 11, 10, 8, 142, 191, 105, 28,
+ 255, 206, 111, 27, 255, 203, 104, 24, 255, 19, 15, 10, 255, 0, 12,
+ 9, 8, 6, 57, 21, 15, 8, 198, 28, 19, 9, 255, 32, 21, 11, 227, 11, 9,
+ 6, 76, 0, 8, 11, 9, 8, 170, 203, 125, 42, 255, 220, 146, 59, 255,
+ 219, 146, 60, 255, 24, 19, 13, 255, 0, 12, 11, 10, 8, 170, 204, 136,
+ 47, 255, 220, 146, 59, 255, 218, 147, 55, 255, 25, 19, 12, 232, 0,
+ 8, 11, 10, 8, 119, 161, 87, 22, 255, 195, 98, 20, 255, 202, 103, 23,
+ 255, 18, 15, 9, 255, 0, 32, 14, 12, 9, 170, 200, 125, 37, 255, 214,
+ 124, 37, 255, 205, 106, 26, 255, 20, 16, 9, 221, 0, 32, 16, 13, 9,
+ 170, 205, 130, 42, 255, 219, 144, 56, 255, 219, 146, 60, 255, 24,
+ 19, 13, 255, 0, 12, 6, 5, 3, 23, 21, 14, 6, 170, 26, 16, 7, 255, 26,
+ 17, 7, 224, 14, 10, 5, 31, 0, 8, 11, 9, 6, 125, 170, 89, 23, 255,
+ 211, 115, 30, 255, 214, 126, 41, 255, 23, 19, 12, 255, 0, 12, 11,
+ 10, 8, 170, 195, 112, 30, 255, 206, 106, 25, 255, 200, 105, 21, 255,
+ 29, 20, 10, 170, 0, 8, 11, 9, 6, 85, 134, 70, 19, 255, 177, 85, 18,
+ 255, 172, 80, 19, 255, 18, 13, 7, 255, 0, 40, 14, 12, 9, 170, 195,
+ 112, 30, 255, 206, 111, 27, 255, 202, 103, 23, 255, 31, 22, 10, 170,
+ 0, 8, 13, 10, 6, 85, 151, 79, 20, 255, 189, 92, 20, 255, 183, 89,
+ 19, 255, 17, 13, 8, 255, 0, 4, 8, 7, 5, 59, 57, 34, 16, 255, 184,
+ 97, 27, 255, 198, 115, 33, 255, 114, 77, 33, 255, 16, 14, 11, 210,
+ 6, 5, 5, 8, 0, 8, 12, 10, 7, 170, 195, 113, 32, 255, 215, 123, 42,
+ 255, 217, 133, 50, 255, 32, 24, 15, 255, 0, 32, 12, 11, 7, 170, 175,
+ 90, 22, 255, 198, 104, 21, 255, 189, 92, 20, 255, 192, 97, 21, 255,
+ 189, 97, 22, 255, 45, 29, 14, 255, 10, 9, 7, 210, 22, 17, 11, 255,
+ 183, 102, 30, 255, 212, 121, 41, 255, 216, 135, 49, 255, 217, 137,
+ 52, 255, 214, 125, 39, 255, 29, 21, 12, 204, 0, 8, 11, 9, 6, 85,
+ 143, 75, 20, 255, 193, 97, 20, 255, 195, 98, 20, 255, 180, 93, 23,
+ 255, 88, 54, 23, 255, 11, 10, 8, 113, 0, 4, 14, 12, 7, 85, 170, 89,
+ 23, 255, 202, 103, 23, 255, 202, 102, 21, 255, 32, 22, 11, 178, 0,
+ 8, 12, 10, 7, 113, 176, 91, 23, 255, 205, 105, 24, 255, 209, 117,
+ 28, 255, 39, 28, 16, 255, 5, 5, 5, 28, 0, 8, 15, 14, 10, 198, 206,
+ 132, 45, 255, 217, 133, 50, 255, 215, 133, 44, 255, 25, 19, 12, 232,
+ 0, 8, 11, 10, 8, 125, 198, 118, 39, 255, 218, 145, 51, 255, 218,
+ 146, 53, 255, 20, 17, 11, 255, 0, 12, 9, 8, 6, 170, 198, 124, 37,
+ 255, 216, 134, 45, 255, 214, 139, 41, 255, 22, 18, 11, 255, 0, 8,
+ 11, 10, 8, 136, 191, 105, 28, 255, 206, 111, 27, 255, 206, 106, 25,
+ 255, 36, 26, 15, 255, 5, 5, 4, 28, 0, 8, 15, 13, 10, 198, 192, 105,
+ 27, 255, 206, 106, 25, 255, 204, 105, 25, 255, 23, 17, 10, 232, 0,
+ 8, 12, 10, 7, 125, 196, 119, 37, 255, 218, 141, 51, 255, 218, 139,
+ 55, 255, 20, 16, 11, 255, 0, 12, 9, 8, 6, 170, 196, 110, 33, 255,
+ 215, 126, 40, 255, 214, 125, 39, 255, 23, 18, 12, 252, 0, 8, 11, 9,
+ 8, 167, 201, 123, 40, 255, 217, 133, 50, 255, 214, 136, 43, 255, 20,
+ 16, 11, 255, 0, 12, 6, 5, 5, 23, 29, 21, 12, 153, 32, 22, 13, 255,
+ 35, 25, 14, 227, 15, 12, 8, 85, 0, 24, 12, 10, 9, 170, 198, 124, 37,
+ 255, 215, 125, 38, 255, 213, 124, 38, 255, 23, 18, 12, 255, 0, 24,
+ 14, 12, 9, 170, 204, 132, 47, 255, 219, 144, 56, 255, 211, 127, 36,
+ 255, 28, 21, 13, 255, 0, 12, 14, 12, 9, 170, 198, 117, 37, 255, 215,
+ 123, 42, 255, 214, 125, 39, 255, 25, 20, 12, 215, 0, 8, 11, 10, 8,
+ 130, 198, 119, 35, 255, 215, 126, 40, 255, 212, 123, 37, 255, 30,
+ 22, 13, 255, 0, 12, 14, 12, 9, 170, 196, 114, 33, 255, 206, 106, 25,
+ 255, 200, 105, 21, 255, 30, 21, 11, 184, 0, 8, 13, 11, 8, 99, 184,
+ 100, 25, 255, 209, 117, 28, 255, 210, 115, 31, 255, 28, 21, 13, 255,
+ 0, 20, 14, 12, 9, 170, 198, 117, 37, 255, 215, 126, 40, 255, 214,
+ 126, 41, 255, 25, 19, 12, 255, 0, 12, 10, 9, 7, 125, 61, 42, 22,
+ 255, 190, 107, 33, 255, 153, 98, 38, 255, 29, 23, 16, 255, 13, 12,
+ 10, 255, 17, 15, 10, 255, 108, 74, 37, 255, 210, 144, 59, 255, 153,
+ 98, 38, 255, 16, 14, 11, 224, 6, 6, 5, 17, 0, 12, 15, 13, 8, 227,
+ 115, 67, 24, 255, 197, 100, 22, 255, 150, 81, 25, 255, 32, 24, 13,
+ 255, 15, 13, 8, 255, 19, 15, 10, 255, 85, 48, 18, 255, 178, 95, 21,
+ 255, 115, 65, 20, 255, 15, 12, 8, 255, 5, 5, 4, 34, 0, 32, 10, 9, 7,
+ 198, 69, 46, 22, 255, 186, 103, 29, 255, 195, 111, 28, 255, 92, 58,
+ 25, 255, 15, 12, 8, 198, 0, 12, 10, 9, 7, 170, 194, 112, 31, 255,
+ 215, 125, 38, 255, 218, 146, 53, 255, 24, 19, 13, 255, 0, 20, 15,
+ 14, 10, 227, 159, 103, 42, 255, 212, 127, 43, 255, 177, 118, 48,
+ 255, 19, 17, 12, 227, 6, 6, 5, 28, 0, 32, 11, 10, 8, 170, 182, 98,
+ 23, 255, 202, 106, 21, 255, 195, 98, 20, 255, 24, 17, 9, 212, 0, 12,
+ 18, 14, 9, 227, 102, 54, 19, 255, 157, 83, 18, 255, 85, 46, 14, 255,
+ 19, 13, 6, 255, 47, 27, 10, 255, 150, 81, 19, 255, 131, 67, 20, 255,
+ 39, 26, 14, 255, 12, 11, 9, 85, 0, 64, 10, 9, 7, 170, 118, 75, 33,
+ 255, 215, 141, 54, 255, 44, 33, 19, 255, 0, 16, 9, 9, 8, 108, 19,
+ 17, 12, 170, 27, 23, 16, 170, 23, 21, 16, 170, 23, 21, 16, 170, 24,
+ 20, 15, 170, 20, 18, 13, 170, 15, 14, 10, 170, 10, 9, 7, 113, 7, 6,
+ 6, 28, 0, 12, 12, 11, 9, 170, 189, 99, 26, 255, 209, 110, 30, 255,
+ 211, 118, 36, 255, 141, 88, 36, 255, 19, 17, 12, 227, 20, 18, 13,
+ 170, 24, 20, 15, 170, 21, 19, 14, 170, 16, 14, 11, 170, 10, 9, 7,
+ 113, 6, 6, 5, 28, 0, 20, 8, 7, 5, 65, 11, 10, 8, 142, 16, 14, 11,
+ 170, 24, 21, 15, 170, 25, 22, 16, 170, 23, 21, 16, 170, 21, 19, 14,
+ 170, 16, 14, 11, 170, 11, 10, 8, 113, 7, 7, 6, 28, 0, 20, 8, 7, 5,
+ 62, 10, 9, 5, 136, 12, 10, 7, 170, 14, 11, 7, 170, 13, 10, 6, 170,
+ 11, 9, 6, 198, 31, 21, 10, 255, 153, 82, 18, 255, 177, 85, 18, 255,
+ 169, 78, 18, 255, 22, 15, 7, 204, 0, 16, 8, 7, 5, 57, 11, 10, 6,
+ 142, 19, 17, 12, 170, 23, 21, 16, 170, 25, 22, 16, 170, 23, 21, 16,
+ 170, 21, 19, 14, 170, 15, 14, 10, 170, 10, 10, 9, 113, 7, 6, 6, 28,
+ 0, 16, 12, 10, 7, 153, 55, 32, 14, 255, 175, 93, 20, 255, 185, 94,
+ 20, 255, 183, 89, 19, 255, 80, 44, 17, 255, 13, 11, 8, 187, 7, 6, 6,
+ 25, 0, 16, 8, 7, 5, 62, 11, 10, 6, 142, 16, 14, 11, 170, 23, 19, 14,
+ 170, 25, 22, 16, 170, 23, 21, 16, 170, 19, 17, 12, 170, 15, 14, 10,
+ 170, 17, 15, 10, 170, 19, 17, 12, 142, 9, 8, 8, 28, 0, 8, 12, 10, 9,
+ 170, 204, 137, 49, 255, 220, 146, 59, 255, 218, 146, 53, 255, 141,
+ 91, 38, 255, 19, 17, 12, 227, 19, 17, 12, 170, 24, 20, 15, 170, 21,
+ 19, 14, 170, 15, 14, 10, 170, 10, 10, 9, 113, 7, 6, 6, 28, 0, 16,
+ 12, 10, 7, 57, 14, 12, 7, 102, 14, 11, 7, 85, 0, 32, 12, 10, 7, 57,
+ 13, 11, 8, 105, 15, 13, 8, 85, 0, 12, 12, 11, 9, 170, 204, 136, 47,
+ 255, 220, 146, 59, 255, 218, 153, 59, 255, 24, 19, 13, 255, 0, 12,
+ 8, 7, 5, 82, 11, 10, 6, 156, 11, 9, 6, 170, 10, 9, 7, 91, 0, 12, 10,
+ 8, 5, 127, 144, 78, 19, 255, 180, 87, 19, 255, 174, 81, 19, 255, 24,
+ 15, 7, 210, 0, 12, 14, 11, 7, 68, 12, 10, 7, 170, 12, 10, 7, 170,
+ 17, 15, 10, 170, 24, 20, 15, 170, 19, 17, 12, 170, 15, 14, 10, 170,
+ 18, 15, 11, 170, 24, 21, 15, 170, 21, 19, 14, 170, 15, 14, 10, 170,
+ 11, 10, 8, 113, 7, 7, 6, 28, 0, 16, 15, 13, 10, 119, 17, 15, 12,
+ 170, 15, 13, 10, 170, 16, 14, 11, 170, 19, 17, 12, 170, 21, 18, 12,
+ 170, 18, 15, 11, 170, 15, 13, 8, 170, 11, 9, 6, 170, 10, 8, 7, 88,
+ 6, 5, 5, 23, 0, 20, 10, 9, 7, 85, 14, 12, 9, 170, 19, 17, 12, 170,
+ 21, 19, 14, 170, 21, 19, 14, 170, 21, 19, 14, 170, 19, 17, 12, 170,
+ 15, 14, 10, 170, 11, 10, 8, 116, 7, 7, 6, 28, 0, 16, 15, 14, 10,
+ 119, 18, 15, 11, 170, 15, 14, 10, 170, 18, 15, 11, 170, 21, 19, 14,
+ 170, 25, 22, 16, 170, 23, 21, 16, 170, 21, 19, 14, 170, 16, 14, 11,
+ 170, 11, 10, 8, 113, 7, 7, 6, 28, 0, 20, 10, 9, 7, 85, 14, 12, 9,
+ 170, 19, 17, 12, 170, 20, 18, 13, 170, 20, 18, 13, 170, 23, 19, 14,
+ 170, 19, 17, 12, 170, 15, 14, 10, 170, 17, 14, 10, 170, 19, 17, 12,
+ 142, 10, 9, 7, 28, 0, 12, 15, 13, 10, 113, 18, 15, 11, 170, 15, 14,
+ 10, 170, 18, 15, 11, 170, 21, 19, 14, 170, 25, 22, 16, 170, 23, 21,
+ 16, 170, 20, 18, 13, 170, 16, 14, 11, 170, 11, 10, 8, 113, 7, 7, 6,
+ 28, 0, 20, 7, 7, 6, 82, 11, 10, 6, 142, 16, 13, 9, 170, 19, 17, 12,
+ 170, 21, 19, 14, 170, 24, 21, 15, 170, 25, 22, 16, 170, 25, 22, 16,
+ 170, 15, 13, 10, 170, 12, 11, 9, 57, 0, 16, 15, 13, 10, 170, 97, 65,
+ 34, 255, 209, 132, 42, 255, 214, 136, 43, 255, 214, 127, 43, 255,
+ 159, 103, 42, 255, 21, 19, 14, 227, 11, 10, 8, 28, 0, 12, 16, 14,
+ 11, 113, 21, 19, 14, 170, 18, 15, 11, 153, 11, 10, 8, 28, 0, 16, 15,
+ 14, 10, 125, 21, 19, 14, 170, 19, 17, 12, 142, 10, 9, 7, 28, 0, 12,
+ 15, 14, 10, 113, 21, 19, 14, 170, 18, 16, 11, 153, 11, 10, 8, 28, 0,
+ 16, 15, 13, 10, 125, 21, 19, 14, 170, 19, 17, 12, 142, 10, 9, 7, 28,
+ 0, 12, 15, 14, 10, 113, 21, 19, 14, 170, 18, 16, 11, 153, 11, 10, 8,
+ 28, 0, 24, 15, 14, 10, 125, 21, 19, 14, 170, 19, 17, 12, 142, 9, 9,
+ 8, 28, 0, 12, 17, 14, 10, 130, 27, 24, 16, 170, 21, 19, 14, 142, 10,
+ 9, 7, 28, 0, 16, 16, 14, 11, 113, 28, 24, 17, 170, 24, 21, 15, 161,
+ 12, 11, 9, 28, 0, 12, 16, 14, 11, 113, 21, 19, 14, 170, 18, 15, 11,
+ 153, 11, 10, 8, 28, 0, 16, 15, 13, 10, 125, 21, 19, 14, 170, 19, 17,
+ 12, 142, 9, 8, 6, 28, 0, 12, 18, 15, 11, 136, 19, 16, 10, 170, 16,
+ 13, 9, 170, 16, 14, 9, 170, 15, 13, 8, 170, 13, 11, 8, 170, 12, 11,
+ 9, 170, 13, 12, 8, 170, 15, 14, 10, 170, 14, 13, 11, 170, 11, 11,
+ 10, 113, 0, 20, 13, 11, 8, 170, 190, 98, 23, 255, 204, 116, 31, 255,
+ 74, 52, 27, 255, 9, 8, 8, 113, 0, 16, 13, 11, 8, 170, 192, 106, 29,
+ 255, 208, 112, 27, 255, 208, 117, 29, 255, 27, 21, 12, 255, 0, 16,
+ 5, 5, 4, 28, 27, 23, 16, 255, 199, 121, 44, 255, 214, 139, 41, 255,
+ 31, 23, 14, 255, 0, 16, 13, 11, 8, 28, 32, 24, 13, 227, 36, 26, 15,
+ 255, 19, 16, 12, 198, 8, 8, 7, 51, 0, 4, 8, 8, 7, 57, 29, 21, 12,
+ 218, 48, 32, 17, 255, 45, 30, 16, 255, 20, 16, 11, 218, 10, 9, 7,
+ 105, 0, 44, 14, 12, 9, 170, 204, 130, 51, 255, 224, 153, 77, 255,
+ 225, 169, 88, 255, 33, 27, 18, 255, 0, 12, 21, 19, 14, 215, 217,
+ 163, 86, 255, 61, 46, 28, 255, 0, 12, 19, 16, 12, 201, 203, 121, 40,
+ 255, 51, 38, 22, 255, 0, 12, 4, 4, 3, 25, 16, 14, 11, 227, 212, 147,
+ 71, 255, 224, 160, 77, 255, 223, 161, 80, 255, 31, 25, 16, 255, 4,
+ 4, 4, 102, 10, 10, 9, 215, 206, 133, 55, 255, 223, 156, 70, 255,
+ 224, 164, 85, 255, 51, 39, 24, 255, 5, 5, 4, 82, 0, 12, 15, 12, 8,
+ 110, 178, 98, 27, 255, 211, 115, 30, 255, 211, 121, 34, 255, 36, 26,
+ 15, 255, 3, 3, 2, 85, 0, 60, 8, 8, 5, 28, 27, 20, 10, 232, 125, 73,
+ 22, 255, 190, 97, 21, 255, 180, 92, 21, 255, 97, 56, 20, 255, 14,
+ 11, 7, 170, 0, 16, 12, 10, 7, 142, 165, 89, 22, 255, 198, 104, 21,
+ 255, 84, 50, 19, 255, 7, 6, 4, 159, 0, 4, 5, 5, 4, 82, 32, 23, 11,
+ 255, 121, 69, 22, 255, 97, 56, 20, 255, 15, 13, 8, 142, 0, 32, 14,
+ 12, 7, 198, 172, 92, 21, 255, 28, 19, 9, 207, 0, 8, 11, 10, 6, 85,
+ 148, 78, 21, 255, 198, 104, 21, 255, 192, 97, 21, 255, 21, 15, 8,
+ 255, 0, 24, 10, 9, 5, 170, 167, 90, 22, 255, 202, 93, 21, 255, 202,
+ 103, 23, 255, 21, 16, 10, 255, 0, 20, 4, 3, 3, 133, 20, 16, 9, 255,
+ 151, 80, 22, 255, 75, 42, 16, 255, 10, 8, 7, 255, 32, 22, 11, 255,
+ 164, 86, 23, 255, 60, 39, 17, 255, 5, 5, 4, 252, 0, 36, 12, 11, 9,
+ 198, 213, 155, 80, 255, 224, 166, 83, 255, 211, 121, 34, 255, 20,
+ 16, 9, 255, 3, 3, 2, 28, 0, 144, 6, 6, 5, 51, 27, 20, 10, 255, 160,
+ 84, 23, 255, 198, 104, 21, 255, 67, 40, 16, 255, 8, 7, 5, 125, 0,
+ 12, 12, 10, 9, 170, 195, 112, 30, 255, 215, 125, 38, 255, 217, 133,
+ 50, 255, 49, 35, 22, 255, 5, 5, 4, 133, 13, 12, 10, 210, 189, 119,
+ 50, 255, 211, 127, 44, 255, 212, 121, 41, 255, 218, 135, 53, 255,
+ 220, 148, 63, 255, 34, 27, 17, 255, 0, 20, 4, 4, 4, 17, 13, 12, 10,
+ 227, 196, 113, 31, 255, 212, 118, 35, 255, 214, 123, 43, 255, 33,
+ 26, 16, 255, 0, 56, 12, 11, 9, 187, 208, 134, 55, 255, 223, 146, 70,
+ 255, 221, 152, 70, 255, 34, 26, 17, 255, 0, 40, 8, 7, 5, 164, 165,
+ 86, 22, 255, 202, 98, 21, 255, 198, 96, 21, 255, 22, 16, 9, 255, 0,
+ 20, 8, 8, 5, 85, 32, 22, 11, 255, 167, 87, 22, 255, 160, 84, 23,
+ 255, 93, 54, 20, 255, 120, 65, 21, 255, 188, 96, 21, 255, 196, 99,
+ 21, 255, 200, 105, 21, 255, 24, 19, 11, 207, 0, 8, 15, 14, 10, 110,
+ 208, 152, 71, 255, 227, 174, 98, 255, 228, 179, 103, 255, 225, 176,
+ 98, 255, 217, 169, 94, 255, 213, 166, 92, 255, 215, 167, 92, 255,
+ 213, 155, 80, 255, 204, 136, 55, 255, 138, 89, 37, 255, 25, 22, 16,
+ 227, 9, 9, 8, 28, 0, 8, 11, 10, 8, 170, 203, 129, 50, 255, 223, 149,
+ 70, 255, 222, 158, 75, 255, 31, 25, 16, 255, 4, 4, 4, 28, 0, 60, 8,
+ 8, 7, 57, 49, 40, 26, 255, 206, 152, 83, 255, 224, 169, 91, 255,
+ 194, 140, 71, 255, 31, 27, 20, 255, 9, 8, 8, 28, 0, 8, 12, 10, 9,
+ 161, 196, 110, 33, 255, 218, 130, 51, 255, 222, 158, 75, 255, 31,
+ 25, 16, 255, 4, 4, 4, 28, 0, 8, 11, 10, 8, 198, 213, 160, 84, 255,
+ 228, 180, 105, 255, 227, 175, 100, 255, 33, 28, 18, 207, 0, 8, 12,
+ 11, 9, 130, 210, 155, 77, 255, 228, 169, 99, 255, 226, 172, 95, 255,
+ 30, 25, 17, 255, 4, 4, 4, 28, 0, 8, 11, 10, 8, 198, 204, 129, 49,
+ 255, 214, 127, 43, 255, 213, 125, 40, 255, 23, 19, 12, 232, 0, 8,
+ 14, 13, 9, 125, 208, 152, 71, 255, 223, 159, 76, 255, 218, 153, 59,
+ 255, 33, 26, 16, 210, 0, 8, 13, 12, 10, 127, 198, 118, 39, 255, 215,
+ 127, 42, 255, 213, 126, 42, 255, 41, 31, 18, 227, 0, 12, 6, 6, 5,
+ 28, 25, 21, 16, 227, 204, 150, 79, 255, 223, 171, 98, 255, 175, 122,
+ 60, 255, 18, 15, 11, 218, 5, 4, 4, 17, 0, 20, 20, 18, 13, 85, 177,
+ 101, 34, 255, 204, 123, 37, 255, 199, 117, 36, 255, 199, 117, 36,
+ 255, 202, 122, 37, 255, 199, 117, 36, 255, 198, 114, 31, 255, 198,
+ 110, 31, 255, 202, 118, 35, 255, 46, 33, 21, 170, 0, 24, 10, 9, 7,
+ 153, 110, 78, 37, 255, 213, 162, 82, 255, 218, 164, 87, 255, 67, 51,
+ 30, 255, 9, 8, 8, 85, 0, 40, 6, 5, 5, 28, 21, 19, 14, 255, 217, 166,
+ 92, 255, 227, 175, 100, 255, 224, 169, 91, 255, 31, 25, 16, 215, 0,
+ 8, 12, 10, 7, 85, 154, 80, 21, 255, 197, 99, 20, 255, 192, 97, 21,
+ 255, 28, 20, 9, 255, 4, 3, 3, 110, 11, 9, 6, 170, 117, 63, 20, 255,
+ 184, 94, 21, 255, 198, 104, 21, 255, 203, 104, 24, 255, 210, 122,
+ 37, 255, 21, 17, 12, 252, 0, 8, 10, 9, 7, 161, 203, 129, 50, 255,
+ 224, 160, 77, 255, 225, 169, 88, 255, 30, 25, 17, 255, 4, 4, 4, 28,
+ 0, 8, 8, 7, 5, 190, 165, 86, 22, 255, 198, 104, 21, 255, 196, 99,
+ 21, 255, 28, 19, 9, 170, 0, 8, 13, 11, 8, 85, 176, 91, 23, 255, 208,
+ 112, 27, 255, 210, 121, 35, 255, 27, 22, 14, 255, 4, 4, 4, 28, 0, 8,
+ 11, 10, 8, 198, 211, 149, 76, 255, 224, 168, 87, 255, 224, 162, 81,
+ 255, 32, 26, 17, 210, 0, 8, 12, 10, 7, 113, 176, 91, 23, 255, 202,
+ 107, 23, 255, 202, 95, 23, 255, 20, 16, 9, 255, 0, 40, 15, 13, 10,
+ 170, 213, 160, 84, 255, 228, 180, 105, 255, 227, 174, 98, 255, 33,
+ 26, 18, 255, 0, 12, 15, 13, 10, 170, 213, 155, 80, 255, 226, 172,
+ 95, 255, 224, 167, 85, 255, 23, 20, 14, 244, 0, 8, 11, 10, 8, 127,
+ 189, 104, 28, 255, 214, 127, 43, 255, 221, 148, 70, 255, 31, 25, 16,
+ 255, 4, 4, 4, 28, 0, 28, 14, 12, 9, 170, 195, 113, 32, 255, 209,
+ 117, 28, 255, 202, 103, 23, 255, 20, 15, 9, 252, 3, 3, 3, 14, 0, 28,
+ 15, 14, 10, 170, 213, 155, 80, 255, 226, 172, 95, 255, 221, 152, 70,
+ 255, 28, 24, 15, 255, 0, 40, 14, 12, 9, 170, 208, 141, 61, 255, 225,
+ 162, 88, 255, 227, 174, 98, 255, 33, 26, 18, 255, 4, 4, 4, 28, 0, 8,
+ 10, 8, 7, 198, 182, 98, 23, 255, 202, 103, 23, 255, 198, 104, 21,
+ 255, 28, 19, 9, 170, 0, 8, 11, 10, 6, 85, 154, 80, 21, 255, 202, 98,
+ 21, 255, 202, 103, 23, 255, 25, 20, 12, 255, 0, 40, 12, 10, 7, 170,
+ 186, 100, 23, 255, 202, 99, 23, 255, 200, 105, 21, 255, 30, 21, 9,
+ 170, 0, 8, 12, 9, 7, 85, 154, 80, 21, 255, 198, 104, 21, 255, 196,
+ 99, 21, 255, 28, 20, 9, 255, 4, 4, 3, 113, 11, 10, 6, 227, 183, 100,
+ 26, 255, 212, 127, 43, 255, 167, 117, 52, 255, 17, 15, 12, 215, 5,
+ 5, 5, 14, 0, 12, 15, 13, 10, 170, 211, 149, 76, 255, 224, 166, 83,
+ 255, 223, 161, 80, 255, 34, 26, 17, 255, 0, 32, 10, 9, 7, 170, 167,
+ 87, 22, 255, 198, 92, 21, 255, 196, 99, 21, 255, 196, 95, 21, 255,
+ 198, 92, 21, 255, 195, 99, 22, 255, 192, 106, 29, 255, 206, 127, 43,
+ 255, 217, 141, 60, 255, 223, 146, 70, 255, 224, 165, 81, 255, 220,
+ 148, 63, 255, 212, 124, 39, 255, 25, 19, 12, 215, 0, 8, 12, 11, 9,
+ 116, 196, 116, 37, 255, 218, 141, 51, 255, 218, 139, 55, 255, 218,
+ 142, 61, 255, 215, 143, 58, 255, 24, 19, 13, 212, 0, 4, 10, 9, 7,
+ 156, 203, 129, 50, 255, 221, 150, 66, 255, 220, 148, 63, 255, 25,
+ 21, 14, 227, 0, 8, 10, 10, 7, 159, 204, 134, 59, 255, 225, 160, 84,
+ 255, 225, 169, 88, 255, 36, 29, 19, 255, 0, 12, 15, 14, 10, 170,
+ 204, 130, 51, 255, 220, 142, 59, 255, 218, 139, 55, 255, 21, 18, 12,
+ 249, 0, 8, 11, 10, 8, 142, 206, 145, 67, 255, 226, 172, 95, 255,
+ 227, 174, 98, 255, 32, 26, 17, 255, 4, 4, 4, 28, 0, 8, 11, 10, 8,
+ 198, 198, 117, 37, 255, 215, 125, 38, 255, 211, 122, 36, 255, 28,
+ 21, 13, 215, 0, 8, 13, 11, 8, 96, 174, 91, 23, 255, 202, 107, 23,
+ 255, 202, 103, 23, 255, 22, 17, 9, 255, 0, 12, 11, 10, 6, 170, 176,
+ 91, 23, 255, 202, 103, 23, 255, 203, 108, 24, 255, 21, 15, 10, 238,
+ 0, 8, 11, 10, 8, 142, 206, 145, 67, 255, 226, 170, 91, 255, 224,
+ 160, 85, 255, 30, 24, 17, 255, 4, 4, 4, 28, 0, 8, 11, 10, 8, 198,
+ 209, 149, 70, 255, 224, 160, 77, 255, 222, 158, 75, 255, 31, 25, 16,
+ 212, 0, 8, 12, 11, 9, 127, 198, 116, 35, 255, 215, 125, 38, 255,
+ 211, 122, 36, 255, 28, 21, 13, 255, 4, 4, 4, 28, 0, 52, 13, 12, 8,
+ 170, 195, 112, 30, 255, 209, 110, 30, 255, 207, 105, 30, 255, 25,
+ 20, 12, 255, 0, 24, 15, 14, 10, 170, 213, 158, 80, 255, 226, 172,
+ 95, 255, 224, 164, 85, 255, 33, 27, 18, 255, 0, 12, 15, 14, 10, 170,
+ 210, 143, 65, 255, 224, 168, 87, 255, 224, 165, 81, 255, 25, 21, 14,
+ 232, 0, 8, 10, 10, 9, 153, 208, 147, 67, 255, 224, 166, 83, 255,
+ 222, 158, 75, 255, 34, 26, 17, 255, 0, 12, 15, 14, 10, 170, 211,
+ 149, 76, 255, 223, 149, 70, 255, 219, 146, 60, 255, 25, 20, 14, 235,
+ 0, 8, 10, 10, 9, 150, 204, 134, 59, 255, 224, 156, 83, 255, 224,
+ 165, 81, 255, 33, 27, 18, 255, 0, 20, 15, 14, 10, 170, 211, 150, 70,
+ 255, 226, 170, 91, 255, 226, 172, 95, 255, 33, 26, 18, 255, 0, 16,
+ 9, 9, 8, 150, 101, 74, 38, 255, 198, 145, 77, 255, 206, 157, 87,
+ 255, 202, 151, 79, 255, 197, 141, 74, 255, 200, 146, 75, 255, 180,
+ 126, 57, 255, 21, 19, 14, 227, 5, 5, 4, 28, 0, 16, 8, 7, 5, 113, 43,
+ 28, 14, 255, 187, 96, 22, 255, 181, 93, 22, 255, 98, 55, 21, 255,
+ 68, 42, 17, 255, 77, 46, 18, 255, 129, 72, 22, 255, 174, 89, 21,
+ 255, 83, 47, 18, 255, 11, 9, 6, 221, 0, 28, 6, 6, 5, 28, 16, 14, 11,
+ 195, 108, 76, 35, 255, 210, 141, 59, 255, 218, 162, 81, 255, 167,
+ 118, 54, 255, 16, 14, 11, 221, 5, 5, 5, 14, 0, 12, 15, 13, 10, 170,
+ 211, 149, 76, 255, 224, 168, 87, 255, 223, 154, 80, 255, 31, 25, 16,
+ 255, 0, 20, 6, 6, 5, 57, 34, 27, 17, 255, 203, 122, 36, 255, 208,
+ 124, 41, 255, 109, 76, 34, 255, 13, 12, 10, 142, 0, 32, 13, 11, 8,
+ 170, 176, 91, 23, 255, 202, 93, 21, 255, 196, 99, 21, 255, 28, 19,
+ 9, 170, 0, 8, 11, 9, 6, 85, 132, 71, 21, 255, 195, 99, 22, 255, 103,
+ 59, 20, 255, 11, 10, 6, 170, 3, 3, 2, 25, 6, 6, 5, 110, 55, 35, 16,
+ 255, 198, 113, 29, 255, 212, 134, 51, 255, 41, 32, 20, 210, 0, 68,
+ 21, 19, 14, 215, 217, 163, 86, 255, 49, 38, 24, 255, 0, 12, 11, 10,
+ 8, 82, 54, 43, 27, 255, 200, 135, 59, 255, 210, 137, 59, 255, 207,
+ 131, 50, 255, 205, 127, 44, 255, 199, 117, 36, 255, 195, 111, 28,
+ 255, 187, 101, 24, 255, 93, 54, 22, 255, 19, 15, 10, 227, 7, 6, 6,
+ 28, 0, 8, 10, 9, 7, 170, 195, 109, 32, 255, 218, 138, 53, 255, 224,
+ 158, 81, 255, 223, 173, 95, 255, 219, 167, 94, 255, 217, 169, 94,
+ 255, 218, 171, 97, 255, 217, 166, 92, 255, 208, 136, 59, 255, 110,
+ 68, 27, 255, 19, 15, 10, 227, 6, 6, 5, 28, 0, 12, 12, 11, 7, 170,
+ 61, 42, 20, 255, 188, 106, 33, 255, 208, 134, 55, 255, 215, 163, 82,
+ 255, 217, 166, 92, 255, 216, 167, 88, 255, 216, 167, 89, 255, 211,
+ 150, 70, 255, 146, 94, 39, 255, 26, 21, 15, 229, 9, 8, 6, 28, 0, 12,
+ 12, 10, 7, 170, 51, 32, 14, 255, 151, 80, 22, 255, 169, 91, 22, 255,
+ 173, 86, 22, 255, 169, 88, 22, 255, 173, 86, 22, 255, 180, 92, 21,
+ 255, 194, 98, 21, 255, 196, 95, 21, 255, 192, 97, 21, 255, 31, 21,
+ 10, 170, 0, 12, 12, 10, 7, 170, 57, 37, 18, 255, 189, 107, 34, 255,
+ 212, 149, 67, 255, 217, 166, 92, 255, 217, 166, 92, 255, 218, 171,
+ 97, 255, 215, 163, 82, 255, 205, 126, 48, 255, 116, 72, 29, 255, 20,
+ 16, 11, 227, 6, 6, 5, 28, 0, 8, 11, 9, 6, 68, 126, 68, 21, 255, 191,
+ 98, 22, 255, 194, 98, 21, 255, 192, 97, 21, 255, 192, 97, 21, 255,
+ 191, 98, 22, 255, 177, 91, 22, 255, 26, 19, 9, 142, 0, 12, 12, 10,
+ 7, 170, 58, 37, 17, 255, 185, 107, 30, 255, 208, 134, 55, 255, 216,
+ 167, 88, 255, 218, 171, 97, 255, 217, 166, 92, 255, 213, 148, 72,
+ 255, 204, 130, 51, 255, 209, 141, 60, 255, 211, 159, 76, 255, 30,
+ 25, 17, 170, 0, 8, 10, 10, 7, 167, 210, 155, 77, 255, 228, 178, 99,
+ 255, 224, 165, 81, 255, 221, 165, 86, 255, 217, 166, 92, 255, 218,
+ 169, 93, 255, 217, 166, 92, 255, 214, 156, 81, 255, 206, 135, 51,
+ 255, 116, 72, 29, 255, 20, 16, 11, 227, 6, 6, 5, 28, 0, 8, 13, 10,
+ 6, 57, 115, 62, 20, 255, 169, 91, 22, 255, 165, 86, 22, 255, 24, 18,
+ 9, 167, 0, 24, 12, 10, 7, 88, 117, 63, 20, 255, 186, 100, 23, 255,
+ 191, 107, 32, 255, 35, 27, 16, 144, 0, 8, 10, 10, 7, 170, 210, 155,
+ 77, 255, 228, 178, 99, 255, 221, 152, 70, 255, 24, 19, 13, 255, 0,
+ 8, 12, 10, 7, 170, 58, 36, 15, 255, 157, 79, 22, 255, 151, 80, 22,
+ 255, 58, 35, 15, 255, 11, 9, 6, 57, 0, 8, 12, 10, 7, 85, 157, 81,
+ 20, 255, 197, 99, 20, 255, 192, 97, 21, 255, 28, 20, 9, 170, 0, 8,
+ 11, 9, 6, 57, 115, 62, 20, 255, 189, 94, 24, 255, 198, 117, 37, 255,
+ 213, 157, 76, 255, 218, 171, 97, 255, 217, 169, 94, 255, 214, 161,
+ 85, 255, 213, 157, 76, 255, 212, 149, 67, 255, 208, 134, 55, 255,
+ 205, 126, 48, 255, 143, 96, 40, 255, 28, 26, 19, 229, 8, 8, 7, 28,
+ 0, 8, 13, 12, 8, 85, 141, 74, 24, 255, 190, 94, 23, 255, 183, 95,
+ 24, 255, 183, 95, 24, 255, 187, 93, 24, 255, 189, 97, 22, 255, 181,
+ 93, 22, 255, 177, 91, 22, 255, 169, 88, 22, 255, 89, 52, 20, 255,
+ 21, 18, 12, 227, 9, 9, 8, 28, 0, 12, 18, 17, 13, 181, 103, 74, 40,
+ 255, 207, 146, 74, 255, 214, 156, 81, 255, 210, 144, 67, 255, 208,
+ 138, 55, 255, 207, 129, 52, 255, 205, 133, 48, 255, 205, 126, 48,
+ 255, 151, 101, 42, 255, 28, 26, 19, 232, 9, 8, 8, 28, 0, 8, 13, 12,
+ 10, 110, 186, 127, 63, 255, 214, 156, 81, 255, 213, 158, 80, 255,
+ 213, 155, 80, 255, 214, 156, 81, 255, 214, 153, 75, 255, 213, 148,
+ 72, 255, 213, 148, 72, 255, 211, 150, 70, 255, 159, 111, 54, 255,
+ 28, 25, 19, 241, 9, 8, 8, 31, 0, 12, 18, 17, 13, 181, 103, 74, 40,
+ 255, 208, 156, 81, 255, 214, 156, 81, 255, 208, 138, 55, 255, 209,
+ 137, 60, 255, 213, 158, 80, 255, 213, 155, 80, 255, 213, 160, 84,
+ 255, 215, 160, 88, 255, 213, 163, 84, 255, 30, 24, 17, 178, 0, 8,
+ 12, 11, 9, 93, 178, 121, 53, 255, 213, 158, 80, 255, 210, 143, 65,
+ 255, 211, 146, 62, 255, 213, 148, 72, 255, 215, 163, 82, 255, 213,
+ 158, 80, 255, 212, 149, 67, 255, 209, 141, 60, 255, 153, 106, 49,
+ 255, 28, 25, 19, 235, 9, 9, 8, 31, 0, 12, 18, 15, 11, 173, 66, 43,
+ 21, 255, 187, 101, 32, 255, 207, 132, 52, 255, 210, 144, 67, 255,
+ 213, 148, 72, 255, 214, 156, 81, 255, 216, 167, 88, 255, 214, 156,
+ 81, 255, 176, 128, 65, 255, 46, 39, 27, 255, 0, 12, 15, 14, 10, 85,
+ 181, 111, 42, 255, 215, 136, 52, 255, 213, 125, 40, 255, 211, 122,
+ 36, 255, 212, 123, 37, 255, 210, 123, 39, 255, 202, 122, 37, 255,
+ 31, 24, 14, 170, 0, 8, 12, 11, 9, 88, 164, 89, 29, 255, 203, 122,
+ 36, 255, 199, 117, 36, 255, 30, 23, 15, 212, 0, 12, 15, 13, 10, 127,
+ 187, 133, 62, 255, 213, 148, 72, 255, 208, 138, 55, 255, 31, 24, 16,
+ 170, 0, 8, 13, 12, 10, 85, 172, 104, 37, 255, 209, 134, 54, 255,
+ 206, 135, 51, 255, 32, 25, 17, 212, 0, 12, 15, 13, 10, 127, 181,
+ 116, 46, 255, 211, 143, 62, 255, 210, 153, 71, 255, 29, 24, 16, 178,
+ 0, 8, 13, 12, 10, 91, 178, 121, 53, 255, 213, 154, 70, 255, 208,
+ 134, 55, 255, 31, 25, 16, 210, 0, 20, 15, 14, 10, 125, 179, 110, 42,
+ 255, 210, 135, 55, 255, 208, 139, 65, 255, 26, 21, 15, 184, 0, 8,
+ 14, 13, 9, 85, 179, 117, 44, 255, 217, 165, 82, 255, 213, 163, 84,
+ 255, 27, 23, 16, 221, 0, 12, 14, 12, 9, 136, 174, 103, 39, 255, 206,
+ 127, 43, 255, 199, 117, 36, 255, 31, 24, 14, 170, 0, 8, 12, 11, 9,
+ 88, 164, 89, 29, 255, 202, 118, 35, 255, 196, 114, 33, 255, 29, 22,
+ 14, 210, 0, 12, 14, 12, 9, 125, 169, 95, 30, 255, 202, 119, 37, 255,
+ 199, 119, 39, 255, 24, 19, 13, 190, 0, 8, 14, 12, 9, 85, 170, 95,
+ 29, 255, 198, 113, 29, 255, 199, 116, 34, 255, 204, 128, 47, 255,
+ 206, 135, 51, 255, 204, 129, 49, 255, 204, 129, 49, 255, 208, 134,
+ 55, 255, 211, 149, 76, 255, 192, 140, 73, 255, 95, 74, 39, 255, 17,
+ 15, 12, 85, 0, 16, 14, 12, 9, 198, 211, 150, 70, 255, 206, 152, 81,
+ 255, 31, 26, 20, 255, 7, 7, 6, 48, 0, 16, 15, 13, 10, 170, 211, 149,
+ 76, 255, 226, 170, 91, 255, 226, 172, 95, 255, 35, 28, 18, 255, 0,
+ 20, 15, 14, 12, 218, 171, 120, 60, 255, 219, 154, 70, 255, 41, 31,
+ 20, 255, 4, 4, 3, 28, 0, 104, 17, 16, 12, 170, 219, 179, 116, 255,
+ 232, 193, 137, 255, 232, 199, 135, 255, 40, 33, 23, 255, 0, 12, 10,
+ 10, 9, 76, 62, 50, 31, 255, 20, 18, 13, 167, 0, 12, 11, 10, 8, 76,
+ 58, 46, 29, 255, 20, 18, 13, 167, 0, 16, 13, 12, 10, 170, 210, 150,
+ 71, 255, 223, 147, 72, 255, 221, 150, 66, 255, 26, 21, 15, 210, 0,
+ 4, 11, 10, 8, 119, 211, 159, 84, 255, 229, 184, 114, 255, 230, 186,
+ 123, 255, 30, 26, 19, 255, 0, 16, 12, 11, 9, 93, 137, 90, 40, 255,
+ 223, 167, 94, 255, 228, 180, 111, 255, 167, 133, 80, 255, 17, 16,
+ 14, 227, 11, 11, 10, 170, 12, 11, 9, 170, 12, 11, 9, 170, 12, 11, 9,
+ 119, 7, 7, 6, 57, 0, 36, 7, 7, 6, 62, 21, 18, 12, 227, 157, 92, 28,
+ 255, 203, 105, 26, 255, 197, 106, 26, 255, 82, 48, 21, 255, 14, 12,
+ 7, 173, 5, 5, 4, 8, 0, 16, 8, 7, 5, 28, 26, 19, 11, 227, 103, 68,
+ 25, 255, 158, 96, 29, 255, 57, 41, 22, 255, 13, 12, 10, 241, 33, 26,
+ 16, 255, 146, 88, 31, 255, 66, 47, 23, 255, 12, 10, 9, 201, 6, 5, 5,
+ 14, 0, 32, 8, 7, 5, 57, 30, 22, 11, 255, 15, 12, 8, 96, 0, 8, 10,
+ 10, 7, 130, 190, 104, 27, 255, 209, 118, 30, 255, 211, 117, 34, 255,
+ 27, 21, 14, 255, 0, 24, 13, 12, 10, 170, 199, 122, 39, 255, 218,
+ 130, 51, 255, 223, 146, 70, 255, 30, 24, 17, 255, 0, 12, 23, 22, 18,
+ 139, 30, 27, 21, 170, 16, 15, 11, 255, 89, 59, 26, 255, 203, 110,
+ 28, 255, 196, 113, 31, 255, 122, 81, 33, 255, 186, 117, 43, 255,
+ 216, 129, 51, 255, 184, 126, 57, 255, 38, 34, 25, 255, 24, 22, 19,
+ 221, 33, 30, 24, 170, 15, 15, 12, 28, 0, 12, 24, 22, 19, 142, 32,
+ 31, 25, 170, 21, 20, 16, 198, 90, 71, 45, 255, 223, 179, 110, 255,
+ 226, 172, 95, 255, 221, 150, 66, 255, 143, 100, 44, 255, 22, 21, 17,
+ 227, 28, 27, 21, 170, 29, 28, 22, 170, 13, 13, 12, 42, 0, 36, 8, 8,
+ 8, 11, 25, 24, 20, 142, 39, 35, 28, 170, 30, 28, 23, 170, 29, 27,
+ 22, 170, 29, 27, 22, 170, 29, 27, 22, 170, 29, 27, 22, 170, 29, 27,
+ 20, 170, 23, 21, 16, 170, 14, 13, 11, 34, 0, 52, 13, 12, 10, 159,
+ 142, 86, 31, 255, 208, 116, 35, 255, 201, 119, 38, 255, 32, 26, 17,
+ 255, 5, 5, 4, 28, 0, 12, 14, 13, 11, 170, 216, 167, 97, 255, 231,
+ 184, 124, 255, 231, 193, 128, 255, 181, 146, 92, 255, 52, 44, 33,
+ 255, 90, 71, 45, 255, 201, 155, 88, 255, 223, 173, 102, 255, 228,
+ 179, 115, 255, 230, 183, 123, 255, 230, 184, 119, 255, 39, 32, 22,
+ 255, 0, 24, 12, 12, 11, 170, 206, 139, 61, 255, 226, 164, 91, 255,
+ 228, 174, 103, 255, 39, 32, 22, 255, 0, 48, 6, 6, 5, 28, 9, 9, 8,
+ 142, 56, 46, 31, 255, 222, 180, 113, 255, 230, 187, 119, 255, 222,
+ 180, 113, 255, 23, 21, 16, 255, 0, 36, 15, 14, 12, 164, 79, 59, 30,
+ 255, 209, 128, 42, 255, 211, 127, 44, 255, 171, 117, 46, 255, 18,
+ 15, 11, 170, 0, 16, 9, 9, 8, 116, 33, 28, 16, 255, 161, 94, 28, 255,
+ 199, 107, 26, 255, 65, 40, 18, 255, 8, 7, 5, 255, 25, 20, 12, 255,
+ 198, 113, 29, 255, 210, 120, 33, 255, 217, 133, 50, 255, 27, 23, 16,
+ 255, 0, 8, 7, 7, 6, 23, 34, 28, 19, 198, 46, 36, 25, 255, 39, 31,
+ 22, 255, 41, 33, 22, 255, 59, 46, 28, 255, 51, 40, 26, 255, 61, 47,
+ 28, 255, 180, 133, 71, 255, 227, 175, 100, 255, 226, 175, 103, 255,
+ 181, 143, 88, 255, 17, 16, 12, 142, 0, 8, 11, 11, 10, 170, 214, 166,
+ 97, 255, 229, 179, 114, 255, 228, 185, 111, 255, 161, 121, 68, 255,
+ 23, 21, 16, 227, 23, 22, 18, 170, 22, 21, 17, 170, 16, 15, 13, 170,
+ 11, 11, 8, 147, 8, 8, 7, 85, 0, 40, 14, 13, 11, 170, 181, 143, 88,
+ 255, 228, 185, 123, 255, 218, 168, 97, 255, 70, 54, 35, 255, 9, 9,
+ 8, 113, 0, 12, 11, 10, 8, 85, 120, 87, 45, 255, 223, 183, 120, 255,
+ 231, 190, 132, 255, 167, 135, 80, 255, 24, 22, 19, 227, 19, 18, 16,
+ 170, 19, 18, 16, 198, 95, 80, 46, 255, 226, 193, 129, 255, 228, 187,
+ 129, 255, 186, 148, 87, 255, 15, 14, 12, 170, 0, 8, 10, 10, 9, 85,
+ 155, 113, 64, 255, 229, 196, 132, 255, 232, 191, 133, 255, 179, 142,
+ 90, 255, 27, 25, 20, 227, 18, 18, 15, 170, 19, 18, 16, 198, 90, 71,
+ 45, 255, 222, 175, 101, 255, 227, 174, 98, 255, 228, 185, 111, 255,
+ 28, 25, 19, 255, 0, 8, 7, 7, 6, 23, 34, 28, 19, 198, 49, 35, 22,
+ 255, 39, 29, 18, 227, 12, 11, 9, 85, 0, 8, 8, 7, 7, 28, 33, 26, 16,
+ 198, 52, 39, 23, 255, 47, 35, 22, 227, 13, 12, 8, 85, 0, 8, 8, 8, 7,
+ 28, 33, 30, 24, 227, 201, 157, 100, 255, 230, 186, 123, 255, 181,
+ 137, 74, 255, 16, 15, 11, 207, 6, 6, 5, 23, 0, 24, 11, 10, 8, 28,
+ 27, 21, 12, 193, 26, 19, 11, 255, 23, 18, 10, 255, 23, 18, 10, 255,
+ 24, 18, 11, 255, 24, 18, 11, 255, 26, 20, 11, 255, 35, 27, 16, 255,
+ 42, 31, 19, 241, 17, 14, 10, 85, 0, 28, 9, 9, 8, 144, 91, 67, 36,
+ 255, 217, 154, 72, 255, 211, 150, 70, 255, 69, 55, 34, 255, 15, 14,
+ 12, 85, 0, 28, 6, 6, 5, 11, 11, 11, 10, 142, 24, 22, 19, 255, 167,
+ 135, 80, 255, 225, 172, 104, 255, 224, 166, 83, 255, 193, 126, 54,
+ 255, 16, 14, 11, 170, 0, 8, 13, 12, 8, 85, 185, 97, 26, 255, 207,
+ 112, 28, 255, 204, 110, 27, 255, 71, 46, 22, 255, 8, 8, 7, 255, 28,
+ 22, 13, 255, 198, 107, 27, 255, 193, 111, 30, 255, 126, 78, 31, 255,
+ 199, 139, 62, 255, 226, 184, 111, 255, 27, 24, 18, 255, 0, 8, 11,
+ 10, 8, 170, 214, 166, 97, 255, 230, 187, 119, 255, 228, 179, 103,
+ 255, 143, 102, 48, 255, 17, 16, 12, 227, 12, 12, 9, 170, 13, 12, 10,
+ 198, 46, 33, 17, 255, 199, 112, 28, 255, 206, 111, 27, 255, 204,
+ 110, 27, 255, 32, 23, 13, 176, 0, 8, 12, 11, 9, 136, 204, 134, 59,
+ 255, 226, 172, 95, 255, 228, 181, 107, 255, 162, 125, 73, 255, 24,
+ 22, 19, 227, 19, 18, 16, 170, 19, 18, 16, 198, 95, 80, 46, 255, 224,
+ 179, 109, 255, 223, 173, 95, 255, 173, 117, 50, 255, 15, 13, 10,
+ 156, 0, 8, 12, 11, 7, 99, 185, 97, 26, 255, 208, 112, 27, 255, 204,
+ 110, 27, 255, 22, 18, 11, 255, 0, 40, 16, 15, 13, 170, 219, 179,
+ 116, 255, 232, 194, 133, 255, 231, 193, 128, 255, 40, 33, 23, 255,
+ 0, 12, 16, 15, 13, 170, 219, 177, 112, 255, 230, 187, 119, 255, 224,
+ 159, 83, 255, 24, 21, 15, 255, 0, 8, 11, 10, 8, 164, 211, 158, 82,
+ 255, 229, 184, 114, 255, 230, 191, 123, 255, 166, 127, 77, 255, 22,
+ 21, 17, 227, 22, 21, 17, 170, 20, 19, 13, 170, 14, 13, 11, 28, 0,
+ 16, 12, 11, 9, 170, 195, 112, 30, 255, 209, 106, 30, 255, 206, 111,
+ 27, 255, 101, 63, 26, 255, 16, 14, 11, 227, 23, 21, 16, 170, 29, 27,
+ 22, 170, 13, 13, 12, 42, 0, 16, 16, 15, 13, 170, 216, 167, 97, 255,
+ 224, 158, 87, 255, 216, 125, 45, 255, 24, 20, 13, 255, 0, 40, 17,
+ 16, 12, 170, 219, 177, 112, 255, 232, 195, 137, 255, 231, 189, 128,
+ 255, 162, 125, 73, 255, 22, 21, 17, 227, 14, 14, 11, 170, 13, 12,
+ 10, 198, 50, 35, 19, 255, 199, 112, 28, 255, 206, 111, 27, 255, 204,
+ 110, 27, 255, 32, 24, 13, 170, 0, 8, 13, 12, 8, 93, 194, 109, 33,
+ 255, 219, 139, 54, 255, 224, 158, 81, 255, 39, 32, 22, 255, 0, 40,
+ 11, 10, 8, 170, 190, 104, 27, 255, 208, 112, 27, 255, 204, 110, 27,
+ 255, 32, 24, 13, 170, 0, 8, 13, 12, 8, 85, 184, 96, 25, 255, 207,
+ 112, 28, 255, 204, 102, 27, 255, 129, 78, 28, 255, 31, 26, 16, 255,
+ 127, 84, 34, 255, 219, 147, 70, 255, 173, 122, 62, 255, 15, 14, 12,
+ 212, 6, 6, 5, 25, 0, 16, 16, 15, 13, 170, 213, 155, 80, 255, 221,
+ 144, 68, 255, 217, 130, 52, 255, 31, 25, 16, 255, 0, 32, 10, 9, 7,
+ 170, 189, 99, 26, 255, 208, 112, 27, 255, 204, 110, 27, 255, 155,
+ 87, 26, 255, 72, 46, 21, 255, 179, 103, 36, 255, 223, 156, 76, 255,
+ 216, 170, 97, 255, 134, 96, 47, 255, 174, 127, 71, 255, 221, 167,
+ 90, 255, 223, 147, 72, 255, 222, 158, 75, 255, 23, 19, 14, 252, 0,
+ 8, 11, 10, 8, 170, 214, 166, 97, 255, 231, 187, 124, 255, 230, 191,
+ 123, 255, 228, 182, 117, 255, 222, 175, 101, 255, 64, 50, 33, 255,
+ 7, 7, 6, 229, 26, 23, 19, 255, 220, 175, 105, 255, 228, 183, 113,
+ 255, 228, 188, 117, 255, 25, 21, 16, 255, 0, 8, 11, 10, 8, 170, 217,
+ 176, 112, 255, 232, 197, 137, 255, 232, 199, 135, 255, 37, 31, 22,
+ 255, 0, 12, 13, 12, 10, 170, 198, 117, 37, 255, 215, 127, 42, 255,
+ 217, 130, 52, 255, 21, 19, 14, 255, 0, 8, 11, 10, 8, 167, 215, 172,
+ 104, 255, 232, 191, 133, 255, 231, 190, 132, 255, 166, 127, 77, 255,
+ 23, 21, 16, 227, 18, 17, 15, 170, 17, 16, 12, 198, 74, 52, 27, 255,
+ 204, 117, 33, 255, 211, 111, 30, 255, 173, 93, 28, 255, 15, 12, 8,
+ 164, 0, 8, 13, 12, 8, 88, 185, 97, 26, 255, 208, 112, 27, 255, 204,
+ 110, 27, 255, 19, 16, 10, 255, 0, 12, 10, 9, 7, 170, 190, 104, 27,
+ 255, 212, 118, 35, 255, 216, 136, 51, 255, 21, 19, 14, 252, 0, 8,
+ 11, 10, 8, 167, 215, 172, 104, 255, 232, 194, 127, 255, 231, 193,
+ 128, 255, 166, 129, 77, 255, 23, 21, 16, 227, 19, 18, 16, 170, 19,
+ 18, 14, 198, 81, 59, 34, 255, 213, 144, 62, 255, 215, 140, 60, 255,
+ 165, 108, 40, 255, 13, 12, 10, 167, 0, 8, 8, 8, 7, 85, 101, 63, 26,
+ 255, 206, 114, 33, 255, 212, 121, 33, 255, 155, 92, 36, 255, 23, 21,
+ 16, 227, 22, 21, 17, 170, 28, 26, 21, 170, 21, 20, 18, 170, 13, 13,
+ 12, 164, 10, 10, 9, 85, 6, 6, 6, 6, 0, 28, 12, 11, 9, 170, 194, 112,
+ 31, 255, 212, 119, 37, 255, 216, 134, 45, 255, 35, 28, 18, 255, 0,
+ 24, 16, 15, 13, 170, 217, 171, 106, 255, 231, 187, 124, 255, 228,
+ 181, 107, 255, 39, 32, 22, 255, 0, 12, 16, 15, 11, 170, 208, 134,
+ 55, 255, 223, 156, 70, 255, 221, 148, 70, 255, 23, 20, 14, 238, 0,
+ 8, 11, 10, 8, 170, 204, 136, 55, 255, 223, 156, 70, 255, 222, 158,
+ 75, 255, 34, 28, 19, 255, 0, 12, 14, 13, 11, 170, 217, 171, 106,
+ 255, 232, 189, 127, 255, 230, 186, 123, 255, 25, 22, 16, 255, 0, 8,
+ 10, 10, 9, 167, 210, 155, 77, 255, 226, 172, 95, 255, 224, 165, 81,
+ 255, 31, 26, 18, 255, 0, 20, 15, 13, 12, 170, 217, 173, 104, 255,
+ 232, 191, 133, 255, 231, 195, 132, 255, 40, 33, 23, 255, 0, 20, 10,
+ 9, 9, 133, 73, 58, 36, 255, 225, 184, 120, 255, 231, 193, 128, 255,
+ 228, 180, 111, 255, 147, 102, 48, 255, 15, 13, 10, 227, 8, 7, 7, 28,
+ 0, 24, 12, 11, 7, 198, 100, 59, 23, 255, 169, 93, 26, 255, 156, 91,
+ 27, 255, 174, 96, 27, 255, 180, 99, 27, 255, 168, 97, 27, 255, 105,
+ 62, 24, 255, 18, 15, 9, 255, 7, 6, 6, 48, 0, 24, 7, 7, 7, 28, 15,
+ 15, 12, 227, 144, 114, 67, 255, 219, 177, 112, 255, 223, 176, 102,
+ 255, 153, 113, 62, 255, 17, 16, 12, 227, 7, 7, 6, 28, 0, 16, 16, 15,
+ 13, 170, 213, 155, 80, 255, 223, 146, 70, 255, 217, 129, 50, 255,
+ 27, 22, 14, 255, 0, 24, 12, 10, 9, 195, 161, 94, 28, 255, 207, 114,
+ 32, 255, 193, 114, 36, 255, 23, 20, 16, 255, 0, 32, 12, 11, 9, 170,
+ 191, 105, 28, 255, 207, 100, 28, 255, 204, 110, 27, 255, 26, 20, 11,
+ 204, 0, 8, 6, 5, 5, 3, 26, 19, 9, 198, 24, 18, 9, 246, 15, 12, 8,
+ 142, 0, 12, 15, 13, 10, 91, 31, 24, 16, 244, 51, 39, 24, 255, 21,
+ 19, 14, 91, 0, 68, 10, 10, 9, 76, 61, 49, 30, 255, 20, 18, 13, 156,
+ 0, 16, 17, 15, 12, 142, 27, 22, 14, 232, 30, 22, 13, 255, 25, 20,
+ 12, 255, 22, 18, 11, 238, 21, 16, 10, 255, 99, 58, 22, 255, 203,
+ 113, 26, 255, 205, 111, 28, 255, 131, 80, 30, 255, 12, 11, 9, 142,
+ 0, 8, 11, 10, 8, 170, 212, 160, 85, 255, 232, 191, 127, 255, 231,
+ 195, 132, 255, 196, 155, 91, 255, 81, 59, 34, 255, 41, 32, 20, 255,
+ 54, 43, 27, 255, 180, 133, 71, 255, 216, 144, 59, 255, 208, 115, 33,
+ 255, 129, 78, 28, 255, 12, 11, 7, 142, 0, 8, 8, 7, 7, 57, 72, 52,
+ 29, 255, 215, 155, 78, 255, 227, 174, 98, 255, 207, 158, 94, 255,
+ 85, 63, 34, 255, 36, 29, 19, 255, 57, 43, 26, 255, 189, 130, 66,
+ 255, 219, 149, 66, 255, 212, 121, 41, 255, 172, 105, 33, 255, 17,
+ 15, 10, 147, 0, 8, 7, 6, 6, 54, 58, 40, 21, 255, 198, 113, 29, 255,
+ 206, 103, 27, 255, 165, 87, 24, 255, 42, 28, 13, 255, 21, 16, 8,
+ 255, 27, 20, 10, 255, 95, 60, 22, 255, 202, 105, 27, 255, 206, 100,
+ 29, 255, 204, 110, 27, 255, 35, 24, 12, 170, 0, 8, 7, 7, 6, 54, 70,
+ 50, 27, 255, 212, 145, 65, 255, 227, 174, 98, 255, 201, 155, 88,
+ 255, 59, 44, 28, 255, 23, 20, 14, 255, 34, 28, 19, 255, 157, 104,
+ 48, 255, 211, 126, 42, 255, 208, 115, 33, 255, 132, 82, 29, 255, 13,
+ 11, 8, 142, 0, 12, 24, 18, 9, 221, 108, 61, 23, 255, 201, 112, 26,
+ 255, 207, 112, 28, 255, 204, 110, 27, 255, 158, 91, 25, 255, 46, 29,
+ 13, 249, 11, 10, 6, 57, 0, 8, 8, 8, 7, 57, 70, 50, 27, 255, 212,
+ 142, 59, 255, 226, 172, 95, 255, 207, 158, 94, 255, 85, 63, 34, 255,
+ 41, 32, 20, 255, 57, 43, 26, 255, 174, 124, 59, 255, 224, 170, 93,
+ 255, 229, 184, 114, 255, 231, 196, 128, 255, 28, 25, 19, 255, 0, 8,
+ 10, 10, 9, 167, 215, 169, 102, 255, 232, 191, 127, 255, 231, 193,
+ 128, 255, 196, 154, 87, 255, 77, 59, 34, 255, 41, 31, 20, 255, 54,
+ 43, 27, 255, 168, 113, 49, 255, 212, 121, 41, 255, 206, 114, 33,
+ 255, 132, 82, 29, 255, 12, 11, 9, 130, 0, 8, 12, 11, 7, 110, 188,
+ 98, 25, 255, 206, 111, 27, 255, 206, 106, 25, 255, 26, 19, 11, 255,
+ 0, 24, 14, 12, 9, 170, 199, 117, 36, 255, 221, 148, 62, 255, 227,
+ 174, 98, 255, 28, 26, 19, 255, 0, 8, 10, 10, 9, 167, 212, 161, 89,
+ 255, 224, 166, 83, 255, 217, 129, 50, 255, 32, 24, 15, 255, 5, 5, 4,
+ 31, 7, 7, 6, 136, 65, 44, 22, 255, 192, 106, 29, 255, 203, 108, 24,
+ 255, 114, 66, 23, 255, 17, 13, 8, 221, 0, 12, 10, 9, 7, 139, 185,
+ 97, 26, 255, 208, 112, 27, 255, 208, 117, 29, 255, 32, 24, 13, 170,
+ 0, 8, 15, 13, 8, 91, 189, 99, 26, 255, 215, 123, 42, 255, 226, 172,
+ 95, 255, 198, 152, 87, 255, 81, 58, 34, 255, 176, 133, 71, 255, 224,
+ 168, 95, 255, 197, 138, 62, 255, 65, 47, 26, 255, 133, 81, 30, 255,
+ 208, 121, 37, 255, 212, 115, 37, 255, 152, 98, 35, 255, 12, 11, 9,
+ 142, 0, 8, 10, 9, 7, 147, 190, 107, 25, 255, 206, 111, 27, 255, 206,
+ 106, 25, 255, 158, 91, 25, 255, 42, 28, 13, 255, 21, 15, 8, 255, 26,
+ 19, 9, 255, 114, 66, 23, 255, 204, 113, 25, 255, 208, 115, 33, 255,
+ 173, 122, 62, 255, 16, 15, 13, 150, 0, 8, 8, 8, 7, 71, 110, 87, 51,
+ 255, 222, 180, 113, 255, 224, 166, 83, 255, 209, 137, 60, 255, 133,
+ 84, 32, 255, 77, 50, 24, 255, 89, 59, 26, 255, 181, 109, 32, 255,
+ 210, 121, 35, 255, 212, 121, 41, 255, 171, 116, 52, 255, 15, 14, 12,
+ 142, 0, 8, 14, 13, 11, 170, 219, 177, 112, 255, 231, 187, 124, 255,
+ 228, 180, 111, 255, 205, 158, 90, 255, 79, 58, 32, 255, 38, 29, 19,
+ 255, 49, 35, 22, 255, 167, 114, 46, 255, 217, 146, 62, 255, 219,
+ 154, 70, 255, 169, 117, 56, 255, 15, 13, 12, 156, 0, 8, 8, 8, 7, 71,
+ 104, 80, 45, 255, 224, 183, 119, 255, 232, 191, 127, 255, 210, 166,
+ 97, 255, 81, 60, 32, 255, 39, 30, 18, 255, 52, 40, 25, 255, 175,
+ 128, 66, 255, 225, 173, 98, 255, 228, 180, 105, 255, 226, 175, 95,
+ 255, 29, 25, 18, 255, 0, 8, 12, 12, 11, 170, 208, 138, 55, 255, 222,
+ 145, 63, 255, 220, 139, 59, 255, 193, 121, 50, 255, 68, 50, 29, 255,
+ 38, 28, 19, 255, 48, 35, 23, 255, 175, 112, 44, 255, 217, 142, 54,
+ 255, 217, 144, 66, 255, 191, 137, 66, 255, 19, 16, 12, 170, 0, 8, 9,
+ 8, 8, 74, 111, 82, 40, 255, 216, 155, 75, 255, 226, 172, 95, 255,
+ 200, 151, 81, 255, 57, 41, 26, 255, 27, 23, 16, 255, 35, 28, 18,
+ 255, 41, 32, 20, 255, 39, 30, 20, 255, 25, 22, 16, 227, 15, 14, 10,
+ 142, 0, 12, 10, 9, 7, 28, 33, 24, 14, 227, 135, 81, 28, 255, 206,
+ 117, 31, 255, 210, 108, 33, 255, 208, 110, 31, 255, 171, 92, 28,
+ 255, 49, 33, 16, 252, 13, 11, 8, 68, 0, 8, 11, 10, 8, 170, 195, 108,
+ 30, 255, 212, 118, 35, 255, 217, 137, 52, 255, 42, 33, 23, 255, 0,
+ 12, 20, 18, 15, 170, 214, 156, 81, 255, 221, 148, 62, 255, 214, 127,
+ 43, 255, 23, 19, 12, 238, 0, 8, 10, 10, 7, 159, 196, 109, 31, 255,
+ 213, 119, 36, 255, 212, 123, 37, 255, 31, 24, 14, 255, 0, 12, 15,
+ 14, 10, 170, 209, 137, 60, 255, 228, 172, 99, 255, 230, 189, 119,
+ 255, 28, 26, 19, 255, 0, 8, 12, 12, 11, 170, 208, 134, 55, 255, 218,
+ 137, 51, 255, 214, 127, 43, 255, 35, 27, 16, 255, 0, 20, 16, 14, 11,
+ 170, 199, 116, 34, 255, 217, 132, 48, 255, 224, 166, 83, 255, 32,
+ 26, 19, 255, 0, 8, 10, 10, 7, 34, 81, 58, 34, 255, 224, 178, 105,
+ 255, 226, 172, 95, 255, 129, 92, 40, 255, 9, 9, 8, 170, 6, 6, 6, 85,
+ 6, 6, 5, 113, 35, 27, 16, 255, 204, 117, 33, 255, 208, 117, 29, 255,
+ 110, 69, 25, 255, 14, 12, 7, 108, 0, 8, 10, 10, 7, 170, 195, 112,
+ 30, 255, 211, 115, 30, 255, 211, 115, 30, 255, 30, 23, 13, 255, 0,
+ 12, 14, 12, 9, 170, 196, 113, 31, 255, 211, 120, 32, 255, 214, 126,
+ 41, 255, 33, 26, 18, 255, 0, 8, 9, 8, 6, 28, 44, 33, 19, 212, 60,
+ 42, 23, 255, 46, 35, 21, 255, 74, 53, 31, 255, 156, 109, 53, 255,
+ 216, 167, 97, 255, 228, 179, 109, 255, 229, 177, 110, 255, 227, 184,
+ 108, 255, 168, 123, 69, 255, 23, 21, 16, 227, 9, 8, 8, 28, 0, 12,
+ 17, 16, 14, 170, 134, 98, 51, 255, 223, 166, 92, 255, 132, 100, 53,
+ 255, 9, 9, 8, 133, 0, 20, 16, 15, 13, 170, 219, 177, 112, 255, 232,
+ 191, 133, 255, 231, 195, 132, 255, 40, 33, 23, 255, 0, 20, 6, 6, 5,
+ 45, 39, 32, 22, 255, 210, 129, 49, 255, 172, 106, 35, 255, 20, 17,
+ 13, 227, 11, 11, 8, 28, 0, 100, 17, 17, 14, 170, 221, 189, 132, 255,
+ 235, 205, 154, 255, 234, 205, 155, 255, 42, 39, 29, 255, 0, 16, 9,
+ 9, 8, 25, 0, 20, 9, 8, 8, 25, 0, 20, 14, 14, 11, 170, 208, 141, 61,
+ 255, 224, 168, 87, 255, 228, 174, 103, 255, 31, 26, 20, 221, 0, 4,
+ 13, 12, 12, 130, 218, 185, 127, 255, 234, 202, 147, 255, 232, 198,
+ 139, 255, 40, 33, 25, 255, 0, 20, 17, 17, 14, 176, 140, 115, 71,
+ 255, 230, 202, 147, 255, 232, 202, 149, 255, 218, 170, 101, 255,
+ 200, 124, 43, 255, 198, 117, 37, 255, 198, 117, 37, 255, 196, 116,
+ 37, 255, 72, 52, 27, 255, 12, 11, 9, 170, 0, 28, 8, 8, 7, 85, 37,
+ 31, 20, 255, 174, 110, 41, 255, 210, 123, 39, 255, 204, 120, 37,
+ 255, 130, 87, 31, 255, 15, 13, 10, 190, 0, 28, 5, 5, 4, 113, 28, 26,
+ 19, 255, 210, 143, 65, 255, 220, 163, 81, 255, 217, 166, 92, 255,
+ 222, 173, 97, 255, 225, 176, 98, 255, 42, 37, 25, 255, 4, 4, 4, 74,
+ 0, 56, 13, 12, 10, 170, 208, 141, 61, 255, 226, 172, 95, 255, 228,
+ 183, 111, 255, 40, 34, 25, 255, 0, 24, 17, 16, 14, 170, 219, 177,
+ 112, 255, 232, 194, 133, 255, 233, 202, 148, 255, 27, 24, 20, 255,
+ 0, 8, 16, 15, 13, 85, 199, 161, 102, 255, 220, 166, 89, 255, 211,
+ 143, 62, 255, 217, 154, 72, 255, 223, 161, 80, 255, 224, 169, 91,
+ 255, 225, 185, 114, 255, 229, 188, 124, 255, 231, 190, 132, 255,
+ 231, 200, 143, 255, 227, 195, 140, 255, 227, 196, 138, 255, 225,
+ 195, 136, 255, 44, 37, 27, 170, 0, 8, 17, 16, 14, 85, 200, 165, 109,
+ 255, 227, 198, 142, 255, 225, 191, 132, 255, 227, 195, 134, 255,
+ 231, 199, 136, 255, 231, 197, 132, 255, 231, 194, 124, 255, 229,
+ 191, 130, 255, 225, 195, 136, 255, 225, 195, 136, 255, 225, 191,
+ 132, 255, 49, 42, 30, 198, 0, 36, 18, 17, 13, 105, 193, 135, 66,
+ 255, 221, 175, 102, 255, 222, 186, 123, 255, 223, 190, 132, 255,
+ 224, 192, 135, 255, 223, 190, 132, 255, 222, 186, 123, 255, 221,
+ 178, 110, 255, 218, 172, 105, 255, 46, 39, 27, 195, 0, 48, 6, 6, 6,
+ 28, 27, 26, 20, 255, 216, 170, 97, 255, 225, 178, 104, 255, 176,
+ 136, 83, 255, 16, 15, 13, 198, 0, 16, 17, 17, 14, 170, 221, 188,
+ 130, 255, 235, 205, 154, 255, 234, 205, 155, 255, 232, 204, 149,
+ 255, 228, 199, 143, 255, 171, 144, 96, 255, 64, 57, 41, 255, 154,
+ 126, 81, 255, 227, 189, 122, 255, 230, 184, 119, 255, 227, 171, 98,
+ 255, 34, 30, 21, 255, 0, 24, 17, 16, 14, 170, 221, 186, 126, 255,
+ 234, 202, 147, 255, 232, 192, 135, 255, 44, 39, 27, 255, 0, 44, 9,
+ 9, 8, 142, 25, 24, 20, 255, 114, 95, 53, 255, 207, 169, 102, 255,
+ 227, 187, 118, 255, 226, 188, 123, 255, 178, 148, 95, 255, 19, 18,
+ 16, 170, 0, 32, 24, 22, 19, 85, 197, 145, 84, 255, 227, 187, 118,
+ 255, 231, 194, 124, 255, 207, 173, 114, 255, 61, 55, 38, 255, 8, 8,
+ 8, 136, 0, 12, 10, 10, 9, 108, 45, 36, 21, 255, 195, 116, 38, 255,
+ 207, 122, 38, 255, 139, 90, 32, 255, 13, 12, 8, 170, 0, 4, 10, 10,
+ 9, 198, 208, 140, 59, 255, 226, 170, 91, 255, 231, 193, 128, 255,
+ 40, 35, 27, 255, 0, 36, 4, 4, 3, 28, 18, 17, 13, 227, 222, 189, 131,
+ 255, 234, 201, 143, 255, 229, 191, 130, 255, 34, 30, 23, 204, 0, 8,
+ 11, 11, 10, 170, 211, 158, 82, 255, 226, 170, 91, 255, 224, 165, 81,
+ 255, 219, 154, 70, 255, 208, 132, 51, 255, 206, 128, 45, 255, 204,
+ 122, 41, 255, 201, 120, 40, 255, 196, 116, 37, 255, 111, 74, 30,
+ 255, 20, 18, 13, 227, 8, 8, 7, 28, 0, 28, 6, 6, 6, 28, 28, 26, 21,
+ 255, 222, 186, 123, 255, 229, 196, 132, 255, 181, 144, 92, 255, 16,
+ 15, 13, 212, 0, 16, 6, 6, 6, 85, 25, 24, 20, 255, 180, 149, 101,
+ 255, 231, 205, 154, 255, 232, 204, 149, 255, 227, 198, 142, 255,
+ 223, 192, 138, 255, 223, 193, 136, 255, 230, 199, 139, 255, 232,
+ 197, 141, 255, 211, 176, 122, 255, 64, 57, 41, 255, 8, 8, 7, 113, 0,
+ 8, 6, 6, 5, 14, 33, 31, 24, 227, 186, 155, 107, 255, 232, 204, 149,
+ 255, 233, 205, 152, 255, 227, 197, 140, 255, 221, 189, 132, 255,
+ 224, 192, 135, 255, 228, 198, 141, 255, 232, 201, 141, 255, 232,
+ 192, 135, 255, 231, 197, 132, 255, 41, 35, 26, 255, 0, 64, 17, 16,
+ 14, 139, 211, 178, 120, 255, 233, 202, 148, 255, 233, 202, 148, 255,
+ 56, 48, 33, 255, 4, 4, 4, 85, 0, 104, 11, 11, 10, 255, 216, 164, 89,
+ 255, 230, 191, 123, 255, 227, 195, 134, 255, 40, 35, 27, 227, 0, 28,
+ 16, 15, 13, 227, 126, 105, 69, 255, 217, 176, 112, 255, 225, 175,
+ 104, 255, 223, 159, 76, 255, 189, 124, 49, 255, 43, 35, 20, 255, 9,
+ 8, 8, 57, 0, 8, 10, 10, 9, 133, 194, 109, 33, 255, 215, 125, 38,
+ 255, 212, 124, 39, 255, 144, 93, 33, 255, 29, 24, 16, 255, 68, 53,
+ 29, 255, 186, 123, 49, 255, 128, 95, 47, 255, 25, 24, 20, 255, 143,
+ 119, 78, 255, 230, 201, 145, 255, 33, 30, 24, 255, 0, 8, 11, 11, 10,
+ 170, 217, 176, 112, 255, 228, 182, 109, 255, 222, 158, 75, 255, 212,
+ 134, 51, 255, 204, 122, 41, 255, 198, 117, 37, 255, 200, 118, 37,
+ 255, 208, 123, 39, 255, 212, 123, 37, 255, 214, 121, 39, 255, 217,
+ 133, 50, 255, 24, 21, 15, 244, 0, 8, 11, 11, 10, 170, 218, 185, 127,
+ 255, 235, 203, 148, 255, 233, 202, 148, 255, 230, 201, 145, 255,
+ 227, 197, 140, 255, 221, 187, 128, 255, 221, 184, 120, 255, 224,
+ 178, 105, 255, 224, 164, 85, 255, 189, 129, 58, 255, 39, 32, 20,
+ 255, 7, 7, 6, 85, 0, 8, 11, 10, 8, 125, 194, 109, 33, 255, 215, 125,
+ 38, 255, 213, 125, 40, 255, 29, 24, 16, 255, 0, 40, 17, 17, 14, 170,
+ 221, 188, 130, 255, 235, 201, 152, 255, 232, 201, 141, 255, 42, 36,
+ 27, 255, 0, 12, 17, 17, 14, 170, 219, 179, 116, 255, 231, 187, 124,
+ 255, 228, 183, 111, 255, 24, 22, 17, 255, 0, 8, 11, 11, 10, 170,
+ 218, 185, 127, 255, 232, 197, 137, 255, 227, 179, 104, 255, 219,
+ 155, 72, 255, 208, 132, 51, 255, 204, 122, 41, 255, 202, 120, 39,
+ 255, 38, 31, 19, 170, 0, 16, 12, 11, 9, 170, 196, 110, 33, 255, 215,
+ 113, 38, 255, 213, 122, 42, 255, 215, 143, 58, 255, 217, 166, 92,
+ 255, 222, 186, 123, 255, 225, 195, 136, 255, 52, 44, 33, 198, 0, 16,
+ 17, 16, 14, 170, 211, 150, 70, 255, 219, 140, 56, 255, 213, 126, 42,
+ 255, 25, 21, 14, 255, 0, 40, 17, 17, 14, 170, 221, 187, 128, 255,
+ 232, 199, 141, 255, 228, 180, 111, 255, 219, 155, 72, 255, 207, 128,
+ 44, 255, 199, 119, 39, 255, 200, 118, 37, 255, 208, 123, 39, 255,
+ 212, 123, 37, 255, 214, 125, 39, 255, 212, 124, 39, 255, 34, 26, 15,
+ 181, 0, 8, 11, 10, 10, 161, 215, 172, 104, 255, 234, 201, 143, 255,
+ 234, 206, 151, 255, 42, 39, 29, 255, 0, 40, 12, 11, 9, 170, 196,
+ 110, 33, 255, 215, 125, 38, 255, 212, 124, 39, 255, 36, 28, 17, 170,
+ 0, 8, 15, 14, 10, 85, 194, 109, 33, 255, 215, 125, 38, 255, 212,
+ 124, 39, 255, 210, 128, 41, 255, 211, 135, 54, 255, 225, 176, 98,
+ 255, 231, 197, 132, 255, 56, 48, 33, 255, 4, 4, 4, 85, 0, 20, 17,
+ 16, 14, 170, 206, 135, 51, 255, 217, 133, 50, 255, 213, 122, 42,
+ 255, 25, 21, 14, 255, 0, 32, 12, 11, 9, 170, 196, 110, 33, 255, 215,
+ 125, 38, 255, 213, 122, 42, 255, 67, 51, 28, 255, 6, 6, 5, 255, 40,
+ 34, 25, 255, 226, 190, 127, 255, 138, 110, 69, 255, 7, 7, 7, 255,
+ 25, 24, 20, 255, 221, 179, 112, 255, 232, 191, 127, 255, 232, 201,
+ 141, 255, 26, 23, 19, 255, 0, 8, 11, 11, 10, 170, 214, 168, 101,
+ 255, 230, 187, 119, 255, 228, 188, 117, 255, 212, 173, 105, 255,
+ 150, 118, 67, 255, 102, 86, 47, 255, 111, 90, 50, 255, 185, 145, 88,
+ 255, 227, 187, 118, 255, 231, 195, 132, 255, 232, 201, 141, 255, 26,
+ 23, 19, 255, 0, 8, 11, 11, 10, 170, 219, 184, 128, 255, 235, 205,
+ 154, 255, 234, 206, 151, 255, 42, 36, 27, 255, 0, 12, 15, 15, 12,
+ 170, 213, 158, 80, 255, 228, 182, 109, 255, 230, 191, 123, 255, 27,
+ 23, 18, 255, 0, 8, 11, 11, 10, 170, 219, 189, 132, 255, 235, 205,
+ 154, 255, 232, 197, 141, 255, 225, 185, 114, 255, 215, 155, 78, 255,
+ 206, 135, 51, 255, 205, 126, 42, 255, 209, 128, 42, 255, 212, 121,
+ 41, 255, 181, 111, 36, 255, 39, 30, 18, 255, 8, 8, 7, 57, 0, 8, 10,
+ 10, 9, 136, 194, 109, 33, 255, 215, 125, 38, 255, 212, 124, 39, 255,
+ 24, 20, 13, 255, 0, 12, 15, 14, 12, 170, 210, 146, 71, 255, 229,
+ 183, 110, 255, 231, 197, 132, 255, 26, 23, 19, 255, 0, 8, 11, 11,
+ 10, 170, 218, 189, 127, 255, 234, 199, 143, 255, 231, 197, 132, 255,
+ 225, 176, 106, 255, 214, 153, 75, 255, 208, 138, 55, 255, 205, 133,
+ 48, 255, 210, 127, 45, 255, 214, 134, 49, 255, 179, 119, 42, 255,
+ 37, 30, 18, 255, 7, 7, 6, 85, 0, 12, 23, 20, 14, 227, 161, 115, 50,
+ 255, 222, 167, 89, 255, 227, 186, 114, 255, 225, 190, 130, 255, 223,
+ 198, 136, 255, 227, 198, 142, 255, 224, 196, 141, 255, 221, 191,
+ 134, 255, 161, 130, 86, 255, 33, 30, 24, 229, 10, 10, 9, 42, 0, 24,
+ 15, 15, 12, 170, 211, 149, 76, 255, 228, 182, 109, 255, 231, 189,
+ 128, 255, 44, 39, 27, 255, 0, 24, 17, 17, 14, 170, 216, 170, 97,
+ 255, 226, 172, 95, 255, 224, 165, 81, 255, 31, 26, 18, 255, 0, 12,
+ 13, 12, 10, 170, 201, 120, 40, 255, 217, 133, 50, 255, 216, 125, 45,
+ 255, 25, 21, 14, 212, 0, 8, 11, 10, 8, 144, 203, 130, 52, 255, 224,
+ 166, 83, 255, 228, 174, 103, 255, 40, 34, 25, 255, 0, 12, 17, 16,
+ 14, 170, 221, 187, 128, 255, 234, 201, 143, 255, 230, 191, 123, 255,
+ 28, 25, 19, 244, 0, 8, 10, 10, 9, 164, 203, 122, 50, 255, 220, 148,
+ 63, 255, 217, 141, 52, 255, 23, 20, 14, 255, 0, 8, 14, 13, 11, 108,
+ 10, 10, 9, 28, 0, 4, 13, 13, 12, 170, 221, 189, 134, 255, 235, 205,
+ 154, 255, 234, 206, 151, 255, 42, 37, 27, 255, 0, 24, 11, 11, 10,
+ 255, 222, 189, 131, 255, 232, 195, 131, 255, 224, 162, 81, 255, 36,
+ 29, 19, 255, 4, 4, 4, 54, 0, 28, 7, 7, 6, 28, 19, 17, 12, 232, 93,
+ 66, 30, 255, 183, 112, 36, 255, 209, 122, 38, 255, 212, 120, 39,
+ 255, 159, 102, 34, 255, 22, 19, 13, 255, 7, 7, 6, 85, 0, 24, 6, 6,
+ 5, 28, 17, 16, 14, 227, 149, 122, 84, 255, 227, 195, 140, 255, 227,
+ 191, 134, 255, 179, 142, 90, 255, 17, 16, 14, 227, 5, 5, 4, 25, 0,
+ 20, 15, 14, 12, 170, 204, 129, 49, 255, 218, 141, 51, 255, 213, 126,
+ 42, 255, 25, 21, 14, 255, 0, 24, 8, 7, 7, 91, 68, 48, 25, 255, 205,
+ 127, 44, 255, 220, 153, 75, 255, 99, 78, 44, 255, 8, 8, 7, 113, 0,
+ 28, 12, 11, 9, 170, 196, 110, 33, 255, 215, 125, 38, 255, 212, 124,
+ 39, 255, 24, 20, 13, 255, 0, 124, 9, 9, 8, 25, 0, 40, 2, 2, 1, 23,
+ 9, 8, 6, 255, 199, 116, 34, 255, 215, 125, 38, 255, 212, 128, 45,
+ 255, 27, 24, 16, 207, 0, 8, 11, 11, 10, 170, 219, 184, 128, 255,
+ 235, 205, 154, 255, 234, 205, 155, 255, 58, 49, 35, 255, 5, 5, 4,
+ 85, 0, 4, 4, 4, 3, 28, 16, 15, 11, 227, 204, 122, 41, 255, 215, 126,
+ 40, 255, 210, 123, 39, 255, 32, 25, 15, 170, 0, 8, 13, 13, 12, 122,
+ 208, 168, 99, 255, 234, 199, 143, 255, 234, 204, 151, 255, 63, 54,
+ 38, 255, 5, 5, 4, 85, 0, 4, 4, 4, 3, 28, 18, 17, 13, 215, 204, 127,
+ 45, 255, 214, 125, 39, 255, 212, 121, 41, 255, 34, 27, 15, 170, 0,
+ 8, 13, 12, 10, 85, 185, 112, 34, 255, 215, 125, 38, 255, 212, 123,
+ 37, 255, 35, 28, 16, 255, 4, 4, 3, 85, 0, 4, 3, 3, 2, 28, 12, 10, 9,
+ 224, 198, 117, 37, 255, 215, 125, 38, 255, 212, 124, 39, 255, 34,
+ 27, 15, 178, 0, 8, 14, 13, 11, 113, 206, 162, 94, 255, 232, 199,
+ 141, 255, 234, 207, 155, 255, 63, 53, 36, 255, 4, 4, 3, 113, 0, 4,
+ 3, 3, 3, 28, 10, 10, 9, 255, 200, 118, 37, 255, 215, 125, 38, 255,
+ 210, 123, 39, 255, 27, 22, 14, 227, 0, 12, 3, 3, 2, 6, 13, 11, 8,
+ 221, 199, 116, 34, 255, 215, 125, 38, 255, 212, 124, 39, 255, 35,
+ 27, 16, 255, 5, 4, 4, 57, 0, 12, 15, 14, 12, 147, 206, 154, 87, 255,
+ 232, 195, 137, 255, 234, 204, 151, 255, 63, 54, 38, 255, 5, 5, 4,
+ 85, 0, 4, 4, 4, 3, 28, 18, 16, 13, 227, 222, 189, 131, 255, 235,
+ 205, 152, 255, 234, 205, 155, 255, 27, 24, 20, 255, 0, 8, 11, 11,
+ 10, 170, 219, 184, 130, 255, 235, 205, 152, 255, 234, 205, 155, 255,
+ 58, 49, 35, 255, 5, 5, 4, 85, 0, 4, 4, 4, 3, 28, 14, 12, 9, 227,
+ 199, 117, 36, 255, 215, 113, 38, 255, 210, 123, 39, 255, 32, 25, 15,
+ 170, 0, 8, 12, 12, 9, 102, 194, 109, 33, 255, 215, 125, 38, 255,
+ 212, 124, 39, 255, 27, 22, 14, 255, 0, 24, 18, 16, 13, 170, 217,
+ 176, 110, 255, 234, 196, 143, 255, 234, 204, 151, 255, 27, 24, 20,
+ 255, 0, 8, 11, 10, 10, 170, 204, 134, 59, 255, 219, 136, 54, 255,
+ 213, 122, 42, 255, 72, 50, 27, 255, 8, 8, 7, 255, 25, 22, 14, 255,
+ 195, 116, 38, 255, 208, 123, 39, 255, 142, 91, 31, 255, 16, 14, 9,
+ 193, 4, 4, 3, 17, 0, 12, 11, 11, 8, 170, 198, 117, 37, 255, 219,
+ 133, 56, 255, 221, 152, 70, 255, 27, 23, 16, 221, 0, 8, 13, 12, 10,
+ 99, 193, 113, 34, 255, 223, 156, 70, 255, 231, 193, 128, 255, 40,
+ 34, 25, 255, 4, 3, 3, 113, 17, 16, 12, 227, 208, 136, 59, 255, 45,
+ 36, 21, 255, 4, 3, 3, 113, 10, 9, 7, 207, 196, 110, 33, 255, 215,
+ 125, 38, 255, 210, 128, 41, 255, 32, 25, 15, 170, 0, 8, 12, 11, 9,
+ 108, 194, 109, 33, 255, 215, 125, 38, 255, 212, 124, 39, 255, 35,
+ 27, 16, 255, 4, 4, 3, 85, 0, 4, 3, 3, 2, 28, 12, 11, 9, 227, 199,
+ 117, 36, 255, 221, 150, 66, 255, 229, 191, 126, 255, 32, 29, 23,
+ 210, 0, 8, 13, 13, 12, 122, 204, 150, 79, 255, 223, 159, 76, 255,
+ 217, 141, 52, 255, 84, 57, 29, 255, 9, 8, 6, 170, 5, 5, 4, 85, 6, 6,
+ 5, 113, 27, 22, 14, 255, 207, 128, 44, 255, 223, 147, 72, 255, 227,
+ 187, 118, 255, 34, 30, 23, 207, 0, 8, 12, 11, 11, 170, 218, 180,
+ 119, 255, 229, 184, 114, 255, 224, 167, 85, 255, 50, 40, 25, 255, 5,
+ 5, 4, 85, 0, 4, 4, 4, 3, 28, 14, 12, 9, 227, 203, 125, 42, 255, 217,
+ 128, 48, 255, 213, 128, 45, 255, 35, 27, 16, 173, 0, 8, 12, 12, 11,
+ 130, 209, 163, 98, 255, 235, 203, 148, 255, 233, 202, 148, 255, 63,
+ 54, 36, 255, 5, 5, 4, 85, 0, 4, 4, 4, 3, 28, 15, 15, 12, 227, 209,
+ 137, 60, 255, 221, 151, 68, 255, 219, 147, 62, 255, 23, 20, 14, 238,
+ 0, 8, 10, 10, 9, 150, 196, 121, 41, 255, 217, 128, 48, 255, 215,
+ 133, 44, 255, 40, 31, 19, 255, 5, 5, 5, 85, 0, 4, 4, 4, 3, 28, 16,
+ 14, 11, 207, 201, 120, 40, 255, 217, 133, 50, 255, 221, 161, 76,
+ 255, 57, 44, 28, 170, 0, 8, 15, 14, 12, 105, 211, 165, 98, 255, 232,
+ 197, 137, 255, 232, 199, 141, 255, 58, 49, 35, 255, 4, 4, 3, 113, 0,
+ 40, 3, 3, 2, 17, 12, 11, 9, 227, 199, 116, 34, 255, 215, 125, 38,
+ 255, 212, 124, 39, 255, 35, 27, 16, 255, 4, 4, 3, 62, 0, 12, 12, 11,
+ 9, 170, 200, 120, 41, 255, 223, 159, 76, 255, 230, 191, 123, 255,
+ 44, 37, 27, 255, 0, 12, 18, 17, 15, 170, 208, 140, 59, 255, 217,
+ 133, 50, 255, 213, 125, 40, 255, 27, 23, 14, 195, 0, 8, 12, 11, 9,
+ 108, 194, 109, 33, 255, 215, 125, 38, 255, 212, 124, 39, 255, 25,
+ 21, 14, 255, 0, 12, 17, 16, 14, 170, 219, 179, 116, 255, 235, 201,
+ 152, 255, 234, 204, 151, 255, 27, 24, 20, 255, 0, 8, 10, 10, 9, 170,
+ 198, 122, 41, 255, 215, 127, 42, 255, 213, 125, 40, 255, 27, 22, 14,
+ 255, 0, 20, 12, 11, 9, 170, 201, 120, 40, 255, 224, 156, 83, 255,
+ 231, 190, 132, 255, 40, 33, 25, 255, 0, 12, 10, 10, 9, 85, 52, 42,
+ 29, 255, 200, 142, 59, 255, 183, 119, 44, 255, 72, 52, 27, 255, 39,
+ 30, 18, 255, 49, 37, 22, 255, 150, 99, 33, 255, 196, 116, 37, 255,
+ 77, 50, 24, 255, 10, 9, 7, 144, 0, 12, 10, 10, 9, 170, 196, 115, 35,
+ 255, 215, 125, 38, 255, 212, 124, 39, 255, 25, 21, 14, 255, 0, 12,
+ 12, 11, 9, 170, 196, 110, 33, 255, 214, 127, 43, 255, 222, 158, 75,
+ 255, 41, 34, 24, 255, 0, 24, 5, 5, 4, 85, 11, 11, 10, 255, 130, 101,
+ 59, 255, 223, 176, 102, 255, 224, 176, 101, 255, 177, 137, 74, 255,
+ 18, 17, 13, 227, 6, 5, 5, 28, 0, 12, 20, 19, 15, 85, 186, 120, 49,
+ 255, 217, 142, 62, 255, 217, 139, 56, 255, 34, 29, 19, 255, 4, 4, 3,
+ 17, 0, 20, 17, 17, 14, 170, 221, 188, 130, 255, 235, 205, 152, 255,
+ 234, 205, 155, 255, 42, 39, 29, 255, 0, 24, 13, 13, 10, 181, 199,
+ 119, 39, 255, 212, 121, 41, 255, 203, 121, 40, 255, 35, 29, 17, 170,
+ 0, 100, 20, 18, 15, 170, 222, 186, 123, 255, 234, 201, 143, 255,
+ 232, 197, 135, 255, 47, 40, 28, 255, 0, 64, 14, 13, 11, 170, 213,
+ 160, 84, 255, 230, 187, 119, 255, 231, 197, 132, 255, 35, 30, 22,
+ 198, 0, 4, 14, 13, 11, 108, 217, 176, 112, 255, 232, 193, 137, 255,
+ 231, 197, 132, 255, 33, 28, 22, 255, 0, 24, 12, 12, 11, 113, 31, 29,
+ 22, 210, 40, 35, 27, 255, 41, 34, 24, 255, 29, 24, 16, 255, 32, 26,
+ 17, 255, 146, 92, 35, 255, 214, 134, 49, 255, 212, 128, 45, 255,
+ 123, 81, 36, 255, 15, 13, 10, 142, 0, 20, 7, 7, 6, 85, 28, 26, 19,
+ 252, 194, 140, 71, 255, 212, 127, 43, 255, 202, 118, 35, 255, 97,
+ 66, 30, 255, 15, 14, 10, 207, 6, 6, 5, 25, 0, 24, 6, 6, 5, 8, 15,
+ 13, 12, 227, 111, 86, 50, 255, 209, 168, 102, 255, 176, 136, 83,
+ 255, 85, 67, 44, 255, 163, 129, 80, 255, 221, 186, 126, 255, 83, 69,
+ 44, 255, 7, 7, 6, 170, 5, 5, 5, 8, 0, 4, 9, 9, 8, 108, 20, 18, 13,
+ 170, 13, 12, 10, 51, 0, 36, 16, 15, 13, 170, 217, 176, 110, 255,
+ 232, 194, 133, 255, 232, 198, 139, 255, 36, 33, 25, 255, 0, 24, 15,
+ 15, 12, 170, 219, 179, 116, 255, 232, 193, 137, 255, 232, 199, 135,
+ 255, 31, 26, 20, 255, 0, 8, 11, 11, 10, 28, 56, 48, 33, 227, 98, 76,
+ 45, 255, 104, 80, 45, 255, 195, 154, 96, 255, 227, 186, 114, 255,
+ 226, 189, 125, 255, 207, 173, 114, 255, 222, 188, 123, 255, 231,
+ 190, 132, 255, 217, 188, 124, 255, 137, 109, 70, 255, 99, 86, 54,
+ 255, 78, 64, 43, 255, 21, 20, 16, 85, 0, 8, 12, 12, 11, 28, 54, 48,
+ 35, 227, 86, 72, 47, 255, 74, 63, 43, 255, 171, 137, 84, 255, 229,
+ 191, 130, 255, 230, 191, 123, 255, 230, 186, 123, 255, 202, 164,
+ 105, 255, 97, 80, 50, 255, 75, 64, 44, 255, 72, 61, 39, 255, 22, 21,
+ 17, 102, 0, 36, 12, 11, 11, 45, 55, 45, 30, 227, 90, 71, 45, 255,
+ 78, 63, 41, 255, 72, 61, 39, 255, 74, 63, 43, 255, 72, 61, 39, 255,
+ 72, 61, 39, 255, 91, 74, 46, 255, 78, 63, 41, 255, 22, 20, 17, 102,
+ 0, 48, 12, 12, 11, 176, 132, 106, 61, 255, 228, 188, 125, 255, 210,
+ 172, 113, 255, 42, 37, 29, 255, 9, 9, 8, 62, 0, 16, 17, 16, 14, 170,
+ 221, 186, 124, 255, 234, 199, 143, 255, 232, 201, 141, 255, 232,
+ 201, 141, 255, 221, 189, 134, 255, 52, 46, 33, 255, 6, 7, 6, 227,
+ 24, 23, 17, 255, 208, 132, 51, 255, 215, 133, 44, 255, 212, 124, 39,
+ 255, 24, 20, 13, 255, 0, 24, 17, 16, 12, 170, 219, 177, 112, 255,
+ 231, 187, 124, 255, 228, 182, 109, 255, 40, 33, 23, 255, 0, 36, 9,
+ 9, 8, 74, 17, 15, 12, 227, 67, 51, 28, 255, 162, 107, 43, 255, 200,
+ 142, 67, 255, 204, 157, 91, 255, 177, 140, 86, 255, 74, 63, 43, 255,
+ 19, 17, 16, 198, 9, 9, 8, 28, 0, 32, 14, 14, 11, 31, 56, 46, 31,
+ 227, 192, 157, 103, 255, 229, 194, 128, 255, 225, 188, 124, 255,
+ 146, 112, 67, 255, 11, 10, 8, 164, 0, 8, 7, 7, 6, 28, 34, 27, 17,
+ 255, 190, 107, 33, 255, 210, 121, 35, 255, 146, 95, 35, 255, 16, 14,
+ 11, 187, 0, 8, 9, 9, 8, 170, 214, 164, 93, 255, 232, 194, 127, 255,
+ 231, 195, 132, 255, 40, 34, 25, 255, 0, 40, 13, 13, 10, 170, 213,
+ 157, 84, 255, 224, 166, 83, 255, 221, 150, 66, 255, 23, 20, 14, 246,
+ 0, 8, 12, 11, 9, 113, 194, 109, 33, 255, 212, 119, 37, 255, 210,
+ 113, 35, 255, 168, 103, 33, 255, 56, 42, 23, 255, 27, 23, 14, 255,
+ 38, 31, 19, 255, 149, 92, 30, 255, 207, 118, 32, 255, 207, 113, 30,
+ 255, 124, 75, 27, 255, 13, 11, 8, 161, 0, 28, 12, 12, 11, 176, 130,
+ 99, 59, 255, 229, 191, 126, 255, 211, 174, 116, 255, 43, 37, 28,
+ 255, 9, 9, 8, 59, 0, 16, 8, 8, 7, 85, 68, 58, 37, 255, 214, 177,
+ 119, 255, 231, 196, 136, 255, 207, 171, 114, 255, 97, 80, 50, 255,
+ 54, 47, 35, 255, 66, 59, 41, 255, 178, 148, 95, 255, 228, 189, 121,
+ 255, 224, 187, 123, 255, 146, 112, 67, 255, 12, 12, 11, 170, 0, 12,
+ 10, 10, 9, 28, 16, 15, 13, 147, 29, 28, 22, 221, 48, 42, 31, 255,
+ 70, 61, 41, 255, 66, 57, 39, 255, 70, 61, 41, 255, 171, 140, 92,
+ 255, 224, 170, 101, 255, 224, 168, 87, 255, 224, 165, 81, 255, 39,
+ 32, 22, 255, 0, 64, 14, 13, 11, 57, 100, 82, 51, 255, 222, 186, 123,
+ 255, 226, 172, 95, 255, 113, 82, 38, 255, 9, 8, 8, 127, 0, 32, 11,
+ 9, 6, 102, 11, 10, 6, 170, 11, 10, 8, 170, 12, 11, 9, 170, 15, 13,
+ 10, 170, 15, 13, 10, 170, 15, 14, 10, 170, 18, 15, 11, 170, 18, 15,
+ 11, 156, 12, 11, 9, 28, 0, 28, 6, 6, 5, 65, 40, 34, 25, 255, 224,
+ 183, 119, 255, 229, 195, 136, 255, 171, 140, 92, 255, 21, 20, 18,
+ 142, 0, 24, 11, 10, 8, 102, 131, 92, 46, 255, 213, 145, 56, 255,
+ 214, 119, 43, 255, 210, 128, 41, 255, 151, 94, 32, 255, 23, 21, 14,
+ 255, 10, 10, 9, 85, 0, 12, 10, 9, 7, 170, 191, 106, 30, 255, 211,
+ 115, 30, 255, 208, 114, 31, 255, 141, 87, 30, 255, 36, 31, 19, 255,
+ 121, 90, 42, 255, 217, 168, 92, 255, 205, 163, 102, 255, 132, 102,
+ 59, 255, 213, 172, 108, 255, 231, 193, 128, 255, 35, 30, 22, 255, 0,
+ 8, 11, 11, 10, 164, 203, 129, 50, 255, 215, 127, 42, 255, 211, 117,
+ 34, 255, 166, 97, 29, 255, 54, 40, 21, 255, 29, 23, 14, 255, 38, 31,
+ 19, 255, 120, 78, 29, 255, 206, 118, 33, 255, 214, 127, 43, 255,
+ 224, 155, 81, 255, 23, 21, 16, 255, 0, 8, 11, 10, 10, 170, 217, 183,
+ 116, 255, 234, 201, 143, 255, 232, 198, 139, 255, 202, 166, 109,
+ 255, 97, 78, 50, 255, 52, 46, 33, 255, 58, 50, 33, 255, 150, 96, 39,
+ 255, 208, 121, 37, 255, 195, 112, 30, 255, 83, 53, 24, 255, 9, 8, 6,
+ 113, 0, 8, 13, 12, 8, 96, 189, 104, 28, 255, 210, 120, 33, 255, 214,
+ 132, 45, 255, 34, 29, 19, 255, 0, 40, 17, 16, 12, 170, 217, 172,
+ 102, 255, 228, 180, 105, 255, 228, 181, 107, 255, 40, 33, 23, 255,
+ 0, 12, 17, 15, 12, 170, 216, 171, 101, 255, 232, 191, 127, 255, 231,
+ 197, 132, 255, 24, 22, 17, 255, 0, 8, 11, 11, 10, 167, 209, 146, 72,
+ 255, 221, 151, 68, 255, 213, 126, 42, 255, 172, 106, 35, 255, 57,
+ 41, 22, 255, 42, 32, 19, 255, 43, 33, 20, 252, 18, 15, 11, 85, 0,
+ 16, 11, 10, 8, 170, 193, 111, 30, 255, 215, 113, 38, 255, 220, 144,
+ 63, 255, 197, 145, 84, 255, 91, 71, 44, 255, 75, 62, 42, 255, 75,
+ 64, 44, 255, 22, 21, 17, 99, 0, 16, 14, 13, 11, 170, 196, 110, 33,
+ 255, 210, 115, 31, 255, 210, 115, 31, 255, 22, 19, 11, 227, 0, 8,
+ 16, 13, 9, 113, 24, 21, 15, 170, 17, 15, 12, 170, 18, 15, 13, 170,
+ 19, 17, 12, 142, 9, 8, 8, 28, 0, 8, 14, 13, 11, 170, 210, 146, 71,
+ 255, 220, 142, 59, 255, 213, 125, 40, 255, 168, 103, 33, 255, 54,
+ 40, 21, 255, 29, 23, 14, 255, 38, 31, 19, 255, 119, 78, 30, 255,
+ 204, 116, 31, 255, 210, 119, 31, 255, 210, 115, 31, 255, 26, 20, 13,
+ 210, 0, 8, 11, 11, 10, 170, 217, 179, 120, 255, 234, 202, 147, 255,
+ 232, 201, 141, 255, 40, 35, 25, 255, 0, 40, 11, 10, 8, 170, 193,
+ 111, 30, 255, 211, 115, 30, 255, 210, 115, 31, 255, 36, 25, 13, 170,
+ 0, 8, 14, 12, 9, 85, 190, 105, 29, 255, 210, 107, 31, 255, 208, 114,
+ 31, 255, 187, 124, 42, 255, 143, 111, 56, 255, 210, 171, 109, 255,
+ 229, 187, 128, 255, 131, 99, 54, 255, 8, 8, 7, 156, 0, 20, 13, 12,
+ 10, 170, 194, 112, 31, 255, 210, 107, 31, 255, 210, 115, 31, 255,
+ 22, 19, 11, 255, 0, 32, 11, 10, 8, 170, 193, 111, 30, 255, 215, 125,
+ 38, 255, 218, 141, 59, 255, 39, 33, 22, 255, 5, 5, 5, 28, 12, 12,
+ 11, 170, 156, 126, 83, 255, 27, 24, 20, 227, 5, 5, 5, 23, 14, 13,
+ 11, 198, 219, 177, 112, 255, 232, 191, 127, 255, 230, 191, 123, 255,
+ 25, 22, 16, 249, 0, 8, 11, 10, 8, 153, 200, 120, 41, 255, 214, 127,
+ 43, 255, 213, 126, 42, 255, 93, 66, 32, 255, 11, 11, 10, 255, 34,
+ 31, 23, 255, 206, 152, 81, 255, 226, 179, 111, 255, 231, 189, 128,
+ 255, 232, 192, 135, 255, 232, 201, 141, 255, 25, 22, 18, 255, 0, 8,
+ 11, 10, 10, 170, 215, 171, 102, 255, 228, 174, 105, 255, 222, 158,
+ 75, 255, 27, 24, 16, 255, 0, 12, 15, 15, 12, 170, 219, 177, 112,
+ 255, 232, 193, 137, 255, 232, 201, 141, 255, 25, 22, 18, 255, 0, 8,
+ 11, 10, 10, 170, 215, 172, 104, 255, 228, 182, 109, 255, 221, 155,
+ 70, 255, 177, 114, 46, 255, 55, 42, 24, 255, 35, 28, 18, 255, 41,
+ 31, 18, 255, 35, 28, 17, 255, 27, 22, 14, 255, 17, 16, 12, 187, 9,
+ 9, 8, 79, 0, 12, 10, 9, 7, 170, 191, 106, 30, 255, 211, 115, 30,
+ 255, 210, 115, 31, 255, 33, 25, 14, 255, 0, 12, 21, 20, 16, 170,
+ 221, 180, 116, 255, 232, 193, 137, 255, 232, 201, 141, 255, 25, 22,
+ 18, 255, 0, 8, 11, 11, 10, 170, 212, 160, 85, 255, 224, 156, 83,
+ 255, 218, 141, 59, 255, 175, 115, 44, 255, 55, 42, 24, 255, 31, 25,
+ 16, 255, 38, 30, 19, 255, 127, 82, 30, 255, 204, 116, 31, 255, 195,
+ 112, 30, 255, 82, 55, 25, 255, 11, 10, 8, 150, 0, 12, 9, 9, 8, 28,
+ 15, 14, 12, 142, 28, 25, 19, 221, 46, 40, 29, 255, 71, 60, 38, 255,
+ 66, 57, 39, 255, 70, 61, 41, 255, 193, 159, 106, 255, 227, 184, 108,
+ 255, 221, 153, 72, 255, 155, 98, 36, 255, 13, 12, 10, 170, 0, 24,
+ 17, 15, 12, 170, 219, 180, 112, 255, 232, 197, 137, 255, 232, 201,
+ 141, 255, 40, 35, 25, 255, 0, 24, 14, 13, 11, 170, 198, 117, 37,
+ 255, 213, 124, 38, 255, 210, 121, 35, 255, 23, 19, 12, 255, 0, 12,
+ 11, 10, 8, 170, 193, 111, 30, 255, 211, 115, 30, 255, 208, 114, 31,
+ 255, 23, 19, 12, 207, 0, 8, 14, 13, 11, 85, 181, 132, 68, 255, 228,
+ 185, 117, 255, 231, 193, 128, 255, 54, 46, 31, 255, 5, 5, 4, 8, 0,
+ 8, 21, 20, 16, 178, 215, 160, 88, 255, 223, 147, 72, 255, 206, 135,
+ 51, 255, 23, 20, 14, 170, 0, 8, 12, 11, 9, 102, 192, 111, 31, 255,
+ 210, 108, 33, 255, 208, 114, 31, 255, 22, 18, 11, 255, 0, 4, 10, 10,
+ 9, 113, 79, 61, 38, 255, 17, 16, 12, 198, 0, 4, 16, 15, 13, 170,
+ 219, 179, 116, 255, 231, 187, 124, 255, 224, 169, 91, 255, 33, 28,
+ 20, 255, 0, 20, 9, 8, 8, 85, 39, 33, 24, 255, 217, 166, 92, 255,
+ 219, 140, 56, 255, 210, 121, 35, 255, 66, 44, 21, 255, 7, 7, 6, 133,
+ 0, 32, 6, 6, 5, 74, 19, 18, 12, 255, 183, 102, 30, 255, 207, 105,
+ 30, 255, 210, 111, 31, 255, 73, 51, 24, 255, 8, 8, 7, 116, 0, 24, 6,
+ 6, 6, 28, 15, 13, 12, 227, 144, 112, 61, 255, 221, 180, 116, 255,
+ 224, 178, 113, 255, 152, 116, 65, 255, 18, 17, 13, 221, 8, 8, 7, 28,
+ 0, 24, 12, 10, 9, 170, 193, 111, 30, 255, 210, 107, 31, 255, 210,
+ 115, 31, 255, 22, 19, 11, 255, 0, 28, 16, 15, 13, 227, 164, 122, 63,
+ 255, 225, 185, 114, 255, 192, 153, 97, 255, 21, 19, 16, 232, 7, 7,
+ 6, 28, 0, 24, 11, 10, 8, 170, 193, 111, 30, 255, 211, 115, 30, 255,
+ 210, 115, 31, 255, 23, 19, 12, 255, 0, 148, 6, 6, 5, 51, 11, 9, 6,
+ 85, 12, 10, 7, 102, 10, 8, 5, 156, 10, 8, 5, 127, 8, 7, 5, 184, 27,
+ 22, 12, 255, 198, 105, 29, 255, 211, 122, 36, 255, 220, 136, 61,
+ 255, 25, 22, 16, 255, 0, 8, 10, 10, 9, 170, 218, 181, 123, 255, 234,
+ 202, 147, 255, 232, 197, 141, 255, 30, 27, 21, 255, 0, 12, 9, 8, 6,
+ 170, 191, 106, 30, 255, 211, 115, 30, 255, 210, 111, 31, 255, 39,
+ 27, 14, 170, 0, 8, 12, 11, 11, 170, 218, 180, 119, 255, 234, 196,
+ 143, 255, 232, 201, 141, 255, 29, 26, 20, 255, 0, 12, 7, 7, 6, 28,
+ 27, 22, 14, 156, 25, 22, 14, 255, 32, 25, 15, 210, 22, 18, 11, 28,
+ 0, 8, 10, 9, 7, 150, 195, 112, 30, 255, 211, 115, 30, 255, 210, 115,
+ 31, 255, 19, 15, 10, 252, 0, 12, 9, 9, 8, 170, 191, 106, 30, 255,
+ 211, 111, 30, 255, 208, 114, 31, 255, 25, 20, 12, 204, 0, 8, 12, 11,
+ 11, 170, 218, 180, 119, 255, 234, 202, 147, 255, 232, 201, 141, 255,
+ 142, 111, 63, 255, 14, 12, 9, 227, 10, 9, 7, 127, 8, 7, 5, 181, 35,
+ 25, 14, 255, 199, 112, 28, 255, 209, 118, 30, 255, 209, 117, 28,
+ 255, 30, 22, 13, 255, 0, 16, 9, 8, 6, 167, 191, 106, 30, 255, 211,
+ 115, 30, 255, 210, 115, 31, 255, 19, 15, 10, 252, 0, 16, 21, 19, 16,
+ 170, 220, 178, 113, 255, 232, 197, 137, 255, 232, 201, 141, 255, 26,
+ 23, 19, 255, 0, 12, 11, 11, 10, 170, 218, 181, 123, 255, 234, 201,
+ 143, 255, 231, 197, 132, 255, 24, 22, 17, 255, 0, 8, 11, 10, 10,
+ 170, 218, 181, 123, 255, 234, 201, 143, 255, 231, 197, 132, 255, 30,
+ 26, 21, 255, 0, 12, 9, 8, 6, 167, 191, 106, 30, 255, 211, 115, 30,
+ 255, 210, 111, 31, 255, 39, 27, 14, 170, 0, 8, 13, 12, 8, 85, 190,
+ 105, 29, 255, 213, 119, 36, 255, 214, 132, 45, 255, 32, 26, 17, 255,
+ 0, 24, 17, 16, 14, 170, 221, 186, 124, 255, 234, 202, 147, 255, 232,
+ 199, 135, 255, 25, 22, 18, 252, 0, 8, 11, 10, 8, 127, 192, 111, 31,
+ 255, 210, 107, 31, 255, 208, 114, 31, 255, 161, 94, 28, 255, 65, 43,
+ 20, 255, 145, 85, 26, 255, 207, 117, 30, 255, 122, 75, 29, 255, 15,
+ 14, 10, 170, 5, 5, 4, 8, 0, 16, 11, 10, 8, 170, 196, 115, 35, 255,
+ 223, 146, 70, 255, 228, 183, 111, 255, 25, 22, 16, 252, 0, 8, 14,
+ 12, 9, 85, 190, 105, 29, 255, 215, 125, 38, 255, 218, 141, 59, 255,
+ 30, 24, 17, 195, 0, 4, 10, 10, 7, 170, 193, 111, 30, 255, 20, 17,
+ 11, 252, 0, 4, 11, 10, 8, 85, 188, 103, 27, 255, 211, 115, 30, 255,
+ 209, 106, 30, 255, 39, 27, 14, 170, 0, 8, 13, 12, 8, 85, 190, 105,
+ 29, 255, 211, 115, 30, 255, 210, 115, 31, 255, 19, 15, 10, 255, 0,
+ 12, 9, 8, 6, 167, 192, 111, 31, 255, 218, 137, 51, 255, 227, 175,
+ 100, 255, 27, 24, 18, 255, 0, 8, 11, 10, 8, 147, 196, 106, 33, 255,
+ 210, 108, 33, 255, 210, 115, 31, 255, 30, 23, 13, 255, 4, 4, 3, 14,
+ 0, 8, 15, 14, 12, 195, 211, 149, 76, 255, 229, 184, 114, 255, 232,
+ 199, 135, 255, 28, 25, 19, 255, 0, 8, 11, 10, 8, 167, 203, 129, 50,
+ 255, 215, 127, 42, 255, 210, 121, 35, 255, 20, 17, 11, 232, 0, 12,
+ 9, 8, 6, 139, 190, 105, 29, 255, 211, 111, 30, 255, 209, 114, 30,
+ 255, 30, 22, 13, 198, 0, 8, 13, 12, 10, 170, 217, 173, 104, 255,
+ 232, 193, 137, 255, 232, 194, 139, 255, 25, 22, 18, 255, 0, 12, 9,
+ 8, 8, 156, 192, 111, 31, 255, 210, 108, 33, 255, 210, 115, 31, 255,
+ 32, 24, 13, 173, 0, 8, 13, 12, 8, 88, 190, 105, 29, 255, 211, 115,
+ 30, 255, 208, 114, 31, 255, 19, 15, 10, 255, 0, 12, 7, 7, 6, 28, 27,
+ 22, 14, 198, 45, 36, 21, 255, 52, 43, 29, 244, 14, 13, 11, 85, 0, 8,
+ 13, 13, 12, 88, 177, 143, 90, 255, 230, 194, 131, 255, 226, 172, 95,
+ 255, 137, 91, 36, 255, 10, 9, 7, 227, 8, 8, 5, 161, 10, 9, 7, 167,
+ 10, 9, 7, 136, 13, 10, 6, 85, 7, 6, 6, 74, 0, 24, 9, 8, 6, 167, 191,
+ 106, 30, 255, 211, 115, 30, 255, 210, 115, 31, 255, 19, 15, 10, 252,
+ 0, 16, 12, 11, 9, 170, 208, 141, 61, 255, 230, 187, 119, 255, 232,
+ 201, 141, 255, 40, 34, 25, 255, 0, 12, 14, 12, 9, 170, 196, 109, 31,
+ 255, 210, 107, 31, 255, 210, 115, 31, 255, 36, 25, 13, 170, 0, 8,
+ 10, 9, 7, 85, 155, 91, 28, 255, 208, 114, 31, 255, 209, 106, 30,
+ 255, 30, 22, 13, 255, 0, 12, 22, 21, 17, 176, 222, 186, 123, 255,
+ 234, 199, 143, 255, 226, 195, 135, 255, 35, 29, 22, 178, 0, 8, 12,
+ 11, 9, 105, 190, 105, 29, 255, 211, 115, 30, 255, 208, 114, 31, 255,
+ 23, 19, 12, 210, 0, 8, 15, 12, 8, 59, 7, 6, 4, 3, 0, 4, 9, 9, 8,
+ 159, 204, 134, 59, 255, 230, 182, 119, 255, 232, 198, 139, 255, 39,
+ 33, 24, 255, 0, 16, 10, 10, 9, 34, 15, 14, 10, 198, 52, 40, 21, 255,
+ 165, 96, 28, 255, 198, 113, 29, 255, 185, 102, 28, 255, 80, 53, 25,
+ 255, 19, 17, 12, 227, 10, 9, 7, 76, 0, 16, 11, 10, 8, 170, 195, 112,
+ 30, 255, 211, 115, 30, 255, 210, 115, 31, 255, 20, 16, 11, 255, 0,
+ 12, 10, 9, 7, 170, 192, 111, 31, 255, 215, 125, 38, 255, 224, 159,
+ 83, 255, 41, 33, 24, 255, 0, 24, 7, 7, 6, 108, 24, 20, 13, 255, 146,
+ 88, 31, 255, 195, 127, 38, 255, 113, 77, 34, 255, 15, 14, 12, 210,
+ 7, 7, 6, 28, 0, 16, 12, 12, 11, 28, 37, 30, 18, 227, 168, 99, 31,
+ 255, 206, 114, 33, 255, 51, 34, 18, 255, 6, 5, 5, 71, 0, 20, 17, 16,
+ 14, 170, 221, 186, 124, 255, 234, 202, 147, 255, 232, 201, 141, 255,
+ 40, 35, 25, 255, 0, 24, 17, 15, 10, 227, 198, 105, 29, 255, 194,
+ 109, 33, 255, 62, 44, 23, 255, 16, 14, 11, 85, 0, 100, 19, 17, 12,
+ 142, 214, 171, 97, 255, 228, 183, 113, 255, 227, 186, 108, 255, 50,
+ 40, 25, 227, 0, 64, 12, 11, 9, 198, 214, 158, 85, 255, 229, 183,
+ 110, 255, 228, 181, 107, 255, 21, 19, 14, 249, 2, 2, 1, 20, 8, 8, 7,
+ 181, 210, 156, 79, 255, 226, 169, 95, 255, 224, 155, 81, 255, 33,
+ 26, 18, 255, 4, 4, 4, 28, 0, 40, 3, 3, 2, 28, 11, 10, 8, 255, 209,
+ 138, 62, 255, 223, 154, 72, 255, 221, 164, 82, 255, 27, 23, 16, 249,
+ 0, 16, 7, 7, 6, 79, 46, 38, 25, 255, 197, 151, 84, 255, 222, 161,
+ 89, 255, 209, 128, 42, 255, 141, 91, 32, 255, 15, 13, 10, 218, 5, 5,
+ 5, 11, 0, 28, 15, 13, 10, 139, 191, 131, 60, 255, 220, 168, 93, 255,
+ 168, 123, 69, 255, 14, 13, 11, 227, 5, 5, 5, 85, 9, 9, 8, 170, 105,
+ 78, 40, 255, 162, 116, 61, 255, 88, 66, 37, 255, 23, 21, 16, 255,
+ 11, 11, 10, 255, 78, 58, 35, 255, 208, 150, 75, 255, 61, 46, 28,
+ 181, 0, 36, 15, 13, 10, 170, 216, 170, 97, 255, 230, 187, 119, 255,
+ 228, 178, 113, 255, 34, 28, 19, 255, 0, 24, 15, 13, 10, 170, 215,
+ 167, 92, 255, 229, 179, 114, 255, 228, 181, 107, 255, 32, 27, 19,
+ 255, 0, 16, 6, 6, 6, 25, 5, 5, 4, 198, 52, 42, 27, 255, 220, 169,
+ 97, 255, 189, 142, 76, 255, 35, 31, 22, 255, 134, 96, 51, 255, 225,
+ 176, 106, 255, 140, 106, 53, 255, 6, 6, 5, 255, 6, 6, 6, 51, 0, 28,
+ 5, 5, 5, 28, 15, 13, 10, 227, 208, 136, 59, 255, 218, 138, 53, 255,
+ 213, 122, 42, 255, 43, 31, 18, 255, 5, 5, 4, 85, 0, 136, 9, 8, 8,
+ 57, 57, 47, 30, 255, 212, 163, 93, 255, 224, 157, 85, 255, 124, 90,
+ 45, 255, 10, 10, 9, 147, 0, 20, 15, 13, 10, 170, 216, 170, 97, 255,
+ 228, 181, 107, 255, 224, 165, 81, 255, 194, 136, 61, 255, 58, 46,
+ 29, 255, 12, 12, 11, 85, 0, 4, 10, 9, 7, 156, 174, 91, 23, 255, 202,
+ 103, 23, 255, 202, 102, 21, 255, 20, 16, 9, 255, 0, 24, 15, 13, 10,
+ 170, 213, 155, 80, 255, 227, 175, 100, 255, 227, 171, 98, 255, 35,
+ 29, 20, 255, 0, 32, 7, 7, 6, 85, 49, 33, 18, 255, 183, 108, 34, 255,
+ 209, 128, 42, 255, 209, 137, 60, 255, 186, 134, 67, 255, 95, 74, 39,
+ 255, 22, 20, 15, 229, 8, 8, 7, 105, 0, 44, 5, 4, 4, 28, 17, 15, 12,
+ 227, 216, 167, 89, 255, 228, 181, 107, 255, 223, 176, 102, 255, 34,
+ 28, 19, 184, 0, 8, 12, 11, 9, 108, 180, 106, 33, 255, 214, 125, 39,
+ 255, 217, 141, 52, 255, 42, 33, 21, 255, 4, 4, 4, 85, 0, 8, 11, 10,
+ 8, 198, 211, 149, 76, 255, 224, 160, 77, 255, 220, 144, 63, 255, 34,
+ 27, 17, 255, 0, 40, 12, 10, 7, 170, 189, 99, 26, 255, 206, 102, 25,
+ 255, 203, 100, 24, 255, 30, 21, 11, 176, 0, 8, 12, 10, 7, 85, 167,
+ 87, 22, 255, 202, 103, 23, 255, 202, 102, 21, 255, 27, 20, 10, 255,
+ 4, 4, 3, 68, 0, 4, 4, 4, 4, 28, 12, 10, 7, 215, 176, 91, 23, 255,
+ 203, 104, 24, 255, 202, 105, 27, 255, 28, 21, 13, 249, 0, 24, 9, 8,
+ 8, 57, 57, 47, 30, 255, 213, 167, 94, 255, 228, 184, 115, 255, 126,
+ 92, 47, 255, 9, 9, 8, 147, 0, 20, 13, 12, 10, 167, 199, 131, 58,
+ 255, 220, 148, 63, 255, 219, 147, 62, 255, 49, 38, 24, 255, 6, 6, 6,
+ 85, 0, 4, 5, 5, 5, 28, 15, 14, 12, 227, 217, 169, 94, 255, 228, 183,
+ 111, 255, 225, 174, 102, 255, 31, 25, 18, 241, 0, 36, 5, 5, 5, 28,
+ 15, 13, 10, 227, 204, 127, 45, 255, 219, 133, 56, 255, 221, 150, 66,
+ 255, 35, 28, 18, 255, 0, 68, 10, 9, 9, 85, 45, 34, 21, 255, 201,
+ 110, 30, 255, 192, 100, 25, 255, 57, 35, 16, 255, 12, 10, 7, 85, 0,
+ 24, 13, 11, 6, 79, 126, 68, 21, 255, 191, 100, 26, 255, 198, 117,
+ 37, 255, 208, 139, 65, 255, 213, 155, 80, 255, 214, 161, 85, 255,
+ 215, 167, 92, 255, 216, 167, 89, 255, 215, 160, 88, 255, 49, 38, 24,
+ 170, 0, 24, 7, 7, 6, 76, 45, 36, 24, 249, 207, 164, 90, 255, 228,
+ 183, 111, 255, 143, 111, 56, 255, 13, 12, 10, 170, 0, 28, 13, 12, 8,
+ 142, 182, 99, 25, 255, 203, 108, 24, 255, 202, 102, 21, 255, 112,
+ 65, 23, 255, 15, 13, 8, 227, 6, 6, 5, 45, 0, 16, 10, 8, 7, 170, 171,
+ 89, 22, 255, 202, 95, 23, 255, 202, 103, 23, 255, 103, 64, 26, 255,
+ 20, 18, 13, 255, 79, 61, 36, 255, 222, 173, 97, 255, 227, 179, 104,
+ 255, 224, 172, 97, 255, 226, 171, 99, 255, 224, 176, 93, 255, 36,
+ 29, 19, 207, 0, 8, 12, 10, 7, 113, 176, 91, 23, 255, 202, 95, 23,
+ 255, 202, 102, 21, 255, 27, 20, 10, 255, 4, 4, 3, 74, 0, 4, 4, 4, 4,
+ 28, 11, 9, 6, 215, 187, 101, 24, 255, 216, 134, 45, 255, 226, 172,
+ 95, 255, 23, 21, 16, 241, 0, 8, 10, 10, 9, 161, 212, 160, 85, 255,
+ 226, 172, 95, 255, 222, 158, 75, 255, 51, 39, 24, 255, 6, 6, 6, 85,
+ 0, 4, 4, 4, 3, 28, 11, 10, 6, 215, 176, 91, 23, 255, 202, 102, 21,
+ 255, 191, 102, 22, 255, 22, 17, 9, 170, 0, 8, 12, 10, 7, 85, 167,
+ 87, 22, 255, 204, 105, 25, 255, 217, 133, 50, 255, 35, 28, 18, 255,
+ 0, 40, 15, 13, 10, 170, 199, 116, 34, 255, 212, 114, 35, 255, 218,
+ 139, 55, 255, 33, 27, 18, 255, 0, 12, 15, 13, 10, 170, 213, 160, 84,
+ 255, 227, 175, 100, 255, 224, 165, 81, 255, 25, 21, 14, 235, 0, 8,
+ 13, 11, 8, 108, 184, 96, 25, 255, 203, 96, 24, 255, 202, 95, 23,
+ 255, 27, 20, 10, 255, 4, 4, 3, 71, 0, 28, 10, 9, 7, 170, 187, 101,
+ 24, 255, 216, 134, 45, 255, 224, 167, 85, 255, 54, 42, 27, 255, 6,
+ 6, 6, 85, 0, 28, 10, 9, 7, 170, 171, 89, 22, 255, 202, 103, 23, 255,
+ 202, 102, 21, 255, 29, 21, 10, 170, 0, 4, 11, 9, 6, 42, 137, 77, 24,
+ 255, 211, 136, 56, 255, 215, 167, 92, 255, 216, 166, 95, 255, 213,
+ 163, 84, 255, 33, 28, 18, 161, 0, 8, 11, 10, 8, 130, 184, 100, 25,
+ 255, 203, 100, 24, 255, 202, 102, 21, 255, 27, 20, 10, 255, 4, 4, 3,
+ 74, 0, 4, 4, 4, 4, 28, 11, 9, 6, 215, 176, 91, 23, 255, 202, 103,
+ 23, 255, 202, 95, 23, 255, 28, 21, 11, 190, 0, 8, 10, 10, 9, 161,
+ 212, 161, 89, 255, 228, 174, 105, 255, 223, 161, 80, 255, 33, 28,
+ 18, 255, 0, 40, 10, 9, 7, 167, 171, 89, 22, 255, 202, 103, 23, 255,
+ 202, 102, 21, 255, 29, 21, 10, 170, 0, 8, 12, 10, 7, 85, 167, 87,
+ 22, 255, 202, 103, 23, 255, 203, 108, 24, 255, 68, 47, 25, 255, 6,
+ 6, 5, 255, 31, 26, 20, 255, 220, 168, 93, 255, 220, 177, 101, 255,
+ 110, 80, 41, 255, 12, 11, 9, 150, 0, 16, 10, 9, 7, 170, 171, 89, 22,
+ 255, 202, 103, 23, 255, 202, 102, 21, 255, 20, 16, 9, 255, 0, 32,
+ 10, 9, 7, 170, 193, 111, 30, 255, 219, 136, 54, 255, 224, 165, 81,
+ 255, 27, 24, 16, 255, 0, 4, 7, 7, 7, 28, 21, 20, 16, 181, 10, 10, 9,
+ 85, 0, 4, 12, 11, 9, 170, 204, 130, 51, 255, 218, 141, 51, 255, 211,
+ 122, 36, 255, 32, 23, 13, 187, 0, 8, 13, 11, 8, 85, 167, 87, 22,
+ 255, 203, 100, 24, 255, 208, 105, 29, 255, 23, 19, 12, 255, 4, 4, 3,
+ 28, 11, 10, 8, 181, 211, 158, 82, 255, 229, 183, 110, 255, 228, 183,
+ 111, 255, 228, 183, 113, 255, 228, 181, 107, 255, 27, 23, 16, 229,
+ 0, 8, 10, 10, 9, 150, 192, 111, 31, 255, 208, 112, 27, 255, 203,
+ 108, 24, 255, 21, 17, 10, 255, 0, 12, 15, 13, 10, 170, 216, 170, 97,
+ 255, 229, 183, 110, 255, 228, 181, 107, 255, 25, 21, 16, 235, 0, 8,
+ 11, 10, 8, 142, 194, 116, 33, 255, 209, 106, 30, 255, 203, 108, 24,
+ 255, 27, 20, 10, 255, 4, 4, 3, 74, 0, 36, 10, 8, 7, 170, 171, 89,
+ 22, 255, 202, 103, 23, 255, 202, 102, 21, 255, 42, 28, 13, 255, 6,
+ 5, 5, 48, 0, 4, 6, 6, 6, 28, 21, 19, 14, 255, 221, 175, 102, 255,
+ 229, 179, 114, 255, 228, 181, 107, 255, 24, 20, 15, 246, 0, 8, 12,
+ 11, 9, 127, 190, 104, 27, 255, 206, 106, 25, 255, 202, 103, 23, 255,
+ 27, 20, 10, 255, 4, 4, 3, 74, 0, 4, 4, 4, 4, 28, 11, 10, 6, 215,
+ 176, 91, 23, 255, 204, 105, 25, 255, 207, 122, 38, 255, 28, 22, 15,
+ 238, 0, 36, 5, 5, 5, 28, 15, 13, 10, 227, 195, 111, 28, 255, 204,
+ 105, 25, 255, 197, 100, 22, 255, 22, 17, 9, 224, 0, 24, 15, 13, 10,
+ 170, 216, 170, 97, 255, 229, 184, 114, 255, 228, 181, 107, 255, 34,
+ 28, 19, 255, 0, 24, 10, 9, 7, 170, 174, 91, 23, 255, 202, 103, 23,
+ 255, 202, 102, 21, 255, 20, 16, 9, 252, 0, 12, 10, 9, 7, 170, 171,
+ 89, 22, 255, 202, 107, 23, 255, 206, 111, 27, 255, 22, 17, 11, 252,
+ 0, 8, 8, 7, 7, 45, 73, 59, 36, 255, 218, 174, 105, 255, 228, 178,
+ 107, 255, 89, 67, 36, 255, 7, 7, 6, 113, 0, 4, 5, 5, 4, 28, 20, 18,
+ 13, 255, 199, 110, 30, 255, 202, 105, 27, 255, 88, 54, 23, 255, 10,
+ 9, 7, 113, 0, 8, 13, 11, 6, 85, 167, 87, 22, 255, 202, 95, 23, 255,
+ 202, 90, 23, 255, 32, 24, 13, 255, 4, 4, 3, 178, 19, 16, 12, 238,
+ 212, 163, 93, 255, 66, 52, 31, 255, 5, 5, 5, 184, 14, 13, 11, 255,
+ 205, 133, 48, 255, 212, 114, 35, 255, 208, 117, 29, 255, 29, 22, 14,
+ 255, 0, 16, 12, 11, 9, 85, 101, 74, 38, 255, 189, 121, 49, 255, 185,
+ 104, 32, 255, 180, 98, 25, 255, 180, 93, 23, 255, 154, 82, 23, 255,
+ 75, 44, 18, 255, 11, 9, 6, 144, 0, 32, 10, 9, 7, 170, 157, 79, 22,
+ 255, 202, 102, 21, 255, 202, 102, 21, 255, 22, 17, 9, 255, 0, 28,
+ 14, 13, 11, 224, 136, 98, 53, 255, 217, 165, 82, 255, 213, 145, 56,
+ 255, 150, 92, 35, 255, 19, 16, 12, 173, 5, 5, 5, 8, 0, 28, 10, 8, 7,
+ 170, 171, 89, 22, 255, 202, 103, 23, 255, 202, 102, 21, 255, 20, 16,
+ 9, 252, 0, 28, 7, 7, 6, 59, 43, 35, 24, 255, 221, 175, 102, 255,
+ 223, 178, 106, 255, 134, 98, 51, 255, 14, 13, 11, 142, 0, 24, 10, 9,
+ 7, 167, 171, 89, 22, 255, 202, 103, 23, 255, 202, 102, 21, 255, 20,
+ 16, 9, 255, 0, 144, 12, 10, 7, 170, 46, 29, 13, 255, 140, 74, 21,
+ 255, 165, 86, 22, 255, 167, 87, 22, 255, 165, 86, 22, 255, 167, 87,
+ 22, 255, 185, 95, 22, 255, 198, 97, 23, 255, 206, 111, 27, 255, 221,
+ 146, 66, 255, 23, 19, 14, 249, 0, 8, 10, 10, 9, 153, 212, 161, 89,
+ 255, 229, 183, 110, 255, 224, 165, 81, 255, 28, 23, 15, 255, 0, 12,
+ 10, 8, 7, 156, 171, 89, 22, 255, 202, 103, 23, 255, 202, 102, 21,
+ 255, 31, 21, 10, 170, 0, 8, 10, 10, 9, 167, 212, 160, 85, 255, 228,
+ 177, 105, 255, 222, 158, 75, 255, 27, 23, 16, 255, 0, 40, 10, 8, 7,
+ 170, 167, 87, 22, 255, 202, 103, 23, 255, 202, 102, 21, 255, 20, 16,
+ 9, 238, 0, 12, 10, 8, 7, 164, 171, 89, 22, 255, 202, 103, 23, 255,
+ 203, 100, 24, 255, 22, 18, 11, 235, 0, 8, 10, 10, 9, 167, 214, 164,
+ 93, 255, 228, 182, 109, 255, 223, 154, 80, 255, 207, 120, 36, 255,
+ 189, 94, 24, 255, 167, 87, 22, 255, 167, 87, 22, 255, 187, 96, 22,
+ 255, 198, 93, 23, 255, 202, 93, 21, 255, 198, 96, 21, 255, 26, 19,
+ 9, 227, 0, 16, 10, 8, 7, 167, 171, 89, 22, 255, 202, 103, 23, 255,
+ 202, 102, 21, 255, 20, 15, 9, 252, 0, 16, 17, 15, 12, 170, 216, 170,
+ 97, 255, 229, 183, 110, 255, 224, 164, 85, 255, 29, 24, 16, 255, 3,
+ 3, 2, 28, 0, 8, 12, 11, 9, 198, 211, 149, 76, 255, 221, 151, 68,
+ 255, 219, 146, 60, 255, 22, 19, 13, 246, 0, 8, 10, 10, 9, 161, 210,
+ 155, 77, 255, 223, 147, 72, 255, 213, 122, 42, 255, 23, 18, 12, 255,
+ 0, 12, 10, 8, 7, 167, 171, 89, 22, 255, 202, 103, 23, 255, 202, 102,
+ 21, 255, 29, 21, 10, 170, 0, 8, 12, 10, 7, 85, 166, 87, 23, 255,
+ 209, 118, 30, 255, 218, 139, 55, 255, 33, 27, 18, 255, 0, 24, 15,
+ 13, 10, 170, 215, 159, 92, 255, 226, 169, 95, 255, 218, 141, 59,
+ 255, 34, 26, 15, 190, 0, 8, 13, 10, 6, 85, 167, 87, 22, 255, 202,
+ 103, 23, 255, 198, 96, 21, 255, 197, 96, 22, 255, 189, 97, 22, 255,
+ 198, 96, 21, 255, 198, 96, 21, 255, 25, 19, 10, 255, 4, 4, 3, 28, 0,
+ 20, 10, 9, 7, 170, 178, 92, 23, 255, 210, 107, 31, 255, 215, 128,
+ 44, 255, 33, 24, 14, 193, 0, 8, 12, 10, 7, 85, 167, 87, 22, 255,
+ 202, 95, 23, 255, 202, 103, 23, 255, 32, 22, 11, 170, 0, 4, 10, 8,
+ 7, 170, 171, 89, 22, 255, 24, 17, 9, 249, 0, 4, 12, 10, 7, 85, 163,
+ 82, 22, 255, 202, 103, 23, 255, 202, 102, 21, 255, 29, 21, 10, 170,
+ 0, 8, 12, 10, 7, 85, 166, 87, 23, 255, 202, 103, 23, 255, 202, 102,
+ 21, 255, 20, 15, 9, 255, 0, 12, 10, 8, 7, 167, 170, 89, 23, 255,
+ 206, 106, 25, 255, 208, 115, 33, 255, 28, 21, 13, 207, 0, 8, 13, 10,
+ 6, 85, 167, 87, 22, 255, 202, 95, 23, 255, 202, 102, 21, 255, 20,
+ 16, 9, 255, 0, 12, 15, 13, 10, 170, 214, 158, 85, 255, 229, 183,
+ 110, 255, 228, 185, 111, 255, 24, 20, 15, 249, 0, 8, 12, 11, 9, 108,
+ 176, 91, 23, 255, 202, 95, 23, 255, 202, 102, 21, 255, 18, 15, 9,
+ 255, 2, 2, 1, 8, 0, 8, 8, 7, 5, 184, 171, 89, 22, 255, 202, 95, 23,
+ 255, 202, 102, 21, 255, 34, 23, 11, 173, 0, 8, 12, 11, 9, 136, 212,
+ 160, 85, 255, 228, 180, 105, 255, 225, 165, 88, 255, 31, 25, 18,
+ 255, 3, 3, 2, 28, 0, 8, 8, 7, 5, 178, 171, 89, 22, 255, 202, 103,
+ 23, 255, 202, 102, 21, 255, 30, 21, 11, 170, 0, 8, 12, 10, 7, 85,
+ 167, 87, 22, 255, 202, 103, 23, 255, 202, 102, 21, 255, 20, 15, 9,
+ 255, 0, 40, 7, 7, 6, 28, 30, 27, 21, 238, 167, 111, 50, 255, 206,
+ 110, 33, 255, 199, 102, 24, 255, 175, 90, 22, 255, 165, 86, 22, 255,
+ 167, 87, 22, 255, 167, 87, 22, 255, 161, 87, 22, 255, 84, 48, 19,
+ 255, 18, 15, 9, 227, 8, 7, 5, 28, 0, 16, 10, 8, 7, 167, 171, 89, 22,
+ 255, 202, 103, 23, 255, 202, 102, 21, 255, 20, 15, 9, 252, 0, 16,
+ 15, 13, 10, 170, 211, 159, 76, 255, 229, 180, 110, 255, 228, 182,
+ 109, 255, 34, 28, 19, 255, 0, 12, 10, 9, 7, 170, 171, 89, 22, 255,
+ 202, 103, 23, 255, 202, 102, 21, 255, 31, 22, 10, 170, 0, 8, 7, 6,
+ 6, 28, 48, 31, 15, 255, 189, 93, 22, 255, 202, 102, 21, 255, 45, 29,
+ 14, 255, 5, 5, 4, 113, 0, 4, 5, 5, 4, 28, 22, 20, 15, 255, 220, 169,
+ 97, 255, 226, 178, 103, 255, 167, 118, 54, 255, 15, 13, 10, 133, 0,
+ 8, 13, 11, 6, 85, 167, 87, 22, 255, 202, 103, 23, 255, 202, 102, 21,
+ 255, 19, 15, 8, 215, 0, 4, 11, 9, 6, 105, 121, 65, 20, 255, 26, 18,
+ 9, 190, 0, 4, 9, 9, 8, 167, 208, 150, 75, 255, 229, 183, 110, 255,
+ 228, 181, 113, 255, 37, 29, 20, 255, 0, 24, 8, 8, 5, 218, 167, 87,
+ 22, 255, 202, 93, 21, 255, 198, 104, 21, 255, 23, 18, 10, 255, 3, 3,
+ 2, 51, 0, 20, 10, 9, 7, 153, 171, 89, 22, 255, 202, 95, 23, 255,
+ 202, 102, 21, 255, 20, 15, 9, 255, 2, 2, 1, 17, 0, 8, 8, 7, 5, 181,
+ 184, 100, 25, 255, 215, 119, 42, 255, 224, 160, 85, 255, 34, 28, 19,
+ 255, 0, 20, 9, 8, 6, 85, 31, 22, 12, 255, 166, 87, 23, 255, 189, 97,
+ 22, 255, 99, 60, 22, 255, 15, 13, 8, 170, 0, 28, 4, 3, 3, 23, 13,
+ 11, 8, 227, 182, 94, 23, 255, 149, 87, 26, 255, 19, 17, 12, 227, 7,
+ 7, 7, 23, 0, 16, 15, 13, 10, 170, 216, 170, 97, 255, 229, 179, 114,
+ 255, 228, 182, 109, 255, 34, 28, 19, 255, 0, 20, 9, 8, 6, 130, 69,
+ 42, 18, 255, 195, 95, 22, 255, 35, 24, 12, 255, 5, 5, 4, 76, 0, 104,
+ 10, 9, 7, 28, 27, 24, 16, 184, 32, 27, 19, 255, 39, 29, 20, 212, 13,
+ 12, 10, 85, 0, 60, 13, 11, 8, 170, 81, 54, 28, 255, 216, 148, 67,
+ 255, 223, 161, 72, 255, 220, 147, 61, 255, 117, 76, 32, 255, 13, 11,
+ 8, 255, 44, 33, 19, 255, 207, 123, 40, 255, 217, 136, 50, 255, 218,
+ 142, 53, 255, 156, 100, 39, 255, 18, 15, 11, 227, 10, 8, 7, 28, 0,
+ 12, 15, 13, 8, 125, 19, 14, 10, 170, 14, 11, 7, 170, 10, 8, 7, 170,
+ 11, 9, 6, 122, 13, 10, 8, 85, 8, 7, 5, 153, 46, 33, 21, 255, 212,
+ 138, 51, 255, 221, 151, 68, 255, 191, 132, 62, 255, 19, 17, 12, 176,
+ 0, 12, 7, 7, 6, 76, 26, 22, 15, 241, 189, 129, 58, 255, 219, 152,
+ 72, 255, 217, 154, 72, 255, 133, 87, 38, 255, 15, 13, 10, 221, 6, 6,
+ 5, 28, 0, 8, 15, 12, 8, 113, 20, 16, 11, 170, 17, 14, 10, 142, 7, 6,
+ 6, 28, 0, 8, 19, 16, 12, 170, 200, 117, 35, 255, 212, 123, 37, 255,
+ 115, 74, 30, 255, 9, 8, 6, 113, 0, 8, 12, 11, 9, 178, 104, 73, 37,
+ 255, 206, 147, 63, 255, 178, 121, 53, 255, 58, 46, 29, 255, 46, 36,
+ 25, 255, 40, 32, 21, 252, 19, 17, 12, 85, 0, 36, 12, 10, 9, 164,
+ 191, 131, 60, 255, 223, 161, 80, 255, 221, 151, 68, 255, 46, 34, 21,
+ 255, 4, 4, 3, 3, 0, 20, 19, 16, 12, 173, 208, 134, 55, 255, 223,
+ 156, 70, 255, 216, 160, 81, 255, 21, 19, 14, 255, 0, 16, 6, 5, 5,
+ 25, 17, 14, 10, 227, 67, 48, 28, 255, 94, 67, 35, 255, 20, 17, 13,
+ 227, 6, 6, 5, 113, 12, 11, 9, 198, 67, 51, 30, 255, 85, 62, 32, 255,
+ 25, 20, 14, 255, 9, 8, 6, 82, 0, 32, 10, 8, 5, 170, 161, 87, 22,
+ 255, 195, 90, 20, 255, 187, 91, 20, 255, 19, 14, 8, 255, 0, 28, 15,
+ 12, 8, 119, 20, 16, 11, 170, 17, 14, 10, 156, 10, 8, 7, 28, 0, 64,
+ 15, 12, 8, 122, 18, 15, 11, 170, 17, 14, 10, 144, 10, 8, 7, 28, 0,
+ 16, 13, 12, 10, 170, 157, 96, 36, 255, 211, 123, 38, 255, 199, 116,
+ 34, 255, 31, 24, 16, 255, 6, 6, 6, 28, 0, 20, 16, 13, 11, 170, 197,
+ 110, 32, 255, 209, 110, 30, 255, 202, 103, 23, 255, 58, 36, 15, 255,
+ 8, 7, 5, 113, 0, 8, 10, 8, 5, 85, 137, 68, 18, 255, 185, 86, 20,
+ 255, 174, 88, 19, 255, 18, 13, 7, 255, 0, 24, 12, 10, 9, 170, 204,
+ 129, 49, 255, 220, 144, 63, 255, 217, 133, 50, 255, 26, 20, 13, 255,
+ 0, 28, 7, 6, 6, 76, 23, 19, 12, 244, 185, 113, 36, 255, 207, 129,
+ 52, 255, 173, 117, 50, 255, 59, 46, 28, 255, 18, 15, 13, 198, 9, 9,
+ 8, 113, 6, 6, 6, 11, 0, 24, 15, 12, 8, 133, 22, 17, 11, 170, 17, 14,
+ 10, 142, 8, 7, 5, 28, 0, 12, 9, 8, 6, 170, 202, 128, 49, 255, 220,
+ 148, 63, 255, 219, 140, 56, 255, 22, 19, 13, 255, 0, 8, 12, 10, 9,
+ 170, 200, 125, 37, 255, 218, 141, 51, 255, 220, 147, 61, 255, 138,
+ 86, 35, 255, 13, 10, 8, 227, 11, 9, 6, 170, 13, 11, 8, 198, 61, 41,
+ 22, 255, 202, 111, 31, 255, 204, 105, 25, 255, 200, 105, 21, 255,
+ 22, 17, 9, 221, 0, 12, 11, 9, 6, 108, 14, 11, 7, 170, 11, 9, 6, 139,
+ 6, 5, 3, 17, 0, 12, 9, 7, 6, 133, 144, 75, 19, 255, 185, 86, 20,
+ 255, 178, 86, 19, 255, 27, 18, 8, 170, 0, 8, 11, 9, 6, 85, 134, 70,
+ 19, 255, 181, 88, 20, 255, 180, 87, 19, 255, 24, 15, 7, 178, 0, 12,
+ 10, 8, 5, 99, 165, 86, 22, 255, 206, 111, 27, 255, 213, 124, 38,
+ 255, 36, 27, 17, 255, 0, 24, 10, 10, 9, 133, 167, 112, 48, 255, 222,
+ 166, 77, 255, 223, 157, 72, 255, 54, 39, 23, 255, 5, 5, 4, 37, 0,
+ 20, 13, 11, 8, 170, 181, 93, 22, 255, 206, 111, 27, 255, 214, 127,
+ 43, 255, 20, 16, 11, 255, 0, 12, 9, 8, 8, 170, 203, 129, 50, 255,
+ 222, 145, 63, 255, 220, 147, 61, 255, 33, 26, 16, 255, 0, 12, 12,
+ 10, 7, 113, 15, 12, 8, 170, 13, 10, 8, 122, 0, 16, 10, 8, 7, 170,
+ 200, 120, 41, 255, 220, 142, 59, 255, 219, 146, 60, 255, 27, 21, 14,
+ 255, 0, 12, 13, 11, 8, 113, 18, 15, 11, 170, 17, 14, 10, 142, 8, 7,
+ 5, 28, 0, 12, 14, 12, 9, 113, 20, 15, 11, 170, 17, 14, 10, 153, 10,
+ 8, 7, 28, 0, 16, 9, 8, 6, 85, 29, 21, 10, 255, 119, 62, 20, 255,
+ 153, 79, 20, 255, 40, 25, 11, 255, 9, 8, 6, 85, 0, 20, 10, 8, 7, 28,
+ 32, 24, 13, 218, 68, 47, 25, 255, 61, 43, 24, 255, 61, 46, 28, 255,
+ 61, 47, 28, 255, 61, 47, 28, 255, 66, 50, 29, 255, 73, 55, 32, 255,
+ 66, 48, 29, 255, 24, 20, 15, 85, 0, 20, 7, 6, 6, 79, 32, 26, 17,
+ 244, 199, 132, 54, 255, 208, 150, 75, 255, 122, 87, 41, 255, 17, 15,
+ 10, 170, 0, 32, 10, 9, 7, 28, 32, 23, 11, 227, 53, 33, 14, 255, 34,
+ 23, 11, 255, 12, 10, 7, 190, 6, 5, 5, 28, 0, 20, 9, 7, 4, 170, 146,
+ 76, 19, 255, 197, 99, 20, 255, 204, 110, 27, 255, 59, 41, 22, 255,
+ 6, 6, 6, 170, 10, 9, 9, 113, 31, 26, 18, 184, 30, 25, 17, 255, 29,
+ 25, 18, 255, 34, 27, 19, 255, 37, 28, 18, 221, 13, 11, 8, 57, 0, 8,
+ 13, 10, 6, 88, 144, 75, 19, 255, 185, 86, 20, 255, 178, 90, 19, 255,
+ 20, 14, 7, 212, 0, 12, 9, 7, 4, 125, 157, 81, 20, 255, 212, 117, 33,
+ 255, 220, 148, 63, 255, 27, 21, 14, 218, 0, 8, 12, 10, 9, 127, 192,
+ 111, 31, 255, 208, 112, 27, 255, 202, 103, 23, 255, 22, 16, 9, 204,
+ 0, 12, 10, 8, 5, 93, 137, 68, 18, 255, 185, 94, 20, 255, 180, 91,
+ 19, 255, 30, 20, 9, 170, 0, 8, 11, 9, 6, 85, 140, 67, 19, 255, 202,
+ 106, 21, 255, 214, 125, 39, 255, 25, 20, 14, 255, 0, 12, 6, 6, 5,
+ 28, 13, 11, 8, 139, 20, 16, 11, 170, 19, 15, 10, 142, 8, 7, 5, 28,
+ 0, 8, 10, 9, 5, 142, 153, 79, 20, 255, 195, 90, 20, 255, 206, 111,
+ 27, 255, 24, 20, 13, 255, 0, 12, 12, 10, 9, 170, 195, 113, 32, 255,
+ 211, 115, 30, 255, 203, 108, 24, 255, 31, 21, 10, 173, 0, 8, 11, 9,
+ 6, 85, 140, 70, 19, 255, 185, 86, 20, 255, 180, 87, 19, 255, 24, 15,
+ 7, 181, 0, 32, 9, 8, 6, 170, 174, 91, 23, 255, 215, 123, 42, 255,
+ 221, 150, 66, 255, 25, 20, 14, 255, 0, 32, 9, 7, 4, 170, 148, 77,
+ 19, 255, 181, 92, 20, 255, 180, 87, 19, 255, 25, 17, 8, 170, 0, 8,
+ 34, 24, 13, 170, 161, 102, 38, 255, 219, 154, 70, 255, 220, 142, 59,
+ 255, 213, 124, 38, 255, 32, 24, 13, 198, 0, 8, 11, 9, 6, 85, 140,
+ 70, 19, 255, 185, 86, 20, 255, 178, 90, 19, 255, 20, 14, 7, 212, 0,
+ 12, 8, 7, 5, 127, 144, 78, 19, 255, 185, 86, 20, 255, 180, 87, 19,
+ 255, 29, 19, 10, 170, 0, 8, 13, 11, 8, 116, 194, 116, 33, 255, 209,
+ 110, 30, 255, 202, 95, 23, 255, 22, 17, 9, 221, 0, 12, 10, 8, 5, 85,
+ 12, 9, 5, 170, 10, 8, 5, 130, 6, 5, 3, 8, 0, 12, 10, 8, 5, 110, 144,
+ 78, 19, 255, 185, 86, 20, 255, 178, 86, 19, 255, 27, 18, 8, 170, 0,
+ 8, 11, 8, 6, 85, 137, 68, 18, 255, 185, 86, 20, 255, 200, 105, 21,
+ 255, 29, 21, 12, 255, 4, 4, 4, 25, 10, 9, 7, 139, 154, 100, 47, 255,
+ 215, 148, 70, 255, 198, 131, 45, 255, 46, 34, 19, 255, 11, 9, 6, 88,
+ 0, 12, 10, 8, 5, 119, 144, 78, 19, 255, 185, 86, 20, 255, 180, 87,
+ 19, 255, 21, 15, 8, 210, 0, 32, 13, 11, 8, 170, 199, 119, 39, 255,
+ 220, 144, 63, 255, 221, 155, 70, 255, 27, 21, 14, 255, 0, 20, 10, 9,
+ 7, 170, 171, 89, 22, 255, 195, 98, 20, 255, 183, 89, 19, 255, 29,
+ 20, 8, 170, 0, 8, 11, 9, 6, 85, 139, 70, 20, 255, 202, 103, 23, 255,
+ 211, 118, 36, 255, 28, 21, 13, 201, 0, 4, 8, 8, 7, 57, 118, 84, 39,
+ 255, 215, 159, 86, 255, 219, 149, 66, 255, 216, 129, 45, 255, 211,
+ 121, 34, 255, 34, 25, 13, 178, 0, 8, 11, 10, 6, 88, 146, 76, 19,
+ 255, 185, 94, 20, 255, 178, 90, 19, 255, 24, 18, 9, 255, 0, 12, 18,
+ 15, 11, 170, 203, 122, 42, 255, 215, 126, 40, 255, 209, 106, 30,
+ 255, 32, 22, 13, 184, 0, 8, 12, 10, 7, 85, 143, 72, 20, 255, 185,
+ 94, 20, 255, 178, 90, 19, 255, 20, 14, 7, 210, 0, 40, 9, 7, 4, 170,
+ 148, 77, 19, 255, 180, 87, 19, 255, 178, 86, 19, 255, 30, 21, 9,
+ 255, 5, 5, 4, 37, 8, 7, 5, 28, 20, 17, 13, 227, 133, 89, 38, 255,
+ 215, 142, 56, 255, 216, 129, 45, 255, 209, 115, 32, 255, 26, 19, 11,
+ 210, 0, 8, 11, 9, 6, 85, 142, 74, 19, 255, 185, 86, 20, 255, 178,
+ 90, 19, 255, 20, 14, 7, 210, 0, 12, 9, 7, 4, 122, 143, 75, 20, 255,
+ 203, 108, 24, 255, 216, 129, 45, 255, 30, 23, 15, 255, 0, 12, 12,
+ 10, 7, 110, 16, 13, 9, 170, 13, 10, 8, 122, 0, 16, 9, 8, 6, 105,
+ 142, 74, 19, 255, 185, 86, 20, 255, 180, 87, 19, 255, 23, 16, 8,
+ 255, 0, 24, 15, 13, 10, 170, 203, 122, 42, 255, 215, 126, 40, 255,
+ 209, 118, 30, 255, 24, 17, 11, 255, 0, 24, 9, 8, 4, 170, 148, 77,
+ 19, 255, 181, 92, 20, 255, 180, 87, 19, 255, 23, 16, 8, 198, 0, 12,
+ 9, 7, 6, 139, 159, 82, 20, 255, 203, 100, 24, 255, 212, 121, 33,
+ 255, 28, 21, 13, 255, 0, 12, 12, 11, 9, 119, 81, 59, 34, 255, 216,
+ 153, 71, 255, 173, 117, 50, 255, 21, 18, 14, 255, 10, 10, 9, 244,
+ 11, 10, 8, 255, 60, 35, 15, 255, 173, 85, 20, 255, 84, 49, 17, 255,
+ 13, 10, 6, 170, 0, 12, 10, 8, 5, 130, 146, 79, 19, 255, 193, 89, 20,
+ 255, 203, 104, 24, 255, 120, 77, 31, 255, 19, 17, 12, 255, 117, 80,
+ 36, 255, 219, 154, 70, 255, 178, 121, 53, 255, 20, 17, 13, 255, 45,
+ 33, 18, 255, 184, 94, 21, 255, 195, 90, 20, 255, 205, 106, 26, 255,
+ 30, 22, 13, 255, 0, 12, 7, 7, 6, 82, 35, 28, 18, 255, 196, 114, 33,
+ 255, 148, 80, 25, 255, 32, 22, 11, 255, 20, 15, 9, 255, 26, 18, 9,
+ 255, 88, 49, 17, 255, 149, 78, 20, 255, 40, 26, 11, 255, 9, 7, 4,
+ 85, 0, 28, 9, 7, 4, 127, 140, 70, 19, 255, 181, 88, 20, 255, 180,
+ 87, 19, 255, 18, 13, 7, 235, 0, 24, 10, 9, 7, 93, 104, 69, 35, 255,
+ 201, 131, 48, 255, 194, 109, 33, 255, 65, 42, 20, 255, 12, 10, 7,
+ 170, 0, 36, 9, 7, 4, 170, 146, 79, 19, 255, 181, 88, 20, 255, 180,
+ 87, 19, 255, 23, 16, 8, 198, 0, 32, 15, 14, 10, 198, 188, 133, 61,
+ 255, 219, 149, 66, 255, 194, 115, 37, 255, 17, 15, 10, 244, 0, 24,
+ 10, 8, 5, 113, 144, 78, 19, 255, 185, 86, 20, 255, 180, 87, 19, 255,
+ 18, 13, 7, 255, 0, 140, 7, 6, 4, 65, 53, 31, 12, 255, 162, 83, 19,
+ 255, 185, 94, 20, 255, 130, 70, 21, 255, 31, 22, 10, 255, 25, 19,
+ 10, 198, 22, 17, 9, 246, 70, 40, 15, 255, 169, 87, 20, 255, 200,
+ 105, 21, 255, 212, 123, 37, 255, 28, 21, 13, 221, 0, 8, 12, 10, 9,
+ 133, 200, 127, 41, 255, 210, 120, 33, 255, 202, 95, 23, 255, 19, 14,
+ 8, 238, 0, 12, 10, 8, 5, 110, 144, 78, 19, 255, 185, 86, 20, 255,
+ 178, 86, 19, 255, 28, 19, 9, 170, 0, 8, 12, 10, 9, 133, 194, 112,
+ 31, 255, 209, 110, 30, 255, 202, 102, 21, 255, 21, 15, 8, 235, 0,
+ 16, 9, 7, 4, 57, 12, 10, 5, 88, 10, 8, 5, 85, 0, 12, 10, 8, 5, 125,
+ 146, 79, 19, 255, 181, 88, 20, 255, 180, 87, 19, 255, 25, 17, 8,
+ 195, 0, 12, 10, 8, 5, 119, 144, 78, 19, 255, 185, 94, 20, 255, 200,
+ 105, 21, 255, 23, 18, 10, 221, 0, 8, 11, 9, 8, 153, 200, 123, 41,
+ 255, 212, 117, 33, 255, 202, 103, 23, 255, 111, 63, 20, 255, 27, 20,
+ 10, 255, 20, 16, 9, 246, 22, 17, 9, 249, 28, 20, 9, 198, 30, 21, 9,
+ 170, 24, 17, 9, 215, 28, 20, 9, 201, 10, 8, 5, 85, 0, 16, 9, 7, 4,
+ 170, 146, 79, 19, 255, 181, 88, 20, 255, 180, 87, 19, 255, 18, 13,
+ 7, 255, 0, 16, 11, 10, 8, 113, 152, 104, 47, 255, 214, 134, 49, 255,
+ 204, 105, 25, 255, 98, 54, 19, 255, 18, 13, 9, 227, 13, 10, 8, 170,
+ 14, 12, 9, 198, 60, 41, 21, 255, 199, 112, 28, 255, 202, 102, 21,
+ 255, 202, 103, 23, 255, 26, 19, 11, 204, 0, 8, 12, 11, 9, 116, 187,
+ 101, 24, 255, 202, 93, 21, 255, 187, 91, 20, 255, 18, 13, 7, 255, 0,
+ 12, 9, 7, 4, 170, 146, 79, 19, 255, 181, 88, 20, 255, 178, 90, 19,
+ 255, 27, 17, 8, 170, 0, 8, 11, 9, 6, 85, 139, 70, 20, 255, 202, 103,
+ 23, 255, 212, 123, 37, 255, 32, 24, 15, 255, 0, 24, 13, 12, 10, 170,
+ 196, 114, 33, 255, 206, 106, 25, 255, 196, 99, 21, 255, 28, 19, 9,
+ 170, 0, 8, 11, 8, 6, 85, 137, 68, 18, 255, 181, 88, 20, 255, 178,
+ 86, 19, 255, 164, 85, 21, 255, 138, 73, 21, 255, 175, 93, 20, 255,
+ 178, 86, 19, 255, 46, 28, 11, 255, 6, 5, 3, 108, 0, 20, 9, 7, 4,
+ 170, 146, 76, 19, 255, 189, 88, 20, 255, 189, 88, 20, 255, 28, 19,
+ 9, 170, 0, 8, 11, 9, 6, 85, 137, 68, 18, 255, 185, 86, 20, 255, 178,
+ 90, 19, 255, 27, 17, 8, 170, 0, 4, 9, 7, 4, 167, 146, 79, 19, 255,
+ 20, 14, 7, 252, 0, 4, 11, 9, 6, 85, 137, 68, 18, 255, 185, 94, 20,
+ 255, 178, 90, 19, 255, 27, 17, 8, 170, 0, 8, 11, 9, 6, 85, 137, 68,
+ 18, 255, 185, 86, 20, 255, 180, 87, 19, 255, 18, 13, 7, 255, 0, 12,
+ 9, 7, 4, 170, 146, 79, 19, 255, 185, 94, 20, 255, 183, 85, 19, 255,
+ 27, 19, 8, 170, 0, 8, 11, 9, 6, 85, 140, 73, 19, 255, 181, 88, 20,
+ 255, 178, 90, 19, 255, 20, 15, 7, 255, 0, 12, 16, 14, 11, 170, 208,
+ 143, 59, 255, 223, 156, 70, 255, 216, 135, 49, 255, 28, 22, 13, 210,
+ 0, 8, 11, 9, 6, 85, 140, 70, 19, 255, 185, 94, 20, 255, 178, 90, 19,
+ 255, 72, 39, 13, 255, 10, 8, 5, 218, 8, 6, 3, 170, 9, 7, 4, 193, 39,
+ 24, 10, 255, 160, 82, 19, 255, 185, 94, 20, 255, 144, 74, 23, 255,
+ 16, 13, 9, 170, 0, 8, 10, 9, 7, 85, 145, 101, 48, 255, 218, 149, 67,
+ 255, 210, 115, 31, 255, 99, 57, 19, 255, 10, 8, 5, 227, 8, 6, 3,
+ 170, 9, 7, 4, 190, 30, 20, 9, 255, 158, 81, 19, 255, 185, 94, 20,
+ 255, 178, 90, 19, 255, 27, 17, 8, 170, 0, 8, 11, 8, 6, 85, 137, 68,
+ 18, 255, 185, 86, 20, 255, 180, 87, 19, 255, 18, 13, 7, 255, 0, 44,
+ 9, 9, 8, 28, 13, 12, 8, 142, 27, 20, 10, 170, 29, 21, 10, 193, 24,
+ 17, 9, 252, 22, 17, 9, 232, 22, 17, 9, 255, 87, 49, 18, 255, 181,
+ 88, 20, 255, 178, 90, 19, 255, 100, 54, 17, 255, 11, 10, 6, 150, 0,
+ 16, 9, 7, 4, 170, 146, 79, 19, 255, 181, 88, 20, 255, 180, 87, 19,
+ 255, 18, 13, 7, 255, 0, 16, 15, 13, 10, 170, 208, 141, 55, 255, 223,
+ 156, 70, 255, 217, 133, 50, 255, 23, 19, 12, 255, 0, 12, 10, 8, 5,
+ 122, 144, 78, 19, 255, 185, 86, 20, 255, 180, 87, 19, 255, 30, 20,
+ 9, 176, 0, 12, 12, 10, 7, 85, 39, 26, 12, 255, 155, 80, 20, 255, 99,
+ 55, 19, 255, 19, 16, 12, 255, 12, 11, 9, 255, 18, 15, 11, 255, 119,
+ 84, 38, 255, 209, 137, 60, 255, 138, 86, 35, 255, 18, 15, 11, 178,
+ 0, 12, 10, 8, 5, 130, 144, 78, 19, 255, 181, 92, 20, 255, 178, 90,
+ 19, 255, 39, 24, 10, 255, 6, 5, 3, 210, 29, 20, 8, 255, 169, 87, 20,
+ 255, 97, 53, 18, 255, 8, 7, 5, 255, 26, 21, 15, 255, 212, 142, 59,
+ 255, 221, 151, 68, 255, 218, 142, 53, 255, 34, 25, 15, 255, 0, 20,
+ 5, 5, 4, 82, 16, 12, 7, 255, 160, 82, 19, 255, 185, 86, 20, 255,
+ 185, 86, 20, 255, 52, 29, 11, 255, 7, 6, 4, 170, 0, 20, 8, 7, 5, 85,
+ 83, 46, 16, 255, 181, 92, 20, 255, 178, 86, 19, 255, 87, 47, 14,
+ 255, 10, 8, 5, 224, 8, 6, 3, 170, 9, 7, 4, 190, 29, 20, 8, 255, 195,
+ 104, 24, 255, 217, 136, 50, 255, 221, 155, 70, 255, 30, 23, 15, 255,
+ 0, 16, 8, 7, 5, 85, 26, 18, 9, 255, 107, 59, 20, 255, 151, 80, 22,
+ 255, 60, 34, 15, 255, 11, 9, 6, 170, 0, 36, 8, 7, 5, 170, 159, 82,
+ 20, 255, 202, 118, 35, 255, 66, 51, 29, 255, 9, 9, 8, 96, 0, 16, 15,
+ 13, 10, 170, 208, 140, 59, 255, 223, 156, 70, 255, 215, 133, 44,
+ 255, 27, 20, 12, 255, 0, 20, 14, 12, 7, 244, 131, 67, 20, 255, 176,
+ 89, 19, 255, 17, 12, 6, 255, 0, 184, 17, 14, 10, 85, 171, 95, 28,
+ 255, 206, 123, 33, 255, 208, 123, 31, 255, 207, 112, 28, 255, 202,
+ 107, 23, 255, 191, 98, 22, 255, 170, 91, 21, 255, 195, 107, 22, 255,
+ 209, 123, 30, 255, 212, 132, 37, 255, 214, 134, 39, 255, 211, 133,
+ 40, 255, 202, 121, 35, 255, 29, 21, 12, 164, 0, 8, 12, 10, 7, 82,
+ 168, 98, 29, 255, 202, 121, 35, 255, 196, 120, 31, 255, 194, 115,
+ 31, 255, 190, 115, 27, 255, 185, 101, 26, 255, 184, 100, 25, 255,
+ 199, 107, 26, 255, 208, 123, 31, 255, 168, 105, 37, 255, 25, 21, 14,
+ 227, 9, 8, 8, 28, 0, 8, 8, 8, 7, 28, 39, 30, 18, 249, 183, 122, 42,
+ 255, 211, 133, 40, 255, 210, 133, 43, 255, 161, 106, 41, 255, 15,
+ 13, 10, 221, 5, 4, 4, 17, 0, 8, 14, 11, 7, 113, 148, 83, 25, 255,
+ 193, 108, 24, 255, 180, 93, 23, 255, 27, 18, 10, 153, 0, 8, 12, 9,
+ 7, 122, 144, 78, 19, 255, 180, 91, 19, 255, 83, 46, 16, 255, 7, 6,
+ 4, 184, 0, 8, 4, 4, 3, 85, 28, 21, 13, 255, 202, 121, 35, 255, 209,
+ 132, 42, 255, 131, 87, 36, 255, 10, 9, 7, 255, 5, 5, 5, 28, 0, 40,
+ 10, 9, 7, 68, 86, 62, 31, 255, 206, 131, 43, 255, 214, 130, 39, 255,
+ 76, 50, 25, 255, 7, 6, 6, 113, 0, 16, 5, 5, 4, 28, 21, 17, 12, 255,
+ 202, 121, 35, 255, 210, 135, 37, 255, 157, 100, 38, 255, 18, 15, 11,
+ 150, 0, 16, 18, 15, 9, 91, 161, 88, 24, 255, 105, 64, 28, 255, 11,
+ 10, 8, 170, 0, 12, 8, 7, 7, 85, 40, 28, 17, 255, 174, 91, 23, 255,
+ 42, 27, 13, 173, 0, 32, 10, 8, 5, 116, 133, 66, 16, 255, 161, 85,
+ 17, 255, 161, 78, 17, 255, 25, 16, 8, 221, 0, 24, 15, 12, 8, 119,
+ 170, 99, 29, 255, 203, 126, 36, 255, 199, 127, 34, 255, 27, 20, 12,
+ 210, 0, 60, 13, 11, 8, 122, 170, 99, 29, 255, 204, 127, 37, 255,
+ 199, 119, 34, 255, 27, 20, 12, 198, 0, 12, 4, 4, 3, 11, 18, 13, 9,
+ 255, 154, 79, 19, 255, 174, 88, 19, 255, 92, 51, 17, 255, 12, 10, 7,
+ 198, 0, 24, 11, 9, 6, 147, 142, 74, 19, 255, 171, 90, 18, 255, 159,
+ 81, 18, 255, 17, 12, 6, 255, 0, 12, 8, 7, 5, 142, 133, 66, 16, 255,
+ 161, 85, 17, 255, 161, 85, 17, 255, 21, 14, 6, 215, 0, 24, 10, 9, 7,
+ 198, 190, 107, 25, 255, 203, 104, 24, 255, 196, 99, 21, 255, 21, 15,
+ 8, 255, 2, 2, 1, 14, 0, 20, 9, 8, 6, 37, 35, 28, 18, 255, 183, 112,
+ 36, 255, 212, 132, 37, 255, 178, 118, 41, 255, 27, 23, 16, 255, 5,
+ 5, 4, 198, 0, 32, 15, 12, 8, 105, 142, 79, 23, 255, 189, 97, 22,
+ 255, 160, 83, 21, 255, 18, 13, 7, 218, 0, 12, 10, 8, 7, 198, 196,
+ 114, 33, 255, 214, 129, 37, 255, 212, 132, 37, 255, 27, 21, 12, 210,
+ 0, 8, 13, 11, 8, 116, 192, 114, 31, 255, 210, 125, 33, 255, 209,
+ 123, 30, 255, 203, 113, 26, 255, 177, 91, 22, 255, 159, 82, 20, 255,
+ 160, 83, 21, 255, 165, 85, 20, 255, 168, 89, 19, 255, 163, 86, 18,
+ 255, 161, 78, 17, 255, 23, 15, 6, 170, 0, 8, 9, 7, 4, 57, 99, 48,
+ 14, 255, 142, 73, 17, 255, 133, 66, 16, 255, 19, 13, 6, 190, 0, 12,
+ 7, 6, 4, 164, 135, 66, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255,
+ 25, 16, 6, 170, 0, 8, 10, 8, 5, 85, 131, 65, 16, 255, 161, 85, 17,
+ 255, 161, 85, 17, 255, 19, 13, 6, 227, 0, 12, 10, 8, 5, 176, 190,
+ 107, 25, 255, 212, 127, 35, 255, 214, 134, 39, 255, 30, 21, 13, 255,
+ 0, 24, 12, 10, 7, 170, 194, 109, 33, 255, 213, 132, 36, 255, 208,
+ 122, 29, 255, 28, 20, 11, 255, 0, 24, 9, 7, 4, 147, 136, 70, 17,
+ 255, 202, 98, 21, 255, 211, 126, 34, 255, 27, 20, 12, 255, 3, 3, 2,
+ 28, 0, 8, 10, 8, 7, 195, 180, 93, 23, 255, 202, 102, 21, 255, 202,
+ 102, 21, 255, 25, 17, 10, 221, 0, 8, 13, 11, 8, 65, 129, 70, 22,
+ 255, 172, 88, 21, 255, 144, 78, 19, 255, 22, 15, 7, 176, 0, 12, 10,
+ 8, 7, 198, 198, 124, 37, 255, 215, 136, 42, 255, 214, 134, 39, 255,
+ 27, 21, 12, 212, 0, 8, 12, 10, 7, 79, 151, 88, 26, 255, 198, 116,
+ 29, 255, 192, 109, 27, 255, 25, 18, 10, 167, 0, 8, 12, 9, 7, 82,
+ 119, 62, 20, 255, 174, 89, 21, 255, 154, 79, 19, 255, 22, 15, 7,
+ 181, 0, 20, 5, 5, 4, 68, 20, 14, 7, 249, 142, 73, 17, 255, 143, 74,
+ 18, 255, 45, 26, 10, 255, 10, 8, 5, 85, 0, 76, 7, 6, 6, 85, 39, 30,
+ 18, 255, 196, 121, 41, 255, 213, 135, 42, 255, 115, 72, 30, 255, 10,
+ 9, 7, 170, 0, 40, 5, 5, 4, 17, 6, 5, 5, 85, 5, 5, 4, 45, 0, 28, 9,
+ 7, 4, 142, 146, 79, 19, 255, 204, 108, 23, 255, 212, 126, 33, 255,
+ 30, 22, 13, 255, 3, 3, 3, 40, 0, 36, 10, 8, 5, 125, 133, 66, 16,
+ 255, 161, 85, 17, 255, 161, 85, 17, 255, 19, 13, 6, 212, 0, 12, 10,
+ 8, 5, 127, 136, 70, 17, 255, 193, 97, 20, 255, 203, 108, 24, 255,
+ 30, 21, 11, 193, 0, 8, 13, 10, 6, 85, 134, 70, 19, 255, 171, 90, 18,
+ 255, 159, 81, 18, 255, 17, 12, 6, 238, 0, 12, 8, 6, 5, 144, 135, 66,
+ 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 23, 15, 6, 170, 0, 8,
+ 10, 7, 5, 85, 133, 66, 16, 255, 185, 94, 20, 255, 209, 123, 30, 255,
+ 23, 18, 12, 255, 3, 3, 2, 28, 0, 4, 5, 5, 4, 28, 18, 15, 11, 227,
+ 134, 72, 21, 255, 158, 81, 19, 255, 143, 74, 18, 255, 22, 15, 7,
+ 142, 0, 8, 10, 8, 5, 85, 131, 65, 16, 255, 163, 79, 18, 255, 178,
+ 90, 19, 255, 22, 16, 9, 255, 3, 2, 2, 20, 0, 8, 9, 7, 6, 176, 144,
+ 78, 19, 255, 175, 88, 18, 255, 163, 79, 18, 255, 26, 16, 7, 170, 0,
+ 8, 10, 8, 5, 85, 129, 64, 16, 255, 161, 85, 17, 255, 161, 78, 17,
+ 255, 19, 13, 6, 229, 0, 32, 8, 7, 5, 156, 144, 78, 19, 255, 202,
+ 102, 21, 255, 206, 111, 27, 255, 27, 20, 12, 255, 0, 32, 10, 8, 5,
+ 133, 135, 66, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 19, 13,
+ 6, 227, 0, 12, 8, 7, 5, 255, 172, 85, 21, 255, 189, 92, 20, 255,
+ 172, 87, 19, 255, 24, 16, 7, 170, 0, 8, 10, 8, 5, 85, 129, 64, 16,
+ 255, 161, 85, 17, 255, 161, 85, 17, 255, 19, 13, 6, 212, 0, 12, 10,
+ 8, 5, 127, 135, 66, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 26,
+ 16, 7, 170, 0, 8, 11, 9, 6, 85, 134, 70, 19, 255, 171, 90, 18, 255,
+ 159, 78, 18, 255, 23, 15, 6, 170, 0, 8, 9, 7, 4, 57, 98, 49, 13,
+ 255, 139, 71, 16, 255, 133, 66, 16, 255, 19, 13, 6, 193, 0, 12, 7,
+ 6, 4, 176, 133, 66, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 23,
+ 15, 6, 170, 0, 8, 10, 8, 5, 85, 129, 64, 16, 255, 165, 87, 18, 255,
+ 180, 91, 19, 255, 20, 15, 9, 255, 0, 4, 5, 5, 4, 17, 26, 21, 15,
+ 227, 126, 75, 25, 255, 178, 95, 21, 255, 142, 74, 19, 255, 46, 28,
+ 11, 255, 10, 8, 5, 57, 0, 8, 10, 8, 5, 85, 131, 65, 16, 255, 161,
+ 85, 17, 255, 161, 85, 17, 255, 17, 12, 6, 252, 2, 1, 1, 8, 0, 28,
+ 13, 11, 8, 170, 199, 119, 34, 255, 215, 136, 42, 255, 214, 139, 41,
+ 255, 28, 20, 13, 255, 0, 20, 8, 7, 5, 170, 135, 66, 16, 255, 161,
+ 85, 17, 255, 161, 85, 17, 255, 23, 15, 6, 170, 0, 8, 10, 8, 5, 85,
+ 131, 67, 16, 255, 202, 102, 21, 255, 211, 127, 36, 255, 22, 17, 11,
+ 249, 0, 8, 16, 14, 11, 201, 101, 67, 28, 255, 191, 98, 22, 255, 185,
+ 94, 20, 255, 172, 87, 19, 255, 26, 17, 7, 170, 0, 8, 10, 8, 5, 85,
+ 129, 64, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 31, 20, 8,
+ 255, 5, 5, 4, 102, 0, 4, 5, 4, 4, 28, 16, 13, 9, 255, 164, 85, 21,
+ 255, 180, 91, 19, 255, 165, 87, 18, 255, 26, 17, 7, 170, 0, 8, 10,
+ 8, 5, 85, 129, 64, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 19,
+ 13, 6, 212, 0, 40, 10, 8, 5, 133, 135, 66, 16, 255, 161, 85, 17,
+ 255, 161, 85, 17, 255, 26, 17, 7, 255, 3, 3, 2, 136, 9, 7, 4, 227,
+ 131, 67, 20, 255, 197, 104, 22, 255, 198, 104, 21, 255, 183, 93, 19,
+ 255, 172, 87, 19, 255, 26, 17, 7, 170, 0, 8, 10, 8, 5, 85, 129, 64,
+ 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 19, 13, 6, 212, 0, 12,
+ 10, 8, 5, 127, 135, 66, 16, 255, 193, 97, 20, 255, 209, 123, 30,
+ 255, 19, 15, 10, 252, 0, 8, 13, 11, 8, 65, 125, 68, 22, 255, 174,
+ 86, 21, 255, 146, 76, 19, 255, 22, 14, 7, 178, 0, 12, 8, 6, 5, 144,
+ 135, 66, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 19, 14, 6,
+ 238, 0, 24, 13, 11, 8, 170, 163, 87, 20, 255, 180, 91, 19, 255, 165,
+ 87, 18, 255, 17, 12, 6, 255, 0, 24, 9, 7, 4, 139, 135, 66, 16, 255,
+ 161, 85, 17, 255, 161, 85, 17, 255, 15, 11, 6, 246, 0, 12, 9, 7, 6,
+ 184, 180, 93, 23, 255, 211, 115, 30, 255, 213, 133, 38, 255, 28, 20,
+ 13, 255, 0, 16, 12, 11, 9, 170, 152, 91, 31, 255, 188, 105, 31, 255,
+ 115, 66, 22, 255, 91, 50, 16, 255, 84, 46, 15, 255, 116, 59, 17,
+ 255, 118, 62, 17, 255, 15, 11, 6, 221, 0, 16, 10, 8, 5, 116, 146,
+ 79, 19, 255, 202, 103, 23, 255, 209, 128, 32, 255, 200, 127, 41,
+ 255, 167, 106, 40, 255, 197, 122, 42, 255, 210, 130, 35, 255, 186,
+ 106, 27, 255, 88, 51, 19, 255, 102, 55, 17, 255, 157, 83, 18, 255,
+ 189, 92, 20, 255, 209, 123, 30, 255, 29, 21, 12, 224, 0, 8, 7, 6, 6,
+ 28, 41, 31, 18, 235, 160, 84, 23, 255, 170, 87, 19, 255, 45, 26, 10,
+ 255, 5, 5, 4, 170, 4, 4, 4, 8, 4, 4, 3, 99, 15, 12, 6, 255, 140, 72,
+ 17, 255, 138, 71, 17, 255, 45, 26, 10, 255, 10, 8, 5, 85, 0, 24, 8,
+ 7, 5, 142, 133, 66, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 19,
+ 13, 6, 229, 0, 24, 13, 11, 8, 170, 160, 86, 21, 255, 185, 90, 20,
+ 255, 91, 50, 16, 255, 7, 6, 4, 255, 0, 40, 8, 7, 5, 150, 133, 66,
+ 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 15, 11, 6, 246, 0, 32,
+ 8, 8, 7, 110, 74, 52, 27, 255, 191, 103, 24, 255, 176, 89, 19, 255,
+ 34, 22, 9, 255, 6, 5, 3, 57, 0, 20, 8, 6, 5, 161, 133, 66, 16, 255,
+ 161, 85, 17, 255, 161, 78, 17, 255, 15, 11, 6, 252, 0, 140, 12, 10,
+ 5, 85, 123, 61, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 22, 15,
+ 7, 255, 2, 2, 1, 85, 0, 8, 7, 6, 4, 244, 133, 66, 16, 255, 167, 88,
+ 18, 255, 189, 92, 20, 255, 27, 19, 10, 195, 0, 8, 12, 10, 7, 110,
+ 160, 83, 21, 255, 177, 85, 18, 255, 161, 78, 17, 255, 15, 11, 6,
+ 252, 0, 12, 7, 6, 4, 161, 133, 66, 16, 255, 161, 85, 17, 255, 161,
+ 85, 17, 255, 23, 15, 6, 170, 0, 8, 11, 9, 6, 85, 134, 70, 19, 255,
+ 171, 90, 18, 255, 159, 78, 18, 255, 15, 11, 6, 249, 0, 12, 10, 8, 5,
+ 85, 98, 49, 13, 255, 135, 72, 16, 255, 133, 66, 16, 255, 19, 13, 6,
+ 139, 0, 8, 10, 8, 5, 85, 131, 65, 16, 255, 161, 85, 17, 255, 161,
+ 85, 17, 255, 15, 11, 6, 246, 0, 12, 7, 6, 4, 164, 133, 66, 16, 255,
+ 165, 87, 18, 255, 178, 90, 19, 255, 24, 17, 9, 212, 0, 8, 13, 11, 8,
+ 105, 165, 86, 22, 255, 180, 91, 19, 255, 159, 81, 18, 255, 19, 14,
+ 6, 255, 2, 2, 1, 79, 0, 44, 8, 6, 5, 167, 133, 66, 16, 255, 161, 85,
+ 17, 255, 161, 85, 17, 255, 15, 11, 6, 252, 0, 16, 7, 6, 6, 28, 24,
+ 19, 13, 227, 103, 59, 20, 255, 157, 83, 18, 255, 154, 78, 17, 255,
+ 150, 81, 19, 255, 154, 79, 19, 255, 158, 81, 19, 255, 162, 83, 19,
+ 255, 161, 85, 17, 255, 159, 81, 18, 255, 163, 86, 18, 255, 27, 18,
+ 8, 170, 0, 8, 11, 9, 6, 85, 131, 67, 16, 255, 165, 87, 18, 255, 161,
+ 85, 17, 255, 15, 11, 6, 252, 0, 12, 8, 6, 5, 167, 133, 66, 16, 255,
+ 161, 85, 17, 255, 161, 85, 17, 255, 23, 15, 6, 170, 0, 8, 10, 8, 5,
+ 85, 131, 65, 16, 255, 175, 88, 18, 255, 191, 96, 20, 255, 25, 18,
+ 10, 255, 0, 24, 11, 9, 6, 170, 148, 77, 19, 255, 169, 82, 18, 255,
+ 161, 85, 17, 255, 23, 15, 6, 170, 0, 8, 10, 8, 5, 85, 129, 64, 16,
+ 255, 161, 85, 17, 255, 161, 85, 17, 255, 87, 47, 14, 255, 23, 17, 8,
+ 255, 65, 34, 12, 255, 150, 76, 17, 255, 132, 68, 17, 255, 41, 25,
+ 10, 255, 10, 8, 5, 85, 0, 16, 8, 7, 5, 150, 133, 66, 16, 255, 161,
+ 85, 17, 255, 161, 78, 17, 255, 23, 15, 6, 170, 0, 8, 10, 8, 5, 85,
+ 129, 64, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 23, 15, 6,
+ 170, 0, 4, 8, 7, 5, 153, 133, 66, 16, 255, 19, 13, 6, 238, 0, 4, 10,
+ 8, 5, 85, 129, 64, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 23,
+ 15, 6, 170, 0, 8, 10, 8, 5, 85, 129, 64, 16, 255, 161, 85, 17, 255,
+ 161, 85, 17, 255, 15, 11, 6, 252, 0, 12, 8, 6, 5, 167, 133, 66, 16,
+ 255, 161, 85, 17, 255, 161, 85, 17, 255, 23, 15, 6, 170, 0, 8, 10,
+ 8, 5, 85, 129, 64, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 31,
+ 20, 8, 255, 5, 4, 4, 85, 0, 4, 5, 4, 4, 40, 17, 14, 10, 255, 200,
+ 120, 35, 255, 207, 112, 28, 255, 195, 98, 20, 255, 29, 20, 8, 170,
+ 0, 8, 10, 8, 5, 85, 131, 65, 16, 255, 163, 86, 18, 255, 159, 81, 18,
+ 255, 150, 76, 17, 255, 137, 70, 16, 255, 135, 72, 16, 255, 135, 66,
+ 16, 255, 146, 75, 17, 255, 159, 81, 18, 255, 131, 67, 20, 255, 42,
+ 31, 17, 255, 10, 9, 7, 62, 0, 8, 5, 5, 4, 8, 26, 21, 15, 227, 137,
+ 79, 28, 255, 174, 88, 19, 255, 158, 83, 17, 255, 137, 70, 16, 255,
+ 135, 72, 16, 255, 135, 66, 16, 255, 146, 75, 17, 255, 159, 81, 18,
+ 255, 161, 85, 17, 255, 161, 85, 17, 255, 23, 15, 6, 170, 0, 8, 10,
+ 8, 5, 85, 131, 67, 16, 255, 163, 86, 18, 255, 159, 81, 18, 255, 17,
+ 12, 6, 255, 0, 68, 2, 1, 1, 8, 7, 6, 4, 249, 137, 67, 16, 255, 165,
+ 80, 18, 255, 154, 78, 17, 255, 27, 18, 8, 170, 0, 16, 8, 6, 5, 167,
+ 133, 66, 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 15, 11, 6,
+ 252, 0, 16, 13, 11, 8, 170, 199, 124, 36, 255, 211, 125, 32, 255,
+ 200, 105, 21, 255, 18, 13, 7, 255, 0, 12, 7, 6, 4, 164, 133, 66, 16,
+ 255, 161, 85, 17, 255, 161, 78, 17, 255, 19, 13, 6, 227, 0, 16, 8,
+ 7, 5, 122, 68, 38, 13, 255, 150, 83, 23, 255, 174, 107, 35, 255,
+ 181, 112, 38, 255, 190, 117, 39, 255, 193, 114, 36, 255, 143, 84,
+ 26, 255, 15, 12, 8, 212, 4, 4, 3, 6, 0, 12, 10, 8, 5, 108, 135, 66,
+ 16, 255, 161, 85, 17, 255, 161, 85, 17, 255, 125, 65, 16, 255, 90,
+ 47, 13, 255, 121, 60, 16, 255, 164, 84, 19, 255, 189, 97, 22, 255,
+ 177, 104, 32, 255, 194, 123, 39, 255, 212, 134, 41, 255, 210, 124,
+ 31, 255, 200, 105, 21, 255, 23, 17, 8, 218, 0, 16, 10, 8, 5, 167,
+ 56, 31, 11, 255, 110, 55, 15, 255, 118, 62, 17, 255, 115, 58, 16,
+ 255, 115, 58, 16, 255, 120, 63, 17, 255, 95, 46, 14, 255, 17, 13, 6,
+ 227, 7, 6, 4, 28, 0, 16, 14, 12, 7, 227, 87, 43, 14, 255, 154, 78,
+ 17, 255, 152, 77, 17, 255, 139, 71, 16, 255, 135, 72, 16, 255, 135,
+ 66, 16, 255, 146, 75, 17, 255, 200, 105, 21, 255, 211, 127, 36, 255,
+ 214, 134, 39, 255, 23, 18, 12, 255, 0, 12, 7, 6, 4, 85, 26, 16, 7,
+ 255, 131, 67, 16, 255, 145, 75, 18, 255, 78, 43, 15, 255, 7, 6, 4,
+ 255, 0, 40, 10, 8, 5, 136, 157, 81, 20, 255, 210, 129, 33, 255, 139,
+ 89, 36, 255, 10, 9, 7, 198, 0, 16, 13, 11, 8, 170, 196, 113, 31,
+ 255, 206, 114, 25, 255, 189, 92, 20, 255, 18, 13, 7, 244, 0, 16, 5,
+ 4, 4, 88, 27, 19, 8, 255, 141, 73, 18, 255, 161, 85, 17, 255, 21,
+ 14, 6, 218, 0, 112, 12, 9, 7, 99, 11, 8, 6, 170, 10, 8, 5, 91, 0,
+ 60, 11, 10, 8, 28, 32, 23, 13, 227, 108, 57, 19, 255, 153, 82, 18,
+ 255, 154, 78, 17, 255, 146, 75, 17, 255, 97, 47, 14, 255, 36, 24,
+ 11, 255, 108, 64, 25, 255, 203, 111, 30, 255, 207, 118, 32, 255,
+ 207, 118, 32, 255, 189, 110, 32, 255, 63, 41, 20, 255, 15, 12, 8,
+ 76, 0, 8, 9, 8, 6, 28, 38, 27, 15, 218, 51, 33, 18, 255, 48, 32, 17,
+ 255, 131, 74, 24, 255, 182, 97, 21, 255, 176, 89, 19, 255, 170, 87,
+ 19, 255, 134, 72, 21, 255, 37, 25, 14, 255, 15, 13, 8, 144, 7, 7, 6,
+ 28, 0, 12, 11, 9, 8, 127, 171, 99, 28, 255, 208, 123, 31, 255, 203,
+ 124, 30, 255, 104, 63, 27, 255, 15, 13, 10, 212, 7, 6, 6, 28, 0, 12,
+ 14, 11, 7, 170, 142, 74, 19, 255, 161, 85, 17, 255, 159, 81, 18,
+ 255, 27, 18, 8, 184, 0, 8, 6, 5, 3, 28, 27, 17, 8, 227, 92, 46, 13,
+ 255, 111, 55, 14, 255, 31, 20, 8, 255, 8, 6, 3, 198, 9, 7, 4, 170,
+ 10, 8, 5, 227, 22, 16, 9, 255, 61, 39, 18, 255, 107, 64, 26, 255,
+ 108, 66, 25, 255, 32, 22, 11, 255, 9, 7, 6, 170, 0, 44, 10, 9, 7,
+ 156, 56, 36, 19, 255, 191, 114, 32, 255, 175, 98, 30, 255, 41, 27,
+ 16, 255, 11, 9, 6, 57, 0, 12, 21, 15, 10, 227, 100, 56, 21, 255,
+ 160, 83, 21, 255, 80, 44, 17, 255, 14, 12, 7, 190, 7, 6, 6, 28, 0,
+ 16, 13, 10, 6, 28, 29, 20, 10, 212, 21, 15, 10, 144, 0, 20, 12, 9,
+ 7, 85, 39, 24, 10, 173, 16, 12, 7, 85, 0, 32, 6, 5, 3, 20, 19, 13,
+ 6, 173, 21, 14, 6, 255, 21, 15, 6, 215, 10, 8, 5, 85, 0, 24, 15, 12,
+ 8, 170, 190, 98, 23, 255, 203, 108, 24, 255, 202, 111, 23, 255, 23,
+ 17, 10, 255, 0, 60, 17, 13, 10, 170, 195, 112, 30, 255, 211, 124,
+ 30, 255, 205, 106, 26, 255, 31, 21, 12, 255, 0, 12, 8, 6, 5, 139,
+ 44, 25, 9, 255, 135, 72, 16, 255, 104, 54, 13, 255, 15, 11, 6, 249,
+ 7, 6, 4, 28, 0, 24, 7, 6, 4, 57, 44, 25, 9, 255, 137, 73, 16, 255,
+ 143, 70, 16, 255, 49, 25, 8, 255, 8, 6, 3, 184, 8, 6, 3, 85, 8, 6,
+ 3, 142, 23, 16, 6, 255, 130, 66, 15, 255, 145, 77, 16, 255, 87, 44,
+ 12, 255, 10, 8, 5, 142, 0, 20, 11, 9, 8, 164, 53, 31, 14, 255, 150,
+ 74, 19, 255, 154, 78, 17, 255, 148, 76, 17, 255, 65, 33, 10, 255,
+ 10, 8, 5, 184, 6, 5, 5, 28, 0, 16, 11, 9, 6, 142, 175, 102, 30, 255,
+ 207, 123, 32, 255, 208, 114, 31, 255, 196, 114, 33, 255, 89, 56, 26,
+ 255, 17, 13, 10, 255, 11, 8, 6, 170, 9, 7, 6, 170, 11, 8, 6, 170,
+ 15, 11, 8, 170, 18, 13, 9, 142, 8, 6, 5, 28, 0, 8, 10, 8, 5, 93,
+ 102, 53, 17, 255, 159, 81, 18, 255, 154, 78, 17, 255, 72, 37, 11,
+ 255, 11, 8, 6, 227, 9, 7, 6, 170, 11, 8, 6, 198, 61, 36, 20, 255,
+ 196, 107, 27, 255, 204, 114, 27, 255, 182, 102, 31, 255, 19, 14, 10,
+ 170, 0, 8, 6, 6, 5, 20, 26, 19, 11, 198, 28, 20, 11, 255, 22, 16, 9,
+ 255, 23, 16, 8, 255, 27, 18, 8, 255, 24, 16, 7, 255, 24, 16, 7, 255,
+ 74, 39, 11, 255, 139, 68, 16, 255, 143, 70, 16, 255, 143, 70, 16,
+ 255, 20, 13, 5, 170, 0, 8, 7, 6, 4, 74, 87, 44, 12, 255, 155, 79,
+ 18, 255, 151, 73, 16, 255, 67, 34, 10, 255, 9, 7, 4, 198, 9, 7, 4,
+ 96, 8, 6, 5, 159, 27, 17, 8, 255, 137, 67, 16, 255, 158, 80, 17,
+ 255, 112, 56, 15, 255, 10, 8, 5, 167, 0, 8, 7, 5, 4, 85, 74, 36, 11,
+ 255, 150, 83, 17, 255, 145, 77, 16, 255, 55, 29, 10, 255, 8, 6, 3,
+ 198, 8, 6, 3, 88, 7, 6, 4, 153, 39, 24, 12, 255, 199, 112, 28, 255,
+ 210, 115, 31, 255, 184, 108, 33, 255, 17, 14, 10, 198, 0, 24, 11, 9,
+ 6, 170, 139, 69, 18, 255, 168, 86, 19, 255, 154, 78, 17, 255, 17,
+ 12, 6, 235, 0, 24, 7, 6, 4, 85, 64, 32, 11, 255, 162, 80, 19, 255,
+ 198, 96, 21, 255, 109, 63, 26, 255, 15, 11, 8, 227, 10, 8, 7, 170,
+ 8, 7, 5, 195, 29, 18, 8, 255, 137, 67, 16, 255, 154, 78, 17, 255,
+ 114, 59, 15, 255, 11, 10, 6, 164, 0, 8, 9, 7, 6, 85, 97, 50, 16,
+ 255, 159, 81, 18, 255, 152, 77, 17, 255, 74, 36, 11, 255, 10, 8, 5,
+ 198, 7, 6, 4, 125, 10, 8, 5, 198, 61, 36, 20, 255, 200, 105, 29,
+ 255, 209, 122, 28, 255, 180, 104, 29, 255, 16, 12, 9, 170, 0, 8, 12,
+ 10, 7, 170, 160, 83, 21, 255, 183, 89, 19, 255, 174, 88, 19, 255,
+ 28, 19, 9, 187, 0, 8, 14, 10, 7, 85, 143, 75, 20, 255, 195, 98, 20,
+ 255, 189, 92, 20, 255, 21, 15, 8, 224, 0, 24, 7, 6, 4, 85, 26, 16,
+ 7, 255, 111, 55, 14, 255, 132, 67, 15, 255, 39, 23, 8, 255, 8, 6, 3,
+ 113, 0, 68, 9, 7, 6, 85, 32, 22, 13, 255, 188, 112, 31, 255, 193,
+ 114, 30, 255, 94, 57, 25, 255, 17, 13, 10, 170, 0, 44, 9, 7, 4, 142,
+ 10, 8, 5, 255, 10, 8, 5, 198, 6, 5, 3, 28, 0, 24, 8, 7, 5, 85, 88,
+ 48, 19, 255, 204, 114, 27, 255, 208, 118, 31, 255, 111, 62, 26, 255,
+ 11, 8, 6, 227, 8, 7, 5, 150, 10, 8, 5, 116, 10, 8, 5, 88, 9, 7, 4,
+ 85, 6, 5, 3, 74, 0, 16, 10, 8, 5, 99, 114, 56, 13, 255, 143, 70, 16,
+ 255, 143, 70, 16, 255, 18, 12, 5, 215, 0, 12, 8, 7, 3, 130, 118, 60,
+ 13, 255, 148, 76, 17, 255, 150, 76, 17, 255, 24, 16, 7, 170, 0, 8,
+ 9, 7, 4, 85, 114, 56, 13, 255, 145, 74, 16, 255, 143, 70, 16, 255,
+ 52, 28, 9, 255, 8, 6, 3, 198, 8, 6, 3, 88, 8, 6, 3, 144, 23, 15, 6,
+ 255, 130, 66, 15, 255, 151, 80, 16, 255, 111, 55, 14, 255, 10, 8, 5,
+ 144, 0, 8, 6, 5, 3, 59, 59, 32, 10, 255, 157, 83, 18, 255, 185, 90,
+ 20, 255, 97, 54, 22, 255, 14, 10, 7, 227, 13, 10, 6, 170, 13, 10, 6,
+ 255, 84, 41, 13, 255, 148, 76, 17, 255, 155, 82, 18, 255, 135, 66,
+ 16, 255, 14, 10, 5, 159, 0, 8, 9, 7, 4, 85, 114, 56, 13, 255, 145,
+ 77, 16, 255, 145, 74, 16, 255, 55, 28, 10, 255, 9, 7, 4, 198, 8, 6,
+ 3, 93, 8, 6, 3, 147, 25, 16, 6, 255, 130, 64, 15, 255, 151, 80, 16,
+ 255, 111, 55, 14, 255, 10, 8, 5, 142, 0, 8, 9, 7, 4, 85, 114, 56,
+ 13, 255, 145, 77, 16, 255, 143, 70, 16, 255, 52, 28, 9, 255, 8, 6,
+ 3, 198, 8, 6, 3, 102, 8, 6, 3, 139, 8, 6, 3, 170, 9, 8, 4, 113, 0,
+ 12, 10, 8, 5, 91, 114, 56, 13, 255, 150, 76, 17, 255, 150, 76, 17,
+ 255, 17, 12, 6, 252, 0, 32, 7, 6, 4, 85, 64, 33, 11, 255, 145, 77,
+ 16, 255, 143, 70, 16, 255, 56, 29, 9, 255, 8, 6, 3, 198, 8, 6, 3,
+ 85, 6, 5, 3, 119, 14, 11, 5, 255, 128, 66, 15, 255, 151, 73, 16,
+ 255, 143, 76, 16, 255, 20, 13, 5, 170, 0, 8, 9, 7, 4, 85, 114, 56,
+ 13, 255, 143, 70, 16, 255, 143, 70, 16, 255, 18, 12, 5, 215, 0, 12,
+ 8, 7, 3, 130, 114, 56, 13, 255, 143, 70, 16, 255, 143, 70, 16, 255,
+ 20, 13, 5, 170, 0, 8, 9, 7, 4, 85, 114, 56, 13, 255, 143, 70, 16,
+ 255, 143, 70, 16, 255, 20, 13, 5, 170, 0, 8, 7, 6, 4, 71, 87, 44,
+ 12, 255, 158, 87, 17, 255, 161, 85, 17, 255, 103, 53, 20, 255, 15,
+ 11, 8, 227, 10, 8, 7, 170, 10, 8, 7, 195, 33, 20, 10, 255, 137, 67,
+ 16, 255, 151, 73, 16, 255, 111, 55, 14, 255, 10, 8, 5, 142, 0, 8, 9,
+ 7, 4, 85, 114, 56, 13, 255, 143, 70, 16, 255, 146, 75, 17, 255, 18,
+ 13, 7, 255, 0, 8, 7, 6, 6, 74, 24, 16, 7, 255, 132, 67, 15, 255,
+ 145, 77, 16, 255, 135, 72, 16, 255, 14, 10, 5, 170, 0, 8, 9, 7, 4,
+ 85, 114, 56, 13, 255, 145, 77, 16, 255, 143, 70, 16, 255, 58, 31,
+ 11, 255, 11, 8, 6, 227, 11, 9, 6, 170, 11, 8, 6, 170, 10, 7, 5, 170,
+ 9, 8, 4, 113, 0, 12, 11, 9, 6, 161, 175, 92, 24, 255, 203, 108, 24,
+ 255, 198, 101, 23, 255, 25, 18, 10, 255, 0, 20, 8, 6, 3, 147, 114,
+ 56, 13, 255, 143, 70, 16, 255, 143, 70, 16, 255, 20, 13, 5, 170, 0,
+ 8, 9, 7, 4, 85, 114, 56, 13, 255, 170, 87, 19, 255, 199, 106, 24,
+ 255, 24, 17, 11, 255, 0, 8, 6, 6, 5, 28, 15, 12, 6, 255, 128, 66,
+ 15, 255, 145, 74, 16, 255, 143, 70, 16, 255, 20, 13, 5, 170, 0, 8,
+ 6, 5, 3, 57, 57, 31, 10, 255, 145, 77, 16, 255, 143, 70, 16, 255,
+ 90, 44, 13, 255, 19, 13, 6, 255, 10, 8, 5, 255, 13, 10, 6, 255, 62,
+ 33, 11, 255, 135, 72, 16, 255, 151, 73, 16, 255, 108, 53, 13, 255,
+ 10, 8, 5, 142, 0, 8, 9, 7, 4, 85, 114, 56, 13, 255, 143, 70, 16,
+ 255, 143, 70, 16, 255, 18, 12, 5, 215, 0, 40, 7, 6, 4, 85, 64, 33,
+ 11, 255, 145, 77, 16, 255, 143, 70, 16, 255, 67, 34, 10, 255, 14,
+ 10, 5, 255, 49, 27, 9, 255, 140, 72, 17, 255, 160, 85, 19, 255, 160,
+ 85, 19, 255, 110, 55, 15, 255, 31, 20, 8, 255, 9, 7, 4, 57, 0, 8, 9,
+ 8, 4, 85, 114, 56, 13, 255, 143, 70, 16, 255, 143, 70, 16, 255, 18,
+ 12, 5, 215, 0, 12, 8, 7, 3, 136, 118, 60, 13, 255, 154, 75, 17, 255,
+ 172, 87, 19, 255, 24, 17, 9, 204, 0, 8, 8, 7, 5, 85, 95, 49, 16,
+ 255, 161, 85, 17, 255, 152, 77, 17, 255, 71, 34, 10, 255, 9, 7, 4,
+ 198, 8, 6, 3, 88, 8, 6, 3, 142, 23, 15, 6, 255, 130, 66, 15, 255,
+ 151, 80, 16, 255, 111, 55, 14, 255, 14, 10, 5, 170, 0, 24, 9, 7, 4,
+ 164, 118, 56, 15, 255, 145, 74, 16, 255, 143, 70, 16, 255, 16, 12,
+ 5, 224, 0, 24, 9, 7, 4, 85, 85, 43, 12, 255, 151, 80, 16, 255, 143,
+ 70, 16, 255, 55, 29, 10, 255, 8, 6, 3, 198, 8, 6, 3, 93, 8, 6, 5,
+ 173, 45, 27, 14, 255, 199, 112, 28, 255, 210, 124, 31, 255, 199,
+ 119, 34, 255, 19, 15, 10, 221, 0, 20, 13, 11, 8, 170, 46, 28, 11,
+ 255, 131, 65, 16, 255, 145, 74, 16, 255, 137, 67, 16, 255, 70, 35,
+ 11, 255, 12, 10, 5, 224, 7, 6, 4, 28, 0, 16, 8, 6, 5, 34, 37, 25,
+ 14, 255, 181, 100, 28, 255, 206, 113, 31, 255, 207, 123, 32, 255,
+ 199, 119, 34, 255, 107, 67, 28, 255, 28, 20, 11, 255, 28, 19, 9,
+ 255, 84, 41, 13, 255, 141, 75, 16, 255, 145, 74, 16, 255, 159, 82,
+ 20, 255, 88, 53, 25, 255, 13, 11, 8, 99, 0, 8, 13, 10, 6, 85, 114,
+ 60, 17, 255, 148, 76, 17, 255, 143, 70, 16, 255, 21, 14, 6, 255, 0,
+ 12, 10, 8, 5, 170, 119, 61, 14, 255, 145, 77, 16, 255, 135, 72, 16,
+ 255, 19, 13, 6, 170, 0, 24, 8, 7, 3, 142, 114, 56, 13, 255, 143, 70,
+ 16, 255, 143, 70, 16, 255, 16, 12, 5, 218, 0, 24, 11, 8, 6, 170,
+ 126, 62, 15, 255, 151, 80, 16, 255, 112, 57, 13, 255, 19, 13, 6,
+ 255, 8, 6, 3, 144, 8, 6, 3, 85, 9, 7, 4, 113, 8, 6, 3, 167, 8, 6, 3,
+ 170, 8, 6, 3, 170, 9, 8, 4, 113, 0, 12, 10, 8, 5, 91, 114, 56, 13,
+ 255, 145, 74, 16, 255, 143, 70, 16, 255, 61, 32, 10, 255, 9, 8, 4,
+ 170, 0, 32, 12, 10, 7, 207, 74, 36, 11, 255, 139, 74, 16, 255, 79,
+ 40, 12, 255, 10, 8, 5, 210, 0, 16, 9, 7, 4, 85, 27, 17, 6, 255, 130,
+ 66, 15, 255, 143, 70, 16, 255, 143, 76, 16, 255, 16, 12, 5, 221, 0,
+ 140, 8, 6, 3, 85, 74, 39, 11, 255, 145, 77, 16, 255, 143, 70, 16,
+ 255, 41, 23, 8, 255, 7, 6, 4, 173, 5, 5, 2, 85, 6, 5, 3, 113, 14,
+ 10, 5, 255, 129, 65, 14, 255, 145, 74, 16, 255, 145, 74, 16, 255,
+ 24, 16, 7, 170, 0, 8, 10, 8, 5, 85, 112, 57, 13, 255, 145, 77, 16,
+ 255, 143, 70, 16, 255, 52, 28, 9, 255, 8, 6, 3, 198, 8, 6, 3, 88, 8,
+ 6, 3, 144, 23, 15, 6, 255, 130, 66, 15, 255, 151, 80, 16, 255, 111,
+ 55, 14, 255, 10, 8, 5, 144, 0, 8, 6, 5, 3, 59, 63, 34, 10, 255, 145,
+ 77, 16, 255, 143, 70, 16, 255, 55, 29, 10, 255, 8, 6, 3, 198, 8, 6,
+ 3, 85, 8, 6, 3, 144, 32, 19, 7, 255, 139, 74, 16, 255, 155, 79, 18,
+ 255, 135, 66, 16, 255, 14, 10, 5, 170, 0, 8, 6, 5, 3, 57, 57, 31,
+ 10, 255, 145, 77, 16, 255, 143, 70, 16, 255, 55, 29, 10, 255, 8, 6,
+ 3, 198, 8, 6, 3, 88, 8, 6, 3, 144, 21, 15, 6, 255, 130, 66, 15, 255,
+ 143, 76, 16, 255, 146, 75, 17, 255, 24, 15, 7, 184, 0, 8, 7, 6, 4,
+ 71, 66, 33, 11, 255, 148, 79, 17, 255, 143, 70, 16, 255, 45, 25, 8,
+ 255, 7, 5, 4, 176, 7, 5, 4, 85, 8, 6, 3, 85, 9, 7, 4, 85, 8, 6, 3,
+ 82, 0, 28, 8, 7, 3, 136, 114, 56, 13, 255, 143, 70, 16, 255, 143,
+ 70, 16, 255, 16, 12, 5, 221, 0, 20, 7, 6, 4, 28, 10, 8, 5, 130, 19,
+ 13, 6, 170, 29, 19, 8, 173, 24, 16, 7, 212, 27, 18, 8, 193, 20, 13,
+ 7, 246, 55, 29, 10, 255, 139, 74, 16, 255, 143, 70, 16, 255, 143,
+ 70, 16, 255, 18, 13, 5, 170, 0, 8, 9, 7, 4, 85, 115, 54, 14, 255,
+ 143, 70, 16, 255, 143, 70, 16, 255, 16, 12, 5, 221, 0, 12, 8, 7, 3,
+ 136, 114, 56, 13, 255, 143, 70, 16, 255, 143, 70, 16, 255, 20, 13,
+ 5, 170, 0, 8, 9, 7, 4, 85, 114, 56, 13, 255, 145, 74, 16, 255, 145,
+ 74, 16, 255, 17, 11, 6, 252, 0, 24, 10, 8, 5, 170, 119, 61, 14, 255,
+ 145, 74, 16, 255, 143, 70, 16, 255, 18, 13, 5, 170, 0, 8, 9, 7, 4,
+ 85, 114, 56, 13, 255, 143, 70, 16, 255, 143, 70, 16, 255, 33, 20, 8,
+ 255, 5, 4, 4, 195, 8, 6, 5, 198, 46, 26, 9, 255, 126, 62, 15, 255,
+ 132, 67, 15, 255, 35, 22, 8, 255, 9, 7, 4, 93, 0, 12, 10, 8, 5, 93,
+ 114, 56, 13, 255, 143, 70, 16, 255, 143, 70, 16, 255, 20, 13, 5,
+ 170, 0, 8, 9, 7, 4, 85, 114, 56, 13, 255, 143, 70, 16, 255, 143, 70,
+ 16, 255, 20, 13, 5, 170, 0, 4, 9, 7, 4, 125, 114, 56, 13, 255, 21,
+ 13, 6, 210, 0, 4, 9, 7, 4, 85, 114, 56, 13, 255, 143, 70, 16, 255,
+ 143, 70, 16, 255, 20, 13, 5, 170, 0, 8, 9, 7, 4, 85, 114, 56, 13,
+ 255, 143, 70, 16, 255, 143, 70, 16, 255, 16, 12, 5, 221, 0, 12, 8,
+ 7, 3, 136, 114, 56, 13, 255, 143, 70, 16, 255, 143, 70, 16, 255, 20,
+ 13, 5, 170, 0, 8, 6, 5, 3, 57, 57, 31, 10, 255, 145, 77, 16, 255,
+ 143, 70, 16, 255, 90, 44, 13, 255, 17, 12, 6, 255, 12, 9, 5, 255,
+ 20, 15, 9, 255, 97, 51, 20, 255, 169, 87, 20, 255, 161, 85, 17, 255,
+ 112, 54, 15, 255, 10, 8, 5, 142, 0, 8, 9, 7, 4, 85, 121, 60, 16,
+ 255, 174, 88, 19, 255, 176, 89, 19, 255, 112, 59, 17, 255, 37, 23,
+ 10, 255, 26, 16, 7, 255, 25, 18, 8, 255, 24, 15, 7, 255, 23, 16, 8,
+ 255, 18, 13, 9, 198, 10, 9, 7, 99, 0, 16, 9, 8, 6, 34, 12, 10, 7,
+ 167, 20, 14, 7, 210, 21, 15, 6, 255, 26, 17, 7, 255, 24, 16, 7, 255,
+ 26, 17, 7, 255, 70, 35, 11, 255, 142, 73, 17, 255, 148, 76, 17, 255,
+ 152, 77, 17, 255, 24, 15, 7, 170, 0, 8, 13, 10, 6, 96, 129, 65, 18,
+ 255, 170, 87, 19, 255, 170, 87, 19, 255, 24, 16, 9, 255, 0, 48, 5,
+ 4, 2, 76, 8, 6, 3, 85, 8, 6, 3, 85, 8, 6, 3, 85, 7, 5, 4, 85, 6, 5,
+ 3, 119, 16, 11, 5, 255, 129, 65, 14, 255, 151, 73, 16, 255, 118, 61,
+ 15, 255, 14, 10, 5, 170, 0, 16, 8, 7, 3, 136, 114, 56, 13, 255, 143,
+ 70, 16, 255, 143, 70, 16, 255, 16, 12, 5, 221, 0, 16, 10, 8, 7, 113,
+ 109, 67, 26, 255, 184, 90, 21, 255, 148, 76, 17, 255, 52, 28, 9,
+ 255, 8, 6, 3, 198, 8, 6, 3, 88, 8, 6, 3, 144, 21, 15, 6, 255, 130,
+ 66, 15, 255, 143, 76, 16, 255, 143, 76, 16, 255, 16, 12, 5, 227, 0,
+ 20, 9, 8, 6, 170, 67, 42, 20, 255, 202, 124, 31, 255, 208, 128, 33,
+ 255, 205, 106, 26, 255, 104, 58, 21, 255, 14, 11, 7, 218, 6, 5, 5,
+ 28, 0, 16, 7, 6, 4, 28, 27, 17, 8, 229, 102, 51, 13, 255, 139, 68,
+ 16, 255, 143, 73, 16, 255, 145, 74, 16, 255, 71, 37, 12, 255, 26,
+ 18, 9, 255, 80, 50, 23, 255, 204, 122, 33, 255, 208, 115, 33, 255,
+ 202, 104, 25, 255, 149, 78, 20, 255, 52, 30, 11, 255, 10, 8, 5, 85,
+ 0, 12, 14, 10, 5, 170, 85, 43, 12, 255, 137, 73, 16, 255, 77, 39,
+ 12, 255, 14, 10, 5, 227, 10, 8, 5, 170, 10, 8, 5, 198, 46, 26, 9,
+ 255, 137, 73, 16, 255, 115, 59, 14, 255, 25, 16, 6, 232, 8, 6, 3,
+ 31, 0, 12, 6, 5, 3, 28, 10, 8, 5, 119, 19, 13, 6, 170, 29, 19, 8,
+ 173, 26, 16, 7, 210, 27, 18, 8, 187, 17, 12, 6, 246, 58, 30, 11,
+ 255, 151, 77, 18, 255, 192, 97, 21, 255, 192, 97, 21, 255, 24, 16,
+ 9, 207, 0, 8, 4, 4, 3, 3, 25, 16, 6, 235, 115, 59, 14, 255, 143, 73,
+ 16, 255, 145, 77, 16, 255, 108, 53, 13, 255, 21, 14, 6, 255, 7, 6,
+ 4, 164, 10, 7, 5, 85, 8, 7, 5, 147, 9, 7, 4, 136, 8, 6, 5, 76, 0,
+ 20, 8, 6, 5, 57, 58, 33, 13, 255, 188, 107, 27, 255, 192, 111, 31,
+ 255, 85, 51, 24, 255, 18, 13, 9, 187, 6, 5, 5, 20, 0, 8, 11, 9, 6,
+ 156, 139, 69, 18, 255, 158, 83, 17, 255, 148, 76, 17, 255, 23, 15,
+ 6, 170, 0, 12, 9, 7, 4, 85, 19, 13, 6, 255, 102, 51, 13, 255, 128,
+ 66, 15, 255, 81, 41, 12, 255, 12, 9, 5, 142, 0, 108, 13, 10, 8, 85,
+ 115, 60, 24, 255, 162, 75, 23, 255, 121, 60, 20, 255, 23, 15, 8,
+ 142, 0, 60, 3, 3, 2, 6, 10, 8, 5, 170, 93, 48, 12, 255, 123, 65, 14,
+ 255, 123, 60, 14, 255, 14, 10, 5, 227, 3, 3, 2, 85, 12, 10, 7, 170,
+ 163, 83, 24, 255, 199, 99, 26, 255, 193, 96, 24, 255, 41, 26, 14,
+ 227, 6, 6, 5, 45, 0, 24, 3, 3, 2, 28, 11, 8, 6, 170, 106, 50, 13,
+ 255, 129, 63, 14, 255, 129, 63, 14, 255, 29, 18, 8, 227, 6, 5, 5,
+ 31, 0, 20, 13, 10, 8, 136, 144, 73, 21, 255, 182, 89, 21, 255, 99,
+ 55, 19, 255, 14, 11, 7, 187, 4, 4, 3, 3, 0, 16, 9, 7, 4, 113, 93,
+ 46, 12, 255, 131, 66, 14, 255, 121, 62, 14, 255, 16, 11, 5, 170, 0,
+ 12, 7, 6, 4, 28, 14, 10, 5, 227, 100, 50, 13, 255, 110, 59, 13, 255,
+ 103, 52, 14, 255, 121, 59, 18, 255, 134, 69, 21, 255, 32, 21, 11,
+ 255, 6, 5, 5, 198, 10, 8, 7, 227, 46, 28, 13, 255, 104, 51, 15, 255,
+ 96, 46, 13, 255, 14, 10, 5, 139, 0, 44, 10, 8, 7, 108, 63, 37, 18,
+ 255, 176, 88, 23, 255, 160, 80, 21, 255, 20, 14, 9, 170, 0, 8, 8, 6,
+ 5, 79, 85, 41, 12, 255, 131, 65, 16, 255, 66, 34, 11, 255, 10, 8, 5,
+ 170, 0, 144, 9, 7, 4, 167, 115, 56, 16, 255, 165, 85, 20, 255, 112,
+ 65, 23, 255, 18, 13, 9, 142, 0, 60, 13, 10, 8, 142, 132, 68, 21,
+ 255, 162, 80, 19, 255, 141, 70, 18, 255, 17, 12, 6, 181, 0, 12, 17,
+ 12, 6, 255, 103, 54, 14, 255, 130, 66, 15, 255, 31, 20, 8, 255, 6,
+ 5, 3, 113, 0, 32, 8, 6, 3, 156, 35, 22, 8, 255, 114, 58, 13, 255,
+ 110, 59, 13, 255, 88, 45, 11, 255, 88, 42, 11, 255, 92, 47, 11, 255,
+ 104, 54, 13, 255, 119, 58, 14, 255, 61, 32, 10, 255, 10, 8, 5, 224,
+ 5, 4, 4, 20, 0, 16, 11, 8, 6, 85, 113, 58, 22, 255, 180, 90, 23,
+ 255, 140, 69, 17, 255, 123, 63, 14, 255, 123, 60, 14, 255, 119, 56,
+ 14, 255, 120, 61, 17, 255, 24, 15, 9, 167, 0, 16, 12, 10, 7, 133,
+ 180, 88, 27, 255, 203, 107, 30, 255, 199, 100, 28, 255, 197, 104,
+ 28, 255, 191, 93, 28, 255, 167, 78, 24, 255, 132, 68, 21, 255, 121,
+ 62, 18, 255, 117, 60, 18, 255, 118, 57, 17, 255, 108, 50, 15, 255,
+ 17, 12, 6, 113, 0, 12, 14, 10, 5, 227, 65, 33, 10, 255, 115, 59, 14,
+ 255, 115, 59, 14, 255, 109, 52, 14, 255, 116, 57, 17, 255, 121, 59,
+ 18, 255, 139, 68, 20, 255, 154, 73, 19, 255, 115, 62, 20, 255, 33,
+ 23, 12, 255, 9, 8, 6, 71, 0, 36, 2, 2, 1, 8, 8, 6, 3, 170, 93, 50,
+ 12, 255, 125, 64, 14, 255, 123, 60, 14, 255, 14, 10, 5, 159, 0, 12,
+ 14, 10, 5, 224, 65, 33, 10, 255, 115, 59, 14, 255, 115, 59, 14, 255,
+ 109, 52, 14, 255, 119, 61, 18, 255, 129, 66, 20, 255, 148, 75, 21,
+ 255, 170, 84, 21, 255, 129, 67, 22, 255, 37, 25, 14, 255, 8, 7, 5,
+ 57, 0, 8, 5, 5, 4, 23, 24, 17, 9, 255, 103, 54, 18, 255, 132, 63,
+ 17, 255, 120, 62, 15, 255, 98, 49, 13, 255, 90, 45, 11, 255, 94, 45,
+ 13, 255, 124, 60, 17, 255, 172, 81, 21, 255, 150, 78, 25, 255, 44,
+ 29, 17, 255, 9, 8, 6, 91, 0, 24, 8, 7, 3, 102, 93, 46, 12, 255, 125,
+ 64, 14, 255, 121, 62, 14, 255, 18, 12, 5, 170, 0, 28, 12, 10, 5,
+ 227, 64, 33, 11, 255, 132, 66, 17, 255, 158, 79, 21, 255, 151, 70,
+ 22, 255, 130, 67, 21, 255, 110, 53, 15, 255, 108, 53, 13, 255, 118,
+ 60, 13, 255, 85, 43, 12, 255, 21, 14, 6, 255, 7, 6, 4, 57, 0, 12,
+ 14, 10, 5, 227, 65, 33, 10, 255, 131, 65, 16, 255, 149, 72, 20, 255,
+ 133, 68, 20, 255, 111, 54, 16, 255, 110, 53, 15, 255, 138, 72, 19,
+ 255, 163, 81, 20, 255, 112, 58, 19, 255, 28, 20, 9, 255, 8, 7, 5,
+ 57, 0, 8, 9, 7, 4, 91, 96, 48, 13, 255, 132, 70, 15, 255, 123, 60,
+ 14, 255, 14, 10, 5, 161, 0, 8, 13, 10, 6, 85, 148, 73, 23, 255, 202,
+ 101, 27, 255, 129, 67, 26, 255, 18, 13, 9, 142, 0, 28, 6, 5, 3, 48,
+ 17, 12, 6, 227, 108, 55, 13, 255, 112, 55, 13, 255, 35, 22, 8, 255,
+ 9, 7, 4, 57, 0, 64, 32, 22, 13, 255, 137, 68, 22, 255, 154, 73, 19,
+ 255, 45, 26, 10, 255, 8, 6, 5, 144, 0, 44, 8, 6, 3, 68, 67, 34, 10,
+ 255, 115, 56, 16, 255, 109, 52, 14, 255, 16, 11, 5, 147, 0, 24, 5,
+ 4, 4, 11, 22, 17, 11, 227, 129, 76, 28, 255, 195, 95, 28, 255, 186,
+ 84, 23, 255, 121, 59, 18, 255, 107, 51, 14, 255, 96, 46, 13, 255,
+ 90, 45, 11, 255, 88, 45, 11, 255, 41, 24, 8, 255, 12, 10, 5, 176, 0,
+ 12, 8, 6, 3, 76, 88, 44, 11, 255, 125, 66, 14, 255, 123, 60, 14,
+ 255, 18, 12, 5, 170, 0, 12, 9, 7, 4, 85, 92, 47, 11, 255, 125, 64,
+ 14, 255, 123, 60, 14, 255, 16, 11, 5, 150, 0, 8, 8, 6, 3, 62, 88,
+ 45, 11, 255, 125, 64, 14, 255, 123, 60, 14, 255, 114, 58, 13, 255,
+ 93, 50, 12, 255, 88, 44, 11, 255, 92, 47, 11, 255, 104, 54, 13, 255,
+ 119, 58, 14, 255, 85, 43, 12, 255, 21, 15, 6, 255, 7, 6, 4, 51, 0,
+ 12, 12, 10, 5, 221, 61, 32, 10, 255, 120, 62, 15, 255, 123, 61, 16,
+ 255, 109, 52, 14, 255, 96, 46, 13, 255, 102, 51, 13, 255, 115, 59,
+ 14, 255, 123, 65, 14, 255, 85, 43, 12, 255, 25, 16, 6, 255, 7, 6, 4,
+ 51, 0, 8, 8, 6, 3, 74, 88, 45, 11, 255, 125, 64, 14, 255, 123, 60,
+ 14, 255, 114, 58, 13, 255, 93, 50, 12, 255, 88, 45, 11, 255, 92, 47,
+ 11, 255, 104, 52, 13, 255, 118, 60, 13, 255, 85, 43, 12, 255, 21,
+ 15, 6, 255, 7, 5, 4, 40, 0, 8, 8, 6, 3, 74, 88, 45, 11, 255, 125,
+ 64, 14, 255, 123, 60, 14, 255, 114, 58, 13, 255, 93, 50, 12, 255,
+ 88, 45, 11, 255, 92, 43, 11, 255, 93, 50, 12, 255, 93, 50, 12, 255,
+ 20, 13, 5, 85, 0, 8, 8, 6, 3, 65, 88, 45, 11, 255, 125, 64, 14, 255,
+ 121, 62, 14, 255, 18, 13, 5, 170, 0, 36, 12, 10, 5, 227, 59, 31, 10,
+ 255, 115, 62, 14, 255, 114, 58, 13, 255, 93, 50, 12, 255, 88, 44,
+ 11, 255, 88, 44, 11, 255, 104, 54, 13, 255, 118, 60, 13, 255, 123,
+ 60, 14, 255, 123, 60, 14, 255, 14, 10, 5, 150, 0, 8, 8, 6, 3, 65,
+ 88, 45, 11, 255, 125, 66, 14, 255, 123, 60, 14, 255, 18, 12, 5, 170,
+ 0, 12, 9, 7, 4, 85, 92, 47, 11, 255, 125, 66, 14, 255, 123, 65, 14,
+ 255, 14, 10, 5, 150, 0, 8, 8, 6, 3, 65, 88, 45, 11, 255, 125, 66,
+ 14, 255, 123, 65, 14, 255, 14, 10, 5, 159, 0, 12, 14, 10, 5, 221,
+ 70, 35, 11, 255, 155, 74, 20, 255, 193, 89, 26, 255, 185, 91, 28,
+ 255, 172, 85, 27, 255, 165, 80, 24, 255, 155, 78, 22, 255, 132, 66,
+ 17, 255, 90, 44, 13, 255, 21, 15, 6, 255, 7, 5, 4, 40, 0, 8, 8, 6,
+ 3, 74, 88, 45, 11, 255, 125, 64, 14, 255, 121, 62, 14, 255, 19, 13,
+ 6, 176, 0, 12, 9, 6, 4, 133, 93, 50, 12, 255, 131, 66, 14, 255, 123,
+ 65, 14, 255, 14, 11, 5, 150, 0, 8, 8, 6, 3, 62, 88, 45, 11, 255,
+ 125, 64, 14, 255, 123, 60, 14, 255, 118, 56, 15, 255, 120, 61, 17,
+ 255, 136, 67, 21, 255, 118, 57, 17, 255, 96, 48, 13, 255, 92, 47,
+ 11, 255, 18, 12, 5, 85, 0, 8, 9, 7, 4, 79, 104, 51, 15, 255, 140,
+ 66, 17, 255, 135, 66, 16, 255, 17, 12, 6, 198, 0, 20, 9, 7, 4, 85,
+ 92, 47, 11, 255, 125, 66, 14, 255, 123, 65, 14, 255, 14, 10, 5, 150,
+ 0, 8, 8, 6, 3, 65, 88, 45, 11, 255, 135, 66, 16, 255, 136, 67, 17,
+ 255, 22, 14, 7, 198, 0, 12, 8, 6, 3, 119, 88, 45, 11, 255, 125, 64,
+ 14, 255, 123, 60, 14, 255, 14, 10, 5, 159, 0, 12, 12, 10, 5, 210,
+ 59, 31, 10, 255, 115, 62, 14, 255, 118, 60, 13, 255, 104, 54, 13,
+ 255, 100, 50, 13, 255, 100, 50, 13, 255, 114, 58, 13, 255, 119, 63,
+ 14, 255, 85, 43, 12, 255, 21, 15, 6, 255, 7, 5, 4, 40, 0, 8, 8, 6,
+ 3, 74, 88, 45, 11, 255, 125, 66, 14, 255, 123, 60, 14, 255, 18, 12,
+ 5, 170, 0, 44, 12, 10, 5, 227, 59, 31, 10, 255, 115, 62, 14, 255,
+ 114, 58, 13, 255, 100, 50, 13, 255, 114, 56, 13, 255, 133, 66, 16,
+ 255, 160, 80, 21, 255, 176, 83, 21, 255, 45, 27, 12, 255, 6, 5, 3,
+ 170, 0, 12, 8, 6, 3, 82, 88, 45, 11, 255, 125, 66, 14, 255, 123, 60,
+ 14, 255, 18, 12, 5, 170, 0, 12, 9, 7, 4, 85, 92, 47, 11, 255, 131,
+ 61, 14, 255, 126, 62, 15, 255, 17, 11, 6, 170, 0, 12, 14, 10, 5,
+ 227, 65, 33, 10, 255, 115, 59, 14, 255, 115, 62, 14, 255, 93, 50,
+ 12, 255, 88, 44, 11, 255, 92, 47, 11, 255, 104, 54, 13, 255, 119,
+ 58, 14, 255, 85, 43, 12, 255, 21, 15, 6, 255, 7, 6, 4, 57, 0, 24, 9,
+ 7, 4, 85, 92, 47, 11, 255, 125, 66, 14, 255, 123, 60, 14, 255, 18,
+ 12, 5, 170, 0, 24, 5, 5, 4, 28, 19, 13, 6, 255, 84, 42, 11, 255,
+ 115, 62, 14, 255, 110, 59, 13, 255, 93, 50, 12, 255, 84, 44, 11,
+ 255, 106, 54, 15, 255, 176, 84, 23, 255, 199, 100, 28, 255, 188,
+ 101, 31, 255, 90, 54, 25, 255, 13, 10, 8, 142, 0, 24, 8, 6, 3, 164,
+ 72, 37, 11, 255, 131, 66, 14, 255, 110, 54, 13, 255, 12, 9, 5, 224,
+ 3, 3, 2, 17, 0, 24, 7, 6, 6, 85, 30, 20, 13, 255, 190, 96, 27, 255,
+ 199, 98, 24, 255, 121, 69, 22, 255, 13, 10, 6, 190, 4, 3, 3, 28, 5,
+ 4, 2, 105, 27, 17, 6, 255, 114, 56, 13, 255, 125, 64, 14, 255, 45,
+ 26, 10, 255, 8, 7, 5, 153, 0, 12, 10, 7, 5, 85, 96, 48, 13, 255,
+ 125, 64, 14, 255, 123, 60, 14, 255, 16, 11, 5, 195, 0, 12, 8, 6, 3,
+ 110, 92, 47, 11, 255, 131, 66, 14, 255, 123, 65, 14, 255, 18, 13, 5,
+ 170, 0, 24, 9, 7, 4, 85, 92, 47, 11, 255, 125, 66, 14, 255, 123, 60,
+ 14, 255, 18, 12, 5, 170, 0, 24, 8, 7, 3, 99, 93, 50, 12, 255, 125,
+ 66, 14, 255, 115, 59, 14, 255, 104, 54, 13, 255, 88, 45, 11, 255,
+ 88, 44, 11, 255, 92, 43, 11, 255, 92, 43, 11, 255, 92, 43, 11, 255,
+ 93, 50, 12, 255, 93, 50, 12, 255, 20, 13, 5, 85, 0, 8, 8, 6, 3, 65,
+ 88, 45, 11, 255, 125, 64, 14, 255, 123, 60, 14, 255, 115, 62, 14,
+ 255, 93, 46, 12, 255, 16, 11, 5, 127, 0, 28, 5, 4, 4, 28, 12, 10, 5,
+ 246, 104, 54, 13, 255, 115, 59, 14, 255, 39, 23, 8, 255, 8, 6, 3,
+ 82, 0, 12, 58, 31, 9, 255, 114, 58, 13, 255, 119, 63, 14, 255, 123,
+ 60, 14, 255, 123, 65, 14, 255, 18, 12, 5, 170, 0, 144, 14, 10, 5,
+ 227, 59, 31, 10, 255, 115, 62, 14, 255, 110, 59, 13, 255, 88, 44,
+ 11, 255, 80, 42, 11, 255, 88, 44, 11, 255, 104, 54, 13, 255, 115,
+ 59, 14, 255, 123, 60, 14, 255, 123, 60, 14, 255, 16, 11, 5, 150, 0,
+ 8, 8, 6, 3, 65, 88, 44, 11, 255, 125, 64, 14, 255, 123, 60, 14, 255,
+ 114, 58, 13, 255, 93, 50, 12, 255, 88, 44, 11, 255, 92, 47, 11, 255,
+ 104, 54, 13, 255, 119, 58, 14, 255, 85, 43, 12, 255, 21, 15, 6, 255,
+ 7, 6, 4, 51, 0, 12, 12, 9, 5, 224, 63, 32, 10, 255, 115, 62, 14,
+ 255, 114, 56, 13, 255, 93, 50, 12, 255, 88, 44, 11, 255, 88, 45, 11,
+ 255, 110, 59, 13, 255, 119, 61, 14, 255, 85, 43, 12, 255, 25, 16, 6,
+ 255, 7, 6, 4, 57, 0, 12, 12, 10, 5, 221, 59, 31, 10, 255, 115, 62,
+ 14, 255, 114, 56, 13, 255, 93, 50, 12, 255, 88, 44, 11, 255, 92, 47,
+ 11, 255, 104, 54, 13, 255, 115, 59, 14, 255, 123, 60, 14, 255, 121,
+ 62, 14, 255, 16, 11, 5, 167, 0, 12, 12, 10, 5, 218, 59, 31, 10, 255,
+ 115, 62, 14, 255, 110, 59, 13, 255, 88, 44, 11, 255, 80, 42, 11,
+ 255, 88, 44, 11, 255, 88, 45, 11, 255, 88, 44, 11, 255, 16, 11, 5,
+ 105, 0, 24, 9, 7, 4, 85, 92, 47, 11, 255, 125, 66, 14, 255, 123, 60,
+ 14, 255, 18, 12, 5, 170, 0, 48, 7, 5, 4, 198, 93, 50, 12, 255, 125,
+ 66, 14, 255, 123, 60, 14, 255, 12, 10, 5, 170, 0, 8, 8, 6, 3, 65,
+ 88, 45, 11, 255, 125, 66, 14, 255, 123, 65, 14, 255, 18, 12, 5, 170,
+ 0, 12, 9, 7, 4, 85, 92, 47, 11, 255, 125, 66, 14, 255, 123, 65, 14,
+ 255, 14, 10, 5, 150, 0, 8, 8, 6, 3, 65, 88, 45, 11, 255, 125, 66,
+ 14, 255, 123, 60, 14, 255, 18, 13, 5, 170, 0, 20, 3, 3, 2, 11, 9, 7,
+ 4, 227, 100, 50, 13, 255, 123, 60, 14, 255, 123, 60, 14, 255, 12,
+ 10, 5, 170, 0, 8, 8, 6, 3, 62, 88, 45, 11, 255, 125, 66, 14, 255,
+ 123, 60, 14, 255, 14, 10, 5, 198, 0, 8, 8, 6, 3, 170, 35, 22, 8,
+ 255, 115, 59, 14, 255, 112, 55, 13, 255, 33, 21, 8, 255, 8, 6, 3,
+ 37, 0, 8, 8, 6, 3, 74, 88, 45, 11, 255, 125, 66, 14, 255, 123, 65,
+ 14, 255, 14, 10, 5, 150, 0, 8, 8, 6, 3, 65, 88, 45, 11, 255, 125,
+ 66, 14, 255, 123, 65, 14, 255, 14, 11, 5, 147, 0, 4, 9, 7, 4, 85,
+ 92, 47, 11, 255, 20, 13, 5, 170, 0, 4, 8, 6, 3, 62, 88, 45, 11, 255,
+ 125, 66, 14, 255, 123, 65, 14, 255, 14, 10, 5, 150, 0, 8, 8, 6, 3,
+ 65, 88, 45, 11, 255, 125, 66, 14, 255, 123, 60, 14, 255, 18, 12, 5,
+ 170, 0, 12, 9, 7, 4, 85, 92, 47, 11, 255, 125, 66, 14, 255, 123, 60,
+ 14, 255, 14, 10, 5, 159, 0, 12, 12, 10, 5, 210, 59, 31, 10, 255,
+ 115, 59, 14, 255, 118, 60, 13, 255, 104, 54, 13, 255, 102, 51, 13,
+ 255, 112, 53, 13, 255, 122, 63, 15, 255, 123, 58, 14, 255, 85, 43,
+ 12, 255, 21, 15, 6, 255, 7, 5, 4, 45, 0, 8, 8, 6, 3, 85, 113, 55,
+ 16, 255, 196, 92, 23, 255, 195, 96, 24, 255, 25, 17, 10, 255, 4, 3,
+ 3, 79, 0, 64, 3, 2, 2, 28, 10, 8, 5, 227, 138, 71, 21, 255, 177, 87,
+ 20, 255, 174, 86, 21, 255, 24, 16, 9, 170, 0, 8, 13, 10, 8, 85, 142,
+ 73, 23, 255, 195, 96, 24, 255, 194, 91, 23, 255, 24, 17, 11, 227, 0,
+ 44, 12, 9, 5, 150, 35, 22, 8, 255, 80, 42, 11, 255, 84, 44, 11, 255,
+ 88, 44, 11, 255, 80, 42, 11, 255, 88, 44, 11, 255, 97, 50, 12, 255,
+ 118, 60, 13, 255, 85, 43, 12, 255, 21, 15, 6, 255, 8, 6, 3, 57, 0,
+ 16, 9, 7, 4, 85, 92, 47, 11, 255, 125, 66, 14, 255, 123, 60, 14,
+ 255, 18, 12, 5, 170, 0, 16, 6, 5, 5, 28, 17, 13, 8, 227, 68, 34, 11,
+ 255, 115, 59, 14, 255, 110, 59, 13, 255, 93, 50, 12, 255, 88, 44,
+ 11, 255, 92, 47, 11, 255, 104, 54, 13, 255, 115, 59, 14, 255, 123,
+ 60, 14, 255, 123, 65, 14, 255, 18, 12, 5, 170, 0, 24, 12, 9, 7, 170,
+ 131, 69, 24, 255, 191, 90, 22, 255, 136, 71, 19, 255, 15, 11, 6,
+ 227, 4, 3, 3, 17, 0, 24, 7, 6, 4, 31, 16, 11, 5, 227, 104, 52, 13,
+ 255, 131, 66, 14, 255, 98, 49, 13, 255, 10, 8, 5, 193, 3, 2, 2, 68,
+ 8, 7, 5, 170, 121, 66, 26, 255, 195, 96, 24, 255, 156, 74, 19, 255,
+ 34, 21, 9, 255, 9, 7, 4, 85, 0, 12, 8, 6, 3, 51, 69, 35, 10, 255,
+ 121, 62, 14, 255, 123, 60, 14, 255, 16, 11, 5, 227, 4, 3, 3, 28, 0,
+ 8, 8, 6, 3, 170, 92, 47, 11, 255, 125, 64, 14, 255, 108, 55, 13,
+ 255, 14, 10, 5, 164, 0, 40, 7, 5, 4, 198, 96, 48, 13, 255, 134, 65,
+ 15, 255, 133, 66, 16, 255, 15, 11, 6, 170, 0, 8, 7, 5, 4, 85, 78,
+ 39, 11, 255, 130, 64, 15, 255, 130, 64, 15, 255, 134, 65, 15, 255,
+ 136, 67, 17, 255, 124, 62, 17, 255, 114, 56, 17, 255, 113, 55, 16,
+ 255, 118, 60, 17, 255, 107, 55, 20, 255, 48, 29, 15, 255, 12, 10, 7,
+ 85, 0, 20, 9, 8, 6, 170, 45, 27, 12, 255, 139, 70, 20, 255, 131, 66,
+ 18, 255, 107, 53, 14, 255, 19, 13, 6, 99, 0, 8, 8, 6, 5, 85, 92, 46,
+ 13, 255, 131, 61, 14, 255, 125, 64, 14, 255, 14, 10, 5, 170, 0, 12,
+ 58, 31, 9, 255, 110, 59, 13, 255, 115, 59, 14, 255, 56, 29, 9, 255,
+ 10, 8, 5, 227, 5, 4, 4, 23, 0, 108, 10, 8, 7, 28, 28, 18, 11, 212,
+ 49, 28, 16, 255, 35, 21, 12, 241, 13, 10, 6, 85, 0, 68, 14, 10, 5,
+ 142, 20, 14, 5, 170, 16, 12, 5, 164, 8, 6, 3, 28, 0, 8, 24, 16, 9,
+ 142, 21, 15, 8, 252, 23, 15, 8, 184, 11, 8, 6, 34, 0, 36, 14, 10, 5,
+ 142, 20, 14, 5, 170, 16, 11, 5, 170, 10, 8, 5, 28, 0, 24, 7, 6, 4,
+ 25, 20, 13, 7, 147, 22, 15, 7, 170, 10, 8, 5, 142, 5, 4, 4, 3, 0,
+ 24, 14, 10, 5, 142, 20, 13, 5, 170, 16, 11, 5, 170, 9, 7, 4, 28, 0,
+ 16, 7, 5, 4, 28, 14, 10, 5, 156, 14, 10, 5, 229, 24, 15, 9, 255, 32,
+ 20, 11, 255, 28, 18, 11, 244, 12, 9, 7, 108, 0, 8, 10, 8, 5, 142,
+ 19, 13, 8, 235, 24, 15, 7, 227, 10, 8, 5, 59, 0, 48, 10, 8, 5, 93,
+ 23, 15, 8, 170, 28, 18, 9, 173, 15, 11, 6, 28, 0, 12, 18, 12, 5,
+ 142, 21, 14, 6, 170, 9, 7, 4, 133, 0, 148, 8, 6, 5, 113, 89, 44, 14,
+ 255, 100, 51, 21, 255, 13, 10, 8, 227, 6, 5, 5, 28, 0, 60, 6, 5, 5,
+ 8, 17, 12, 6, 142, 26, 16, 7, 170, 18, 12, 5, 170, 9, 7, 4, 28, 0,
+ 8, 6, 5, 3, 85, 54, 28, 11, 255, 136, 66, 19, 255, 121, 59, 18, 255,
+ 15, 10, 6, 241, 0, 40, 8, 6, 3, 57, 12, 9, 5, 170, 18, 13, 5, 178,
+ 14, 10, 5, 241, 14, 10, 5, 255, 14, 10, 5, 252, 16, 11, 5, 195, 16,
+ 11, 5, 170, 8, 6, 3, 113, 0, 24, 8, 6, 5, 28, 24, 16, 9, 204, 24,
+ 17, 9, 255, 17, 12, 6, 210, 14, 10, 5, 170, 16, 11, 5, 170, 17, 11,
+ 6, 246, 27, 17, 10, 246, 14, 10, 7, 85, 0, 16, 8, 6, 5, 28, 21, 14,
+ 10, 195, 22, 15, 11, 255, 18, 13, 9, 255, 18, 13, 9, 255, 22, 15, 9,
+ 255, 19, 13, 8, 255, 17, 12, 6, 255, 17, 11, 6, 255, 15, 11, 6, 255,
+ 17, 12, 6, 255, 19, 13, 6, 204, 12, 9, 5, 28, 0, 12, 5, 4, 2, 25, 8,
+ 6, 3, 122, 14, 10, 5, 170, 18, 13, 5, 176, 14, 10, 5, 235, 15, 11,
+ 6, 255, 15, 11, 6, 255, 19, 12, 6, 204, 19, 13, 6, 170, 10, 8, 5,
+ 170, 8, 6, 5, 57, 0, 48, 14, 10, 5, 142, 21, 13, 6, 170, 16, 11, 5,
+ 170, 9, 7, 4, 28, 0, 12, 5, 4, 2, 25, 8, 6, 3, 125, 14, 10, 5, 170,
+ 14, 10, 5, 210, 23, 15, 8, 255, 30, 20, 11, 255, 30, 20, 11, 255,
+ 23, 17, 10, 255, 20, 14, 9, 244, 16, 12, 9, 170, 9, 8, 6, 79, 0, 16,
+ 9, 7, 6, 65, 15, 11, 8, 170, 17, 12, 8, 232, 21, 14, 8, 255, 26, 16,
+ 9, 255, 23, 15, 8, 255, 21, 14, 8, 255, 15, 11, 6, 255, 22, 15, 7,
+ 178, 11, 9, 6, 170, 10, 8, 7, 57, 0, 32, 12, 10, 5, 142, 20, 13, 5,
+ 170, 16, 11, 5, 170, 9, 7, 4, 28, 0, 28, 5, 5, 4, 28, 8, 6, 3, 133,
+ 15, 11, 6, 193, 20, 15, 9, 255, 28, 18, 11, 255, 30, 20, 11, 255,
+ 26, 16, 9, 255, 14, 10, 5, 238, 16, 11, 5, 170, 9, 7, 4, 153, 7, 5,
+ 4, 57, 0, 16, 5, 4, 2, 28, 8, 6, 3, 142, 18, 12, 7, 207, 22, 15, 9,
+ 255, 28, 18, 11, 255, 27, 18, 10, 255, 18, 13, 7, 255, 15, 11, 6,
+ 227, 21, 13, 6, 170, 10, 7, 5, 164, 7, 6, 4, 57, 0, 16, 14, 10, 5,
+ 142, 20, 13, 5, 170, 16, 12, 5, 170, 9, 7, 4, 28, 0, 8, 10, 8, 7,
+ 119, 149, 64, 26, 255, 131, 63, 26, 255, 14, 11, 7, 227, 6, 5, 5,
+ 28, 0, 32, 7, 5, 4, 28, 14, 10, 5, 156, 20, 13, 5, 170, 12, 9, 5,
+ 142, 6, 5, 3, 6, 0, 64, 12, 10, 7, 142, 24, 15, 7, 170, 21, 13, 6,
+ 170, 8, 6, 3, 76, 0, 48, 9, 7, 6, 85, 83, 43, 16, 255, 176, 88, 23,
+ 255, 130, 62, 21, 255, 16, 11, 7, 170, 0, 28, 9, 8, 6, 28, 13, 10,
+ 8, 164, 23, 16, 10, 190, 16, 11, 7, 252, 15, 11, 6, 255, 14, 10, 5,
+ 255, 14, 10, 5, 255, 14, 10, 5, 255, 16, 11, 5, 232, 14, 10, 5, 170,
+ 8, 6, 3, 85, 0, 16, 14, 10, 5, 142, 21, 13, 6, 170, 16, 11, 5, 170,
+ 9, 7, 4, 28, 0, 16, 14, 10, 5, 142, 20, 13, 5, 170, 16, 11, 5, 170,
+ 9, 7, 4, 28, 0, 12, 14, 10, 5, 136, 16, 12, 5, 170, 16, 11, 5, 170,
+ 18, 12, 5, 170, 16, 11, 5, 210, 14, 10, 5, 255, 14, 10, 5, 249, 16,
+ 12, 5, 193, 16, 11, 5, 170, 9, 7, 4, 153, 7, 5, 4, 57, 0, 16, 5, 5,
+ 4, 28, 8, 6, 3, 125, 14, 10, 5, 170, 18, 12, 5, 176, 14, 10, 5, 238,
+ 14, 10, 5, 246, 16, 12, 5, 195, 18, 13, 5, 170, 16, 11, 5, 170, 9,
+ 7, 4, 150, 7, 5, 4, 54, 0, 16, 14, 10, 5, 142, 16, 12, 5, 170, 16,
+ 11, 5, 170, 18, 12, 5, 170, 16, 11, 5, 210, 14, 10, 5, 255, 14, 10,
+ 5, 249, 16, 12, 5, 193, 16, 11, 5, 170, 9, 7, 4, 153, 7, 6, 4, 57,
+ 0, 16, 14, 10, 5, 142, 16, 12, 5, 170, 16, 11, 5, 170, 18, 12, 5,
+ 170, 16, 11, 5, 210, 14, 10, 5, 252, 12, 9, 5, 255, 16, 11, 5, 255,
+ 20, 13, 5, 201, 11, 9, 4, 28, 0, 12, 14, 10, 5, 139, 20, 13, 5, 170,
+ 16, 11, 5, 170, 9, 7, 4, 28, 0, 36, 5, 5, 4, 28, 8, 6, 3, 125, 14,
+ 10, 5, 170, 18, 13, 5, 176, 14, 10, 5, 238, 14, 10, 5, 255, 16, 11,
+ 5, 235, 18, 13, 5, 173, 16, 11, 5, 170, 16, 12, 5, 170, 16, 11, 5,
+ 164, 9, 7, 4, 28, 0, 12, 12, 9, 5, 142, 21, 13, 6, 170, 16, 11, 5,
+ 170, 9, 7, 4, 28, 0, 16, 14, 10, 5, 142, 20, 13, 5, 170, 16, 11, 5,
+ 170, 9, 7, 4, 28, 0, 12, 12, 9, 5, 142, 21, 13, 6, 170, 16, 11, 5,
+ 170, 9, 7, 4, 28, 0, 12, 6, 5, 3, 28, 8, 7, 5, 139, 19, 13, 8, 193,
+ 21, 15, 10, 255, 31, 21, 12, 255, 32, 21, 13, 255, 31, 20, 12, 255,
+ 23, 17, 10, 255, 18, 12, 7, 212, 10, 8, 5, 159, 7, 6, 4, 57, 0, 16,
+ 14, 10, 5, 142, 21, 13, 6, 170, 16, 11, 5, 170, 9, 7, 4, 28, 0, 16,
+ 14, 10, 5, 142, 21, 13, 6, 170, 16, 12, 5, 170, 9, 7, 4, 28, 0, 12,
+ 14, 10, 5, 136, 16, 12, 5, 170, 16, 11, 5, 170, 18, 12, 5, 176, 17,
+ 12, 6, 252, 21, 14, 8, 255, 17, 12, 6, 255, 16, 11, 5, 255, 20, 13,
+ 5, 204, 11, 9, 4, 28, 0, 12, 14, 10, 5, 142, 21, 14, 6, 170, 18, 12,
+ 5, 170, 9, 8, 4, 28, 0, 24, 14, 10, 5, 142, 20, 13, 5, 170, 16, 11,
+ 5, 170, 9, 7, 4, 28, 0, 12, 12, 9, 5, 142, 21, 13, 6, 170, 16, 12,
+ 5, 170, 10, 8, 5, 28, 0, 16, 12, 9, 5, 142, 20, 13, 5, 170, 16, 11,
+ 5, 170, 9, 7, 4, 28, 0, 12, 5, 5, 4, 28, 8, 6, 3, 125, 14, 10, 5,
+ 170, 18, 12, 5, 170, 20, 14, 5, 173, 16, 12, 5, 193, 20, 13, 5, 178,
+ 20, 13, 5, 170, 16, 11, 5, 170, 9, 7, 4, 153, 7, 6, 4, 57, 0, 16,
+ 14, 10, 5, 142, 21, 13, 6, 170, 16, 11, 5, 170, 9, 7, 4, 28, 0, 44,
+ 5, 5, 4, 28, 8, 6, 3, 125, 14, 10, 5, 170, 18, 13, 5, 170, 20, 14,
+ 5, 170, 18, 12, 5, 170, 13, 10, 6, 227, 72, 38, 19, 255, 185, 86,
+ 32, 255, 144, 64, 29, 255, 20, 15, 11, 232, 8, 7, 7, 28, 0, 12, 14,
+ 10, 5, 142, 21, 13, 6, 170, 16, 11, 5, 170, 9, 7, 4, 28, 0, 16, 14,
+ 10, 5, 142, 20, 13, 5, 170, 16, 11, 5, 170, 9, 7, 4, 28, 0, 12, 5,
+ 4, 2, 25, 8, 6, 3, 122, 14, 10, 5, 170, 18, 13, 5, 176, 14, 10, 5,
+ 238, 14, 10, 5, 255, 14, 10, 5, 249, 16, 12, 5, 193, 16, 11, 5, 170,
+ 9, 7, 4, 153, 7, 5, 4, 57, 0, 32, 14, 10, 5, 142, 21, 13, 6, 170,
+ 16, 11, 5, 170, 9, 7, 4, 28, 0, 28, 8, 6, 3, 57, 9, 7, 4, 164, 14,
+ 10, 5, 170, 18, 13, 5, 173, 14, 10, 5, 229, 14, 10, 5, 255, 17, 12,
+ 6, 255, 22, 15, 9, 255, 20, 14, 9, 252, 21, 15, 10, 176, 11, 9, 6,
+ 139, 0, 32, 11, 8, 4, 122, 18, 12, 5, 170, 14, 10, 5, 150, 7, 5, 4,
+ 28, 0, 32, 8, 7, 7, 57, 24, 16, 11, 173, 26, 18, 9, 190, 13, 10, 6,
+ 142, 5, 4, 4, 11, 0, 8, 8, 7, 3, 68, 14, 10, 5, 170, 16, 11, 5, 170,
+ 9, 7, 4, 74, 0, 20, 14, 10, 5, 142, 20, 14, 5, 170, 16, 11, 5, 170,
+ 9, 7, 4, 28, 0, 16, 14, 10, 5, 142, 20, 14, 5, 170, 16, 11, 5, 170,
+ 9, 8, 4, 28, 0, 28, 14, 10, 5, 142, 20, 13, 5, 170, 16, 11, 5, 170,
+ 9, 7, 4, 28, 0, 28, 14, 10, 5, 142, 18, 13, 5, 170, 16, 12, 5, 170,
+ 18, 13, 5, 173, 14, 10, 5, 227, 14, 10, 5, 255, 14, 10, 5, 252, 12,
+ 9, 5, 255, 12, 9, 5, 255, 16, 11, 5, 255, 20, 13, 5, 201, 11, 9, 4,
+ 28, 0, 12, 12, 10, 5, 136, 16, 12, 5, 170, 16, 11, 5, 170, 16, 11,
+ 5, 193, 21, 15, 6, 184, 14, 10, 5, 31, 0, 32, 8, 6, 3, 139, 54, 30,
+ 9, 255, 107, 50, 12, 255, 78, 39, 11, 255, 9, 7, 4, 161, 0, 12, 20,
+ 13, 5, 142, 18, 12, 5, 210, 16, 11, 5, 170, 16, 11, 5, 170, 16, 11,
+ 5, 170, 9, 7, 4, 28, 0, 64, 13, 10, 8, 57, 9, 7, 6, 159, 8, 6, 5,
+ 159, 10, 8, 7, 130, 10, 8, 7, 119, 9, 7, 6, 133, 9, 7, 6, 167, 10,
+ 8, 7, 170, 11, 9, 8, 113, 0, 44, 5, 4, 2, 28, 8, 6, 3, 125, 14, 10,
+ 5, 170, 18, 13, 5, 176, 14, 10, 5, 238, 14, 10, 5, 255, 16, 11, 5,
+ 235, 18, 13, 5, 173, 16, 11, 5, 170, 16, 12, 5, 170, 16, 11, 5, 164,
+ 9, 7, 4, 28, 0, 12, 14, 10, 5, 136, 16, 12, 5, 170, 16, 11, 5, 170,
+ 18, 12, 5, 170, 16, 11, 5, 210, 14, 10, 5, 255, 14, 10, 5, 249, 16,
+ 12, 5, 193, 16, 11, 5, 170, 9, 7, 4, 153, 7, 5, 4, 57, 0, 16, 5, 5,
+ 4, 28, 8, 6, 3, 125, 14, 10, 5, 170, 18, 13, 5, 176, 14, 10, 5, 238,
+ 14, 10, 5, 255, 14, 10, 5, 249, 16, 11, 5, 193, 16, 11, 5, 170, 9,
+ 7, 4, 150, 7, 5, 4, 57, 0, 16, 5, 5, 4, 28, 8, 6, 3, 125, 14, 10, 5,
+ 170, 18, 13, 5, 176, 14, 10, 5, 238, 14, 10, 5, 255, 14, 10, 5, 235,
+ 18, 13, 5, 173, 16, 11, 5, 170, 16, 12, 5, 170, 16, 11, 5, 170, 9,
+ 7, 4, 28, 0, 12, 5, 5, 4, 28, 8, 6, 3, 125, 14, 10, 5, 170, 18, 13,
+ 5, 176, 14, 10, 5, 235, 14, 10, 5, 255, 14, 10, 5, 255, 16, 11, 5,
+ 255, 20, 13, 5, 207, 12, 9, 5, 34, 0, 28, 14, 10, 5, 142, 20, 13, 5,
+ 170, 16, 11, 5, 170, 9, 7, 4, 28, 0, 28, 6, 5, 3, 85, 7, 5, 4, 85,
+ 6, 5, 3, 85, 5, 4, 4, 85, 5, 4, 4, 105, 9, 8, 4, 241, 72, 37, 11,
+ 255, 110, 54, 13, 255, 67, 34, 10, 255, 8, 6, 3, 144, 0, 12, 14, 10,
+ 5, 142, 21, 14, 6, 170, 16, 12, 5, 170, 9, 8, 4, 28, 0, 16, 14, 10,
+ 5, 142, 21, 13, 6, 170, 16, 11, 5, 170, 9, 7, 4, 28, 0, 12, 12, 9,
+ 5, 142, 21, 13, 6, 170, 16, 11, 5, 170, 9, 7, 4, 28, 0, 12, 7, 5, 2,
+ 37, 8, 6, 3, 142, 8, 6, 3, 227, 25, 15, 6, 255, 75, 36, 10, 255, 99,
+ 51, 12, 255, 66, 33, 9, 255, 8, 6, 3, 130, 0, 12, 14, 10, 5, 139,
+ 21, 13, 6, 170, 16, 11, 5, 170, 9, 7, 4, 28, 0, 12, 8, 6, 3, 79, 14,
+ 10, 5, 170, 18, 13, 5, 170, 12, 9, 5, 142, 0, 16, 14, 10, 5, 142,
+ 21, 13, 6, 170, 16, 11, 5, 170, 9, 7, 4, 28, 0, 12, 12, 9, 5, 142,
+ 21, 13, 6, 170, 16, 11, 5, 170, 9, 7, 4, 28, 0, 8, 20, 13, 5, 85,
+ 11, 8, 4, 28, 0, 8, 12, 9, 5, 142, 21, 13, 6, 170, 16, 11, 5, 170,
+ 9, 7, 4, 28, 0, 12, 12, 9, 5, 142, 21, 13, 6, 170, 16, 11, 5, 170,
+ 9, 7, 4, 28, 0, 16, 14, 10, 5, 142, 20, 13, 5, 170, 16, 11, 5, 170,
+ 9, 7, 4, 28, 0, 12, 5, 5, 4, 28, 8, 6, 3, 125, 14, 10, 5, 170, 18,
+ 12, 5, 170, 20, 14, 5, 173, 16, 12, 5, 193, 20, 13, 5, 178, 20, 13,
+ 5, 170, 16, 11, 5, 170, 9, 7, 4, 161, 7, 6, 4, 57, 0, 12, 8, 6, 3,
+ 85, 84, 40, 13, 255, 164, 73, 23, 255, 184, 79, 27, 255, 15, 11, 8,
+ 246, 0, 72, 11, 10, 10, 170, 176, 83, 37, 255, 196, 87, 33, 255,
+ 192, 88, 31, 255, 22, 15, 11, 193, 0, 12, 21, 15, 10, 159, 26, 17,
+ 11, 255, 24, 17, 11, 221, 10, 8, 7, 85, 0, 44, 8, 7, 3, 59, 12, 9,
+ 5, 170, 16, 11, 5, 210, 14, 10, 5, 255, 14, 10, 5, 255, 14, 10, 5,
+ 255, 14, 10, 5, 246, 16, 12, 5, 193, 16, 11, 5, 170, 9, 7, 4, 153,
+ 6, 5, 3, 57, 0, 24, 14, 10, 5, 142, 20, 13, 5, 170, 16, 11, 5, 170,
+ 9, 7, 4, 28, 0, 20, 6, 5, 3, 28, 8, 6, 3, 127, 14, 10, 5, 170, 18,
+ 13, 5, 176, 14, 10, 5, 238, 14, 10, 5, 255, 14, 10, 5, 235, 18, 13,
+ 5, 173, 16, 11, 5, 170, 16, 12, 5, 170, 16, 11, 5, 170, 9, 7, 4, 28,
+ 0, 28, 14, 11, 7, 142, 29, 19, 8, 170, 17, 11, 6, 159, 8, 6, 3, 28,
+ 0, 32, 7, 5, 4, 28, 14, 10, 5, 150, 20, 13, 5, 170, 12, 9, 5, 142,
+ 5, 4, 2, 14, 0, 8, 15, 11, 8, 142, 26, 18, 9, 178, 19, 13, 6, 170,
+ 8, 6, 3, 68, 0, 20, 18, 12, 5, 142, 16, 11, 5, 238, 16, 11, 5, 170,
+ 9, 7, 4, 28, 0, 16, 12, 9, 5, 142, 16, 11, 5, 215, 18, 13, 5, 187,
+ 11, 9, 4, 28, 0, 16, 4, 4, 3, 6, 5, 4, 2, 82, 5, 4, 2, 85, 5, 4, 2,
+ 85, 5, 4, 2, 85, 5, 4, 2, 99, 9, 7, 4, 241, 72, 37, 11, 255, 112,
+ 53, 13, 255, 77, 39, 12, 255, 10, 8, 5, 170, 0, 12, 19, 13, 8, 184,
+ 20, 14, 9, 255, 16, 11, 7, 255, 14, 11, 7, 255, 17, 12, 8, 255, 22,
+ 15, 9, 255, 27, 17, 10, 255, 30, 19, 11, 255, 28, 18, 11, 255, 21,
+ 15, 10, 255, 15, 12, 8, 198, 9, 7, 6, 28, 0, 24, 8, 6, 5, 91, 15,
+ 11, 6, 170, 14, 11, 5, 238, 19, 13, 6, 198, 12, 9, 5, 28, 0, 8, 6,
+ 5, 3, 85, 54, 29, 9, 255, 100, 48, 13, 255, 109, 52, 14, 255, 15,
+ 11, 6, 170, 0, 12, 19, 13, 6, 144, 14, 10, 5, 255, 16, 11, 5, 178,
+ 8, 6, 3, 119, 0, 255, 0, 255, 0, 174, 12, 9, 7, 88, 99, 44, 20, 255,
+ 26, 16, 11, 232, 5, 4, 4, 28, 0, 92, 6, 5, 3, 57, 60, 28, 11, 255,
+ 158, 67, 23, 255, 88, 44, 23, 255, 11, 9, 6, 142, 0, 255, 0, 255, 0,
+ 150, 12, 9, 7, 110, 126, 51, 25, 255, 25, 17, 12, 232, 5, 4, 4, 28,
+ 0, 184, 6, 5, 5, 28, 19, 14, 10, 227, 52, 29, 17, 255, 30, 20, 13,
+ 255, 9, 8, 6, 82, 0, 255, 0, 255, 0, 255, 0, 255, 0, 8, 12, 10, 9,
+ 170, 172, 81, 49, 255, 213, 125, 94, 255, 185, 88, 58, 255, 23, 16,
+ 14, 159, 0, 255, 0, 255, 0, 106, 5, 4, 2, 28, 16, 11, 5, 244, 68,
+ 34, 9, 255, 62, 33, 9, 255, 9, 8, 4, 139, 0, 96, 10, 8, 7, 48, 71,
+ 33, 18, 255, 108, 47, 23, 255, 107, 48, 22, 255, 113, 51, 24, 255,
+ 109, 50, 24, 255, 104, 45, 21, 255, 104, 45, 21, 255, 113, 49, 24,
+ 255, 115, 50, 24, 255, 18, 13, 9, 136, 0, 255, 0, 129, 9, 7, 6, 34,
+ 18, 13, 9, 244, 66, 31, 15, 255, 84, 37, 17, 255, 83, 36, 16, 255,
+ 75, 34, 14, 255, 73, 35, 14, 255, 91, 41, 16, 255, 110, 47, 19, 255,
+ 79, 40, 16, 255, 24, 16, 9, 255, 8, 6, 5, 57, 0, 100, 22, 14, 5,
+ 244, 40, 23, 7, 255, 42, 23, 7, 255, 54, 28, 9, 255, 60, 31, 9, 255,
+ 36, 22, 7, 255, 12, 9, 5, 244, 6, 5, 3, 28, 0, 255, 0, 29, 9, 7, 6,
+ 85, 72, 34, 13, 255, 126, 56, 21, 255, 148, 63, 25, 255, 25, 17, 14,
+ 190, 0, 72, 15, 12, 12, 133, 178, 86, 57, 255, 200, 89, 55, 255,
+ 194, 82, 47, 255, 30, 20, 17, 187, 0, 255, 0, 169, 9, 7, 4, 99, 17,
+ 12, 6, 255, 42, 22, 9, 255, 49, 25, 9, 255, 54, 26, 11, 255, 52, 26,
+ 11, 255, 59, 28, 12, 255, 82, 37, 15, 255, 111, 49, 18, 255, 84, 39,
+ 17, 255, 25, 17, 10, 255, 8, 7, 5, 57, 0, 112, 6, 5, 3, 57, 38, 22,
+ 7, 255, 85, 39, 12, 255, 124, 52, 21, 255, 20, 13, 9, 170, 0, 255,
+ 0, 255, 0, 202, 8, 6, 5, 28, 26, 16, 11, 170, 11, 8, 6, 85, 0, 100,
+ 12, 8, 5, 119, 20, 14, 9, 170, 12, 9, 7, 142, 0, 255, 0, 255, 0,
+ 154, 9, 7, 6, 28, 27, 17, 12, 170, 11, 9, 8, 85, 0, 192, 7, 6, 6,
+ 28, 8, 7, 5, 85, 8, 6, 5, 57, 0, 255, 0, 255, 0, 255, 0, 255, 0, 16,
+ 25, 17, 16, 161, 41, 27, 26, 255, 40, 26, 23, 235, 14, 12, 11, 82,
+ 0, 255, 0, 255, 0, 110, 8, 6, 3, 37, 9, 7, 4, 142, 9, 7, 4, 136, 6,
+ 5, 3, 6, 0, 100, 23, 15, 10, 153, 19, 13, 10, 255, 16, 11, 9, 255,
+ 16, 11, 9, 255, 16, 11, 9, 255, 16, 11, 9, 255, 16, 11, 9, 255, 18,
+ 13, 9, 255, 24, 16, 11, 204, 16, 11, 9, 31, 0, 255, 0, 133, 10, 8,
+ 7, 142, 18, 12, 9, 207, 18, 13, 9, 255, 16, 11, 9, 255, 15, 11, 8,
+ 255, 15, 11, 8, 252, 18, 13, 9, 195, 18, 12, 9, 170, 11, 8, 6, 167,
+ 8, 7, 5, 57, 0, 104, 9, 8, 4, 142, 14, 10, 5, 170, 13, 10, 6, 170,
+ 13, 9, 6, 170, 11, 8, 6, 170, 7, 6, 4, 130, 6, 5, 3, 28, 0, 255, 0,
+ 37, 14, 10, 7, 142, 21, 14, 10, 170, 19, 13, 10, 170, 14, 11, 9, 31,
+ 0, 72, 8, 7, 8, 14, 25, 17, 16, 142, 27, 18, 16, 193, 26, 18, 15,
+ 170, 15, 11, 10, 34, 0, 255, 0, 169, 9, 7, 4, 28, 11, 8, 6, 170, 14,
+ 10, 7, 232, 15, 10, 8, 255, 15, 10, 8, 255, 15, 10, 8, 255, 15, 10,
+ 8, 252, 18, 12, 9, 195, 18, 12, 9, 170, 11, 8, 6, 167, 9, 7, 6, 57,
+ 0, 120, 9, 7, 4, 91, 16, 11, 7, 170, 20, 13, 9, 170, 13, 10, 8, 28,
+ 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
+ 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+ 0, 255, 0, 255, 0, 255}};
+ /* Created by MiniCompress.. an iOS RLE compressor.
+ * Compress Rate : 46.36 %
+ */
diff --git a/gst/goom/gfontrle.h b/gst/goom/gfontrle.h
new file mode 100644
index 00000000..41e2462f
--- /dev/null
+++ b/gst/goom/gfontrle.h
@@ -0,0 +1,7 @@
+extern const struct {
+ unsigned int width;
+ unsigned int height;
+ unsigned int bytes_per_pixel;
+ unsigned int rle_size;
+ unsigned char rle_pixel [49725];
+} the_font ;
diff --git a/gst/goom/goom.h b/gst/goom/goom.h
new file mode 100644
index 00000000..b0ddab17
--- /dev/null
+++ b/gst/goom/goom.h
@@ -0,0 +1,30 @@
+#ifndef _GOOMCORE_H
+#define _GOOMCORE_H
+
+#include "goom_config.h"
+#include "goom_plugin_info.h"
+#include "goomsl.h"
+
+#define NB_FX 10
+
+PluginInfo *goom_init (guint32 resx, guint32 resy);
+void goom_set_resolution (PluginInfo *goomInfo, guint32 resx, guint32 resy);
+
+/*
+ * forceMode == 0 : do nothing
+ * forceMode == -1 : lock the FX
+ * forceMode == 1..NB_FX : force a switch to FX n# forceMode
+ *
+ * songTitle = pointer to the title of the song...
+ * - NULL if it is not the start of the song
+ * - only have a value at the start of the song
+ */
+guint32 *goom_update (PluginInfo *goomInfo, gint16 data[2][512], int forceMode, float fps,
+ char *songTitle, char *message);
+
+/* returns 0 if the buffer wasn't accepted */
+int goom_set_screenbuffer(PluginInfo *goomInfo, void *buffer);
+
+void goom_close (PluginInfo *goomInfo);
+
+#endif
diff --git a/gst/goom/goom_config.h b/gst/goom/goom_config.h
new file mode 100644
index 00000000..5f6f1589
--- /dev/null
+++ b/gst/goom/goom_config.h
@@ -0,0 +1,28 @@
+#if WORDS_BIGENDIAN
+#define COLOR_ARGB
+#else
+#define COLOR_BGRA
+#endif
+
+#if 1
+/* ndef COLOR_BGRA */
+/** position des composantes **/
+ #define BLEU 0
+ #define VERT 1
+ #define ROUGE 2
+ #define ALPHA 3
+#else
+ #define ROUGE 1
+ #define BLEU 3
+ #define VERT 2
+ #define ALPHA 0
+#endif
+
+#ifndef guint32
+#define guint8 unsigned char
+#define guin16 unsigned short
+#define guint32 unsigned int
+#define gint8 signed char
+#define gint16 signed short int
+#define gint32 signed int
+#endif
diff --git a/gst/goom/goom_config_param.h b/gst/goom/goom_config_param.h
new file mode 100644
index 00000000..3c6838d3
--- /dev/null
+++ b/gst/goom/goom_config_param.h
@@ -0,0 +1,115 @@
+#ifndef _CONFIG_PARAM_H
+#define _CONFIG_PARAM_H
+
+#include <stdlib.h>
+
+/**
+ * File created on 2003-05-24 by Jeko.
+ * (c)2003, JC Hoelt for iOS-software.
+ *
+ * LGPL Licence.
+ */
+
+typedef enum {
+ PARAM_INTVAL,
+ PARAM_FLOATVAL,
+ PARAM_BOOLVAL,
+ PARAM_STRVAL,
+ PARAM_LISTVAL,
+} ParamType;
+
+struct IntVal {
+ int value;
+ int min;
+ int max;
+ int step;
+};
+struct FloatVal {
+ float value;
+ float min;
+ float max;
+ float step;
+};
+struct StrVal {
+ char *value;
+};
+struct ListVal {
+ char *value;
+ int nbChoices;
+ char **choices;
+};
+struct BoolVal {
+ int value;
+};
+
+
+typedef struct _PARAM {
+ char *name;
+ char *desc;
+ char rw;
+ ParamType type;
+ union {
+ struct IntVal ival;
+ struct FloatVal fval;
+ struct StrVal sval;
+ struct ListVal slist;
+ struct BoolVal bval;
+ } param;
+
+ /* used by the core to inform the GUI of a change */
+ void (*change_listener)(struct _PARAM *_this);
+
+ /* used by the GUI to inform the core of a change */
+ void (*changed)(struct _PARAM *_this);
+
+ void *user_data; /* can be used by the GUI */
+} PluginParam;
+
+#define IVAL(p) ((p).param.ival.value)
+#define SVAL(p) ((p).param.sval.value)
+#define FVAL(p) ((p).param.fval.value)
+#define BVAL(p) ((p).param.bval.value)
+#define LVAL(p) ((p).param.slist.value)
+
+#define FMIN(p) ((p).param.fval.min)
+#define FMAX(p) ((p).param.fval.max)
+#define FSTEP(p) ((p).param.fval.step)
+
+#define IMIN(p) ((p).param.ival.min)
+#define IMAX(p) ((p).param.ival.max)
+#define ISTEP(p) ((p).param.ival.step)
+
+PluginParam goom_secure_param(void);
+
+PluginParam goom_secure_f_param(char *name);
+PluginParam goom_secure_i_param(char *name);
+PluginParam goom_secure_b_param(char *name, int value);
+PluginParam goom_secure_s_param(char *name);
+
+PluginParam goom_secure_f_feedback(char *name);
+PluginParam goom_secure_i_feedback(char *name);
+
+void goom_set_str_param_value(PluginParam *p, const char *str);
+void goom_set_list_param_value(PluginParam *p, const char *str);
+
+typedef struct _PARAMETERS {
+ char *name;
+ char *desc;
+ int nbParams;
+ PluginParam **params;
+} PluginParameters;
+
+PluginParameters goom_plugin_parameters(const char *name, int nb);
+
+#define secure_param goom_secure_param
+#define secure_f_param goom_secure_f_param
+#define secure_i_param goom_secure_i_param
+#define secure_b_param goom_secure_b_param
+#define secure_s_param goom_secure_s_param
+#define secure_f_feedback goom_secure_f_feedback
+#define secure_i_feedback goom_secure_i_feedback
+#define set_list_param_value goom_set_list_param_value
+#define set_str_param_value goom_set_str_param_value
+#define plugin_parameters goom_plugin_parameters
+
+#endif
diff --git a/gst/goom/goom_core.c b/gst/goom/goom_core.c
index d66ffe25..5dee8278 100644
--- a/gst/goom/goom_core.c
+++ b/gst/goom/goom_core.c
@@ -1,412 +1,951 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <glib.h>
-
+/**
+* file: goom_core.c
+ * author: Jean-Christophe Hoelt (which is not so proud of it)
+ *
+ * Contains the core of goom's work.
+ *
+ * (c)2000-2003, by iOS-software.
+ */
+
+#include <math.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "goom_core.h"
+#include <inttypes.h>
+
+#include "goom.h"
#include "goom_tools.h"
-#include "filters.h"
+#include "goom_filters.h"
#include "lines.h"
+#include "ifs.h"
+#include "tentacle3d.h"
+#include "gfontlib.h"
-/*#define VERBOSE */
+#include "sound_tester.h"
+#include "goom_plugin_info.h"
+#include "goom_fx.h"
+#include "goomsl.h"
-#ifdef VERBOSE
-#include <stdio.h>
-#endif
+/* #define VERBOSE */
#define STOP_SPEED 128
+/* TODO: put that as variable in PluginInfo */
+#define TIME_BTW_CHG 300
-void
-goom_init (GoomData * goomdata, guint32 resx, guint32 resy)
+static void choose_a_goom_line (PluginInfo * goomInfo, float *param1,
+ float *param2, int *couleur, int *mode, float *amplitude, int far);
+
+static void update_message (PluginInfo * goomInfo, char *message);
+
+static void
+init_buffers (PluginInfo * goomInfo, int buffsize)
{
+ goomInfo->pixel = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
+ bzero (goomInfo->pixel, buffsize * sizeof (guint32) + 128);
+ goomInfo->back = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
+ bzero (goomInfo->back, buffsize * sizeof (guint32) + 128);
+ goomInfo->conv = (Pixel *) malloc (buffsize * sizeof (guint32) + 128);
+ bzero (goomInfo->conv, buffsize * sizeof (guint32) + 128);
+
+ goomInfo->outputBuf = goomInfo->conv;
+
+ goomInfo->p1 = (Pixel *) ((1 + ((uintptr_t) (goomInfo->pixel)) / 128) * 128);
+ goomInfo->p2 = (Pixel *) ((1 + ((uintptr_t) (goomInfo->back)) / 128) * 128);
+}
+
+/**************************
+* INIT *
+**************************/
+PluginInfo *
+goom_init (guint32 resx, guint32 resy)
+{
+ PluginInfo *goomInfo = (PluginInfo *) malloc (sizeof (PluginInfo));
+
#ifdef VERBOSE
printf ("GOOM: init (%d, %d);\n", resx, resy);
#endif
- goomdata->resolx = 0;
- goomdata->resoly = 0;
- goomdata->buffsize = 0;
-
- goomdata->pixel = NULL;
- goomdata->back = NULL;
- goomdata->p1 = NULL;
- goomdata->p2 = NULL;
-
- goom_set_resolution (goomdata, resx, resy);
- RAND_INIT (goomdata, GPOINTER_TO_INT (goomdata->pixel));
- goomdata->cycle = 0;
-
-
- goomdata->goomlimit = 2; /* sensibilité du goom */
- goomdata->zfd = zoomFilterNew ();
- goomdata->lockvar = 0; /* pour empecher de nouveaux changements */
- goomdata->goomvar = 0; /* boucle des gooms */
- goomdata->totalgoom = 0; /* nombre de gooms par seconds */
- goomdata->agoom = 0; /* un goom a eu lieu.. */
- goomdata->loopvar = 0; /* mouvement des points */
- goomdata->speedvar = 0; /* vitesse des particules */
- goomdata->lineMode = 0; /* l'effet lineaire a dessiner */
+
+ plugin_info_init (goomInfo, 4);
+
+ goomInfo->star_fx = flying_star_create ();
+ goomInfo->star_fx.init (&goomInfo->star_fx, goomInfo);
+
+ goomInfo->zoomFilter_fx = zoomFilterVisualFXWrapper_create ();
+ goomInfo->zoomFilter_fx.init (&goomInfo->zoomFilter_fx, goomInfo);
+
+ goomInfo->tentacles_fx = tentacle_fx_create ();
+ goomInfo->tentacles_fx.init (&goomInfo->tentacles_fx, goomInfo);
+
+ goomInfo->convolve_fx = convolve_create ();
+ goomInfo->convolve_fx.init (&goomInfo->convolve_fx, goomInfo);
+
+ plugin_info_add_visual (goomInfo, 0, &goomInfo->zoomFilter_fx);
+ plugin_info_add_visual (goomInfo, 1, &goomInfo->tentacles_fx);
+ plugin_info_add_visual (goomInfo, 2, &goomInfo->star_fx);
+ plugin_info_add_visual (goomInfo, 3, &goomInfo->convolve_fx);
+
+ goomInfo->screen.width = resx;
+ goomInfo->screen.height = resy;
+ goomInfo->screen.size = resx * resy;
+
+ init_buffers (goomInfo, goomInfo->screen.size);
+ goomInfo->gRandom = goom_random_init ((uintptr_t) goomInfo->pixel);
+
+ goomInfo->cycle = 0;
+
+ goomInfo->ifs_fx = ifs_visualfx_create ();
+ goomInfo->ifs_fx.init (&goomInfo->ifs_fx, goomInfo);
+
+ goomInfo->gmline1 = goom_lines_init (goomInfo, resx, goomInfo->screen.height,
+ GML_HLINE, goomInfo->screen.height, GML_BLACK,
+ GML_CIRCLE, 0.4f * (float) goomInfo->screen.height, GML_VERT);
+ goomInfo->gmline2 = goom_lines_init (goomInfo, resx, goomInfo->screen.height,
+ GML_HLINE, 0, GML_BLACK,
+ GML_CIRCLE, 0.2f * (float) goomInfo->screen.height, GML_RED);
+
+ gfont_load ();
+
+ /* goom_set_main_script(goomInfo, goomInfo->main_script_str); */
+
+ return goomInfo;
}
+
+
void
-goom_set_resolution (GoomData * goomdata, guint32 resx, guint32 resy)
+goom_set_resolution (PluginInfo * goomInfo, guint32 resx, guint32 resy)
{
- guint32 buffsize = resx * resy;
-
- if ((goomdata->resolx == resx) && (goomdata->resoly == resy))
- return;
-
- if (goomdata->buffsize < buffsize) {
- if (goomdata->pixel)
- free (goomdata->pixel);
- if (goomdata->back)
- free (goomdata->back);
- goomdata->pixel = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
- goomdata->back = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
- goomdata->buffsize = buffsize;
-
- goomdata->p1 =
- (void *) (((unsigned long) goomdata->pixel + 0x7f) & (~0x7f));
- goomdata->p2 = (void *) (((unsigned long) goomdata->back + 0x7f) & (~0x7f));
- }
+ free (goomInfo->pixel);
+ free (goomInfo->back);
+ free (goomInfo->conv);
+
+ goomInfo->screen.width = resx;
+ goomInfo->screen.height = resy;
+ goomInfo->screen.size = resx * resy;
+
+ init_buffers (goomInfo, goomInfo->screen.size);
+
+ /* init_ifs (goomInfo, resx, goomInfo->screen.height); */
+ goomInfo->ifs_fx.free (&goomInfo->ifs_fx);
+ goomInfo->ifs_fx.init (&goomInfo->ifs_fx, goomInfo);
- goomdata->resolx = resx;
- goomdata->resoly = resy;
+ goom_lines_set_res (goomInfo->gmline1, resx, goomInfo->screen.height);
+ goom_lines_set_res (goomInfo->gmline2, resx, goomInfo->screen.height);
+}
- memset (goomdata->pixel, 0, buffsize * sizeof (guint32) + 128);
- memset (goomdata->back, 0, buffsize * sizeof (guint32) + 128);
+int
+goom_set_screenbuffer (PluginInfo * goomInfo, void *buffer)
+{
+ goomInfo->outputBuf = (Pixel *) buffer;
+ return 1;
}
+/********************************************
+* UPDATE *
+********************************************
+
+* WARNING: this is a 600 lines function ! (21-11-2003)
+*/
guint32 *
-goom_update (GoomData * goomdata, gint16 data[2][512])
+goom_update (PluginInfo * goomInfo, gint16 data[2][512],
+ int forceMode, float fps, char *songTitle, char *message)
{
- guint32 *return_val;
+ Pixel *return_val;
guint32 pointWidth;
guint32 pointHeight;
- int incvar; /* volume du son */
- int accelvar; /* acceleration des particules */
int i;
float largfactor; /* elargissement de l'intervalle d'évolution des points */
- int zfd_update = 0;
- int resolx = goomdata->resolx;
- int resoly = goomdata->resoly;
- ZoomFilterData *pzfd = goomdata->zfd;
- guint32 *tmp;
+ Pixel *tmp;
- /* test if the config has changed, update it if so */
+ ZoomFilterData *pzfd;
- pointWidth = (resolx * 2) / 5;
- pointHeight = (resoly * 2) / 5;
+ /* test if the config has changed, update it if so */
+ pointWidth = (goomInfo->screen.width * 2) / 5;
+ pointHeight = ((goomInfo->screen.height) * 2) / 5;
/* ! etude du signal ... */
- incvar = 0;
- for (i = 0; i < 512; i++) {
- if (incvar < data[0][i])
- incvar = data[0][i];
- }
-
- accelvar = incvar / 5000;
- if (goomdata->speedvar > 5) {
- accelvar--;
- if (goomdata->speedvar > 20)
- accelvar--;
- if (goomdata->speedvar > 40)
- goomdata->speedvar = 40;
- }
- accelvar--;
- goomdata->speedvar += accelvar;
-
- if (goomdata->speedvar < 0)
- goomdata->speedvar = 0;
- if (goomdata->speedvar > 40)
- goomdata->speedvar = 40;
+ evaluate_sound (data, &(goomInfo->sound));
+ /* goom_execute_main_script(goomInfo); */
/* ! calcul du deplacement des petits points ... */
-
largfactor =
- ((float) goomdata->speedvar / 40.0f + (float) incvar / 50000.0f) / 1.5f;
+ goomInfo->sound.speedvar / 150.0f + goomInfo->sound.volume / 1.5f;
+
if (largfactor > 1.5f)
largfactor = 1.5f;
- for (i = 1; i * 15 <= goomdata->speedvar + 15; i++) {
- goomdata->loopvar += goomdata->speedvar + 1;
-
- pointFilter (goomdata,
- YELLOW,
- ((pointWidth - 6.0f) * largfactor + 5.0f),
- ((pointHeight - 6.0f) * largfactor + 5.0f),
- i * 152.0f, 128.0f, goomdata->loopvar + i * 2032);
- pointFilter (goomdata, ORANGE,
- ((pointWidth / 2) * largfactor) / i + 10.0f * i,
- ((pointHeight / 2) * largfactor) / i + 10.0f * i,
- 96.0f, i * 80.0f, goomdata->loopvar / i);
- pointFilter (goomdata, VIOLET,
- ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
- ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
- i + 122.0f, 134.0f, goomdata->loopvar / i);
- pointFilter (goomdata, BLACK,
- ((pointHeight / 3) * largfactor + 20.0f),
- ((pointHeight / 3) * largfactor + 20.0f),
- 58.0f, i * 66.0f, goomdata->loopvar / i);
- pointFilter (goomdata, WHITE,
- (pointHeight * largfactor + 10.0f * i) / i,
- (pointHeight * largfactor + 10.0f * i) / i,
- 66.0f, 74.0f, goomdata->loopvar + i * 500);
+ goomInfo->update.decay_ifs--;
+ if (goomInfo->update.decay_ifs > 0)
+ goomInfo->update.ifs_incr += 2;
+ if (goomInfo->update.decay_ifs == 0)
+ goomInfo->update.ifs_incr = 0;
+
+ if (goomInfo->update.recay_ifs) {
+ goomInfo->update.ifs_incr -= 2;
+ goomInfo->update.recay_ifs--;
+ if ((goomInfo->update.recay_ifs == 0) && (goomInfo->update.ifs_incr <= 0))
+ goomInfo->update.ifs_incr = 1;
+ }
+
+ if (goomInfo->update.ifs_incr > 0)
+ goomInfo->ifs_fx.apply (&goomInfo->ifs_fx, goomInfo->p2, goomInfo->p1,
+ goomInfo);
+
+ if (goomInfo->curGState->drawPoints) {
+ for (i = 1; i * 15 <= goomInfo->sound.speedvar * 80.0f + 15; i++) {
+ goomInfo->update.loopvar += goomInfo->sound.speedvar * 50 + 1;
+
+ pointFilter (goomInfo, goomInfo->p1,
+ YELLOW,
+ ((pointWidth - 6.0f) * largfactor + 5.0f),
+ ((pointHeight - 6.0f) * largfactor + 5.0f),
+ i * 152.0f, 128.0f, goomInfo->update.loopvar + i * 2032);
+ pointFilter (goomInfo, goomInfo->p1, ORANGE,
+ ((pointWidth / 2) * largfactor) / i + 10.0f * i,
+ ((pointHeight / 2) * largfactor) / i + 10.0f * i,
+ 96.0f, i * 80.0f, goomInfo->update.loopvar / i);
+ pointFilter (goomInfo, goomInfo->p1, VIOLET,
+ ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
+ ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
+ i + 122.0f, 134.0f, goomInfo->update.loopvar / i);
+ pointFilter (goomInfo, goomInfo->p1, BLACK,
+ ((pointHeight / 3) * largfactor + 20.0f),
+ ((pointHeight / 3) * largfactor + 20.0f),
+ 58.0f, i * 66.0f, goomInfo->update.loopvar / i);
+ pointFilter (goomInfo, goomInfo->p1, WHITE,
+ (pointHeight * largfactor + 10.0f * i) / i,
+ (pointHeight * largfactor + 10.0f * i) / i,
+ 66.0f, 74.0f, goomInfo->update.loopvar + i * 500);
+ }
+ }
+
+ /* par défaut pas de changement de zoom */
+ pzfd = NULL;
+
+ /*
+ * Test forceMode
+ */
+#ifdef VERBOSE
+ if (forceMode != 0) {
+ printf ("forcemode = %d\n", forceMode);
}
+#endif
+
/* diminuer de 1 le temps de lockage */
/* note pour ceux qui n'ont pas suivis : le lockvar permet d'empecher un */
- /* changement d'etat du plugins juste apres un autre changement d'etat. oki ? */
- if (--goomdata->lockvar < 0)
- goomdata->lockvar = 0;
-
- /* temps du goom */
- if (--goomdata->agoom < 0)
- goomdata->agoom = 0;
+ /* changement d'etat du plugin juste apres un autre changement d'etat. oki */
+ if (--goomInfo->update.lockvar < 0)
+ goomInfo->update.lockvar = 0;
/* on verifie qu'il ne se pas un truc interressant avec le son. */
- if ((accelvar > goomdata->goomlimit) || (accelvar < -goomdata->goomlimit)) {
- /* UN GOOM !!! YAHOO ! */
- goomdata->totalgoom++;
- goomdata->agoom = 20; /* mais pdt 20 cycles, il n'y en aura plus. */
- goomdata->lineMode = (goomdata->lineMode + 1) % 20; /* Tous les 10 gooms on change de mode lineaire */
+ if ((goomInfo->sound.timeSinceLastGoom == 0)
+ || (forceMode > 0)
+ || (goomInfo->update.cyclesSinceLastChange > TIME_BTW_CHG)) {
/* changement eventuel de mode */
- switch (iRAND (goomdata, 10)) {
- case 0:
- case 1:
- case 2:
- pzfd->mode = WAVE_MODE;
- pzfd->vitesse = STOP_SPEED - 1;
- pzfd->reverse = 0;
- break;
- case 3:
- case 4:
- pzfd->mode = CRYSTAL_BALL_MODE;
- break;
- case 5:
- pzfd->mode = AMULETTE_MODE;
- break;
- case 6:
- pzfd->mode = WATER_MODE;
- break;
- case 7:
- pzfd->mode = SCRUNCH_MODE;
- break;
- default:
- pzfd->mode = NORMAL_MODE;
- }
+ if (goom_irand (goomInfo->gRandom, 16) == 0)
+ switch (goom_irand (goomInfo->gRandom, 34)) {
+ case 0:
+ case 10:
+ goomInfo->update.zoomFilterData.hypercosEffect =
+ goom_irand (goomInfo->gRandom, 2);
+ case 13:
+ case 20:
+ case 21:
+ goomInfo->update.zoomFilterData.mode = WAVE_MODE;
+ goomInfo->update.zoomFilterData.reverse = 0;
+ goomInfo->update.zoomFilterData.waveEffect =
+ (goom_irand (goomInfo->gRandom, 3) == 0);
+ if (goom_irand (goomInfo->gRandom, 2))
+ goomInfo->update.zoomFilterData.vitesse =
+ (goomInfo->update.zoomFilterData.vitesse + 127) >> 1;
+ break;
+ case 1:
+ case 11:
+ goomInfo->update.zoomFilterData.mode = CRYSTAL_BALL_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect = 0;
+ break;
+ case 2:
+ case 12:
+ goomInfo->update.zoomFilterData.mode = AMULETTE_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect = 0;
+ break;
+ case 3:
+ goomInfo->update.zoomFilterData.mode = WATER_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect = 0;
+ break;
+ case 4:
+ case 14:
+ goomInfo->update.zoomFilterData.mode = SCRUNCH_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect = 0;
+ break;
+ case 5:
+ case 15:
+ case 22:
+ goomInfo->update.zoomFilterData.mode = HYPERCOS1_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect =
+ (goom_irand (goomInfo->gRandom, 3) == 0);
+ break;
+ case 6:
+ case 16:
+ goomInfo->update.zoomFilterData.mode = HYPERCOS2_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect = 0;
+ break;
+ case 7:
+ case 17:
+ goomInfo->update.zoomFilterData.mode = CRYSTAL_BALL_MODE;
+ goomInfo->update.zoomFilterData.waveEffect =
+ (goom_irand (goomInfo->gRandom, 4) == 0);
+ goomInfo->update.zoomFilterData.hypercosEffect =
+ goom_irand (goomInfo->gRandom, 2);
+ break;
+ case 8:
+ case 18:
+ case 19:
+ goomInfo->update.zoomFilterData.mode = SCRUNCH_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 1;
+ goomInfo->update.zoomFilterData.hypercosEffect = 1;
+ break;
+ case 29:
+ case 30:
+ goomInfo->update.zoomFilterData.mode = YONLY_MODE;
+ break;
+ case 31:
+ case 32:
+ case 33:
+ goomInfo->update.zoomFilterData.mode = SPEEDWAY_MODE;
+ break;
+ default:
+ goomInfo->update.zoomFilterData.mode = NORMAL_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect = 0;
+ }
}
/* tout ceci ne sera fait qu'en cas de non-blocage */
- if (goomdata->lockvar == 0) {
+ if (goomInfo->update.lockvar == 0) {
/* reperage de goom (acceleration forte de l'acceleration du volume) */
/* -> coup de boost de la vitesse si besoin.. */
- if ((accelvar > goomdata->goomlimit) || (accelvar < -goomdata->goomlimit)) {
- goomdata->goomvar++;
- /*if (goomvar % 1 == 0) */
+ if (goomInfo->sound.timeSinceLastGoom == 0) {
+
+ int i;
+
+ goomInfo->update.goomvar++;
+
+ /* SELECTION OF THE GOOM STATE */
+ if ((!goomInfo->update.stateSelectionBlocker)
+ && (goom_irand (goomInfo->gRandom, 3))) {
+ goomInfo->update.stateSelectionRnd =
+ goom_irand (goomInfo->gRandom, goomInfo->statesRangeMax);
+ goomInfo->update.stateSelectionBlocker = 3;
+ } else if (goomInfo->update.stateSelectionBlocker)
+ goomInfo->update.stateSelectionBlocker--;
+
+ for (i = 0; i < goomInfo->statesNumber; i++)
+ if ((goomInfo->update.stateSelectionRnd >= goomInfo->states[i].rangemin)
+ && (goomInfo->update.stateSelectionRnd <=
+ goomInfo->states[i].rangemax))
+ goomInfo->curGState = &(goomInfo->states[i]);
+
+ if ((goomInfo->curGState->drawIFS) && (goomInfo->update.ifs_incr <= 0)) {
+ goomInfo->update.recay_ifs = 5;
+ goomInfo->update.ifs_incr = 11;
+ }
+
+ if ((!goomInfo->curGState->drawIFS) && (goomInfo->update.ifs_incr > 0)
+ && (goomInfo->update.decay_ifs <= 0))
+ goomInfo->update.decay_ifs = 100;
+
+ if (!goomInfo->curGState->drawScope)
+ goomInfo->update.stop_lines = 0xf000 & 5;
+
+ if (!goomInfo->curGState->drawScope) {
+ goomInfo->update.stop_lines = 0;
+ goomInfo->update.lineMode = goomInfo->update.drawLinesDuration;
+ }
+
+ /* if (goomInfo->update.goomvar % 1 == 0) */
{
guint32 vtmp;
guint32 newvit;
- newvit = STOP_SPEED - goomdata->speedvar / 2;
+ goomInfo->update.lockvar = 50;
+ newvit =
+ STOP_SPEED + 1 -
+ ((float) 3.5f * log10 (goomInfo->sound.speedvar * 60 + 1));
/* retablir le zoom avant.. */
- if ((pzfd->reverse) && (!(goomdata->cycle % 12)) && (rand () % 3 == 0)) {
- pzfd->reverse = 0;
- pzfd->vitesse = STOP_SPEED - 2;
- goomdata->lockvar = 50;
+ if ((goomInfo->update.zoomFilterData.reverse)
+ && (!(goomInfo->cycle % 13)) && (rand () % 5 == 0)) {
+ goomInfo->update.zoomFilterData.reverse = 0;
+ goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - 2;
+ goomInfo->update.lockvar = 75;
}
- if (iRAND (goomdata, 10) == 0) {
- pzfd->reverse = 1;
- goomdata->lockvar = 100;
+ if (goom_irand (goomInfo->gRandom, 10) == 0) {
+ goomInfo->update.zoomFilterData.reverse = 1;
+ goomInfo->update.lockvar = 100;
}
+ if (goom_irand (goomInfo->gRandom, 10) == 0)
+ goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - 1;
+ if (goom_irand (goomInfo->gRandom, 12) == 0)
+ goomInfo->update.zoomFilterData.vitesse = STOP_SPEED + 1;
+
/* changement de milieu.. */
- switch (iRAND (goomdata, 20)) {
+ switch (goom_irand (goomInfo->gRandom, 25)) {
case 0:
- pzfd->middleY = resoly - 1;
- pzfd->middleX = resolx / 2;
+ case 3:
+ case 6:
+ goomInfo->update.zoomFilterData.middleY =
+ goomInfo->screen.height - 1;
+ goomInfo->update.zoomFilterData.middleX =
+ goomInfo->screen.width / 2;
break;
case 1:
- pzfd->middleX = resolx - 1;
+ case 4:
+ goomInfo->update.zoomFilterData.middleX =
+ goomInfo->screen.width - 1;
break;
case 2:
- pzfd->middleX = 1;
+ case 5:
+ goomInfo->update.zoomFilterData.middleX = 1;
break;
default:
- pzfd->middleY = resoly / 2;
- pzfd->middleX = resolx / 2;
+ goomInfo->update.zoomFilterData.middleY =
+ goomInfo->screen.height / 2;
+ goomInfo->update.zoomFilterData.middleX =
+ goomInfo->screen.width / 2;
}
- if (pzfd->mode == WATER_MODE) {
- pzfd->middleX = resolx / 2;
- pzfd->middleY = resoly / 2;
+ if ((goomInfo->update.zoomFilterData.mode == WATER_MODE)
+ || (goomInfo->update.zoomFilterData.mode == YONLY_MODE)
+ || (goomInfo->update.zoomFilterData.mode == AMULETTE_MODE)) {
+ goomInfo->update.zoomFilterData.middleX = goomInfo->screen.width / 2;
+ goomInfo->update.zoomFilterData.middleY = goomInfo->screen.height / 2;
}
- switch (vtmp = (iRAND (goomdata, 27))) {
+ switch (vtmp = (goom_irand (goomInfo->gRandom, 15))) {
case 0:
- pzfd->vPlaneEffect = iRAND (goomdata, 3);
- pzfd->vPlaneEffect -= iRAND (goomdata, 3);
- pzfd->hPlaneEffect = iRAND (goomdata, 3);
- pzfd->hPlaneEffect -= iRAND (goomdata, 3);
+ goomInfo->update.zoomFilterData.vPlaneEffect =
+ goom_irand (goomInfo->gRandom, 3)
+ - goom_irand (goomInfo->gRandom, 3);
+ goomInfo->update.zoomFilterData.hPlaneEffect =
+ goom_irand (goomInfo->gRandom, 3)
+ - goom_irand (goomInfo->gRandom, 3);
break;
case 3:
- pzfd->vPlaneEffect = 0;
- pzfd->hPlaneEffect = iRAND (goomdata, 8);
- pzfd->hPlaneEffect -= iRAND (goomdata, 8);
+ goomInfo->update.zoomFilterData.vPlaneEffect = 0;
+ goomInfo->update.zoomFilterData.hPlaneEffect =
+ goom_irand (goomInfo->gRandom, 8)
+ - goom_irand (goomInfo->gRandom, 8);
break;
case 4:
case 5:
case 6:
case 7:
- pzfd->vPlaneEffect = iRAND (goomdata, 5);
- pzfd->vPlaneEffect -= iRAND (goomdata, 5);
- pzfd->hPlaneEffect = -pzfd->vPlaneEffect;
+ goomInfo->update.zoomFilterData.vPlaneEffect =
+ goom_irand (goomInfo->gRandom, 5)
+ - goom_irand (goomInfo->gRandom, 5);
+ goomInfo->update.zoomFilterData.hPlaneEffect =
+ -goomInfo->update.zoomFilterData.vPlaneEffect;
break;
case 8:
- pzfd->hPlaneEffect = 5 + iRAND (goomdata, 8);
- pzfd->vPlaneEffect = -pzfd->hPlaneEffect;
+ goomInfo->update.zoomFilterData.hPlaneEffect =
+ 5 + goom_irand (goomInfo->gRandom, 8);
+ goomInfo->update.zoomFilterData.vPlaneEffect =
+ -goomInfo->update.zoomFilterData.hPlaneEffect;
break;
case 9:
- pzfd->vPlaneEffect = 5 + iRAND (goomdata, 8);
- pzfd->hPlaneEffect = -pzfd->hPlaneEffect;
+ goomInfo->update.zoomFilterData.vPlaneEffect =
+ 5 + goom_irand (goomInfo->gRandom, 8);
+ goomInfo->update.zoomFilterData.hPlaneEffect =
+ -goomInfo->update.zoomFilterData.hPlaneEffect;
break;
case 13:
- pzfd->hPlaneEffect = 0;
- pzfd->vPlaneEffect = iRAND (goomdata, 10);
- pzfd->vPlaneEffect -= iRAND (goomdata, 10);
+ goomInfo->update.zoomFilterData.hPlaneEffect = 0;
+ goomInfo->update.zoomFilterData.vPlaneEffect =
+ goom_irand (goomInfo->gRandom, 10)
+ - goom_irand (goomInfo->gRandom, 10);
+ break;
+ case 14:
+ goomInfo->update.zoomFilterData.hPlaneEffect =
+ goom_irand (goomInfo->gRandom, 10)
+ - goom_irand (goomInfo->gRandom, 10);
+ goomInfo->update.zoomFilterData.vPlaneEffect =
+ goom_irand (goomInfo->gRandom, 10)
+ - goom_irand (goomInfo->gRandom, 10);
break;
default:
if (vtmp < 10) {
- pzfd->vPlaneEffect = 0;
- pzfd->hPlaneEffect = 0;
+ goomInfo->update.zoomFilterData.vPlaneEffect = 0;
+ goomInfo->update.zoomFilterData.hPlaneEffect = 0;
}
}
- if (iRAND (goomdata, 3) != 0)
- pzfd->noisify = 0;
+ if (goom_irand (goomInfo->gRandom, 5) != 0)
+ goomInfo->update.zoomFilterData.noisify = 0;
else {
- pzfd->noisify = iRAND (goomdata, 3) + 2;
- goomdata->lockvar *= 3;
+ goomInfo->update.zoomFilterData.noisify =
+ goom_irand (goomInfo->gRandom, 2) + 1;
+ goomInfo->update.lockvar *= 2;
}
- if (pzfd->mode == AMULETTE_MODE) {
- pzfd->vPlaneEffect = 0;
- pzfd->hPlaneEffect = 0;
- pzfd->noisify = 0;
+ if (goomInfo->update.zoomFilterData.mode == AMULETTE_MODE) {
+ goomInfo->update.zoomFilterData.vPlaneEffect = 0;
+ goomInfo->update.zoomFilterData.hPlaneEffect = 0;
+ goomInfo->update.zoomFilterData.noisify = 0;
}
- if ((pzfd->middleX == 1) || (pzfd->middleX == resolx - 1)) {
- pzfd->vPlaneEffect = 0;
- pzfd->hPlaneEffect = iRAND (goomdata, 2) ? 0 : pzfd->hPlaneEffect;
+ if ((goomInfo->update.zoomFilterData.middleX == 1)
+ || (goomInfo->update.zoomFilterData.middleX ==
+ (signed int) goomInfo->screen.width - 1)) {
+ goomInfo->update.zoomFilterData.vPlaneEffect = 0;
+ if (goom_irand (goomInfo->gRandom, 2))
+ goomInfo->update.zoomFilterData.hPlaneEffect = 0;
}
- if (newvit < pzfd->vitesse) { /* on accelere */
- zfd_update = 1;
+ if ((signed int) newvit < goomInfo->update.zoomFilterData.vitesse) { /* on accelere */
+ pzfd = &goomInfo->update.zoomFilterData;
if (((newvit < STOP_SPEED - 7) &&
- (pzfd->vitesse < STOP_SPEED - 6) &&
- (goomdata->cycle % 3 == 0)) || (iRAND (goomdata, 40) == 0)) {
- pzfd->vitesse = STOP_SPEED - 1;
- pzfd->reverse = !pzfd->reverse;
+ (goomInfo->update.zoomFilterData.vitesse < STOP_SPEED - 6) &&
+ (goomInfo->cycle % 3 == 0))
+ || (goom_irand (goomInfo->gRandom, 40) == 0)) {
+ goomInfo->update.zoomFilterData.vitesse =
+ STOP_SPEED - goom_irand (goomInfo->gRandom, 2)
+ + goom_irand (goomInfo->gRandom, 2);
+ goomInfo->update.zoomFilterData.reverse =
+ !goomInfo->update.zoomFilterData.reverse;
} else {
- pzfd->vitesse = (newvit + pzfd->vitesse * 4) / 5;
+ goomInfo->update.zoomFilterData.vitesse =
+ (newvit + goomInfo->update.zoomFilterData.vitesse * 7) / 8;
}
- goomdata->lockvar += 50;
+ goomInfo->update.lockvar += 50;
}
}
+
+ if (goomInfo->update.lockvar > 150) {
+ goomInfo->update.switchIncr = goomInfo->update.switchIncrAmount;
+ goomInfo->update.switchMult = 1.0f;
+ }
}
/* mode mega-lent */
- if (iRAND (goomdata, 1000) == 0) {
+ if (goom_irand (goomInfo->gRandom, 700) == 0) {
/*
- printf ("coup du sort...\n") ;
+ * printf ("coup du sort...\n") ;
*/
- zfd_update = 1;
- pzfd->vitesse = STOP_SPEED - 1;
- pzfd->pertedec = 8;
- pzfd->sqrtperte = 16;
- goomdata->goomvar = 1;
- goomdata->lockvar += 70;
+ pzfd = &goomInfo->update.zoomFilterData;
+ goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - 1;
+ goomInfo->update.zoomFilterData.pertedec = 8;
+ goomInfo->update.zoomFilterData.sqrtperte = 16;
+ goomInfo->update.goomvar = 1;
+ goomInfo->update.lockvar += 50;
+ goomInfo->update.switchIncr = goomInfo->update.switchIncrAmount;
+ goomInfo->update.switchMult = 1.0f;
}
}
- /* gros frein si la musique est calme */
- if ((goomdata->speedvar < 1) && (pzfd->vitesse < STOP_SPEED - 4)
- && (goomdata->cycle % 16 == 0)) {
- /*
- printf ("++slow part... %i\n", zfd.vitesse) ;
- */
- zfd_update = 1;
- pzfd->vitesse += 3;
- pzfd->pertedec = 8;
- pzfd->sqrtperte = 16;
- goomdata->goomvar = 0;
+ /*
+ * gros frein si la musique est calme
+ */
+ if ((goomInfo->sound.speedvar < 0.01f)
+ && (goomInfo->update.zoomFilterData.vitesse < STOP_SPEED - 4)
+ && (goomInfo->cycle % 16 == 0)) {
+ pzfd = &goomInfo->update.zoomFilterData;
+ goomInfo->update.zoomFilterData.vitesse += 3;
+ goomInfo->update.zoomFilterData.pertedec = 8;
+ goomInfo->update.zoomFilterData.sqrtperte = 16;
+ goomInfo->update.goomvar = 0;
+ }
+
+ /*
+ * baisser regulierement la vitesse...
+ */
+ if ((goomInfo->cycle % 73 == 0)
+ && (goomInfo->update.zoomFilterData.vitesse < STOP_SPEED - 5)) {
+ pzfd = &goomInfo->update.zoomFilterData;
+ goomInfo->update.zoomFilterData.vitesse++;
+ }
+
+ /*
+ * arreter de decrémenter au bout d'un certain temps
+ */
+ if ((goomInfo->cycle % 101 == 0)
+ && (goomInfo->update.zoomFilterData.pertedec == 7)) {
+ pzfd = &goomInfo->update.zoomFilterData;
+ goomInfo->update.zoomFilterData.pertedec = 8;
+ goomInfo->update.zoomFilterData.sqrtperte = 16;
+ }
+
+ /*
+ * Permet de forcer un effet.
+ */
+ if ((forceMode > 0) && (forceMode <= NB_FX)) {
+ pzfd = &goomInfo->update.zoomFilterData;
+ pzfd->mode = forceMode - 1;
+ }
+
+ if (forceMode == -1) {
+ pzfd = NULL;
+ }
+
+ /*
+ * Changement d'effet de zoom !
+ */
+ if (pzfd != NULL) {
+ int dif;
+
+ goomInfo->update.cyclesSinceLastChange = 0;
+
+ goomInfo->update.switchIncr = goomInfo->update.switchIncrAmount;
+
+ dif =
+ goomInfo->update.zoomFilterData.vitesse -
+ goomInfo->update.previousZoomSpeed;
+ if (dif < 0)
+ dif = -dif;
+
+ if (dif > 2) {
+ goomInfo->update.switchIncr *= (dif + 2) / 2;
+ }
+ goomInfo->update.previousZoomSpeed =
+ goomInfo->update.zoomFilterData.vitesse;
+ goomInfo->update.switchMult = 1.0f;
+
+ if (((goomInfo->sound.timeSinceLastGoom == 0)
+ && (goomInfo->sound.totalgoom < 2)) || (forceMode > 0)) {
+ goomInfo->update.switchIncr = 0;
+ goomInfo->update.switchMult = goomInfo->update.switchMultAmount;
+ }
+ } else {
+ if (goomInfo->update.cyclesSinceLastChange > TIME_BTW_CHG) {
+ pzfd = &goomInfo->update.zoomFilterData;
+ goomInfo->update.cyclesSinceLastChange = 0;
+ } else
+ goomInfo->update.cyclesSinceLastChange++;
+ }
+
+#ifdef VERBOSE
+ if (pzfd) {
+ printf ("GOOM: pzfd->mode = %d\n", pzfd->mode);
+ }
+#endif
+
+ /* Zoom here ! */
+ zoomFilterFastRGB (goomInfo, goomInfo->p1, goomInfo->p2, pzfd,
+ goomInfo->screen.width, goomInfo->screen.height,
+ goomInfo->update.switchIncr, goomInfo->update.switchMult);
+
+ /*
+ * Affichage tentacule
+ */
+
+ goomInfo->tentacles_fx.apply (&goomInfo->tentacles_fx, goomInfo->p1,
+ goomInfo->p2, goomInfo);
+ goomInfo->star_fx.apply (&goomInfo->star_fx, goomInfo->p2, goomInfo->p1,
+ goomInfo);
+
+ /*
+ * Affichage de texte
+ */
+ {
+ /*char title[1024]; */
+ char text[64];
+
/*
- printf ("--slow part... %i\n", zfd.vitesse) ;
+ * Le message
*/
- }
+ update_message (goomInfo, message);
+
+ if (fps > 0) {
+ sprintf (text, "%2.0f fps", fps);
+ goom_draw_text (goomInfo->p1, goomInfo->screen.width,
+ goomInfo->screen.height, 10, 24, text, 1, 0);
+ }
- /* baisser regulierement la vitesse... */
- if ((goomdata->cycle % 73 == 0) && (pzfd->vitesse < STOP_SPEED - 5)) {
/*
- printf ("slow down...\n") ;
+ * Le titre
*/
- zfd_update = 1;
- pzfd->vitesse++;
+ if (songTitle != NULL) {
+ strncpy (goomInfo->update.titleText, songTitle, 1023);
+ goomInfo->update.titleText[1023] = 0;
+ goomInfo->update.timeOfTitleDisplay = 200;
+ }
+
+ if (goomInfo->update.timeOfTitleDisplay) {
+ goom_draw_text (goomInfo->p1, goomInfo->screen.width,
+ goomInfo->screen.height, goomInfo->screen.width / 2,
+ goomInfo->screen.height / 2 + 7, goomInfo->update.titleText,
+ ((float) (190 - goomInfo->update.timeOfTitleDisplay) / 10.0f), 1);
+ goomInfo->update.timeOfTitleDisplay--;
+ if (goomInfo->update.timeOfTitleDisplay < 4)
+ goom_draw_text (goomInfo->p2, goomInfo->screen.width,
+ goomInfo->screen.height, goomInfo->screen.width / 2,
+ goomInfo->screen.height / 2 + 7, goomInfo->update.titleText,
+ ((float) (190 - goomInfo->update.timeOfTitleDisplay) / 10.0f), 1);
+ }
}
- /* arreter de decrémenter au bout d'un certain temps */
- if ((goomdata->cycle % 101 == 0) && (pzfd->pertedec == 7)) {
- zfd_update = 1;
- pzfd->pertedec = 8;
- pzfd->sqrtperte = 16;
+ /*
+ * Gestion du Scope
+ */
+
+ /*
+ * arret demande
+ */
+ if ((goomInfo->update.stop_lines & 0xf000)
+ || (!goomInfo->curGState->drawScope)) {
+ float param1, param2, amplitude;
+ int couleur;
+ int mode;
+
+ choose_a_goom_line (goomInfo, &param1, &param2, &couleur, &mode, &amplitude,
+ 1);
+ couleur = GML_BLACK;
+
+ goom_lines_switch_to (goomInfo->gmline1, mode, param1, amplitude, couleur);
+ goom_lines_switch_to (goomInfo->gmline2, mode, param2, amplitude, couleur);
+ goomInfo->update.stop_lines &= 0x0fff;
}
- /* Zoom here ! */
- zoomFilterFastRGB (goomdata, pzfd, zfd_update);
+ /*
+ * arret aleatore.. changement de mode de ligne..
+ */
+ if (goomInfo->update.lineMode != goomInfo->update.drawLinesDuration) {
+ goomInfo->update.lineMode--;
+ if (goomInfo->update.lineMode == -1)
+ goomInfo->update.lineMode = 0;
+ } else
+ if ((goomInfo->cycle % 80 == 0)
+ && (goom_irand (goomInfo->gRandom, 5) == 0) && goomInfo->update.lineMode)
+ goomInfo->update.lineMode--;
+
+ if ((goomInfo->cycle % 120 == 0)
+ && (goom_irand (goomInfo->gRandom, 4) == 0)
+ && (goomInfo->curGState->drawScope)) {
+ if (goomInfo->update.lineMode == 0)
+ goomInfo->update.lineMode = goomInfo->update.drawLinesDuration;
+ else if (goomInfo->update.lineMode == goomInfo->update.drawLinesDuration) {
+ float param1, param2, amplitude;
+ int couleur1, couleur2;
+ int mode;
+
+ goomInfo->update.lineMode--;
+ choose_a_goom_line (goomInfo, &param1, &param2, &couleur1,
+ &mode, &amplitude, goomInfo->update.stop_lines);
+
+ couleur2 = 5 - couleur1;
+ if (goomInfo->update.stop_lines) {
+ goomInfo->update.stop_lines--;
+ if (goom_irand (goomInfo->gRandom, 2))
+ couleur2 = couleur1 = GML_BLACK;
+ }
- /* si on est dans un goom : afficher les lignes... */
- if (goomdata->agoom > 15)
- goom_lines (goomdata, data, ((pzfd->middleX == resolx / 2)
- && (pzfd->middleY == resoly / 2)
- && (pzfd->mode != WATER_MODE))
- ? (goomdata->lineMode / 10) : 0, goomdata->p2, goomdata->agoom - 15);
+ goom_lines_switch_to (goomInfo->gmline1, mode, param1, amplitude,
+ couleur1);
+ goom_lines_switch_to (goomInfo->gmline2, mode, param2, amplitude,
+ couleur2);
+ }
+ }
+
+ /*
+ * si on est dans un goom : afficher les lignes...
+ */
+ if ((goomInfo->update.lineMode != 0)
+ || (goomInfo->sound.timeSinceLastGoom < 5)) {
+ goomInfo->gmline2->power = goomInfo->gmline1->power;
+
+ goom_lines_draw (goomInfo, goomInfo->gmline1, data[0], goomInfo->p2);
+ goom_lines_draw (goomInfo, goomInfo->gmline2, data[1], goomInfo->p2);
+
+ if (((goomInfo->cycle % 121) == 9)
+ && (goom_irand (goomInfo->gRandom, 3) == 1)
+ && ((goomInfo->update.lineMode == 0)
+ || (goomInfo->update.lineMode ==
+ goomInfo->update.drawLinesDuration))) {
+ float param1, param2, amplitude;
+ int couleur1, couleur2;
+ int mode;
+
+ choose_a_goom_line (goomInfo, &param1, &param2, &couleur1,
+ &mode, &amplitude, goomInfo->update.stop_lines);
+ couleur2 = 5 - couleur1;
+
+ if (goomInfo->update.stop_lines) {
+ goomInfo->update.stop_lines--;
+ if (goom_irand (goomInfo->gRandom, 2))
+ couleur2 = couleur1 = GML_BLACK;
+ }
+ goom_lines_switch_to (goomInfo->gmline1, mode, param1, amplitude,
+ couleur1);
+ goom_lines_switch_to (goomInfo->gmline2, mode, param2, amplitude,
+ couleur2);
+ }
+ }
- return_val = goomdata->p2;
- tmp = goomdata->p1;
- goomdata->p1 = goomdata->p2;
- goomdata->p2 = tmp;
+ return_val = goomInfo->p1;
+ tmp = goomInfo->p1;
+ goomInfo->p1 = goomInfo->p2;
+ goomInfo->p2 = tmp;
/* affichage et swappage des buffers.. */
- goomdata->cycle++;
-
- /* tous les 100 cycles : vérifier si le taux de goom est correct */
- /* et le modifier sinon.. */
- if (!(goomdata->cycle % 100)) {
- if (goomdata->totalgoom > 15) {
- /* printf ("less gooms\n") ; */
- goomdata->goomlimit++;
- } else {
- if ((goomdata->totalgoom == 0) && (goomdata->goomlimit > 1))
- goomdata->goomlimit--;
- }
- goomdata->totalgoom = 0;
+ goomInfo->cycle++;
+
+ goomInfo->convolve_fx.apply (&goomInfo->convolve_fx, return_val,
+ goomInfo->outputBuf, goomInfo);
+
+ return (guint32 *) goomInfo->outputBuf;
+}
+
+/****************************************
+* CLOSE *
+****************************************/
+void
+goom_close (PluginInfo * goomInfo)
+{
+ if (goomInfo->pixel != NULL)
+ free (goomInfo->pixel);
+ if (goomInfo->back != NULL)
+ free (goomInfo->back);
+ if (goomInfo->conv != NULL)
+ free (goomInfo->conv);
+
+ goomInfo->pixel = goomInfo->back = NULL;
+ goomInfo->conv = NULL;
+ goom_random_free (goomInfo->gRandom);
+ goom_lines_free (&goomInfo->gmline1);
+ goom_lines_free (&goomInfo->gmline2);
+
+ /* release_ifs (); */
+ goomInfo->ifs_fx.free (&goomInfo->ifs_fx);
+ goomInfo->convolve_fx.free (&goomInfo->convolve_fx);
+ goomInfo->star_fx.free (&goomInfo->star_fx);
+ goomInfo->tentacles_fx.free (&goomInfo->tentacles_fx);
+ goomInfo->zoomFilter_fx.free (&goomInfo->zoomFilter_fx);
+
+ free (goomInfo);
+}
+
+
+/* *** */
+void
+choose_a_goom_line (PluginInfo * goomInfo, float *param1, float *param2,
+ int *couleur, int *mode, float *amplitude, int far)
+{
+ *mode = goom_irand (goomInfo->gRandom, 3);
+ *amplitude = 1.0f;
+ switch (*mode) {
+ case GML_CIRCLE:
+ if (far) {
+ *param1 = *param2 = 0.47f;
+ *amplitude = 0.8f;
+ break;
+ }
+ if (goom_irand (goomInfo->gRandom, 3) == 0) {
+ *param1 = *param2 = 0;
+ *amplitude = 3.0f;
+ } else if (goom_irand (goomInfo->gRandom, 2)) {
+ *param1 = 0.40f * goomInfo->screen.height;
+ *param2 = 0.22f * goomInfo->screen.height;
+ } else {
+ *param1 = *param2 = goomInfo->screen.height * 0.35;
+ }
+ break;
+ case GML_HLINE:
+ if (goom_irand (goomInfo->gRandom, 4) || far) {
+ *param1 = goomInfo->screen.height / 7;
+ *param2 = 6.0f * goomInfo->screen.height / 7.0f;
+ } else {
+ *param1 = *param2 = goomInfo->screen.height / 2.0f;
+ *amplitude = 2.0f;
+ }
+ break;
+ case GML_VLINE:
+ if (goom_irand (goomInfo->gRandom, 3) || far) {
+ *param1 = goomInfo->screen.width / 7.0f;
+ *param2 = 6.0f * goomInfo->screen.width / 7.0f;
+ } else {
+ *param1 = *param2 = goomInfo->screen.width / 2.0f;
+ *amplitude = 1.5f;
+ }
+ break;
}
- return return_val;
+
+ *couleur = goom_irand (goomInfo->gRandom, 6);
}
+#define ECART_VARIATION 1.5
+#define POS_VARIATION 3.0
+#define SCROLLING_SPEED 80
+
+/*
+ * Met a jour l'affichage du message defilant
+ */
void
-goom_close (GoomData * goomdata)
+update_message (PluginInfo * goomInfo, char *message)
{
- if (goomdata->pixel != NULL)
- free (goomdata->pixel);
- if (goomdata->back != NULL)
- free (goomdata->back);
- if (goomdata->zfd != NULL) {
- zoomFilterDestroy (goomdata->zfd);
- goomdata->zfd = NULL;
+
+ int fin = 0;
+
+ if (message) {
+ int i = 1, j = 0;
+
+ sprintf (goomInfo->update_message.message, message);
+ for (j = 0; goomInfo->update_message.message[j]; j++)
+ if (goomInfo->update_message.message[j] == '\n')
+ i++;
+ goomInfo->update_message.numberOfLinesInMessage = i;
+ goomInfo->update_message.affiche =
+ goomInfo->screen.height +
+ goomInfo->update_message.numberOfLinesInMessage * 25 + 105;
+ goomInfo->update_message.longueur =
+ strlen (goomInfo->update_message.message);
+ }
+ if (goomInfo->update_message.affiche) {
+ int i = 0;
+ char *msg = malloc (goomInfo->update_message.longueur + 1);
+ char *ptr = msg;
+ int pos;
+ float ecart;
+
+ message = msg;
+ sprintf (msg, goomInfo->update_message.message);
+
+ while (!fin) {
+ while (1) {
+ if (*ptr == 0) {
+ fin = 1;
+ break;
+ }
+ if (*ptr == '\n') {
+ *ptr = 0;
+ break;
+ }
+ ++ptr;
+ }
+ pos =
+ goomInfo->update_message.affiche -
+ (goomInfo->update_message.numberOfLinesInMessage - i) * 25;
+ pos += POS_VARIATION * (cos ((double) pos / 20.0));
+ pos -= SCROLLING_SPEED;
+ ecart = (ECART_VARIATION * sin ((double) pos / 20.0));
+ if ((fin) && (2 * pos < (int) goomInfo->screen.height))
+ pos = (int) goomInfo->screen.height / 2;
+ pos += 7;
+
+ goom_draw_text (goomInfo->p1, goomInfo->screen.width,
+ goomInfo->screen.height, goomInfo->screen.width / 2, pos, message,
+ ecart, 1);
+ message = ++ptr;
+ i++;
+ }
+ goomInfo->update_message.affiche--;
+ free (msg);
}
- goomdata->pixel = goomdata->back = NULL;
- RAND_CLOSE (goomdata);
}
diff --git a/gst/goom/goom_core.h b/gst/goom/goom_core.h
deleted file mode 100644
index 1fbc0ee8..00000000
--- a/gst/goom/goom_core.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef _GOOMCORE_H
-#define _GOOMCORE_H
-
-#include <glib.h>
-
-typedef struct ZoomFilterData ZoomFilterData;
-
-typedef struct
-{
-/**-----------------------------------------------------**
- ** SHARED DATA **
- **-----------------------------------------------------**/
- guint32 *pixel;
- guint32 *back;
- guint32 *p1, *p2;
- guint32 cycle;
-
- guint32 resolx, resoly, buffsize;
-
- int lockvar; /* pour empecher de nouveaux changements */
- int goomvar; /* boucle des gooms */
- int totalgoom; /* nombre de gooms par seconds */
- int agoom; /* un goom a eu lieu.. */
- int loopvar; /* mouvement des points */
- int speedvar; /* vitesse des particules */
- int lineMode; /* l'effet lineaire a dessiner */
- char goomlimit; /* sensibilité du goom */
-
- ZoomFilterData *zfd;
-
- /* Random table */
- gint *rand_tab;
- guint rand_pos;
-} GoomData;
-
-void goom_init (GoomData *goomdata, guint32 resx, guint32 resy);
-void goom_set_resolution (GoomData *goomdata, guint32 resx, guint32 resy);
-
-guint32 *goom_update (GoomData *goomdata, gint16 data [2][512]);
-
-void goom_close (GoomData *goomdata);
-
-#endif
diff --git a/gst/goom/goom_filters.h b/gst/goom/goom_filters.h
new file mode 100644
index 00000000..f015499a
--- /dev/null
+++ b/gst/goom/goom_filters.h
@@ -0,0 +1,52 @@
+#ifndef FILTERS_H
+#define FILTERS_H
+
+#include "goom_config.h"
+#include "goom_typedefs.h"
+#include "goom_visual_fx.h"
+#include "goom_graphic.h"
+
+VisualFX zoomFilterVisualFXWrapper_create(void);
+
+struct _ZOOM_FILTER_DATA
+{
+ int vitesse; /* 128 = vitesse nule... * * 256 = en arriere
+ * hyper vite.. * * 0 = en avant hype vite. */
+ unsigned char pertedec;
+ unsigned char sqrtperte;
+ int middleX, middleY; /* milieu de l'effet */
+ char reverse; /* inverse la vitesse */
+ char mode; /* type d'effet à appliquer (cf les #define) */
+ /** @since June 2001 */
+ int hPlaneEffect; /* deviation horitontale */
+ int vPlaneEffect; /* deviation verticale */
+ /** @since April 2002 */
+ int waveEffect; /* applique une "surcouche" de wave effect */
+ int hypercosEffect; /* applique une "surcouche de hypercos effect */
+
+ char noisify; /* ajoute un bruit a la transformation */
+};
+
+#define NORMAL_MODE 0
+#define WAVE_MODE 1
+#define CRYSTAL_BALL_MODE 2
+#define SCRUNCH_MODE 3
+#define AMULETTE_MODE 4
+#define WATER_MODE 5
+#define HYPERCOS1_MODE 6
+#define HYPERCOS2_MODE 7
+#define YONLY_MODE 8
+#define SPEEDWAY_MODE 9
+
+void pointFilter (PluginInfo *goomInfo, Pixel * pix1, Color c,
+ float t1, float t2, float t3, float t4, guint32 cycle);
+
+/* filtre de zoom :
+ * le contenu de pix1 est copie dans pix2.
+ * zf : si non NULL, configure l'effet.
+ * resx,resy : taille des buffers.
+ */
+void zoomFilterFastRGB (PluginInfo *goomInfo, Pixel * pix1, Pixel * pix2, ZoomFilterData * zf, guint32 resx,
+ guint32 resy, int switchIncr, float switchMult);
+
+#endif
diff --git a/gst/goom/goom_fx.h b/gst/goom/goom_fx.h
new file mode 100644
index 00000000..e672ece3
--- /dev/null
+++ b/gst/goom/goom_fx.h
@@ -0,0 +1,12 @@
+#ifndef _GOOM_FX_H
+#define _GOOM_FX_H
+
+#include "goom_visual_fx.h"
+#include "goom_plugin_info.h"
+
+VisualFX convolve_create ();
+VisualFX flying_star_create (void);
+
+void zoom_filter_c(int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
+
+#endif
diff --git a/gst/goom/goom_graphic.h b/gst/goom/goom_graphic.h
new file mode 100644
index 00000000..9deaf5a9
--- /dev/null
+++ b/gst/goom/goom_graphic.h
@@ -0,0 +1,74 @@
+#ifndef GRAPHIC_H
+#define GRAPHIC_H
+
+typedef unsigned int Uint;
+
+typedef struct
+{
+ unsigned short r, v, b;
+}
+Color;
+
+extern const Color BLACK;
+extern const Color WHITE;
+extern const Color RED;
+extern const Color BLUE;
+extern const Color GREEN;
+extern const Color YELLOW;
+extern const Color ORANGE;
+extern const Color VIOLET;
+
+
+#ifdef COLOR_BGRA
+
+#define B_CHANNEL 0xFF000000
+#define G_CHANNEL 0x00FF0000
+#define R_CHANNEL 0x0000FF00
+#define A_CHANNEL 0x000000FF
+#define B_OFFSET 24
+#define G_OFFSET 16
+#define R_OFFSET 8
+#define A_OFFSET 0
+
+typedef union _PIXEL {
+ struct {
+ unsigned char b;
+ unsigned char g;
+ unsigned char r;
+ unsigned char a;
+ } channels;
+ unsigned int val;
+ unsigned char cop[4];
+} Pixel;
+
+#else
+
+#define A_CHANNEL 0xFF000000
+#define R_CHANNEL 0x00FF0000
+#define G_CHANNEL 0x0000FF00
+#define B_CHANNEL 0x000000FF
+#define A_OFFSET 24
+#define R_OFFSET 16
+#define G_OFFSET 8
+#define B_OFFSET 0
+
+typedef union _PIXEL {
+ struct {
+ unsigned char a;
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+ } channels;
+ unsigned int val;
+ unsigned char cop[4];
+} Pixel;
+
+#endif /* COLOR_BGRA */
+
+/*
+inline void setPixelRGB (Pixel * buffer, Uint x, Uint y, Color c);
+inline void getPixelRGB (Pixel * buffer, Uint x, Uint y, Color * c);
+*/
+
+
+#endif /* GRAPHIC_H */
diff --git a/gst/goom/goom_plugin_info.h b/gst/goom/goom_plugin_info.h
new file mode 100644
index 00000000..8d5d098b
--- /dev/null
+++ b/gst/goom/goom_plugin_info.h
@@ -0,0 +1,176 @@
+#ifndef _PLUGIN_INFO_H
+#define _PLUGIN_INFO_H
+
+#include "goom_typedefs.h"
+
+#include "goom_config.h"
+
+#include "goom_graphic.h"
+#include "goom_config_param.h"
+#include "goom_visual_fx.h"
+#include "goom_filters.h"
+#include "goom_tools.h"
+#include "goomsl.h"
+
+typedef struct {
+ char drawIFS;
+ char drawPoints;
+ char drawTentacle;
+
+ char drawScope;
+ int farScope;
+
+ int rangemin;
+ int rangemax;
+} GoomState;
+
+#define STATES_MAX_NB 128
+
+/**
+ * Gives informations about the sound.
+ */
+struct _SOUND_INFO {
+
+ /* nota : a Goom is just a sound event... */
+
+ int timeSinceLastGoom; /* >= 0 */
+ float goomPower; /* power of the last Goom [0..1] */
+
+ int timeSinceLastBigGoom; /* >= 0 */
+
+ float volume; /* [0..1] */
+ short samples[2][512];
+
+ /* other "internal" datas for the sound_tester */
+ float goom_limit; /* auto-updated limit of goom_detection */
+ float bigGoomLimit;
+ float accelvar; /* acceleration of the sound - [0..1] */
+ float speedvar; /* speed of the sound - [0..100] */
+ int allTimesMax;
+ int totalgoom; /* number of goom since last reset
+ * (a reset every 64 cycles) */
+
+ float prov_max; /* accel max since last reset */
+
+ int cycle;
+
+ /* private */
+ PluginParam volume_p;
+ PluginParam speed_p;
+ PluginParam accel_p;
+ PluginParam goom_limit_p;
+ PluginParam goom_power_p;
+ PluginParam last_goom_p;
+ PluginParam last_biggoom_p;
+ PluginParam biggoom_speed_limit_p;
+ PluginParam biggoom_factor_p;
+
+ PluginParameters params; /* contains the previously defined parameters. */
+};
+
+
+/**
+ * Allows FXs to know the current state of the plugin.
+ */
+struct _PLUGIN_INFO {
+
+ /* public datas */
+
+ int nbParams;
+ PluginParameters *params;
+
+ /* private datas */
+
+ struct _SIZE_TYPE {
+ int width;
+ int height;
+ int size; /* == screen.height * screen.width. */
+ } screen;
+
+ SoundInfo sound;
+
+ int nbVisuals;
+ VisualFX **visuals; /* pointers on all the visual fx */
+
+ /** The known FX */
+ VisualFX convolve_fx;
+ VisualFX star_fx;
+ VisualFX zoomFilter_fx;
+ VisualFX tentacles_fx;
+ VisualFX ifs_fx;
+
+ /** image buffers */
+ guint32 *pixel;
+ guint32 *back;
+ Pixel *p1, *p2;
+ Pixel *conv;
+ Pixel *outputBuf;
+
+ /** state of goom */
+ guint32 cycle;
+ GoomState states[STATES_MAX_NB];
+ int statesNumber;
+ int statesRangeMax;
+
+ GoomState *curGState;
+
+ /** effet de ligne.. */
+ GMLine *gmline1;
+ GMLine *gmline2;
+
+ /** sinus table */
+ int sintable[0x10000];
+
+ /* INTERNALS */
+
+ /** goom_update internals.
+ * I took all static variables from goom_update and put them here.. for the moment.
+ */
+ struct {
+ int lockvar; /* pour empecher de nouveaux changements */
+ int goomvar; /* boucle des gooms */
+ int loopvar; /* mouvement des points */
+ int stop_lines;
+ int ifs_incr; /* dessiner l'ifs (0 = non: > = increment) */
+ int decay_ifs; /* disparition de l'ifs */
+ int recay_ifs; /* dedisparition de l'ifs */
+ int cyclesSinceLastChange; /* nombre de Cycle Depuis Dernier Changement */
+ int drawLinesDuration; /* duree de la transition entre afficher les lignes ou pas */
+ int lineMode; /* l'effet lineaire a dessiner */
+ float switchMultAmount; /* SWITCHMULT (29.0f/30.0f) */
+ int switchIncrAmount; /* 0x7f */
+ float switchMult; /* 1.0f */
+ int switchIncr; /* = SWITCHINCR; */
+ int stateSelectionRnd;
+ int stateSelectionBlocker;
+ int previousZoomSpeed;
+ int timeOfTitleDisplay;
+ char titleText[1024];
+ ZoomFilterData zoomFilterData;
+ } update;
+
+ struct {
+ int numberOfLinesInMessage;
+ char message[0x800];
+ int affiche;
+ int longueur;
+ } update_message;
+
+ struct {
+ void (*draw_line) (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny);
+ void (*zoom_filter) (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
+ } methods;
+
+ GoomRandom *gRandom;
+
+ GoomSL *scanner;
+ GoomSL *main_scanner;
+ const char *main_script_str;
+};
+
+void plugin_info_init(PluginInfo *p, int nbVisual);
+
+/* i = [0..p->nbVisual-1] */
+void plugin_info_add_visual(PluginInfo *p, int i, VisualFX *visual);
+
+#endif
diff --git a/gst/goom/goom_tools.c b/gst/goom/goom_tools.c
new file mode 100644
index 00000000..ebca69e2
--- /dev/null
+++ b/gst/goom/goom_tools.c
@@ -0,0 +1,32 @@
+#include "goom_tools.h"
+#include <stdlib.h>
+
+GoomRandom *
+goom_random_init (int i)
+{
+ GoomRandom *grandom = (GoomRandom *) malloc (sizeof (GoomRandom));
+
+ srand (i);
+ grandom->pos = 1;
+ goom_random_update_array (grandom, GOOM_NB_RAND);
+ return grandom;
+}
+
+void
+goom_random_free (GoomRandom * grandom)
+{
+ free (grandom);
+}
+
+void
+goom_random_update_array (GoomRandom * grandom, int numberOfValuesToChange)
+{
+ while (numberOfValuesToChange > 0) {
+#if RAND_MAX < 0x10000
+ grandom->array[grandom->pos++] = ((rand () << 16) + rand ()) / 127;
+#else
+ grandom->array[grandom->pos++] = rand () / 127;
+#endif
+ numberOfValuesToChange--;
+ }
+}
diff --git a/gst/goom/goom_tools.h b/gst/goom/goom_tools.h
index 6178dbaf..31d044e4 100644
--- a/gst/goom/goom_tools.h
+++ b/gst/goom/goom_tools.h
@@ -1,24 +1,33 @@
#ifndef _GOOMTOOLS_H
#define _GOOMTOOLS_H
-#define NB_RAND 0x10000
-
-#define RAND_INIT(gd,i) \
- srand (i); \
- if (gd->rand_tab == NULL) \
- gd->rand_tab = g_malloc (NB_RAND * sizeof(gint)) ;\
- gd->rand_pos = 0; \
- while (gd->rand_pos < NB_RAND) \
- gd->rand_tab [gd->rand_pos++] = rand ();
-
-#define RAND(gd) \
- (gd->rand_tab[gd->rand_pos = ((gd->rand_pos + 1) % NB_RAND)])
-
-#define RAND_CLOSE(gd) \
- g_free (gd->rand_tab); \
- gd->rand_tab = NULL;
-
-/*#define iRAND(i) ((guint32)((float)i * RAND()/RAND_MAX)) */
-#define iRAND(gd,i) (RAND(gd) % i)
-
+/**
+ * Random number generator wrapper for faster random number.
+ */
+
+#define GOOM_NB_RAND 0x10000
+
+typedef struct _GOOM_RANDOM {
+ int array[GOOM_NB_RAND];
+ unsigned short pos;
+} GoomRandom;
+
+GoomRandom *goom_random_init(int i);
+void goom_random_free(GoomRandom *grandom);
+
+inline static int goom_random(GoomRandom *grandom) {
+
+ grandom->pos++; /* works because pos is an unsigned short */
+ return grandom->array[grandom->pos];
+}
+
+inline static int goom_irand(GoomRandom *grandom, int i) {
+
+ grandom->pos++;
+ return grandom->array[grandom->pos] % i;
+}
+
+/* called to change the specified number of value in the array, so that the array does not remain the same*/
+void goom_random_update_array(GoomRandom *grandom, int numberOfValuesToChange);
+
#endif
diff --git a/gst/goom/goom_typedefs.h b/gst/goom/goom_typedefs.h
new file mode 100644
index 00000000..76036504
--- /dev/null
+++ b/gst/goom/goom_typedefs.h
@@ -0,0 +1,11 @@
+#ifndef _GOOM_TYPEDEFS_H
+#define _GOOM_TYPEDEFS_H
+
+typedef struct _PLUGIN_INFO PluginInfo;
+typedef struct _SOUND_INFO SoundInfo;
+typedef struct _GMLINE GMLine;
+typedef struct _GMUNITPOINTER GMUnitPointer;
+typedef struct _ZOOM_FILTER_DATA ZoomFilterData;
+typedef struct _VISUAL_FX VisualFX;
+
+#endif
diff --git a/gst/goom/goom_visual_fx.h b/gst/goom/goom_visual_fx.h
new file mode 100644
index 00000000..6939ac80
--- /dev/null
+++ b/gst/goom/goom_visual_fx.h
@@ -0,0 +1,26 @@
+#ifndef _VISUAL_FX_H
+#define _VISUAL_FX_H
+
+/**
+ * File created on 2003-05-21 by Jeko.
+ * (c)2003, JC Hoelt for iOS-software.
+ *
+ * LGPL Licence.
+ * If you use this file on a visual program,
+ * please make my name being visible on it.
+ */
+
+#include "goom_config_param.h"
+#include "goom_graphic.h"
+#include "goom_typedefs.h"
+
+struct _VISUAL_FX {
+ void (*init) (struct _VISUAL_FX *_this, PluginInfo *info);
+ void (*free) (struct _VISUAL_FX *_this);
+ void (*apply) (struct _VISUAL_FX *_this, Pixel *src, Pixel *dest, PluginInfo *info);
+ void *fx_data;
+
+ PluginParameters *params;
+};
+
+#endif
diff --git a/gst/goom/goomsl.c b/gst/goom/goomsl.c
new file mode 100644
index 00000000..b07b2596
--- /dev/null
+++ b/gst/goom/goomsl.c
@@ -0,0 +1,1660 @@
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "goomsl.h"
+#include "goomsl_private.h"
+#include "goomsl_yacc.h"
+
+/*#define TRACE_SCRIPT*/
+
+ /* {{{ definition of the instructions number */
+#define INSTR_SETI_VAR_INTEGER 1
+#define INSTR_SETI_VAR_VAR 2
+#define INSTR_SETF_VAR_FLOAT 3
+#define INSTR_SETF_VAR_VAR 4
+#define INSTR_NOP 5
+/* #define INSTR_JUMP 6 */
+#define INSTR_SETP_VAR_PTR 7
+#define INSTR_SETP_VAR_VAR 8
+#define INSTR_SUBI_VAR_INTEGER 9
+#define INSTR_SUBI_VAR_VAR 10
+#define INSTR_SUBF_VAR_FLOAT 11
+#define INSTR_SUBF_VAR_VAR 12
+#define INSTR_ISLOWERF_VAR_VAR 13
+#define INSTR_ISLOWERF_VAR_FLOAT 14
+#define INSTR_ISLOWERI_VAR_VAR 15
+#define INSTR_ISLOWERI_VAR_INTEGER 16
+#define INSTR_ADDI_VAR_INTEGER 17
+#define INSTR_ADDI_VAR_VAR 18
+#define INSTR_ADDF_VAR_FLOAT 19
+#define INSTR_ADDF_VAR_VAR 20
+#define INSTR_MULI_VAR_INTEGER 21
+#define INSTR_MULI_VAR_VAR 22
+#define INSTR_MULF_VAR_FLOAT 23
+#define INSTR_MULF_VAR_VAR 24
+#define INSTR_DIVI_VAR_INTEGER 25
+#define INSTR_DIVI_VAR_VAR 26
+#define INSTR_DIVF_VAR_FLOAT 27
+#define INSTR_DIVF_VAR_VAR 28
+/* #define INSTR_JZERO 29 */
+#define INSTR_ISEQUALP_VAR_VAR 30
+#define INSTR_ISEQUALP_VAR_PTR 31
+#define INSTR_ISEQUALI_VAR_VAR 32
+#define INSTR_ISEQUALI_VAR_INTEGER 33
+#define INSTR_ISEQUALF_VAR_VAR 34
+#define INSTR_ISEQUALF_VAR_FLOAT 35
+/* #define INSTR_CALL 36 */
+/* #define INSTR_RET 37 */
+/* #define INSTR_EXT_CALL 38 */
+#define INSTR_NOT_VAR 39
+/* #define INSTR_JNZERO 40 */
+#define INSTR_SETS_VAR_VAR 41
+#define INSTR_ISEQUALS_VAR_VAR 42
+#define INSTR_ADDS_VAR_VAR 43
+#define INSTR_SUBS_VAR_VAR 44
+#define INSTR_MULS_VAR_VAR 45
+#define INSTR_DIVS_VAR_VAR 46
+
+ /* }}} */
+/* {{{ definition of the validation error types */
+static const char *VALIDATE_OK = "ok";
+
+#define VALIDATE_ERROR "error while validating "
+#define VALIDATE_TODO "todo"
+#define VALIDATE_SYNTHAX_ERROR "synthax error"
+#define VALIDATE_NO_SUCH_INT "no such integer variable"
+#define VALIDATE_NO_SUCH_VAR "no such variable"
+#define VALIDATE_NO_SUCH_DEST_VAR "no such destination variable"
+#define VALIDATE_NO_SUCH_SRC_VAR "no such src variable"
+/* }}} */
+
+ /***********************************/
+ /* PROTOTYPE OF INTERNAL FUNCTIONS */
+/***********************************/
+
+/* {{{ */
+static void gsl_instr_free (Instruction * _this);
+static const char *gsl_instr_validate (Instruction * _this);
+static void gsl_instr_display (Instruction * _this);
+
+static InstructionFlow *iflow_new (void);
+static void iflow_add_instr (InstructionFlow * _this, Instruction * instr);
+static void iflow_clean (InstructionFlow * _this);
+static void iflow_free (InstructionFlow * _this);
+static void iflow_execute (FastInstructionFlow * _this, GoomSL * gsl);
+
+/* }}} */
+
+ /************************************/
+ /* DEFINITION OF INTERNAL FUNCTIONS */
+/************************************/
+
+void
+iflow_free (InstructionFlow * _this)
+{ /* {{{ */
+ goom_hash_free (_this->labels);
+ free (_this); /*TODO: finir cette fonction */
+} /* }}} */
+
+void
+iflow_clean (InstructionFlow * _this)
+{ /* {{{ */
+ /* TODO: clean chaque instruction du flot */
+ _this->number = 0;
+ goom_hash_free (_this->labels);
+ _this->labels = goom_hash_new ();
+} /* }}} */
+
+InstructionFlow *
+iflow_new (void)
+{ /* {{{ */
+ InstructionFlow *_this =
+ (InstructionFlow *) malloc (sizeof (InstructionFlow));
+ _this->number = 0;
+ _this->tabsize = 6;
+ _this->instr =
+ (Instruction **) malloc (_this->tabsize * sizeof (Instruction *));
+ _this->labels = goom_hash_new ();
+
+ return _this;
+} /* }}} */
+
+void
+iflow_add_instr (InstructionFlow * _this, Instruction * instr)
+{ /* {{{ */
+ if (_this->number == _this->tabsize) {
+ _this->tabsize *= 2;
+ _this->instr =
+ (Instruction **) realloc (_this->instr,
+ _this->tabsize * sizeof (Instruction *));
+ }
+ _this->instr[_this->number] = instr;
+ instr->address = _this->number;
+ _this->number++;
+} /* }}} */
+
+void
+gsl_instr_set_namespace (Instruction * _this, GoomHash * ns)
+{ /* {{{ */
+ if (_this->cur_param <= 0) {
+ fprintf (stderr, "ERROR: Line %d, No more params to instructions\n",
+ _this->line_number);
+ exit (1);
+ }
+ _this->vnamespace[_this->cur_param - 1] = ns;
+} /* }}} */
+
+void
+gsl_instr_add_param (Instruction * instr, char *param, int type)
+{ /* {{{ */
+ int len;
+
+ if (instr == NULL)
+ return;
+ if (instr->cur_param == 0)
+ return;
+ --instr->cur_param;
+ len = strlen (param);
+ instr->params[instr->cur_param] = (char *) malloc (len + 1);
+ strcpy (instr->params[instr->cur_param], param);
+ instr->types[instr->cur_param] = type;
+ if (instr->cur_param == 0) {
+
+ const char *result = gsl_instr_validate (instr);
+
+ if (result != VALIDATE_OK) {
+ printf ("ERROR: Line %d: ", instr->parent->num_lines + 1);
+ gsl_instr_display (instr);
+ printf ("... %s\n", result);
+ instr->parent->compilationOK = 0;
+ exit (1);
+ }
+#if USE_JITC_X86
+ iflow_add_instr (instr->parent->iflow, instr);
+#else
+ if (instr->id != INSTR_NOP)
+ iflow_add_instr (instr->parent->iflow, instr);
+ else
+ gsl_instr_free (instr);
+#endif
+ }
+} /* }}} */
+
+Instruction *
+gsl_instr_init (GoomSL * parent, const char *name, int id, int nb_param,
+ int line_number)
+{ /* {{{ */
+ Instruction *instr = (Instruction *) malloc (sizeof (Instruction));
+ instr->params = (char **) malloc (nb_param * sizeof (char *));
+ instr->vnamespace = (GoomHash **) malloc (nb_param * sizeof (GoomHash *));
+ instr->types = (int *) malloc (nb_param * sizeof (int));
+ instr->cur_param = instr->nb_param = nb_param;
+ instr->parent = parent;
+ instr->id = id;
+ instr->name = name;
+ instr->jump_label = NULL;
+ instr->line_number = line_number;
+ return instr;
+} /* }}} */
+
+void
+gsl_instr_free (Instruction * _this)
+{ /* {{{ */
+ int i;
+
+ free (_this->types);
+ for (i = _this->cur_param; i < _this->nb_param; ++i)
+ free (_this->params[i]);
+ free (_this->params);
+ free (_this);
+} /* }}} */
+
+void
+gsl_instr_display (Instruction * _this)
+{ /* {{{ */
+ int i = _this->nb_param - 1;
+
+ printf ("%s", _this->name);
+ while (i >= _this->cur_param) {
+ printf (" %s", _this->params[i]);
+ --i;
+ }
+} /* }}} */
+
+ /****************************************/
+ /* VALIDATION OF INSTRUCTION PARAMETERS */
+/****************************************/
+
+static const char *
+validate_v_v (Instruction * _this)
+{ /* {{{ */
+ HashValue *dest = goom_hash_get (_this->vnamespace[1], _this->params[1]);
+ HashValue *src = goom_hash_get (_this->vnamespace[0], _this->params[0]);
+
+ if (dest == NULL) {
+ return VALIDATE_NO_SUCH_DEST_VAR;
+ }
+ if (src == NULL) {
+ return VALIDATE_NO_SUCH_SRC_VAR;
+ }
+ _this->data.udest.var = dest->ptr;
+ _this->data.usrc.var = src->ptr;
+ return VALIDATE_OK;
+} /* }}} */
+
+static const char *
+validate_v_i (Instruction * _this)
+{ /* {{{ */
+ HashValue *dest = goom_hash_get (_this->vnamespace[1], _this->params[1]);
+
+ _this->data.usrc.value_int = strtol (_this->params[0], NULL, 0);
+
+ if (dest == NULL) {
+ return VALIDATE_NO_SUCH_INT;
+ }
+ _this->data.udest.var = dest->ptr;
+ return VALIDATE_OK;
+} /* }}} */
+
+static const char *
+validate_v_p (Instruction * _this)
+{ /* {{{ */
+ HashValue *dest = goom_hash_get (_this->vnamespace[1], _this->params[1]);
+
+ _this->data.usrc.value_ptr = strtol (_this->params[0], NULL, 0);
+
+ if (dest == NULL) {
+ return VALIDATE_NO_SUCH_INT;
+ }
+ _this->data.udest.var = dest->ptr;
+ return VALIDATE_OK;
+} /* }}} */
+
+static const char *
+validate_v_f (Instruction * _this)
+{ /* {{{ */
+ HashValue *dest = goom_hash_get (_this->vnamespace[1], _this->params[1]);
+
+ _this->data.usrc.value_float = atof (_this->params[0]);
+
+ if (dest == NULL) {
+ return VALIDATE_NO_SUCH_VAR;
+ }
+ _this->data.udest.var = dest->ptr;
+ return VALIDATE_OK;
+} /* }}} */
+
+static const char *
+validate (Instruction * _this,
+ int vf_f_id, int vf_v_id,
+ int vi_i_id, int vi_v_id, int vp_p_id, int vp_v_id, int vs_v_id)
+{ /* {{{ */
+ if ((_this->types[1] == TYPE_FVAR) && (_this->types[0] == TYPE_FLOAT)) {
+ _this->id = vf_f_id;
+ return validate_v_f (_this);
+ } else if ((_this->types[1] == TYPE_FVAR) && (_this->types[0] == TYPE_FVAR)) {
+ _this->id = vf_v_id;
+ return validate_v_v (_this);
+ } else if ((_this->types[1] == TYPE_IVAR)
+ && (_this->types[0] == TYPE_INTEGER)) {
+ _this->id = vi_i_id;
+ return validate_v_i (_this);
+ } else if ((_this->types[1] == TYPE_IVAR) && (_this->types[0] == TYPE_IVAR)) {
+ _this->id = vi_v_id;
+ return validate_v_v (_this);
+ } else if ((_this->types[1] == TYPE_PVAR) && (_this->types[0] == TYPE_PTR)) {
+ if (vp_p_id == INSTR_NOP)
+ return VALIDATE_ERROR;
+ _this->id = vp_p_id;
+ return validate_v_p (_this);
+ } else if ((_this->types[1] == TYPE_PVAR) && (_this->types[0] == TYPE_PVAR)) {
+ _this->id = vp_v_id;
+ if (vp_v_id == INSTR_NOP)
+ return VALIDATE_ERROR;
+ return validate_v_v (_this);
+ } else if ((_this->types[1] < FIRST_RESERVED) && (_this->types[1] >= 0)
+ && (_this->types[0] == _this->types[1])) {
+ _this->id = vs_v_id;
+ if (vs_v_id == INSTR_NOP)
+ return "Impossible operation to perform between two structs";
+ return validate_v_v (_this);
+ }
+ return VALIDATE_ERROR;
+} /* }}} */
+
+const char *
+gsl_instr_validate (Instruction * _this)
+{ /* {{{ */
+ if (_this->id != INSTR_EXT_CALL) {
+ int i = _this->nb_param;
+
+ while (i > 0) {
+ i--;
+ if (_this->types[i] == TYPE_VAR) {
+ int type = gsl_type_of_var (_this->vnamespace[i], _this->params[i]);
+
+ if (type == INSTR_INT)
+ _this->types[i] = TYPE_IVAR;
+ else if (type == INSTR_FLOAT)
+ _this->types[i] = TYPE_FVAR;
+ else if (type == INSTR_PTR)
+ _this->types[i] = TYPE_PVAR;
+ else if ((type >= 0) && (type < FIRST_RESERVED))
+ _this->types[i] = type;
+ else
+ fprintf (stderr, "WARNING: Line %d, %s has no namespace\n",
+ _this->line_number, _this->params[i]);
+ }
+ }
+ }
+
+ switch (_this->id) {
+
+ /* set */
+ case INSTR_SET:
+ return validate (_this,
+ INSTR_SETF_VAR_FLOAT, INSTR_SETF_VAR_VAR,
+ INSTR_SETI_VAR_INTEGER, INSTR_SETI_VAR_VAR,
+ INSTR_SETP_VAR_PTR, INSTR_SETP_VAR_VAR, INSTR_SETS_VAR_VAR);
+
+ /* extcall */
+ case INSTR_EXT_CALL:
+ if (_this->types[0] == TYPE_VAR) {
+ HashValue *fval =
+ goom_hash_get (_this->parent->functions, _this->params[0]);
+ if (fval) {
+ _this->data.udest.external_function =
+ (struct _ExternalFunctionStruct *) fval->ptr;
+ return VALIDATE_OK;
+ }
+ }
+ return VALIDATE_ERROR;
+
+ /* call */
+ case INSTR_CALL:
+ if (_this->types[0] == TYPE_LABEL) {
+ _this->jump_label = _this->params[0];
+ return VALIDATE_OK;
+ }
+ return VALIDATE_ERROR;
+
+ /* ret */
+ case INSTR_RET:
+ return VALIDATE_OK;
+
+ /* jump */
+ case INSTR_JUMP:
+
+ if (_this->types[0] == TYPE_LABEL) {
+ _this->jump_label = _this->params[0];
+ return VALIDATE_OK;
+ }
+ return VALIDATE_ERROR;
+
+ /* jzero / jnzero */
+ case INSTR_JZERO:
+ case INSTR_JNZERO:
+
+ if (_this->types[0] == TYPE_LABEL) {
+ _this->jump_label = _this->params[0];
+ return VALIDATE_OK;
+ }
+ return VALIDATE_ERROR;
+
+ /* label */
+ case INSTR_LABEL:
+
+ if (_this->types[0] == TYPE_LABEL) {
+ _this->id = INSTR_NOP;
+ _this->nop_label = _this->params[0];
+ goom_hash_put_int (_this->parent->iflow->labels, _this->params[0],
+ _this->parent->iflow->number);
+ return VALIDATE_OK;
+ }
+ return VALIDATE_ERROR;
+
+ /* isequal */
+ case INSTR_ISEQUAL:
+ return validate (_this,
+ INSTR_ISEQUALF_VAR_FLOAT, INSTR_ISEQUALF_VAR_VAR,
+ INSTR_ISEQUALI_VAR_INTEGER, INSTR_ISEQUALI_VAR_VAR,
+ INSTR_ISEQUALP_VAR_PTR, INSTR_ISEQUALP_VAR_VAR,
+ INSTR_ISEQUALS_VAR_VAR);
+
+ /* not */
+ case INSTR_NOT:
+ _this->id = INSTR_NOT_VAR;
+ return VALIDATE_OK;
+
+ /* islower */
+ case INSTR_ISLOWER:
+ return validate (_this,
+ INSTR_ISLOWERF_VAR_FLOAT, INSTR_ISLOWERF_VAR_VAR,
+ INSTR_ISLOWERI_VAR_INTEGER, INSTR_ISLOWERI_VAR_VAR,
+ INSTR_NOP, INSTR_NOP, INSTR_NOP);
+
+ /* add */
+ case INSTR_ADD:
+ return validate (_this,
+ INSTR_ADDF_VAR_FLOAT, INSTR_ADDF_VAR_VAR,
+ INSTR_ADDI_VAR_INTEGER, INSTR_ADDI_VAR_VAR,
+ INSTR_NOP, INSTR_NOP, INSTR_ADDS_VAR_VAR);
+
+ /* mul */
+ case INSTR_MUL:
+ return validate (_this,
+ INSTR_MULF_VAR_FLOAT, INSTR_MULF_VAR_VAR,
+ INSTR_MULI_VAR_INTEGER, INSTR_MULI_VAR_VAR,
+ INSTR_NOP, INSTR_NOP, INSTR_MULS_VAR_VAR);
+
+ /* sub */
+ case INSTR_SUB:
+ return validate (_this,
+ INSTR_SUBF_VAR_FLOAT, INSTR_SUBF_VAR_VAR,
+ INSTR_SUBI_VAR_INTEGER, INSTR_SUBI_VAR_VAR,
+ INSTR_NOP, INSTR_NOP, INSTR_SUBS_VAR_VAR);
+
+ /* div */
+ case INSTR_DIV:
+ return validate (_this,
+ INSTR_DIVF_VAR_FLOAT, INSTR_DIVF_VAR_VAR,
+ INSTR_DIVI_VAR_INTEGER, INSTR_DIVI_VAR_VAR,
+ INSTR_NOP, INSTR_NOP, INSTR_DIVS_VAR_VAR);
+
+ default:
+ return VALIDATE_TODO;
+ }
+ return VALIDATE_ERROR;
+} /* }}} */
+
+ /*************/
+ /* EXECUTION */
+/*************/
+void
+iflow_execute (FastInstructionFlow * _this, GoomSL * gsl)
+{ /* {{{ */
+ int flag = 0;
+ int ip = 0;
+ FastInstruction *instr = _this->instr;
+ int stack[0x10000];
+ int stack_pointer = 0;
+
+ stack[stack_pointer++] = -1;
+
+ /* Quelques Macro pour rendre le code plus lisible */
+#define pSRC_VAR instr[ip].data.usrc.var
+#define SRC_VAR_INT *instr[ip].data.usrc.var_int
+#define SRC_VAR_FLOAT *instr[ip].data.usrc.var_float
+#define SRC_VAR_PTR *instr[ip].data.usrc.var_ptr
+
+#define pDEST_VAR instr[ip].data.udest.var
+#define DEST_VAR_INT *instr[ip].data.udest.var_int
+#define DEST_VAR_FLOAT *instr[ip].data.udest.var_float
+#define DEST_VAR_PTR *instr[ip].data.udest.var_ptr
+
+#define VALUE_INT instr[ip].data.usrc.value_int
+#define VALUE_FLOAT instr[ip].data.usrc.value_float
+#define VALUE_PTR instr[ip].data.usrc.value_ptr
+
+#define JUMP_OFFSET instr[ip].data.udest.jump_offset
+
+#define SRC_STRUCT_ID instr[ip].data.usrc.var_int[-1]
+#define DEST_STRUCT_ID instr[ip].data.udest.var_int[-1]
+#define SRC_STRUCT_IBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i]
+#define SRC_STRUCT_FBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i]
+#define DEST_STRUCT_IBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i]
+#define DEST_STRUCT_FBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i]
+#define DEST_STRUCT_IBLOCK_VAR(i,j) \
+ ((int*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i].data))[j]
+#define DEST_STRUCT_FBLOCK_VAR(i,j) \
+ ((float*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i].data))[j]
+#define SRC_STRUCT_IBLOCK_VAR(i,j) \
+ ((int*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i].data))[j]
+#define SRC_STRUCT_FBLOCK_VAR(i,j) \
+ ((float*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i].data))[j]
+#define DEST_STRUCT_SIZE gsl->gsl_struct[DEST_STRUCT_ID]->size
+
+ while (1) {
+ int i;
+
+#ifdef TRACE_SCRIPT
+ printf ("execute ");
+ gsl_instr_display (instr[ip].proto);
+ printf ("\n");
+#endif
+ switch (instr[ip].id) {
+
+ /* SET.I */
+ case INSTR_SETI_VAR_INTEGER:
+ DEST_VAR_INT = VALUE_INT;
+ ++ip;
+ break;
+
+ case INSTR_SETI_VAR_VAR:
+ DEST_VAR_INT = SRC_VAR_INT;
+ ++ip;
+ break;
+
+ /* SET.F */
+ case INSTR_SETF_VAR_FLOAT:
+ DEST_VAR_FLOAT = VALUE_FLOAT;
+ ++ip;
+ break;
+
+ case INSTR_SETF_VAR_VAR:
+ DEST_VAR_FLOAT = SRC_VAR_FLOAT;
+ ++ip;
+ break;
+
+ /* SET.P */
+ case INSTR_SETP_VAR_VAR:
+ DEST_VAR_PTR = SRC_VAR_PTR;
+ ++ip;
+ break;
+
+ case INSTR_SETP_VAR_PTR:
+ DEST_VAR_PTR = VALUE_PTR;
+ ++ip;
+ break;
+
+ /* JUMP */
+ case INSTR_JUMP:
+ ip += JUMP_OFFSET;
+ break;
+
+ /* JZERO */
+ case INSTR_JZERO:
+ ip += (flag ? 1 : JUMP_OFFSET);
+ break;
+
+ case INSTR_NOP:
+ ++ip;
+ break;
+
+ /* ISEQUAL.P */
+ case INSTR_ISEQUALP_VAR_VAR:
+ flag = (DEST_VAR_PTR == SRC_VAR_PTR);
+ ++ip;
+ break;
+
+ case INSTR_ISEQUALP_VAR_PTR:
+ flag = (DEST_VAR_PTR == VALUE_PTR);
+ ++ip;
+ break;
+
+ /* ISEQUAL.I */
+ case INSTR_ISEQUALI_VAR_VAR:
+ flag = (DEST_VAR_INT == SRC_VAR_INT);
+ ++ip;
+ break;
+
+ case INSTR_ISEQUALI_VAR_INTEGER:
+ flag = (DEST_VAR_INT == VALUE_INT);
+ ++ip;
+ break;
+
+ /* ISEQUAL.F */
+ case INSTR_ISEQUALF_VAR_VAR:
+ flag = (DEST_VAR_FLOAT == SRC_VAR_FLOAT);
+ ++ip;
+ break;
+
+ case INSTR_ISEQUALF_VAR_FLOAT:
+ flag = (DEST_VAR_FLOAT == VALUE_FLOAT);
+ ++ip;
+ break;
+
+ /* ISLOWER.I */
+ case INSTR_ISLOWERI_VAR_VAR:
+ flag = (DEST_VAR_INT < SRC_VAR_INT);
+ ++ip;
+ break;
+
+ case INSTR_ISLOWERI_VAR_INTEGER:
+ flag = (DEST_VAR_INT < VALUE_INT);
+ ++ip;
+ break;
+
+ /* ISLOWER.F */
+ case INSTR_ISLOWERF_VAR_VAR:
+ flag = (DEST_VAR_FLOAT < SRC_VAR_FLOAT);
+ ++ip;
+ break;
+
+ case INSTR_ISLOWERF_VAR_FLOAT:
+ flag = (DEST_VAR_FLOAT < VALUE_FLOAT);
+ ++ip;
+ break;
+
+ /* ADD.I */
+ case INSTR_ADDI_VAR_VAR:
+ DEST_VAR_INT += SRC_VAR_INT;
+ ++ip;
+ break;
+
+ case INSTR_ADDI_VAR_INTEGER:
+ DEST_VAR_INT += VALUE_INT;
+ ++ip;
+ break;
+
+ /* ADD.F */
+ case INSTR_ADDF_VAR_VAR:
+ DEST_VAR_FLOAT += SRC_VAR_FLOAT;
+ ++ip;
+ break;
+
+ case INSTR_ADDF_VAR_FLOAT:
+ DEST_VAR_FLOAT += VALUE_FLOAT;
+ ++ip;
+ break;
+
+ /* MUL.I */
+ case INSTR_MULI_VAR_VAR:
+ DEST_VAR_INT *= SRC_VAR_INT;
+ ++ip;
+ break;
+
+ case INSTR_MULI_VAR_INTEGER:
+ DEST_VAR_INT *= VALUE_INT;
+ ++ip;
+ break;
+
+ /* MUL.F */
+ case INSTR_MULF_VAR_FLOAT:
+ DEST_VAR_FLOAT *= VALUE_FLOAT;
+ ++ip;
+ break;
+
+ case INSTR_MULF_VAR_VAR:
+ DEST_VAR_FLOAT *= SRC_VAR_FLOAT;
+ ++ip;
+ break;
+
+ /* DIV.I */
+ case INSTR_DIVI_VAR_VAR:
+ DEST_VAR_INT /= SRC_VAR_INT;
+ ++ip;
+ break;
+
+ case INSTR_DIVI_VAR_INTEGER:
+ DEST_VAR_INT /= VALUE_INT;
+ ++ip;
+ break;
+
+ /* DIV.F */
+ case INSTR_DIVF_VAR_FLOAT:
+ DEST_VAR_FLOAT /= VALUE_FLOAT;
+ ++ip;
+ break;
+
+ case INSTR_DIVF_VAR_VAR:
+ DEST_VAR_FLOAT /= SRC_VAR_FLOAT;
+ ++ip;
+ break;
+
+ /* SUB.I */
+ case INSTR_SUBI_VAR_VAR:
+ DEST_VAR_INT -= SRC_VAR_INT;
+ ++ip;
+ break;
+
+ case INSTR_SUBI_VAR_INTEGER:
+ DEST_VAR_INT -= VALUE_INT;
+ ++ip;
+ break;
+
+ /* SUB.F */
+ case INSTR_SUBF_VAR_FLOAT:
+ DEST_VAR_FLOAT -= VALUE_FLOAT;
+ ++ip;
+ break;
+
+ case INSTR_SUBF_VAR_VAR:
+ DEST_VAR_FLOAT -= SRC_VAR_FLOAT;
+ ++ip;
+ break;
+
+ /* CALL */
+ case INSTR_CALL:
+ stack[stack_pointer++] = ip + 1;
+ ip += JUMP_OFFSET;
+ break;
+
+ /* RET */
+ case INSTR_RET:
+ ip = stack[--stack_pointer];
+ if (ip < 0)
+ return;
+ break;
+
+ /* EXT_CALL */
+ case INSTR_EXT_CALL:
+ instr[ip].data.udest.external_function->function (gsl, gsl->vars,
+ instr[ip].data.udest.external_function->vars);
+ ++ip;
+ break;
+
+ /* NOT */
+ case INSTR_NOT_VAR:
+ flag = !flag;
+ ++ip;
+ break;
+
+ /* JNZERO */
+ case INSTR_JNZERO:
+ ip += (flag ? JUMP_OFFSET : 1);
+ break;
+
+ case INSTR_SETS_VAR_VAR:
+ memcpy (pDEST_VAR, pSRC_VAR, DEST_STRUCT_SIZE);
+ ++ip;
+ break;
+
+ case INSTR_ISEQUALS_VAR_VAR:
+ break;
+
+ case INSTR_ADDS_VAR_VAR:
+ /* process integers */
+ i = 0;
+ while (DEST_STRUCT_IBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_IBLOCK (i).size;
+
+ while (j--) {
+ DEST_STRUCT_IBLOCK_VAR (i, j) += SRC_STRUCT_IBLOCK_VAR (i, j);
+ }
+ ++i;
+ }
+ /* process floats */
+ i = 0;
+ while (DEST_STRUCT_FBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_FBLOCK (i).size;
+
+ while (j--) {
+ DEST_STRUCT_FBLOCK_VAR (i, j) += SRC_STRUCT_FBLOCK_VAR (i, j);
+ }
+ ++i;
+ }
+ ++ip;
+ break;
+
+ case INSTR_SUBS_VAR_VAR:
+ /* process integers */
+ i = 0;
+ while (DEST_STRUCT_IBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_IBLOCK (i).size;
+
+ while (j--) {
+ DEST_STRUCT_IBLOCK_VAR (i, j) -= SRC_STRUCT_IBLOCK_VAR (i, j);
+ }
+ ++i;
+ }
+ /* process floats */
+ i = 0;
+ while (DEST_STRUCT_FBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_FBLOCK (i).size;
+
+ while (j--) {
+ DEST_STRUCT_FBLOCK_VAR (i, j) -= SRC_STRUCT_FBLOCK_VAR (i, j);
+ }
+ ++i;
+ }
+ ++ip;
+ break;
+
+ case INSTR_MULS_VAR_VAR:
+ /* process integers */
+ i = 0;
+ while (DEST_STRUCT_IBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_IBLOCK (i).size;
+
+ while (j--) {
+ DEST_STRUCT_IBLOCK_VAR (i, j) *= SRC_STRUCT_IBLOCK_VAR (i, j);
+ }
+ ++i;
+ }
+ /* process floats */
+ i = 0;
+ while (DEST_STRUCT_FBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_FBLOCK (i).size;
+
+ while (j--) {
+ DEST_STRUCT_FBLOCK_VAR (i, j) *= SRC_STRUCT_FBLOCK_VAR (i, j);
+ }
+ ++i;
+ }
+ ++ip;
+ break;
+
+ case INSTR_DIVS_VAR_VAR:
+ /* process integers */
+ i = 0;
+ while (DEST_STRUCT_IBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_IBLOCK (i).size;
+
+ while (j--) {
+ DEST_STRUCT_IBLOCK_VAR (i, j) /= SRC_STRUCT_IBLOCK_VAR (i, j);
+ }
+ ++i;
+ }
+ /* process floats */
+ i = 0;
+ while (DEST_STRUCT_FBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_FBLOCK (i).size;
+
+ while (j--) {
+ DEST_STRUCT_FBLOCK_VAR (i, j) /= SRC_STRUCT_FBLOCK_VAR (i, j);
+ }
+ ++i;
+ }
+ ++ip;
+ break;
+
+ default:
+ printf ("NOT IMPLEMENTED : %d\n", instr[ip].id);
+ ++ip;
+ exit (1);
+ }
+ }
+} /* }}} */
+
+int
+gsl_malloc (GoomSL * _this, int size)
+{ /* {{{ */
+ if (_this->nbPtr >= _this->ptrArraySize) {
+ _this->ptrArraySize *= 2;
+ _this->ptrArray =
+ (void **) realloc (_this->ptrArray,
+ sizeof (void *) * _this->ptrArraySize);
+ }
+ _this->ptrArray[_this->nbPtr] = malloc (size);
+ return _this->nbPtr++;
+} /* }}} */
+
+void *
+gsl_get_ptr (GoomSL * _this, int id)
+{ /* {{{ */
+ if ((id >= 0) && (id < _this->nbPtr))
+ return _this->ptrArray[id];
+ fprintf (stderr, "INVALID GET PTR 0x%08x\n", id);
+ return NULL;
+} /* }}} */
+
+void
+gsl_free_ptr (GoomSL * _this, int id)
+{ /* {{{ */
+ if ((id >= 0) && (id < _this->nbPtr)) {
+ free (_this->ptrArray[id]);
+ _this->ptrArray[id] = 0;
+ }
+} /* }}} */
+
+void
+gsl_enternamespace (const char *name)
+{ /* {{{ */
+ HashValue *val = goom_hash_get (currentGoomSL->functions, name);
+
+ if (val) {
+ ExternalFunctionStruct *function = (ExternalFunctionStruct *) val->ptr;
+
+ currentGoomSL->currentNS++;
+ currentGoomSL->namespaces[currentGoomSL->currentNS] = function->vars;
+ } else {
+ fprintf (stderr, "ERROR: Line %d, Could not find namespace: %s\n",
+ currentGoomSL->num_lines, name);
+ exit (1);
+ }
+} /* }}} */
+
+void
+gsl_reenternamespace (GoomHash * nsinfo)
+{
+ currentGoomSL->currentNS++;
+ currentGoomSL->namespaces[currentGoomSL->currentNS] = nsinfo;
+}
+
+GoomHash *
+gsl_leavenamespace (void)
+{ /* {{{ */
+ currentGoomSL->currentNS--;
+ return currentGoomSL->namespaces[currentGoomSL->currentNS + 1];
+} /* }}} */
+
+GoomHash *
+gsl_find_namespace (const char *name)
+{ /* {{{ */
+ int i;
+
+ for (i = currentGoomSL->currentNS; i >= 0; --i) {
+ if (goom_hash_get (currentGoomSL->namespaces[i], name))
+ return currentGoomSL->namespaces[i];
+ }
+ return NULL;
+} /* }}} */
+
+void
+gsl_declare_task (const char *name)
+{ /* {{{ */
+ if (goom_hash_get (currentGoomSL->functions, name)) {
+ return;
+ } else {
+ ExternalFunctionStruct *gef =
+ (ExternalFunctionStruct *) malloc (sizeof (ExternalFunctionStruct));
+ gef->function = 0;
+ gef->vars = goom_hash_new ();
+ gef->is_extern = 0;
+ goom_hash_put_ptr (currentGoomSL->functions, name, (void *) gef);
+ }
+} /* }}} */
+
+void
+gsl_declare_external_task (const char *name)
+{ /* {{{ */
+ if (goom_hash_get (currentGoomSL->functions, name)) {
+ fprintf (stderr, "ERROR: Line %d, Duplicate declaration of %s\n",
+ currentGoomSL->num_lines, name);
+ return;
+ } else {
+ ExternalFunctionStruct *gef =
+ (ExternalFunctionStruct *) malloc (sizeof (ExternalFunctionStruct));
+ gef->function = 0;
+ gef->vars = goom_hash_new ();
+ gef->is_extern = 1;
+ goom_hash_put_ptr (currentGoomSL->functions, name, (void *) gef);
+ }
+} /* }}} */
+
+static void
+reset_scanner (GoomSL * gss)
+{ /* {{{ */
+ gss->num_lines = 0;
+ gss->instr = NULL;
+ iflow_clean (gss->iflow);
+
+ /* reset variables */
+ goom_hash_free (gss->vars);
+ gss->vars = goom_hash_new ();
+ gss->currentNS = 0;
+ gss->namespaces[0] = gss->vars;
+
+ goom_hash_free (gss->structIDS);
+ gss->structIDS = goom_hash_new ();
+
+ while (gss->nbStructID > 0) {
+ int i;
+
+ gss->nbStructID--;
+ for (i = 0; i < gss->gsl_struct[gss->nbStructID]->nbFields; ++i)
+ free (gss->gsl_struct[gss->nbStructID]->fields[i]);
+ free (gss->gsl_struct[gss->nbStructID]);
+ }
+
+ gss->compilationOK = 1;
+
+ goom_heap_delete (gss->data_heap);
+ gss->data_heap = goom_heap_new ();
+} /* }}} */
+
+static void
+calculate_labels (InstructionFlow * iflow)
+{ /* {{{ */
+ int i = 0;
+
+ while (i < iflow->number) {
+ Instruction *instr = iflow->instr[i];
+
+ if (instr->jump_label) {
+ HashValue *label = goom_hash_get (iflow->labels, instr->jump_label);
+
+ if (label) {
+ instr->data.udest.jump_offset = -instr->address + label->i;
+ } else {
+ fprintf (stderr, "ERROR: Line %d, Could not find label %s\n",
+ instr->line_number, instr->jump_label);
+ instr->id = INSTR_NOP;
+ instr->nop_label = 0;
+ exit (1);
+ }
+ }
+ ++i;
+ }
+} /* }}} */
+
+static int
+powerOfTwo (int i)
+{
+ int b;
+
+ for (b = 0; b < 31; b++)
+ if (i == (1 << b))
+ return b;
+ return 0;
+}
+
+/* Cree un flow d'instruction optimise */
+static void
+gsl_create_fast_iflow (void)
+{ /* {{{ */
+ int number = currentGoomSL->iflow->number;
+ int i;
+
+#ifdef USE_JITC_X86
+
+ /* pour compatibilite avec les MACROS servant a execution */
+ int ip = 0;
+ GoomSL *gsl = currentGoomSL;
+
+ JitcX86Env *jitc;
+
+ if (currentGoomSL->jitc != NULL)
+ jitc_x86_delete (currentGoomSL->jitc);
+ jitc = currentGoomSL->jitc = jitc_x86_env_new (0xffff);
+ currentGoomSL->jitc_func = jitc_prepare_func (jitc);
+
+#if 0
+#define SRC_STRUCT_ID instr[ip].data.usrc.var_int[-1]
+#define DEST_STRUCT_ID instr[ip].data.udest.var_int[-1]
+#define SRC_STRUCT_IBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i]
+#define SRC_STRUCT_FBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i]
+#define DEST_STRUCT_IBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i]
+#define DEST_STRUCT_FBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i]
+#define DEST_STRUCT_IBLOCK_VAR(i,j) \
+ ((int*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i].data))[j]
+#define DEST_STRUCT_FBLOCK_VAR(i,j) \
+ ((float*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i].data))[j]
+#define SRC_STRUCT_IBLOCK_VAR(i,j) \
+ ((int*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i].data))[j]
+#define SRC_STRUCT_FBLOCK_VAR(i,j) \
+ ((float*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i].data))[j]
+#define DEST_STRUCT_SIZE gsl->gsl_struct[DEST_STRUCT_ID]->size
+#endif
+
+ JITC_JUMP_LABEL (jitc, "__very_end__");
+ JITC_ADD_LABEL (jitc, "__very_start__");
+
+ for (i = 0; i < number; ++i) {
+ Instruction *instr = currentGoomSL->iflow->instr[i];
+
+ switch (instr->id) {
+ case INSTR_SETI_VAR_INTEGER:
+ jitc_add (jitc, "mov [$d], $d", instr->data.udest.var_int,
+ instr->data.usrc.value_int);
+ break;
+ case INSTR_SETI_VAR_VAR:
+ jitc_add (jitc, "mov eax, [$d]", instr->data.usrc.var_int);
+ jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
+ break;
+ /* SET.F */
+ case INSTR_SETF_VAR_FLOAT:
+ jitc_add (jitc, "mov [$d], $d", instr->data.udest.var_float,
+ *(int *) (&instr->data.usrc.value_float));
+ break;
+ case INSTR_SETF_VAR_VAR:
+ jitc_add (jitc, "mov eax, [$d]", instr->data.usrc.var_float);
+ jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_float);
+ break;
+ case INSTR_NOP:
+ if (instr->nop_label != 0)
+ JITC_ADD_LABEL (jitc, instr->nop_label);
+ break;
+ case INSTR_JUMP:
+ JITC_JUMP_LABEL (jitc, instr->jump_label);
+ break;
+ case INSTR_SETP_VAR_PTR:
+ jitc_add (jitc, "mov [$d], $d", instr->data.udest.var_ptr,
+ instr->data.usrc.value_ptr);
+ break;
+ case INSTR_SETP_VAR_VAR:
+ jitc_add (jitc, "mov eax, [$d]", instr->data.usrc.var_ptr);
+ jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_ptr);
+ break;
+ case INSTR_SUBI_VAR_INTEGER:
+ jitc_add (jitc, "add [$d], $d", instr->data.udest.var_int,
+ -instr->data.usrc.value_int);
+ break;
+ case INSTR_SUBI_VAR_VAR:
+ jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
+ jitc_add (jitc, "sub eax, [$d]", instr->data.usrc.var_int);
+ jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
+ break;
+ case INSTR_SUBF_VAR_FLOAT:
+ printf ("NOT IMPLEMENTED : %d\n", instr->id);
+ break;
+ case INSTR_SUBF_VAR_VAR:
+ printf ("NOT IMPLEMENTED : %d\n", instr->id);
+ break;
+ case INSTR_ISLOWERF_VAR_VAR:
+ printf ("NOT IMPLEMENTED : %d\n", instr->id);
+ break;
+ case INSTR_ISLOWERF_VAR_FLOAT:
+ printf ("NOT IMPLEMENTED : %d\n", instr->id);
+ break;
+ case INSTR_ISLOWERI_VAR_VAR:
+ jitc_add (jitc, "mov edx, [$d]", instr->data.udest.var_int);
+ jitc_add (jitc, "sub edx, [$d]", instr->data.usrc.var_int);
+ jitc_add (jitc, "shr edx, $d", 31);
+ break;
+ case INSTR_ISLOWERI_VAR_INTEGER:
+ jitc_add (jitc, "mov edx, [$d]", instr->data.udest.var_int);
+ jitc_add (jitc, "sub edx, $d", instr->data.usrc.value_int);
+ jitc_add (jitc, "shr edx, $d", 31);
+ break;
+ case INSTR_ADDI_VAR_INTEGER:
+ jitc_add (jitc, "add [$d], $d", instr->data.udest.var_int,
+ instr->data.usrc.value_int);
+ break;
+ case INSTR_ADDI_VAR_VAR:
+ jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
+ jitc_add (jitc, "add eax, [$d]", instr->data.usrc.var_int);
+ jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
+ break;
+ case INSTR_ADDF_VAR_FLOAT:
+ printf ("NOT IMPLEMENTED : %d\n", instr->id);
+ break;
+ case INSTR_ADDF_VAR_VAR:
+ printf ("NOT IMPLEMENTED : %d\n", instr->id);
+ break;
+ case INSTR_MULI_VAR_INTEGER:
+ if (instr->data.usrc.value_int != 1) {
+ int po2 = powerOfTwo (instr->data.usrc.value_int);
+
+ if (po2) {
+ /* performs (V / 2^n) by doing V >> n */
+ jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
+ jitc_add (jitc, "sal eax, $d", po2);
+ jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
+ } else {
+ jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
+ jitc_add (jitc, "imul eax, $d", instr->data.usrc.value_int);
+ jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
+ }
+ }
+ break;
+ case INSTR_MULI_VAR_VAR:
+ jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
+ jitc_add (jitc, "imul eax, [$d]", instr->data.usrc.var_int);
+ jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
+ break;
+ case INSTR_MULF_VAR_FLOAT:
+ printf ("NOT IMPLEMENTED : %d\n", instr->id);
+ break;
+ case INSTR_MULF_VAR_VAR:
+ printf ("NOT IMPLEMENTED : %d\n", instr->id);
+ break;
+ case INSTR_DIVI_VAR_INTEGER:
+ if ((instr->data.usrc.value_int != 1)
+ && (instr->data.usrc.value_int != 0)) {
+ int po2 = powerOfTwo (instr->data.usrc.value_int);
+
+ if (po2) {
+ /* performs (V / 2^n) by doing V >> n */
+ jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
+ jitc_add (jitc, "sar eax, $d", po2);
+ jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
+ } else {
+ /* performs (V/n) by doing (V*(32^2/n)) */
+ long coef;
+ double dcoef =
+ (double) 4294967296.0 / (double) instr->data.usrc.value_int;
+ if (dcoef < 0.0)
+ dcoef = -dcoef;
+ coef = (long) floor (dcoef);
+ dcoef -= floor (dcoef);
+ if (dcoef < 0.5)
+ coef += 1;
+
+ jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
+ jitc_add (jitc, "mov edx, $d", coef);
+ jitc_add (jitc, "imul edx");
+ if (instr->data.usrc.value_int < 0)
+ jitc_add (jitc, "neg edx");
+ jitc_add (jitc, "mov [$d], edx", instr->data.udest.var_int);
+ }
+ }
+ break;
+ case INSTR_DIVI_VAR_VAR:
+ jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
+ jitc_add (jitc, "cdq"); /* sign extend eax into edx */
+ jitc_add (jitc, "idiv [$d]", instr->data.usrc.var_int);
+ jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
+ break;
+ case INSTR_DIVF_VAR_FLOAT:
+ printf ("NOT IMPLEMENTED : %d\n", instr->id);
+ break;
+ case INSTR_DIVF_VAR_VAR:
+ printf ("NOT IMPLEMENTED : %d\n", instr->id);
+ break;
+ case INSTR_JZERO:
+ jitc_add (jitc, "cmp edx, $d", 0);
+ jitc_add (jitc, "je $s", instr->jump_label);
+ break;
+ case INSTR_ISEQUALP_VAR_VAR:
+ jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_ptr);
+ jitc_add (jitc, "mov edx, $d", 0);
+ jitc_add (jitc, "cmp eax, [$d]", instr->data.usrc.var_ptr);
+ jitc_add (jitc, "jne $d", 1);
+ jitc_add (jitc, "inc edx");
+ break;
+ case INSTR_ISEQUALP_VAR_PTR:
+ jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_ptr);
+ jitc_add (jitc, "mov edx, $d", 0);
+ jitc_add (jitc, "cmp eax, $d", instr->data.usrc.value_ptr);
+ jitc_add (jitc, "jne $d", 1);
+ jitc_add (jitc, "inc edx");
+ break;
+ case INSTR_ISEQUALI_VAR_VAR:
+ jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
+ jitc_add (jitc, "mov edx, $d", 0);
+ jitc_add (jitc, "cmp eax, [$d]", instr->data.usrc.var_int);
+ jitc_add (jitc, "jne $d", 1);
+ jitc_add (jitc, "inc edx");
+ break;
+ case INSTR_ISEQUALI_VAR_INTEGER:
+ jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
+ jitc_add (jitc, "mov edx, $d", 0);
+ jitc_add (jitc, "cmp eax, $d", instr->data.usrc.value_int);
+ jitc_add (jitc, "jne $d", 1);
+ jitc_add (jitc, "inc edx");
+ break;
+ case INSTR_ISEQUALF_VAR_VAR:
+ printf ("NOT IMPLEMENTED : %d\n", instr->id);
+ break;
+ case INSTR_ISEQUALF_VAR_FLOAT:
+ printf ("NOT IMPLEMENTED : %d\n", instr->id);
+ break;
+ case INSTR_CALL:
+ jitc_add (jitc, "call $s", instr->jump_label);
+ break;
+ case INSTR_RET:
+ jitc_add (jitc, "ret");
+ break;
+ case INSTR_EXT_CALL:
+ jitc_add (jitc, "mov eax, [$d]",
+ &(instr->data.udest.external_function->vars));
+ jitc_add (jitc, "push eax");
+ jitc_add (jitc, "mov edx, [$d]", &(currentGoomSL->vars));
+ jitc_add (jitc, "push edx");
+ jitc_add (jitc, "mov eax, [$d]", &(currentGoomSL));
+ jitc_add (jitc, "push eax");
+
+ jitc_add (jitc, "mov eax, [$d]",
+ &(instr->data.udest.external_function));
+ jitc_add (jitc, "mov eax, [eax]");
+ jitc_add (jitc, "call [eax]");
+ jitc_add (jitc, "add esp, $d", 12);
+ break;
+ case INSTR_NOT_VAR:
+ jitc_add (jitc, "mov eax, edx");
+ jitc_add (jitc, "mov edx, $d", 1);
+ jitc_add (jitc, "sub edx, eax");
+ break;
+ case INSTR_JNZERO:
+ jitc_add (jitc, "cmp edx, $d", 0);
+ jitc_add (jitc, "jne $s", instr->jump_label);
+ break;
+ case INSTR_SETS_VAR_VAR:
+ {
+ int loop = DEST_STRUCT_SIZE / sizeof (int);
+ int dst = (int) pDEST_VAR;
+ int src = (int) pSRC_VAR;
+
+ while (loop--) {
+ jitc_add (jitc, "mov eax, [$d]", src);
+ jitc_add (jitc, "mov [$d], eax", dst);
+ src += 4;
+ dst += 4;
+ }
+ }
+ break;
+ case INSTR_ISEQUALS_VAR_VAR:
+ break;
+ case INSTR_ADDS_VAR_VAR:
+ {
+ /* process integers */
+ int i = 0;
+
+ while (DEST_STRUCT_IBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_IBLOCK (i).size;
+
+ while (j--) { /* TODO interlace 2 */
+ jitc_add (jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR (i, j));
+ jitc_add (jitc, "add eax, [$d]", &SRC_STRUCT_IBLOCK_VAR (i, j));
+ jitc_add (jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR (i, j));
+ }
+ ++i;
+ }
+ /* process floats */
+ i = 0;
+ while (DEST_STRUCT_FBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_FBLOCK (i).size;
+
+ while (j--) {
+ /* DEST_STRUCT_FBLOCK_VAR(i,j) += SRC_STRUCT_FBLOCK_VAR(i,j); */
+ /* TODO */
+ }
+ ++i;
+ }
+ break;
+ }
+ case INSTR_SUBS_VAR_VAR:
+ {
+ /* process integers */
+ int i = 0;
+
+ while (DEST_STRUCT_IBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_IBLOCK (i).size;
+
+ while (j--) {
+ jitc_add (jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR (i, j));
+ jitc_add (jitc, "sub eax, [$d]", &SRC_STRUCT_IBLOCK_VAR (i, j));
+ jitc_add (jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR (i, j));
+ }
+ ++i;
+ }
+ break;
+ }
+ case INSTR_MULS_VAR_VAR:
+ {
+ /* process integers */
+ int i = 0;
+
+ while (DEST_STRUCT_IBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_IBLOCK (i).size;
+
+ while (j--) {
+ jitc_add (jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR (i, j));
+ jitc_add (jitc, "imul eax, [$d]", &SRC_STRUCT_IBLOCK_VAR (i, j));
+ jitc_add (jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR (i, j));
+ }
+ ++i;
+ }
+ break;
+ }
+ case INSTR_DIVS_VAR_VAR:
+ {
+ /* process integers */
+ int i = 0;
+
+ while (DEST_STRUCT_IBLOCK (i).size > 0) {
+ int j = DEST_STRUCT_IBLOCK (i).size;
+
+ while (j--) {
+ jitc_add (jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR (i, j));
+ jitc_add (jitc, "cdq");
+ jitc_add (jitc, "idiv [$d]", &SRC_STRUCT_IBLOCK_VAR (i, j));
+ jitc_add (jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR (i, j));
+ }
+ ++i;
+ }
+ break;
+ }
+ }
+ }
+
+ JITC_ADD_LABEL (jitc, "__very_end__");
+ jitc_add (jitc, "call $s", "__very_start__");
+ jitc_add (jitc, "mov eax, $d", 0);
+ jitc_validate_func (jitc);
+#else
+ InstructionFlow *iflow = currentGoomSL->iflow;
+ FastInstructionFlow *fastiflow =
+ (FastInstructionFlow *) malloc (sizeof (FastInstructionFlow));
+ fastiflow->mallocedInstr = calloc (number * 16, sizeof (FastInstruction));
+ /* fastiflow->instr = (FastInstruction*)(((int)fastiflow->mallocedInstr) + 16 - (((int)fastiflow->mallocedInstr)%16)); */
+ fastiflow->instr = (FastInstruction *) fastiflow->mallocedInstr;
+ fastiflow->number = number;
+ for (i = 0; i < number; ++i) {
+ fastiflow->instr[i].id = iflow->instr[i]->id;
+ fastiflow->instr[i].data = iflow->instr[i]->data;
+ fastiflow->instr[i].proto = iflow->instr[i];
+ }
+ currentGoomSL->fastiflow = fastiflow;
+#endif
+} /* }}} */
+
+void yy_scan_string (const char *str);
+void yyparse (void);
+
+GoomHash *
+gsl_globals (GoomSL * _this)
+{
+ return _this->vars;
+}
+
+
+/**
+ * Some native external functions
+ */
+static void
+ext_charAt (GoomSL * gsl, GoomHash * global, GoomHash * local)
+{
+ char *string = GSL_LOCAL_PTR (gsl, local, "value");
+ int index = GSL_LOCAL_INT (gsl, local, "index");
+
+ GSL_GLOBAL_INT (gsl, "charAt") = 0;
+ if (string == NULL) {
+ return;
+ }
+ if (index < strlen (string))
+ GSL_GLOBAL_INT (gsl, "charAt") = string[index];
+}
+
+static void
+ext_i2f (GoomSL * gsl, GoomHash * global, GoomHash * local)
+{
+ int i = GSL_LOCAL_INT (gsl, local, "value");
+
+ GSL_GLOBAL_FLOAT (gsl, "i2f") = i;
+}
+
+static void
+ext_f2i (GoomSL * gsl, GoomHash * global, GoomHash * local)
+{
+ float f = GSL_LOCAL_FLOAT (gsl, local, "value");
+
+ GSL_GLOBAL_INT (gsl, "f2i") = f;
+}
+
+/**
+ *
+ */
+void
+gsl_compile (GoomSL * _currentGoomSL, const char *script)
+{ /* {{{ */
+ char *script_and_externals;
+ static const char *sBinds =
+ "external <charAt: string value, int index> : int\n"
+ "external <f2i: float value> : int\n"
+ "external <i2f: int value> : float\n";
+
+#ifdef VERBOSE
+ printf ("\n=== Starting Compilation ===\n");
+#endif
+
+ script_and_externals = malloc (strlen (script) + strlen (sBinds) + 2);
+ strcpy (script_and_externals, sBinds);
+ strcat (script_and_externals, script);
+
+ /* 0- reset */
+ currentGoomSL = _currentGoomSL;
+ reset_scanner (currentGoomSL);
+
+ /* 1- create the syntaxic tree */
+ yy_scan_string (script_and_externals);
+ yyparse ();
+
+ /* 2- generate code */
+ gsl_commit_compilation ();
+
+ /* 3- resolve symbols */
+ calculate_labels (currentGoomSL->iflow);
+
+ /* 4- optimize code */
+ gsl_create_fast_iflow ();
+
+ /* 5- bind a few internal functions */
+ gsl_bind_function (currentGoomSL, "charAt", ext_charAt);
+ gsl_bind_function (currentGoomSL, "f2i", ext_f2i);
+ gsl_bind_function (currentGoomSL, "i2f", ext_i2f);
+ free (script_and_externals);
+
+#ifdef VERBOSE
+ printf ("=== Compilation done. # of lines: %d. # of instr: %d ===\n",
+ currentGoomSL->num_lines, currentGoomSL->iflow->number);
+#endif
+} /* }}} */
+
+void
+gsl_execute (GoomSL * scanner)
+{ /* {{{ */
+ if (scanner->compilationOK) {
+#if USE_JITC_X86
+ scanner->jitc_func ();
+#else
+ iflow_execute (scanner->fastiflow, scanner);
+#endif
+ }
+} /* }}} */
+
+GoomSL *
+gsl_new (void)
+{ /* {{{ */
+ GoomSL *gss = (GoomSL *) malloc (sizeof (GoomSL));
+
+ gss->iflow = iflow_new ();
+ gss->vars = goom_hash_new ();
+ gss->functions = goom_hash_new ();
+ gss->nbStructID = 0;
+ gss->structIDS = goom_hash_new ();
+ gss->gsl_struct_size = 32;
+ gss->gsl_struct =
+ (GSL_Struct **) malloc (gss->gsl_struct_size * sizeof (GSL_Struct *));
+ gss->currentNS = 0;
+ gss->namespaces[0] = gss->vars;
+ gss->data_heap = goom_heap_new ();
+
+ reset_scanner (gss);
+
+ gss->compilationOK = 0;
+ gss->nbPtr = 0;
+ gss->ptrArraySize = 256;
+ gss->ptrArray = (void **) malloc (gss->ptrArraySize * sizeof (void *));
+#ifdef USE_JITC_X86
+ gss->jitc = NULL;
+#endif
+ return gss;
+} /* }}} */
+
+void
+gsl_bind_function (GoomSL * gss, const char *fname,
+ GoomSL_ExternalFunction func)
+{ /* {{{ */
+ HashValue *val = goom_hash_get (gss->functions, fname);
+
+ if (val) {
+ ExternalFunctionStruct *gef = (ExternalFunctionStruct *) val->ptr;
+
+ gef->function = func;
+ } else
+ fprintf (stderr, "Unable to bind function %s\n", fname);
+} /* }}} */
+
+int
+gsl_is_compiled (GoomSL * gss)
+{ /* {{{ */
+ return gss->compilationOK;
+} /* }}} */
+
+void
+gsl_free (GoomSL * gss)
+{ /* {{{ */
+ iflow_free (gss->iflow);
+ free (gss->vars);
+ free (gss->functions);
+ free (gss);
+} /* }}} */
+
+
+static int gsl_nb_import;
+static char gsl_already_imported[256][256];
+
+char *
+gsl_init_buffer (const char *fname)
+{
+ char *fbuffer;
+
+ fbuffer = (char *) malloc (512);
+ fbuffer[0] = 0;
+ gsl_nb_import = 0;
+ if (fname)
+ gsl_append_file_to_buffer (fname, &fbuffer);
+ return fbuffer;
+}
+
+static char *
+gsl_read_file (const char *fname)
+{
+ FILE *f;
+ char *buffer;
+ int fsize;
+
+ f = fopen (fname, "rt");
+ if (!f) {
+ fprintf (stderr, "ERROR: Could not load file %s\n", fname);
+ exit (1);
+ }
+ fseek (f, 0, SEEK_END);
+ fsize = ftell (f);
+ rewind (f);
+ buffer = (char *) malloc (fsize + 512);
+ fread (buffer, 1, fsize, f);
+ fclose (f);
+ buffer[fsize] = 0;
+ return buffer;
+}
+
+void
+gsl_append_file_to_buffer (const char *fname, char **buffer)
+{
+ char *fbuffer;
+ int size, fsize, i = 0;
+ char reset_msg[256];
+
+ /* look if the file have not been already imported */
+ for (i = 0; i < gsl_nb_import; ++i) {
+ if (strcmp (gsl_already_imported[i], fname) == 0)
+ return;
+ }
+
+ /* add fname to the already imported files. */
+ strcpy (gsl_already_imported[gsl_nb_import++], fname);
+
+ /* load the file */
+ fbuffer = gsl_read_file (fname);
+ fsize = strlen (fbuffer);
+
+ /* look for #import */
+ while (fbuffer[i]) {
+ if ((fbuffer[i] == '#') && (fbuffer[i + 1] == 'i')) {
+ char impName[256];
+ int j;
+
+ while (fbuffer[i] && (fbuffer[i] != ' '))
+ i++;
+ i++;
+ j = 0;
+ while (fbuffer[i] && (fbuffer[i] != '\n'))
+ impName[j++] = fbuffer[i++];
+ impName[j++] = 0;
+ gsl_append_file_to_buffer (impName, buffer);
+ }
+ i++;
+ }
+
+ sprintf (reset_msg, "\n#FILE %s#\n#RST_LINE#\n", fname);
+ strcat (*buffer, reset_msg);
+ size = strlen (*buffer);
+ *buffer = (char *) realloc (*buffer, size + fsize + 256);
+ strcat ((*buffer) + size, fbuffer);
+ free (fbuffer);
+}
diff --git a/gst/goom/goomsl.h b/gst/goom/goomsl.h
new file mode 100644
index 00000000..b9f20d6c
--- /dev/null
+++ b/gst/goom/goomsl.h
@@ -0,0 +1,34 @@
+#ifndef _GOOMSL_H
+#define _GOOMSL_H
+
+#include "goomsl_hash.h"
+
+typedef struct _GoomSL GoomSL;
+typedef void (*GoomSL_ExternalFunction)(GoomSL *gsl, GoomHash *global_vars, GoomHash *local_vars);
+
+GoomSL*gsl_new(void);
+void gsl_free(GoomSL *gss);
+
+char *gsl_init_buffer(const char *file_name);
+void gsl_append_file_to_buffer(const char *file_name, char **buffer);
+
+void gsl_compile (GoomSL *scanner, const char *script);
+void gsl_execute (GoomSL *scanner);
+int gsl_is_compiled (GoomSL *gss);
+void gsl_bind_function(GoomSL *gss, const char *fname, GoomSL_ExternalFunction func);
+
+int gsl_malloc (GoomSL *_this, int size);
+void *gsl_get_ptr (GoomSL *_this, int id);
+void gsl_free_ptr(GoomSL *_this, int id);
+
+GoomHash *gsl_globals(GoomSL *_this);
+
+#define GSL_LOCAL_PTR(gsl,local,name) gsl_get_ptr(gsl, *(int*)goom_hash_get(local,name)->ptr)
+#define GSL_LOCAL_INT(gsl,local,name) (*(int*)goom_hash_get(local,name)->ptr)
+#define GSL_LOCAL_FLOAT(gsl,local,name) (*(float*)goom_hash_get(local,name)->ptr)
+
+#define GSL_GLOBAL_PTR(gsl,name) gsl_get_ptr(gsl, *(int*)goom_hash_get(gsl_globals(gsl),name)->ptr)
+#define GSL_GLOBAL_INT(gsl,name) (*(int*)goom_hash_get(gsl_globals(gsl),name)->ptr)
+#define GSL_GLOBAL_FLOAT(gsl,name) (*(float*)goom_hash_get(gsl_globals(gsl),name)->ptr)
+
+#endif
diff --git a/gst/goom/goomsl_hash.c b/gst/goom/goomsl_hash.c
new file mode 100644
index 00000000..3ce38a72
--- /dev/null
+++ b/gst/goom/goomsl_hash.c
@@ -0,0 +1,153 @@
+#include "goomsl_hash.h"
+#include <string.h>
+#include <stdlib.h>
+
+static GoomHashEntry *
+entry_new (const char *key, HashValue value)
+{
+
+ int len = strlen (key);
+ GoomHashEntry *entry = (GoomHashEntry *) malloc (sizeof (GoomHashEntry));
+
+ entry->key = (char *) malloc (len + 1);
+ memcpy (entry->key, key, len + 1);
+ entry->value = value;
+ entry->lower = NULL;
+ entry->upper = NULL;
+
+ return entry;
+}
+
+static void
+entry_free (GoomHashEntry * entry)
+{
+ if (entry != NULL) {
+ entry_free (entry->lower);
+ entry_free (entry->upper);
+ free (entry->key);
+ free (entry);
+ }
+}
+
+static void
+entry_put (GoomHashEntry * entry, const char *key, HashValue value)
+{
+ int cmp = strcmp (key, entry->key);
+
+ if (cmp == 0) {
+ entry->value = value;
+ } else if (cmp > 0) {
+ if (entry->upper == NULL)
+ entry->upper = entry_new (key, value);
+ else
+ entry_put (entry->upper, key, value);
+ } else {
+ if (entry->lower == NULL)
+ entry->lower = entry_new (key, value);
+ else
+ entry_put (entry->lower, key, value);
+ }
+}
+
+static HashValue *
+entry_get (GoomHashEntry * entry, const char *key)
+{
+
+ int cmp;
+
+ if (entry == NULL)
+ return NULL;
+ cmp = strcmp (key, entry->key);
+ if (cmp > 0)
+ return entry_get (entry->upper, key);
+ else if (cmp < 0)
+ return entry_get (entry->lower, key);
+ else
+ return &(entry->value);
+}
+
+GoomHash *
+goom_hash_new ()
+{
+ GoomHash *_this = (GoomHash *) malloc (sizeof (GoomHash));
+
+ _this->root = NULL;
+ _this->number_of_puts = 0;
+ return _this;
+}
+
+void
+goom_hash_free (GoomHash * _this)
+{
+ entry_free (_this->root);
+ free (_this);
+}
+
+void
+goom_hash_put (GoomHash * _this, const char *key, HashValue value)
+{
+ _this->number_of_puts += 1;
+ if (_this->root == NULL)
+ _this->root = entry_new (key, value);
+ else
+ entry_put (_this->root, key, value);
+}
+
+HashValue *
+goom_hash_get (GoomHash * _this, const char *key)
+{
+ if (_this == NULL)
+ return NULL;
+ return entry_get (_this->root, key);
+}
+
+void
+goom_hash_put_int (GoomHash * _this, const char *key, int i)
+{
+ HashValue value;
+
+ value.i = i;
+ goom_hash_put (_this, key, value);
+}
+
+void
+goom_hash_put_float (GoomHash * _this, const char *key, float f)
+{
+ HashValue value;
+
+ value.f = f;
+ goom_hash_put (_this, key, value);
+}
+
+void
+goom_hash_put_ptr (GoomHash * _this, const char *key, void *ptr)
+{
+ HashValue value;
+
+ value.ptr = ptr;
+ goom_hash_put (_this, key, value);
+}
+
+/* FOR EACH */
+
+static void
+_goom_hash_for_each (GoomHash * _this, GoomHashEntry * entry, GH_Func func)
+{
+ if (entry == NULL)
+ return;
+ func (_this, entry->key, &(entry->value));
+ _goom_hash_for_each (_this, entry->lower, func);
+ _goom_hash_for_each (_this, entry->upper, func);
+}
+
+void
+goom_hash_for_each (GoomHash * _this, GH_Func func)
+{
+ _goom_hash_for_each (_this, _this->root, func);
+}
+
+int
+goom_hash_number_of_puts (GoomHash * _this)
+{
+ return _this->number_of_puts;
+}
diff --git a/gst/goom/goomsl_hash.h b/gst/goom/goomsl_hash.h
new file mode 100644
index 00000000..26f45167
--- /dev/null
+++ b/gst/goom/goomsl_hash.h
@@ -0,0 +1,40 @@
+#ifndef _GOOMSL_HASH_H
+#define _GOOMSL_HASH_H
+
+typedef struct GOOM_HASH_ENTRY GoomHashEntry;
+typedef struct GOOM_HASH GoomHash;
+
+typedef union {
+ void *ptr;
+ int i;
+ float f;
+} HashValue;
+
+struct GOOM_HASH_ENTRY {
+ char *key;
+ HashValue value;
+ GoomHashEntry *lower;
+ GoomHashEntry *upper;
+};
+
+struct GOOM_HASH {
+ GoomHashEntry *root;
+ int number_of_puts;
+};
+
+GoomHash *goom_hash_new();
+void goom_hash_free(GoomHash *gh);
+
+void goom_hash_put(GoomHash *gh, const char *key, HashValue value);
+HashValue *goom_hash_get(GoomHash *gh, const char *key);
+
+void goom_hash_put_int (GoomHash *_this, const char *key, int i);
+void goom_hash_put_float(GoomHash *_this, const char *key, float f);
+void goom_hash_put_ptr (GoomHash *_this, const char *key, void *ptr);
+
+typedef void (*GH_Func)(GoomHash *caller, const char *key, HashValue *value);
+
+void goom_hash_for_each(GoomHash *_this, GH_Func func);
+int goom_hash_number_of_puts(GoomHash *_this);
+
+#endif /* _GOOM_HASH_H */
diff --git a/gst/goom/goomsl_heap.c b/gst/goom/goomsl_heap.c
new file mode 100644
index 00000000..4cbab5cc
--- /dev/null
+++ b/gst/goom/goomsl_heap.c
@@ -0,0 +1,126 @@
+#include "goomsl_heap.h"
+#include <stdlib.h>
+
+struct _GOOM_HEAP
+{
+ void **arrays;
+ int number_of_arrays;
+ int size_of_each_array;
+ int consumed_in_last_array;
+};
+
+/* Constructors / Destructor */
+GoomHeap *
+goom_heap_new (void)
+{
+ return goom_heap_new_with_granularity (4096);
+}
+
+GoomHeap *
+goom_heap_new_with_granularity (int granularity)
+{
+ GoomHeap *_this;
+
+ _this = (GoomHeap *) malloc (sizeof (GoomHeap));
+ _this->number_of_arrays = 0;
+ _this->size_of_each_array = granularity;
+ _this->consumed_in_last_array = 0;
+ _this->arrays = (void **) malloc (sizeof (void *));
+ return _this;
+}
+
+void
+goom_heap_delete (GoomHeap * _this)
+{
+ int i;
+
+ for (i = 0; i < _this->number_of_arrays; ++i) {
+ free (_this->arrays[i]);
+ }
+ free (_this->arrays);
+ free (_this);
+}
+
+static void
+align_it (GoomHeap * _this, int alignment)
+{
+ if ((alignment > 1) && (_this->number_of_arrays > 0)) {
+ void *last_array = _this->arrays[_this->number_of_arrays - 1];
+ int last_address = (int) last_array + _this->consumed_in_last_array;
+ int decal = (last_address % alignment);
+
+ if (decal != 0) {
+ _this->consumed_in_last_array += alignment - decal;
+ }
+ }
+}
+
+void *
+goom_heap_malloc_with_alignment_prefixed (GoomHeap * _this, int nb_bytes,
+ int alignment, int prefix_bytes)
+{
+ void *retval = NULL;
+
+ /* d'abord on gere les problemes d'alignement */
+ _this->consumed_in_last_array += prefix_bytes;
+ align_it (_this, alignment);
+
+ /* ensuite on verifie que la quantite de memoire demandee tient dans le buffer */
+ if ((_this->consumed_in_last_array + nb_bytes >= _this->size_of_each_array)
+ || (_this->number_of_arrays == 0)) {
+
+ if (prefix_bytes + nb_bytes + alignment >= _this->size_of_each_array) {
+
+ /* Si la zone demandee est plus grosse que la granularitee */
+ /* On alloue un buffer plus gros que les autres */
+ _this->arrays =
+ (void **) realloc (_this->arrays,
+ sizeof (void *) * (_this->number_of_arrays + 2));
+
+ _this->number_of_arrays += 1;
+ _this->consumed_in_last_array = prefix_bytes;
+
+ _this->arrays[_this->number_of_arrays - 1] =
+ malloc (prefix_bytes + nb_bytes + alignment);
+ align_it (_this, alignment);
+ retval =
+ (void *) ((char *) _this->arrays[_this->number_of_arrays - 1] +
+ _this->consumed_in_last_array);
+
+ /* puis on repart sur un nouveau buffer vide */
+ _this->number_of_arrays += 1;
+ _this->consumed_in_last_array = 0;
+ _this->arrays[_this->number_of_arrays - 1] =
+ malloc (_this->size_of_each_array);
+ return retval;
+ } else {
+ _this->number_of_arrays += 1;
+ _this->consumed_in_last_array = prefix_bytes;
+ _this->arrays =
+ (void **) realloc (_this->arrays,
+ sizeof (void *) * _this->number_of_arrays);
+
+ _this->arrays[_this->number_of_arrays - 1] =
+ malloc (_this->size_of_each_array);
+ align_it (_this, alignment);
+ }
+ }
+ retval =
+ (void *) ((char *) _this->arrays[_this->number_of_arrays - 1] +
+ _this->consumed_in_last_array);
+ _this->consumed_in_last_array += nb_bytes;
+ return retval;
+}
+
+void *
+goom_heap_malloc_with_alignment (GoomHeap * _this, int nb_bytes, int alignment)
+{
+ return goom_heap_malloc_with_alignment_prefixed (_this, nb_bytes, alignment,
+ 0);
+}
+
+void *
+goom_heap_malloc (GoomHeap * _this, int nb_bytes)
+{
+ return goom_heap_malloc_with_alignment (_this, nb_bytes, 1);
+}
diff --git a/gst/goom/goomsl_heap.h b/gst/goom/goomsl_heap.h
new file mode 100644
index 00000000..a22bac69
--- /dev/null
+++ b/gst/goom/goomsl_heap.h
@@ -0,0 +1,29 @@
+#ifndef GOOMSL_HEAP
+#define GOOMSL_HEAP
+
+/**
+ * Resizable Array that guarranty that resizes don't change address of
+ * the stored datas.
+ *
+ * This is implemented as an array of arrays... granularity is the size
+ * of each arrays.
+ */
+
+typedef struct _GOOM_HEAP GoomHeap;
+
+/* Constructors / Destructor */
+GoomHeap *goom_heap_new(void);
+GoomHeap *goom_heap_new_with_granularity(int granularity);
+void goom_heap_delete(GoomHeap *_this);
+
+/* This method behaves like malloc. */
+void *goom_heap_malloc(GoomHeap *_this, int nb_bytes);
+/* This adds an alignment constraint. */
+void *goom_heap_malloc_with_alignment(GoomHeap *_this, int nb_bytes, int alignment);
+
+/* Returns a pointeur on the bytes... prefix is before */
+void *goom_heap_malloc_with_alignment_prefixed(GoomHeap *_this, int nb_bytes,
+ int alignment, int prefix_bytes);
+
+#endif
+
diff --git a/gst/goom/goomsl_lex.l b/gst/goom/goomsl_lex.l
new file mode 100644
index 00000000..3079c022
--- /dev/null
+++ b/gst/goom/goomsl_lex.l
@@ -0,0 +1,94 @@
+%{
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "goomsl.h"
+#include "goomsl_private.h"
+#include "goomsl_yacc.h"
+void yyerror(char *);
+void yyparse(void);
+
+GoomSL *currentGoomSL;
+static int string_size;
+static char string[1024];
+%}
+
+DIGIT [0-9]
+XDIGIT [0-9a-f]
+ID [a-zA-Z_@&][a-zA-Z0-9_\.]*
+
+%S C_COMMENT
+%S LINE_COMMENT
+%S STRING
+
+%%
+
+<LINE_COMMENT,C_COMMENT,INITIAL>^[ \t]*\n { ++currentGoomSL->num_lines; /* Ignore empty lines */ }
+<LINE_COMMENT,C_COMMENT,INITIAL>^[ \t]*"//"[^\n]*\n { ++currentGoomSL->num_lines; /* Ignore empty lines */ }
+
+<LINE_COMMENT>\n { ++currentGoomSL->num_lines; yylval.charValue=*yytext; BEGIN INITIAL; return '\n'; }
+<INITIAL>\n { ++currentGoomSL->num_lines; yylval.charValue=*yytext; return '\n'; }
+
+<C_COMMENT>"*/" { BEGIN INITIAL; }
+<C_COMMENT>\n { ++currentGoomSL->num_lines; }
+<C_COMMENT,LINE_COMMENT>. { /* eat up comment */ }
+
+<INITIAL>"#RST_LINE#" { currentGoomSL->num_lines = 0; }
+<INITIAL>"#FILE ".*"#" { currentGoomSL->num_lines = 0; printf("%s\n", yytext); }
+<INITIAL>"#"[^\n]* { /* ignore preprocessor lines */ }
+
+<INITIAL>"/*" { BEGIN C_COMMENT; }
+<INITIAL>"//" { BEGIN LINE_COMMENT; }
+<INITIAL>\" { BEGIN STRING; string_size=0; }
+
+<STRING>"\\n" { string[string_size++] = '\n'; }
+<STRING>"\\\"" { string[string_size++] = '\"'; }
+<STRING>\" { /* fin de la chaine: on cree le pointeur qui va bien */
+ unsigned int tmp;
+ BEGIN INITIAL;
+ string[string_size]=0;
+ tmp = gsl_malloc(currentGoomSL, string_size+1);
+ strcpy((char*)currentGoomSL->ptrArray[tmp],string);
+ sprintf(yylval.strValue, "0x%08x", tmp);
+ return LTYPE_PTR;
+ }
+<STRING>. { string[string_size++] = *yytext; }
+
+<INITIAL>"float" { return FLOAT_TK; }
+<INITIAL>"int" { return INT_TK; }
+<INITIAL>"boolean" { return INT_TK; }
+<INITIAL>"ptr" { return PTR_TK; }
+<INITIAL>"string" { return PTR_TK; }
+<INITIAL>"declare" { return DECLARE; }
+<INITIAL>"external" { return EXTERNAL; }
+<INITIAL>"struct" { return STRUCT; }
+<INITIAL>"not" { return NOT; }
+<INITIAL>"while" { return WHILE; }
+<INITIAL>"do" { return DO; }
+<INITIAL>"for" { return FOR; }
+<INITIAL>"in" { return IN; }
+<INITIAL>"true" { strncpy(yylval.strValue, "1", 2047); return LTYPE_INTEGER; }
+<INITIAL>"false" { strncpy(yylval.strValue, "0", 2047); return LTYPE_INTEGER; }
+<INITIAL>{ID} { strncpy(yylval.strValue, yytext, 2047); return LTYPE_VAR; }
+<INITIAL>{DIGIT}+ { strncpy(yylval.strValue, yytext, 2047); return LTYPE_INTEGER; }
+<INITIAL>\'.\' { sprintf(yylval.strValue, "%d", (int)yytext[1]); return LTYPE_INTEGER; }
+<INITIAL>"0x"{XDIGIT}+ { strncpy(yylval.strValue, yytext, 2047); return LTYPE_INTEGER; }
+<INITIAL>{DIGIT}+"."{DIGIT}* { strncpy(yylval.strValue, yytext, 2047); return LTYPE_FLOAT; }
+<INITIAL>{DIGIT}+"%" { sprintf(yylval.strValue, "%3.2f", atof(yytext)/100.0f); return LTYPE_FLOAT; }
+<INITIAL>"+=" { return PLUS_EQ; }
+<INITIAL>"*=" { return MUL_EQ; }
+<INITIAL>"-=" { return SUB_EQ; }
+<INITIAL>"/=" { return DIV_EQ; }
+<INITIAL>"<=" { return LOW_EQ; }
+<INITIAL>">=" { return SUP_EQ; }
+<INITIAL>"!=" { return NOT_EQ; }
+<INITIAL>"<>" { return NOT_EQ; }
+<INITIAL>[ \t]+ /* eat up whitespace */
+<INITIAL>. { yylval.charValue = *yytext; return *yytext; }
+
+%%
+
+
+int yywrap(void) { return 1; yyunput(0,0); }
+
diff --git a/gst/goom/goomsl_private.h b/gst/goom/goomsl_private.h
new file mode 100644
index 00000000..8be15157
--- /dev/null
+++ b/gst/goom/goomsl_private.h
@@ -0,0 +1,251 @@
+#ifndef _GSL_PRIVATE_H
+#define _GSL_PRIVATE_H
+
+/* -- internal use -- */
+
+#include "goomsl.h"
+
+#ifdef USE_JITC_X86
+#include "jitc_x86.h"
+#endif
+
+#include "goomsl_heap.h"
+
+/* {{{ type of nodes */
+#define EMPTY_NODE 0
+#define CONST_INT_NODE 1
+#define CONST_FLOAT_NODE 2
+#define CONST_PTR_NODE 3
+#define VAR_NODE 4
+#define PARAM_NODE 5
+#define READ_PARAM_NODE 6
+#define OPR_NODE 7
+/* }}} */
+/* {{{ type of operations */
+#define OPR_SET 1
+#define OPR_IF 2
+#define OPR_WHILE 3
+#define OPR_BLOCK 4
+#define OPR_ADD 5
+#define OPR_MUL 6
+#define OPR_EQU 7
+#define OPR_NOT 8
+#define OPR_LOW 9
+#define OPR_DIV 10
+#define OPR_SUB 11
+#define OPR_FUNC_INTRO 12
+#define OPR_FUNC_OUTRO 13
+#define OPR_CALL 14
+#define OPR_EXT_CALL 15
+#define OPR_PLUS_EQ 16
+#define OPR_SUB_EQ 17
+#define OPR_MUL_EQ 18
+#define OPR_DIV_EQ 19
+#define OPR_CALL_EXPR 20
+#define OPR_AFFECT_LIST 21
+#define OPR_FOREACH 22
+#define OPR_VAR_LIST 23
+
+/* }}} */
+
+typedef struct _ConstIntNodeType { /* {{{ */
+ int val;
+} ConstIntNodeType; /* }}} */
+typedef struct _ConstFloatNodeType { /* {{{ */
+ float val;
+} ConstFloatNodeType; /* }}} */
+typedef struct _ConstPtrNodeType { /* {{{ */
+ int id;
+} ConstPtrNodeType; /* }}} */
+typedef struct _OprNodeType { /* {{{ */
+ int type;
+ int nbOp;
+ struct _NODE_TYPE *op[3]; /* maximal number of operand needed */
+ struct _NODE_TYPE *next;
+} OprNodeType; /* }}} */
+typedef struct _NODE_TYPE { /* {{{ */
+ int type;
+ char *str;
+ GoomHash *vnamespace;
+ int line_number;
+ union {
+ ConstIntNodeType constInt;
+ ConstFloatNodeType constFloat;
+ ConstPtrNodeType constPtr;
+ OprNodeType opr;
+ } unode;
+} NodeType; /* }}} */
+typedef struct _INSTRUCTION_DATA { /* {{{ */
+
+ union {
+ void *var;
+ int *var_int;
+ int *var_ptr;
+ float *var_float;
+ int jump_offset;
+ struct _ExternalFunctionStruct *external_function;
+ } udest;
+
+ union {
+ void *var;
+ int *var_int;
+ int *var_ptr;
+ float *var_float;
+ int value_int;
+ int value_ptr;
+ float value_float;
+ } usrc;
+} InstructionData;
+/* }}} */
+typedef struct _INSTRUCTION { /* {{{ */
+
+ int id;
+ InstructionData data;
+ GoomSL *parent;
+ const char *name; /* name of the instruction */
+
+ char **params; /* parametres de l'instruction */
+ GoomHash **vnamespace;
+ int *types; /* type des parametres de l'instruction */
+ int cur_param;
+ int nb_param;
+
+ int address;
+ char *jump_label;
+ char *nop_label;
+
+ int line_number;
+
+} Instruction;
+/* }}} */
+typedef struct _INSTRUCTION_FLOW { /* {{{ */
+
+ Instruction **instr;
+ int number;
+ int tabsize;
+ GoomHash *labels;
+} InstructionFlow;
+/* }}} */
+typedef struct _FAST_INSTRUCTION { /* {{{ */
+ int id;
+ InstructionData data;
+ Instruction *proto;
+} FastInstruction;
+/* }}} */
+typedef struct _FastInstructionFlow { /* {{{ */
+ int number;
+ FastInstruction *instr;
+ void *mallocedInstr;
+} FastInstructionFlow;
+/* }}} */
+typedef struct _ExternalFunctionStruct { /* {{{ */
+ GoomSL_ExternalFunction function;
+ GoomHash *vars;
+ int is_extern;
+} ExternalFunctionStruct;
+/* }}} */
+typedef struct _Block {
+ int data;
+ int size;
+} Block;
+typedef struct _GSL_StructField { /* {{{ */
+ int type;
+ char name[256];
+ int offsetInStruct; /* Where this field is stored... */
+} GSL_StructField;
+ /* }}} */
+typedef struct _GSL_Struct { /* {{{ */
+ int nbFields;
+ GSL_StructField *fields[64];
+ int size;
+ Block iBlock[64];
+ Block fBlock[64];
+} GSL_Struct;
+ /* }}} */
+struct _GoomSL { /* {{{ */
+ int num_lines;
+ Instruction *instr; /* instruction en cours de construction */
+
+ InstructionFlow *iflow; /* flow d'instruction 'normal' */
+ FastInstructionFlow *fastiflow; /* flow d'instruction optimise */
+
+ GoomHash *vars; /* table de variables */
+ int currentNS;
+ GoomHash *namespaces[16];
+
+ GoomHash *functions; /* table des fonctions externes */
+
+ GoomHeap *data_heap; /* GSL Heap-like memory space */
+
+ int nbStructID;
+ GoomHash *structIDS;
+ GSL_Struct **gsl_struct;
+ int gsl_struct_size;
+
+ int nbPtr;
+ int ptrArraySize;
+ void **ptrArray;
+
+ int compilationOK;
+#ifdef USE_JITC_X86
+ JitcX86Env *jitc;
+ JitcFunc jitc_func;
+#endif
+}; /* }}} */
+
+extern GoomSL *currentGoomSL;
+
+Instruction *gsl_instr_init(GoomSL *parent, const char *name, int id, int nb_param, int line_number);
+void gsl_instr_add_param(Instruction *_this, char *param, int type);
+void gsl_instr_set_namespace(Instruction *_this, GoomHash *ns);
+
+void gsl_declare_task(const char *name);
+void gsl_declare_external_task(const char *name);
+
+int gsl_type_of_var(GoomHash *namespace, const char *name);
+
+void gsl_enternamespace(const char *name);
+void gsl_reenternamespace(GoomHash *ns);
+GoomHash *gsl_leavenamespace(void);
+GoomHash *gsl_find_namespace(const char *name);
+
+void gsl_commit_compilation(void);
+
+/* #define TYPE_PARAM 1 */
+
+#define FIRST_RESERVED 0x80000
+
+#define TYPE_INTEGER 0x90001
+#define TYPE_FLOAT 0x90002
+#define TYPE_VAR 0x90003
+#define TYPE_PTR 0x90004
+#define TYPE_LABEL 0x90005
+
+#define TYPE_OP_EQUAL 6
+#define TYPE_IVAR 0xa0001
+#define TYPE_FVAR 0xa0002
+#define TYPE_PVAR 0xa0003
+#define TYPE_SVAR 0xa0004
+
+#define INSTR_JUMP 6
+#define INSTR_JZERO 29
+#define INSTR_CALL 36
+#define INSTR_RET 37
+#define INSTR_EXT_CALL 38
+#define INSTR_JNZERO 40
+
+#define INSTR_SET 0x80001
+#define INSTR_INT 0x80002
+#define INSTR_FLOAT 0x80003
+#define INSTR_PTR 0x80004
+#define INSTR_LABEL 0x80005
+#define INSTR_ISLOWER 0x80006
+#define INSTR_ADD 0x80007
+#define INSTR_MUL 0x80008
+#define INSTR_DIV 0x80009
+#define INSTR_SUB 0x80010
+#define INSTR_ISEQUAL 0x80011
+#define INSTR_NOT 0x80012
+
+
+#endif
diff --git a/gst/goom/goomsl_yacc.y b/gst/goom/goomsl_yacc.y
new file mode 100644
index 00000000..c424a50a
--- /dev/null
+++ b/gst/goom/goomsl_yacc.y
@@ -0,0 +1,1405 @@
+/**
+ * copyright 2004, Jean-Christophe Hoelt <jeko@ios-software.com>
+ *
+ * This program is released under the terms of the GNU Lesser General Public Licence.
+ */
+%{
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "goomsl.h"
+ #include "goomsl_private.h"
+
+#define STRUCT_ALIGNMENT 16
+/* #define VERBOSE */
+
+ int yylex(void);
+ void yyerror(char *);
+ extern GoomSL *currentGoomSL;
+
+ static NodeType *nodeNew(const char *str, int type, int line_number);
+ static NodeType *nodeClone(NodeType *node);
+ static void nodeFreeInternals(NodeType *node);
+ static void nodeFree(NodeType *node);
+
+ static void commit_node(NodeType *node, int releaseIfTemp);
+ static void precommit_node(NodeType *node);
+
+ static NodeType *new_constInt(const char *str, int line_number);
+ static NodeType *new_constFloat(const char *str, int line_number);
+ static NodeType *new_constPtr(const char *str, int line_number);
+ static NodeType *new_var(const char *str, int line_number);
+ static NodeType *new_nop(const char *str);
+ static NodeType *new_op(const char *str, int type, int nbOp);
+
+ static int allocateLabel();
+ static int allocateTemp();
+ static void releaseTemp(int n);
+ static void releaseAllTemps();
+
+ static int is_tmp_expr(NodeType *node) {
+ if (node->str) {
+ return (!strncmp(node->str,"_i_tmp_",7))
+ || (!strncmp(node->str,"_f_tmp_",7))
+ || (!strncmp(node->str,"_p_tmp",7));
+ }
+ return 0;
+ }
+ /* pre: is_tmp_expr(node); */
+ static int get_tmp_id(NodeType *node) { return atoi((node->str)+5); }
+
+ static int is_commutative_expr(int itype)
+ { /* {{{ */
+ return (itype == INSTR_ADD)
+ || (itype == INSTR_MUL)
+ || (itype == INSTR_ISEQUAL);
+ } /* }}} */
+
+ static void GSL_PUT_LABEL(char *name, int line_number)
+ { /* {{{ */
+#ifdef VERBOSE
+ printf("label %s\n", name);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "label", INSTR_LABEL, 1, line_number);
+ gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL);
+ } /* }}} */
+ static void GSL_PUT_JUMP(char *name, int line_number)
+ { /* {{{ */
+#ifdef VERBOSE
+ printf("jump %s\n", name);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "jump", INSTR_JUMP, 1, line_number);
+ gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL);
+ } /* }}} */
+
+ static void GSL_PUT_JXXX(char *name, char *iname, int instr_id, int line_number)
+ { /* {{{ */
+#ifdef VERBOSE
+ printf("%s %s\n", iname, name);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, iname, instr_id, 1, line_number);
+ gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL);
+ } /* }}} */
+ static void GSL_PUT_JZERO(char *name,int line_number)
+ { /* {{{ */
+ GSL_PUT_JXXX(name,"jzero.i",INSTR_JZERO,line_number);
+ } /* }}} */
+ static void GSL_PUT_JNZERO(char *name, int line_number)
+ { /* {{{ */
+ GSL_PUT_JXXX(name,"jnzero.i",INSTR_JNZERO,line_number);
+ } /* }}} */
+
+ /* Structures Management */
+
+#define ALIGN_ADDR(_addr,_align) {\
+ if (_align>1) {\
+ int _dec = (_addr%_align);\
+ if (_dec != 0) _addr += _align - _dec;\
+ }}
+
+ /* */
+ void gsl_prepare_struct(GSL_Struct *s, int s_align, int i_align, int f_align)
+ {
+ int i;
+ int consumed = 0;
+ int iblk=0, fblk=0;
+
+ s->iBlock[0].size = 0;
+ s->iBlock[0].data = 0;
+ s->fBlock[0].size = 0;
+ s->fBlock[0].data = 0;
+
+ /* Prepare sub-struct and calculate space needed for their storage */
+ for (i = 0; i < s->nbFields; ++i)
+ {
+ if (s->fields[i]->type < FIRST_RESERVED)
+ {
+ int j=0;
+ GSL_Struct *substruct = currentGoomSL->gsl_struct[s->fields[i]->type];
+ consumed += sizeof(int); /* stocke le prefix */
+ ALIGN_ADDR(consumed, s_align);
+ s->fields[i]->offsetInStruct = consumed;
+ gsl_prepare_struct(substruct, s_align, i_align, f_align);
+ for(j=0;substruct->iBlock[j].size>0;++j) {
+ s->iBlock[iblk].data = consumed + substruct->iBlock[j].data;
+ s->iBlock[iblk].size = substruct->iBlock[j].size;
+ iblk++;
+ }
+ for(j=0;substruct->fBlock[j].size>0;++j) {
+ s->fBlock[fblk].data = consumed + substruct->fBlock[j].data;
+ s->fBlock[fblk].size = substruct->fBlock[j].size;
+ fblk++;
+ }
+ consumed += substruct->size;
+ }
+ }
+
+ /* Then prepare integers */
+ ALIGN_ADDR(consumed, i_align);
+ for (i = 0; i < s->nbFields; ++i)
+ {
+ if (s->fields[i]->type == INSTR_INT)
+ {
+ if (s->iBlock[iblk].size == 0) {
+ s->iBlock[iblk].size = 1;
+ s->iBlock[iblk].data = consumed;
+ } else {
+ s->iBlock[iblk].size += 1;
+ }
+ s->fields[i]->offsetInStruct = consumed;
+ consumed += sizeof(int);
+ }
+ }
+
+ iblk++;
+ s->iBlock[iblk].size = 0;
+ s->iBlock[iblk].data = 0;
+
+ /* Then prepare floats */
+ ALIGN_ADDR(consumed, f_align);
+ for (i = 0; i < s->nbFields; ++i)
+ {
+ if (s->fields[i]->type == INSTR_FLOAT)
+ {
+ if (s->fBlock[fblk].size == 0) {
+ s->fBlock[fblk].size = 1;
+ s->fBlock[fblk].data = consumed;
+ } else {
+ s->fBlock[fblk].size += 1;
+ }
+ s->fields[i]->offsetInStruct = consumed;
+ consumed += sizeof(int);
+ }
+ }
+
+ fblk++;
+ s->fBlock[fblk].size = 0;
+ s->fBlock[fblk].data = 0;
+
+ /* Finally prepare pointers */
+ ALIGN_ADDR(consumed, i_align);
+ for (i = 0; i < s->nbFields; ++i)
+ {
+ if (s->fields[i]->type == INSTR_PTR)
+ {
+ s->fields[i]->offsetInStruct = consumed;
+ consumed += sizeof(int);
+ }
+ }
+ s->size = consumed;
+ }
+
+ /* Returns the ID of a struct from its name */
+ int gsl_get_struct_id(const char *name) /* {{{ */
+ {
+ HashValue *ret = goom_hash_get(currentGoomSL->structIDS, name);
+ if (ret != NULL) return ret->i;
+ return -1;
+ } /* }}} */
+
+ /* Adds the definition of a struct */
+ void gsl_add_struct(const char *name, GSL_Struct *gsl_struct) /* {{{ */
+ {
+ /* Prepare the struct: ie calculate internal storage format */
+ gsl_prepare_struct(gsl_struct, STRUCT_ALIGNMENT, STRUCT_ALIGNMENT, STRUCT_ALIGNMENT);
+
+ /* If the struct does not already exists */
+ if (gsl_get_struct_id(name) < 0)
+ {
+ /* adds it */
+ int id = currentGoomSL->nbStructID++;
+ goom_hash_put_int(currentGoomSL->structIDS, name, id);
+ if (currentGoomSL->gsl_struct_size <= id) {
+ currentGoomSL->gsl_struct_size *= 2;
+ currentGoomSL->gsl_struct = (GSL_Struct**)realloc(currentGoomSL->gsl_struct,
+ sizeof(GSL_Struct*) * currentGoomSL->gsl_struct_size);
+ }
+ currentGoomSL->gsl_struct[id] = gsl_struct;
+ }
+ } /* }}} */
+
+ /* Creates a field for a struct */
+ GSL_StructField *gsl_new_struct_field(const char *name, int type)
+ {
+ GSL_StructField *field = (GSL_StructField*)malloc(sizeof(GSL_StructField));
+ strcpy(field->name, name);
+ field->type = type;
+ return field;
+ }
+
+ /* Create as field for a struct which will be a struct itself */
+ GSL_StructField *gsl_new_struct_field_struct(const char *name, const char *type)
+ {
+ GSL_StructField *field = gsl_new_struct_field(name, gsl_get_struct_id(type));
+ if (field->type < 0) {
+ fprintf(stderr, "ERROR: Line %d, Unknown structure: '%s'\n",
+ currentGoomSL->num_lines, type);
+ exit(1);
+ }
+ return field;
+ }
+
+ /* Creates a Struct */
+ GSL_Struct *gsl_new_struct(GSL_StructField *field)
+ {
+ GSL_Struct *s = (GSL_Struct*)malloc(sizeof(GSL_Struct));
+ s->nbFields = 1;
+ s->fields[0] = field;
+ return s;
+ }
+
+ /* Adds a field to a struct */
+ void gsl_add_struct_field(GSL_Struct *s, GSL_StructField *field)
+ {
+ s->fields[s->nbFields++] = field;
+ }
+
+ int gsl_type_of_var(GoomHash *ns, const char *name)
+ {
+ char type_of[256];
+ HashValue *hv;
+ sprintf(type_of, "__type_of_%s", name);
+ hv = goom_hash_get(ns, type_of);
+ if (hv != NULL)
+ return hv->i;
+ fprintf(stderr, "ERROR: Unknown variable type: '%s'\n", name);
+ return -1;
+ }
+
+ static void gsl_declare_var(GoomHash *ns, const char *name, int type, void *space)
+ {
+ char type_of[256];
+ if (name[0] == '@') { ns = currentGoomSL->vars; }
+
+ if (space == NULL) {
+ switch (type) {
+ case INSTR_INT:
+ case INSTR_FLOAT:
+ case INSTR_PTR:
+ space = goom_heap_malloc_with_alignment(currentGoomSL->data_heap,
+ sizeof(int), sizeof(int));
+ break;
+ case -1:
+ fprintf(stderr, "What the fuck!\n");
+ exit(1);
+ default: /* On a un struct_id */
+ space = goom_heap_malloc_with_alignment_prefixed(currentGoomSL->data_heap,
+ currentGoomSL->gsl_struct[type]->size, STRUCT_ALIGNMENT, sizeof(int));
+ }
+ }
+ goom_hash_put_ptr(ns, name, (void*)space);
+ sprintf(type_of, "__type_of_%s", name);
+ goom_hash_put_int(ns, type_of, type);
+
+ /* Ensuite le hack: on ajoute les champs en tant que variables. */
+ if (type < FIRST_RESERVED)
+ {
+ int i;
+ GSL_Struct *gsl_struct = currentGoomSL->gsl_struct[type];
+ ((int*)space)[-1] = type; /* stockage du type dans le prefixe de structure */
+ for (i = 0; i < gsl_struct->nbFields; ++i)
+ {
+ char full_name[256];
+ char *cspace = (char*)space + gsl_struct->fields[i]->offsetInStruct;
+ sprintf(full_name, "%s.%s", name, gsl_struct->fields[i]->name);
+ gsl_declare_var(ns, full_name, gsl_struct->fields[i]->type, cspace);
+ }
+ }
+ }
+
+ /* Declare a variable which will be a struct */
+ static void gsl_struct_decl(GoomHash *namespace, const char *struct_name, const char *name)
+ {
+ int struct_id = gsl_get_struct_id(struct_name);
+ gsl_declare_var(namespace, name, struct_id, NULL);
+ }
+
+ static void gsl_float_decl_global(const char *name)
+ {
+ gsl_declare_var(currentGoomSL->vars, name, INSTR_FLOAT, NULL);
+ }
+ static void gsl_int_decl_global(const char *name)
+ {
+ gsl_declare_var(currentGoomSL->vars, name, INSTR_INT, NULL);
+ }
+ static void gsl_ptr_decl_global(const char *name)
+ {
+ gsl_declare_var(currentGoomSL->vars, name, INSTR_PTR, NULL);
+ }
+ static void gsl_struct_decl_global_from_id(const char *name, int id)
+ {
+ gsl_declare_var(currentGoomSL->vars, name, id, NULL);
+ }
+
+ /* FLOAT */
+ static void gsl_float_decl_local(const char *name)
+ {
+ gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_FLOAT, NULL);
+ }
+ /* INT */
+ static void gsl_int_decl_local(const char *name)
+ {
+ gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_INT, NULL);
+ }
+ /* PTR */
+ static void gsl_ptr_decl_local(const char *name)
+ {
+ gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_PTR, NULL);
+ }
+ /* STRUCT */
+ static void gsl_struct_decl_local(const char *struct_name, const char *name)
+ {
+ gsl_struct_decl(currentGoomSL->namespaces[currentGoomSL->currentNS],struct_name,name);
+ }
+
+
+ static void commit_test2(NodeType *set,const char *type, int instr);
+ static NodeType *new_call(const char *name, NodeType *affect_list);
+
+ /* SETTER */
+ static NodeType *new_set(NodeType *lvalue, NodeType *expression)
+ { /* {{{ */
+ NodeType *set = new_op("set", OPR_SET, 2);
+ set->unode.opr.op[0] = lvalue;
+ set->unode.opr.op[1] = expression;
+ return set;
+ } /* }}} */
+ static void commit_set(NodeType *set)
+ { /* {{{ */
+ commit_test2(set,"set",INSTR_SET);
+ } /* }}} */
+
+ /* PLUS_EQ */
+ static NodeType *new_plus_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
+ {
+ NodeType *set = new_op("plus_eq", OPR_PLUS_EQ, 2);
+ set->unode.opr.op[0] = lvalue;
+ set->unode.opr.op[1] = expression;
+ return set;
+ }
+ static void commit_plus_eq(NodeType *set)
+ {
+ precommit_node(set->unode.opr.op[1]);
+#ifdef VERBOSE
+ printf("add %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "add", INSTR_ADD, 2, set->line_number);
+ commit_node(set->unode.opr.op[0],0);
+ commit_node(set->unode.opr.op[1],1);
+ } /* }}} */
+
+ /* SUB_EQ */
+ static NodeType *new_sub_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
+ {
+ NodeType *set = new_op("sub_eq", OPR_SUB_EQ, 2);
+ set->unode.opr.op[0] = lvalue;
+ set->unode.opr.op[1] = expression;
+ return set;
+ }
+ static void commit_sub_eq(NodeType *set)
+ {
+ precommit_node(set->unode.opr.op[1]);
+#ifdef VERBOSE
+ printf("sub %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "sub", INSTR_SUB, 2, set->line_number);
+ commit_node(set->unode.opr.op[0],0);
+ commit_node(set->unode.opr.op[1],1);
+ } /* }}} */
+
+ /* MUL_EQ */
+ static NodeType *new_mul_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
+ {
+ NodeType *set = new_op("mul_eq", OPR_MUL_EQ, 2);
+ set->unode.opr.op[0] = lvalue;
+ set->unode.opr.op[1] = expression;
+ return set;
+ }
+ static void commit_mul_eq(NodeType *set)
+ {
+ precommit_node(set->unode.opr.op[1]);
+#ifdef VERBOSE
+ printf("mul %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "mul", INSTR_MUL, 2, set->line_number);
+ commit_node(set->unode.opr.op[0],0);
+ commit_node(set->unode.opr.op[1],1);
+ } /* }}} */
+
+ /* DIV_EQ */
+ static NodeType *new_div_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
+ {
+ NodeType *set = new_op("div_eq", OPR_DIV_EQ, 2);
+ set->unode.opr.op[0] = lvalue;
+ set->unode.opr.op[1] = expression;
+ return set;
+ }
+ static void commit_div_eq(NodeType *set)
+ {
+ precommit_node(set->unode.opr.op[1]);
+#ifdef VERBOSE
+ printf("div %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "div", INSTR_DIV, 2, set->line_number);
+ commit_node(set->unode.opr.op[0],0);
+ commit_node(set->unode.opr.op[1],1);
+ } /* }}} */
+
+ /* commodity method for add, mult, ... */
+
+ static void precommit_expr(NodeType *expr, const char *type, int instr_id)
+ { /* {{{ */
+ NodeType *tmp, *tmpcpy;
+ int toAdd;
+
+ /* compute "left" and "right" */
+ switch (expr->unode.opr.nbOp) {
+ case 2:
+ precommit_node(expr->unode.opr.op[1]);
+ case 1:
+ precommit_node(expr->unode.opr.op[0]);
+ }
+
+ if (is_tmp_expr(expr->unode.opr.op[0])) {
+ tmp = expr->unode.opr.op[0];
+ toAdd = 1;
+ }
+ else if (is_commutative_expr(instr_id) && (expr->unode.opr.nbOp==2) && is_tmp_expr(expr->unode.opr.op[1])) {
+ tmp = expr->unode.opr.op[1];
+ toAdd = 0;
+ }
+ else {
+ char stmp[256];
+ /* declare a temporary variable to store the result */
+ if (expr->unode.opr.op[0]->type == CONST_INT_NODE) {
+ sprintf(stmp,"_i_tmp_%i",allocateTemp());
+ gsl_int_decl_global(stmp);
+ }
+ else if (expr->unode.opr.op[0]->type == CONST_FLOAT_NODE) {
+ sprintf(stmp,"_f_tmp%i",allocateTemp());
+ gsl_float_decl_global(stmp);
+ }
+ else if (expr->unode.opr.op[0]->type == CONST_PTR_NODE) {
+ sprintf(stmp,"_p_tmp%i",allocateTemp());
+ gsl_ptr_decl_global(stmp);
+ }
+ else {
+ int type = gsl_type_of_var(expr->unode.opr.op[0]->vnamespace, expr->unode.opr.op[0]->str);
+ if (type == INSTR_FLOAT) {
+ sprintf(stmp,"_f_tmp_%i",allocateTemp());
+ gsl_float_decl_global(stmp);
+ }
+ else if (type == INSTR_PTR) {
+ sprintf(stmp,"_p_tmp_%i",allocateTemp());
+ gsl_ptr_decl_global(stmp);
+ }
+ else if (type == INSTR_INT) {
+ sprintf(stmp,"_i_tmp_%i",allocateTemp());
+ gsl_int_decl_global(stmp);
+ }
+ else if (type == -1) {
+ fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n",
+ expr->line_number, expr->unode.opr.op[0]->str);
+ exit(1);
+ }
+ else { /* type is a struct_id */
+ sprintf(stmp,"_s_tmp_%i",allocateTemp());
+ gsl_struct_decl_global_from_id(stmp,type);
+ }
+ }
+ tmp = new_var(stmp,expr->line_number);
+
+ /* set the tmp to the value of "op1" */
+ tmpcpy = nodeClone(tmp);
+ commit_node(new_set(tmp,expr->unode.opr.op[0]),0);
+ toAdd = 1;
+
+ tmp = tmpcpy;
+ }
+
+ /* add op2 to tmp */
+#ifdef VERBOSE
+ if (expr->unode.opr.nbOp == 2)
+ printf("%s %s %s\n", type, tmp->str, expr->unode.opr.op[toAdd]->str);
+ else
+ printf("%s %s\n", type, tmp->str);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, type, instr_id, expr->unode.opr.nbOp, expr->line_number);
+ tmpcpy = nodeClone(tmp);
+ commit_node(tmp,0);
+ if (expr->unode.opr.nbOp == 2) {
+ commit_node(expr->unode.opr.op[toAdd],1);
+ }
+
+ /* redefine the ADD node now as the computed variable */
+ nodeFreeInternals(expr);
+ *expr = *tmpcpy;
+ free(tmpcpy);
+ } /* }}} */
+
+ static NodeType *new_expr1(const char *name, int id, NodeType *expr1)
+ { /* {{{ */
+ NodeType *add = new_op(name, id, 1);
+ add->unode.opr.op[0] = expr1;
+ return add;
+ } /* }}} */
+
+ static NodeType *new_expr2(const char *name, int id, NodeType *expr1, NodeType *expr2)
+ { /* {{{ */
+ NodeType *add = new_op(name, id, 2);
+ add->unode.opr.op[0] = expr1;
+ add->unode.opr.op[1] = expr2;
+ return add;
+ } /* }}} */
+
+ /* ADD */
+ static NodeType *new_add(NodeType *expr1, NodeType *expr2) { /* {{{ */
+ return new_expr2("add", OPR_ADD, expr1, expr2);
+ }
+ static void precommit_add(NodeType *add) {
+ precommit_expr(add,"add",INSTR_ADD);
+ } /* }}} */
+
+ /* SUB */
+ static NodeType *new_sub(NodeType *expr1, NodeType *expr2) { /* {{{ */
+ return new_expr2("sub", OPR_SUB, expr1, expr2);
+ }
+ static void precommit_sub(NodeType *sub) {
+ precommit_expr(sub,"sub",INSTR_SUB);
+ } /* }}} */
+
+ /* NEG */
+ static NodeType *new_neg(NodeType *expr) { /* {{{ */
+ NodeType *zeroConst = NULL;
+ if (expr->type == CONST_INT_NODE)
+ zeroConst = new_constInt("0", currentGoomSL->num_lines);
+ else if (expr->type == CONST_FLOAT_NODE)
+ zeroConst = new_constFloat("0.0", currentGoomSL->num_lines);
+ else if (expr->type == CONST_PTR_NODE) {
+ fprintf(stderr, "ERROR: Line %d, Could not negate const pointer.\n",
+ currentGoomSL->num_lines);
+ exit(1);
+ }
+ else {
+ int type = gsl_type_of_var(expr->vnamespace, expr->str);
+ if (type == INSTR_FLOAT)
+ zeroConst = new_constFloat("0.0", currentGoomSL->num_lines);
+ else if (type == INSTR_PTR) {
+ fprintf(stderr, "ERROR: Line %d, Could not negate pointer.\n",
+ currentGoomSL->num_lines);
+ exit(1);
+ }
+ else if (type == INSTR_INT)
+ zeroConst = new_constInt("0", currentGoomSL->num_lines);
+ else if (type == -1) {
+ fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n",
+ expr->line_number, expr->unode.opr.op[0]->str);
+ exit(1);
+ }
+ else { /* type is a struct_id */
+ fprintf(stderr, "ERROR: Line %d, Could not negate struct '%s'\n",
+ expr->line_number, expr->str);
+ exit(1);
+ }
+ }
+ return new_expr2("sub", OPR_SUB, zeroConst, expr);
+ }
+ /* }}} */
+
+ /* MUL */
+ static NodeType *new_mul(NodeType *expr1, NodeType *expr2) { /* {{{ */
+ return new_expr2("mul", OPR_MUL, expr1, expr2);
+ }
+ static void precommit_mul(NodeType *mul) {
+ precommit_expr(mul,"mul",INSTR_MUL);
+ } /* }}} */
+
+ /* DIV */
+ static NodeType *new_div(NodeType *expr1, NodeType *expr2) { /* {{{ */
+ return new_expr2("div", OPR_DIV, expr1, expr2);
+ }
+ static void precommit_div(NodeType *mul) {
+ precommit_expr(mul,"div",INSTR_DIV);
+ } /* }}} */
+
+ /* CALL EXPRESSION */
+ static NodeType *new_call_expr(const char *name, NodeType *affect_list) { /* {{{ */
+ NodeType *call = new_call(name,affect_list);
+ NodeType *node = new_expr1(name, OPR_CALL_EXPR, call);
+ node->vnamespace = gsl_find_namespace(name);
+ if (node->vnamespace == NULL)
+ fprintf(stderr, "ERROR: Line %d, No return type for: '%s'\n", currentGoomSL->num_lines, name);
+ return node;
+ }
+ static void precommit_call_expr(NodeType *call) {
+ char stmp[256];
+ NodeType *tmp,*tmpcpy;
+ int type = gsl_type_of_var(call->vnamespace, call->str);
+ if (type == INSTR_FLOAT) {
+ sprintf(stmp,"_f_tmp_%i",allocateTemp());
+ gsl_float_decl_global(stmp);
+ }
+ else if (type == INSTR_PTR) {
+ sprintf(stmp,"_p_tmp_%i",allocateTemp());
+ gsl_ptr_decl_global(stmp);
+ }
+ else if (type == INSTR_INT) {
+ sprintf(stmp,"_i_tmp_%i",allocateTemp());
+ gsl_int_decl_global(stmp);
+ }
+ else if (type == -1) {
+ fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n",
+ call->line_number, call->str);
+ exit(1);
+ }
+ else { /* type is a struct_id */
+ sprintf(stmp,"_s_tmp_%i",allocateTemp());
+ gsl_struct_decl_global_from_id(stmp,type);
+ }
+ tmp = new_var(stmp,call->line_number);
+ commit_node(call->unode.opr.op[0],0);
+ tmpcpy = nodeClone(tmp);
+ commit_node(new_set(tmp,new_var(call->str,call->line_number)),0);
+
+ nodeFreeInternals(call);
+ *call = *tmpcpy;
+ free(tmpcpy);
+ } /* }}} */
+
+ static void commit_test2(NodeType *set,const char *type, int instr)
+ { /* {{{ */
+ NodeType *tmp;
+ char stmp[256];
+ precommit_node(set->unode.opr.op[0]);
+ precommit_node(set->unode.opr.op[1]);
+ tmp = set->unode.opr.op[0];
+
+ stmp[0] = 0;
+ if (set->unode.opr.op[0]->type == CONST_INT_NODE) {
+ sprintf(stmp,"_i_tmp_%i",allocateTemp());
+ gsl_int_decl_global(stmp);
+ }
+ else if (set->unode.opr.op[0]->type == CONST_FLOAT_NODE) {
+ sprintf(stmp,"_f_tmp%i",allocateTemp());
+ gsl_float_decl_global(stmp);
+ }
+ else if (set->unode.opr.op[0]->type == CONST_PTR_NODE) {
+ sprintf(stmp,"_p_tmp%i",allocateTemp());
+ gsl_ptr_decl_global(stmp);
+ }
+ if (stmp[0]) {
+ NodeType *tmpcpy;
+ tmp = new_var(stmp, set->line_number);
+ tmpcpy = nodeClone(tmp);
+ commit_node(new_set(tmp,set->unode.opr.op[0]),0);
+ tmp = tmpcpy;
+ }
+
+#ifdef VERBOSE
+ printf("%s %s %s\n", type, tmp->str, set->unode.opr.op[1]->str);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, type, instr, 2, set->line_number);
+ commit_node(tmp,instr!=INSTR_SET);
+ commit_node(set->unode.opr.op[1],1);
+ } /* }}} */
+
+ /* NOT */
+ static NodeType *new_not(NodeType *expr1) { /* {{{ */
+ return new_expr1("not", OPR_NOT, expr1);
+ }
+ static void commit_not(NodeType *set)
+ {
+ commit_node(set->unode.opr.op[0],0);
+#ifdef VERBOSE
+ printf("not\n");
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "not", INSTR_NOT, 1, set->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);
+ } /* }}} */
+
+ /* EQU */
+ static NodeType *new_equ(NodeType *expr1, NodeType *expr2) { /* {{{ */
+ return new_expr2("isequal", OPR_EQU, expr1, expr2);
+ }
+ static void commit_equ(NodeType *mul) {
+ commit_test2(mul,"isequal",INSTR_ISEQUAL);
+ } /* }}} */
+
+ /* INF */
+ static NodeType *new_low(NodeType *expr1, NodeType *expr2) { /* {{{ */
+ return new_expr2("islower", OPR_LOW, expr1, expr2);
+ }
+ static void commit_low(NodeType *mul) {
+ commit_test2(mul,"islower",INSTR_ISLOWER);
+ } /* }}} */
+
+ /* WHILE */
+ static NodeType *new_while(NodeType *expression, NodeType *instr) { /* {{{ */
+ NodeType *node = new_op("while", OPR_WHILE, 2);
+ node->unode.opr.op[0] = expression;
+ node->unode.opr.op[1] = instr;
+ return node;
+ }
+
+ static void commit_while(NodeType *node)
+ {
+ int lbl = allocateLabel();
+ char start_while[1024], test_while[1024];
+ sprintf(start_while, "|start_while_%d|", lbl);
+ sprintf(test_while, "|test_while_%d|", lbl);
+
+ GSL_PUT_JUMP(test_while,node->line_number);
+ GSL_PUT_LABEL(start_while,node->line_number);
+
+ /* code */
+ commit_node(node->unode.opr.op[1],0);
+
+ GSL_PUT_LABEL(test_while,node->line_number);
+ commit_node(node->unode.opr.op[0],0);
+ GSL_PUT_JNZERO(start_while,node->line_number);
+ } /* }}} */
+
+ /* FOR EACH */
+ static NodeType *new_static_foreach(NodeType *var, NodeType *var_list, NodeType *instr) { /* {{{ */
+ NodeType *node = new_op("for", OPR_FOREACH, 3);
+ node->unode.opr.op[0] = var;
+ node->unode.opr.op[1] = var_list;
+ node->unode.opr.op[2] = instr;
+ node->line_number = currentGoomSL->num_lines;
+ return node;
+ }
+ static void commit_foreach(NodeType *node)
+ {
+ NodeType *cur = node->unode.opr.op[1];
+ char tmp_func[256], tmp_loop[256];
+ int lbl = allocateLabel();
+ sprintf(tmp_func, "|foreach_func_%d|", lbl);
+ sprintf(tmp_loop, "|foreach_loop_%d|", lbl);
+
+ GSL_PUT_JUMP(tmp_loop, node->line_number);
+ GSL_PUT_LABEL(tmp_func, node->line_number);
+
+ precommit_node(node->unode.opr.op[2]);
+ commit_node(node->unode.opr.op[2], 0);
+
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "ret", INSTR_RET, 1, node->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);
+#ifdef VERBOSE
+ printf("ret\n");
+#endif
+
+ GSL_PUT_LABEL(tmp_loop, node->line_number);
+
+ while (cur != NULL)
+ {
+ NodeType *x, *var;
+
+ /* 1: x=var */
+ x = nodeClone(node->unode.opr.op[0]);
+ var = nodeClone(cur->unode.opr.op[0]);
+ commit_node(new_set(x, var),0);
+
+ /* 2: instr */
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "call", INSTR_CALL, 1, node->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, tmp_func, TYPE_LABEL);
+#ifdef VERBOSE
+ printf("call %s\n", tmp_func);
+#endif
+
+ /* 3: var=x */
+ x = nodeClone(node->unode.opr.op[0]);
+ var = cur->unode.opr.op[0];
+ commit_node(new_set(var, x),0);
+ cur = cur->unode.opr.op[1];
+ }
+ nodeFree(node->unode.opr.op[0]);
+ } /* }}} */
+
+ /* IF */
+ static NodeType *new_if(NodeType *expression, NodeType *instr) { /* {{{ */
+ NodeType *node = new_op("if", OPR_IF, 2);
+ node->unode.opr.op[0] = expression;
+ node->unode.opr.op[1] = instr;
+ return node;
+ }
+ static void commit_if(NodeType *node) {
+
+ char slab[1024];
+ sprintf(slab, "|eif%d|", allocateLabel());
+ commit_node(node->unode.opr.op[0],0);
+ GSL_PUT_JZERO(slab,node->line_number);
+ /* code */
+ commit_node(node->unode.opr.op[1],0);
+ GSL_PUT_LABEL(slab,node->line_number);
+ } /* }}} */
+
+ /* BLOCK */
+ static NodeType *new_block(NodeType *lastNode) { /* {{{ */
+ NodeType *blk = new_op("block", OPR_BLOCK, 2);
+ blk->unode.opr.op[0] = new_nop("start_of_block");
+ blk->unode.opr.op[1] = lastNode;
+ return blk;
+ }
+ static void commit_block(NodeType *node) {
+ commit_node(node->unode.opr.op[0]->unode.opr.next,0);
+ } /* }}} */
+
+ /* FUNCTION INTRO */
+ static NodeType *new_function_intro(const char *name) { /* {{{ */
+ char stmp[256];
+ if (strlen(name) < 200) {
+ sprintf(stmp, "|__func_%s|", name);
+ }
+ return new_op(stmp, OPR_FUNC_INTRO, 0);
+ }
+ static void commit_function_intro(NodeType *node) {
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "label", INSTR_LABEL, 1, node->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_LABEL);
+#ifdef VERBOSE
+ printf("label %s\n", node->str);
+#endif
+ } /* }}} */
+
+ /* FUNCTION OUTRO */
+ static NodeType *new_function_outro() { /* {{{ */
+ return new_op("ret", OPR_FUNC_OUTRO, 0);
+ }
+ static void commit_function_outro(NodeType *node) {
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "ret", INSTR_RET, 1, node->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);
+ releaseAllTemps();
+#ifdef VERBOSE
+ printf("ret\n");
+#endif
+ } /* }}} */
+
+ /* AFFECTATION LIST */
+ static NodeType *new_affec_list(NodeType *set, NodeType *next) /* {{{ */
+ {
+ NodeType *node = new_op("affect_list", OPR_AFFECT_LIST, 2);
+ node->unode.opr.op[0] = set;
+ node->unode.opr.op[1] = next;
+ return node;
+ }
+ static NodeType *new_affect_list_after(NodeType *affect_list)
+ {
+ NodeType *ret = NULL;
+ NodeType *cur = affect_list;
+ while(cur != NULL) {
+ NodeType *set = cur->unode.opr.op[0];
+ NodeType *next = cur->unode.opr.op[1];
+ NodeType *lvalue = set->unode.opr.op[0];
+ NodeType *expression = set->unode.opr.op[1];
+ if ((lvalue->str[0] == '&') && (expression->type == VAR_NODE)) {
+ NodeType *nset = new_set(nodeClone(expression), nodeClone(lvalue));
+ ret = new_affec_list(nset, ret);
+ }
+ cur = next;
+ }
+ return ret;
+ }
+ static void commit_affect_list(NodeType *node)
+ {
+ NodeType *cur = node;
+ while(cur != NULL) {
+ NodeType *set = cur->unode.opr.op[0];
+ precommit_node(set->unode.opr.op[0]);
+ precommit_node(set->unode.opr.op[1]);
+ cur = cur->unode.opr.op[1];
+ }
+ cur = node;
+ while(cur != NULL) {
+ NodeType *set = cur->unode.opr.op[0];
+ commit_node(set,0);
+ cur = cur->unode.opr.op[1];
+ }
+ } /* }}} */
+
+ /* VAR LIST */
+ static NodeType *new_var_list(NodeType *var, NodeType *next) /* {{{ */
+ {
+ NodeType *node = new_op("var_list", OPR_VAR_LIST, 2);
+ node->unode.opr.op[0] = var;
+ node->unode.opr.op[1] = next;
+ return node;
+ }
+ static void commit_var_list(NodeType *node)
+ {
+ } /* }}} */
+
+ /* FUNCTION CALL */
+ static NodeType *new_call(const char *name, NodeType *affect_list) { /* {{{ */
+ HashValue *fval;
+ fval = goom_hash_get(currentGoomSL->functions, name);
+ if (!fval) {
+ gsl_declare_task(name);
+ fval = goom_hash_get(currentGoomSL->functions, name);
+ }
+ if (!fval) {
+ fprintf(stderr, "ERROR: Line %d, Could not find function %s\n", currentGoomSL->num_lines, name);
+ exit(1);
+ return NULL;
+ }
+ else {
+ ExternalFunctionStruct *gef = (ExternalFunctionStruct*)fval->ptr;
+ if (gef->is_extern) {
+ NodeType *node = new_op(name, OPR_EXT_CALL, 1);
+ node->unode.opr.op[0] = affect_list;
+ return node;
+ }
+ else {
+ NodeType *node;
+ char stmp[256];
+ if (strlen(name) < 200) {
+ sprintf(stmp, "|__func_%s|", name);
+ }
+ node = new_op(stmp, OPR_CALL, 1);
+ node->unode.opr.op[0] = affect_list;
+ return node;
+ }
+ }
+ }
+ static void commit_ext_call(NodeType *node) {
+ NodeType *alafter = new_affect_list_after(node->unode.opr.op[0]);
+ commit_node(node->unode.opr.op[0],0);
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "extcall", INSTR_EXT_CALL, 1, node->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_VAR);
+#ifdef VERBOSE
+ printf("extcall %s\n", node->str);
+#endif
+ commit_node(alafter,0);
+ }
+ static void commit_call(NodeType *node) {
+ NodeType *alafter = new_affect_list_after(node->unode.opr.op[0]);
+ commit_node(node->unode.opr.op[0],0);
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "call", INSTR_CALL, 1, node->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_LABEL);
+#ifdef VERBOSE
+ printf("call %s\n", node->str);
+#endif
+ commit_node(alafter,0);
+ } /* }}} */
+
+ /** **/
+
+ static NodeType *rootNode = 0; /* TODO: reinitialiser a chaque compilation. */
+ static NodeType *lastNode = 0;
+ static NodeType *gsl_append(NodeType *curNode) {
+ if (curNode == 0) return 0; /* {{{ */
+ if (lastNode)
+ lastNode->unode.opr.next = curNode;
+ lastNode = curNode;
+ while(lastNode->unode.opr.next) lastNode = lastNode->unode.opr.next;
+ if (rootNode == 0)
+ rootNode = curNode;
+ return curNode;
+ } /* }}} */
+
+#if 1
+ int allocateTemp() {
+ return allocateLabel();
+ }
+ void releaseAllTemps() {}
+ void releaseTemp(int n) {}
+#else
+ static int nbTemp = 0;
+ static int *tempArray = 0;
+ static int tempArraySize = 0;
+ int allocateTemp() { /* TODO: allocateITemp, allocateFTemp */
+ int i = 0; /* {{{ */
+ if (tempArray == 0) {
+ tempArraySize = 256;
+ tempArray = (int*)malloc(tempArraySize * sizeof(int));
+ }
+ while (1) {
+ int j;
+ for (j=0;j<nbTemp;++j) {
+ if (tempArray[j] == i) break;
+ }
+ if (j == nbTemp) {
+ if (nbTemp == tempArraySize) {
+ tempArraySize *= 2;
+ tempArray = (int*)realloc(tempArray,tempArraySize * sizeof(int));
+ }
+ tempArray[nbTemp++] = i;
+ return i;
+ }
+ i++;
+ }
+ } /* }}} */
+ void releaseAllTemps() {
+ nbTemp = 0; /* {{{ */
+ } /* }}} */
+ void releaseTemp(int n) {
+ int j; /* {{{ */
+ for (j=0;j<nbTemp;++j) {
+ if (tempArray[j] == n) {
+ tempArray[j] = tempArray[--nbTemp];
+ break;
+ }
+ }
+ } /* }}} */
+#endif
+
+ static int lastLabel = 0;
+ int allocateLabel() {
+ return ++lastLabel; /* {{{ */
+ } /* }}} */
+
+ void gsl_commit_compilation()
+ { /* {{{ */
+ commit_node(rootNode,0);
+ rootNode = 0;
+ lastNode = 0;
+ } /* }}} */
+
+ void precommit_node(NodeType *node)
+ { /* {{{ */
+ /* do here stuff for expression.. for exemple */
+ if (node->type == OPR_NODE)
+ switch(node->unode.opr.type) {
+ case OPR_ADD: precommit_add(node); break;
+ case OPR_SUB: precommit_sub(node); break;
+ case OPR_MUL: precommit_mul(node); break;
+ case OPR_DIV: precommit_div(node); break;
+ case OPR_CALL_EXPR: precommit_call_expr(node); break;
+ }
+ } /* }}} */
+
+ void commit_node(NodeType *node, int releaseIfTmp)
+ { /* {{{ */
+ if (node == 0) return;
+
+ switch(node->type) {
+ case OPR_NODE:
+ switch(node->unode.opr.type) {
+ case OPR_SET: commit_set(node); break;
+ case OPR_PLUS_EQ: commit_plus_eq(node); break;
+ case OPR_SUB_EQ: commit_sub_eq(node); break;
+ case OPR_MUL_EQ: commit_mul_eq(node); break;
+ case OPR_DIV_EQ: commit_div_eq(node); break;
+ case OPR_IF: commit_if(node); break;
+ case OPR_WHILE: commit_while(node); break;
+ case OPR_BLOCK: commit_block(node); break;
+ case OPR_FUNC_INTRO: commit_function_intro(node); break;
+ case OPR_FUNC_OUTRO: commit_function_outro(node); break;
+ case OPR_CALL: commit_call(node); break;
+ case OPR_EXT_CALL: commit_ext_call(node); break;
+ case OPR_EQU: commit_equ(node); break;
+ case OPR_LOW: commit_low(node); break;
+ case OPR_NOT: commit_not(node); break;
+ case OPR_AFFECT_LIST: commit_affect_list(node); break;
+ case OPR_FOREACH: commit_foreach(node); break;
+ case OPR_VAR_LIST: commit_var_list(node); break;
+#ifdef VERBOSE
+ case EMPTY_NODE: printf("NOP\n"); break;
+#endif
+ }
+
+ commit_node(node->unode.opr.next,0); /* recursive for the moment, maybe better to do something iterative? */
+ break;
+
+ case VAR_NODE: gsl_instr_set_namespace(currentGoomSL->instr, node->vnamespace);
+ gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_VAR); break;
+ case CONST_INT_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_INTEGER); break;
+ case CONST_FLOAT_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_FLOAT); break;
+ case CONST_PTR_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_PTR); break;
+ }
+ if (releaseIfTmp && is_tmp_expr(node))
+ releaseTemp(get_tmp_id(node));
+
+ nodeFree(node);
+ } /* }}} */
+
+ NodeType *nodeNew(const char *str, int type, int line_number) {
+ NodeType *node = (NodeType*)malloc(sizeof(NodeType)); /* {{{ */
+ node->type = type;
+ node->str = (char*)malloc(strlen(str)+1);
+ node->vnamespace = NULL;
+ node->line_number = line_number;
+ strcpy(node->str, str);
+ return node;
+ } /* }}} */
+ static NodeType *nodeClone(NodeType *node) {
+ NodeType *ret = nodeNew(node->str, node->type, node->line_number); /* {{{ */
+ ret->vnamespace = node->vnamespace;
+ ret->unode = node->unode;
+ return ret;
+ } /* }}} */
+
+ void nodeFreeInternals(NodeType *node) {
+ free(node->str); /* {{{ */
+ } /* }}} */
+
+ void nodeFree(NodeType *node) {
+ nodeFreeInternals(node); /* {{{ */
+ free(node);
+ } /* }}} */
+
+ NodeType *new_constInt(const char *str, int line_number) {
+ NodeType *node = nodeNew(str, CONST_INT_NODE, line_number); /* {{{ */
+ node->unode.constInt.val = atoi(str);
+ return node;
+ } /* }}} */
+
+ NodeType *new_constPtr(const char *str, int line_number) {
+ NodeType *node = nodeNew(str, CONST_PTR_NODE, line_number); /* {{{ */
+ node->unode.constPtr.id = strtol(str,NULL,0);
+ return node;
+ } /* }}} */
+
+ NodeType *new_constFloat(const char *str, int line_number) {
+ NodeType *node = nodeNew(str, CONST_FLOAT_NODE, line_number); /* {{{ */
+ node->unode.constFloat.val = atof(str);
+ return node;
+ } /* }}} */
+
+ NodeType *new_var(const char *str, int line_number) {
+ NodeType *node = nodeNew(str, VAR_NODE, line_number); /* {{{ */
+ node->vnamespace = gsl_find_namespace(str);
+ if (node->vnamespace == 0) {
+ fprintf(stderr, "ERROR: Line %d, Variable not found: '%s'\n", line_number, str);
+ exit(1);
+ }
+ return node;
+ } /* }}} */
+
+ NodeType *new_nop(const char *str) {
+ NodeType *node = new_op(str, EMPTY_NODE, 0); /* {{{ */
+ return node;
+ } /* }}} */
+
+ NodeType *new_op(const char *str, int type, int nbOp) {
+ int i; /* {{{ */
+ NodeType *node = nodeNew(str, OPR_NODE, currentGoomSL->num_lines);
+ node->unode.opr.next = 0;
+ node->unode.opr.type = type;
+ node->unode.opr.nbOp = nbOp;
+ for (i=0;i<nbOp;++i) node->unode.opr.op[i] = 0;
+ return node;
+ } /* }}} */
+
+
+ void gsl_declare_global_variable(int type, char *name) {
+ switch(type){
+ case -1: break;
+ case FLOAT_TK:gsl_float_decl_global(name);break;
+ case INT_TK: gsl_int_decl_global(name);break;
+ case PTR_TK: gsl_ptr_decl_global(name);break;
+ default:
+ {
+ int id = type - 1000;
+ gsl_struct_decl_global_from_id(name,id);
+ }
+ }
+ }
+
+%}
+
+%union {
+ int intValue;
+ float floatValue;
+ char charValue;
+ char strValue[2048];
+ NodeType *nPtr;
+ GoomHash *namespace;
+ GSL_Struct *gsl_struct;
+ GSL_StructField *gsl_struct_field;
+ };
+
+%token <strValue> LTYPE_INTEGER
+%token <strValue> LTYPE_FLOAT
+%token <strValue> LTYPE_VAR
+%token <strValue> LTYPE_PTR
+
+%token PTR_TK INT_TK FLOAT_TK DECLARE EXTERNAL WHILE DO NOT PLUS_EQ SUB_EQ DIV_EQ MUL_EQ SUP_EQ LOW_EQ NOT_EQ STRUCT FOR IN
+
+%type <intValue> return_type
+%type <nPtr> expression constValue instruction test func_call func_call_expression
+%type <nPtr> start_block affectation_list affectation_in_list affectation declaration
+%type <nPtr> var_list_content var_list
+%type <strValue> task_name ext_task_name
+%type <namespace> leave_namespace
+%type <gsl_struct> struct_members
+%type <gsl_struct_field> struct_member
+%left '\n'
+%left PLUS_EQ SUB_EQ MUL_EQ DIV_EQ
+%left NOT
+%left '=' '<' '>'
+%left '+' '-'
+%left '/' '*'
+
+%%
+
+/* -------------- Global architechture of a GSL program ------------*/
+
+gsl: gsl_code function_outro gsl_def_functions ;
+
+gsl_code: gsl_code instruction { gsl_append($2); }
+ | gsl_code EXTERNAL '<' ext_task_name '>' return_type '\n' leave_namespace { gsl_declare_global_variable($6,$4); }
+ | gsl_code EXTERNAL '<' ext_task_name ':' arglist '>' return_type '\n' leave_namespace { gsl_declare_global_variable($8,$4); }
+ | gsl_code DECLARE '<' task_name '>' return_type '\n' leave_namespace { gsl_declare_global_variable($6,$4); }
+ | gsl_code DECLARE '<' task_name ':' arglist '>' return_type '\n' leave_namespace { gsl_declare_global_variable($8,$4); }
+ | gsl_code struct_declaration
+ | gsl_code '\n'
+ |
+ ;
+
+/* ------------- Declaration of a structure ------------ */
+
+struct_declaration: STRUCT '<' LTYPE_VAR ':' struct_members '>' '\n' { gsl_add_struct($3, $5); }
+ ;
+
+struct_members: opt_nl struct_member { $$ = gsl_new_struct($2); }
+ | struct_members ',' opt_nl struct_member { $$ = $1; gsl_add_struct_field($1, $4); }
+ ;
+
+struct_member: INT_TK LTYPE_VAR { $$ = gsl_new_struct_field($2, INSTR_INT); }
+ | FLOAT_TK LTYPE_VAR { $$ = gsl_new_struct_field($2, INSTR_FLOAT); }
+ | PTR_TK LTYPE_VAR { $$ = gsl_new_struct_field($2, INSTR_PTR); }
+ | LTYPE_VAR LTYPE_VAR { $$ = gsl_new_struct_field_struct($2, $1); }
+ ;
+
+/* ------------- Fonction declarations -------------- */
+
+ext_task_name: LTYPE_VAR { gsl_declare_external_task($1); gsl_enternamespace($1); strcpy($$,$1); }
+ ;
+task_name: LTYPE_VAR { gsl_declare_task($1); gsl_enternamespace($1); strcpy($$,$1); strcpy($$,$1); }
+ ;
+
+return_type: { $$=-1; }
+ | ':' INT_TK { $$=INT_TK; }
+ | ':' FLOAT_TK { $$=FLOAT_TK; }
+ | ':' PTR_TK { $$=PTR_TK; }
+ | ':' LTYPE_VAR { $$= 1000 + gsl_get_struct_id($2); }
+ ;
+
+arglist: empty_declaration
+ | empty_declaration ',' arglist
+ ;
+
+/* ------------- Fonction definition -------------- */
+
+gsl_def_functions: gsl_def_functions function
+ |
+ ;
+
+function: function_intro gsl_code function_outro { gsl_leavenamespace(); }
+
+function_intro: '<' task_name '>' return_type '\n' { gsl_append(new_function_intro($2));
+ gsl_declare_global_variable($4,$2); }
+ | '<' task_name ':' arglist '>' return_type '\n' { gsl_append(new_function_intro($2));
+ gsl_declare_global_variable($6,$2); }
+ ;
+function_outro: { gsl_append(new_function_outro()); } ;
+
+leave_namespace: { $$ = gsl_leavenamespace(); };
+
+/* ------------ Variable declaration ---------------- */
+
+declaration: FLOAT_TK LTYPE_VAR '=' expression { gsl_float_decl_local($2); $$ = new_set(new_var($2,currentGoomSL->num_lines), $4); }
+ | INT_TK LTYPE_VAR '=' expression { gsl_int_decl_local($2); $$ = new_set(new_var($2,currentGoomSL->num_lines), $4); }
+ | PTR_TK LTYPE_VAR '=' expression { gsl_ptr_decl_local($2); $$ = new_set(new_var($2,currentGoomSL->num_lines), $4); }
+ | LTYPE_VAR LTYPE_VAR '=' expression { gsl_struct_decl_local($1,$2); $$ = new_set(new_var($2,currentGoomSL->num_lines), $4); }
+ | empty_declaration { $$ = 0; }
+ ;
+
+empty_declaration: FLOAT_TK LTYPE_VAR { gsl_float_decl_local($2); }
+ | INT_TK LTYPE_VAR { gsl_int_decl_local($2); }
+ | PTR_TK LTYPE_VAR { gsl_ptr_decl_local($2); }
+ | LTYPE_VAR LTYPE_VAR { gsl_struct_decl_local($1,$2); }
+ ;
+
+/* -------------- Instructions and Expressions ------------------ */
+
+instruction: affectation '\n' { $$ = $1; }
+ | declaration '\n' { $$ = $1; }
+ | '(' test ')' '?' opt_nl instruction { $$ = new_if($2,$6); }
+ | WHILE test opt_nl DO opt_nl instruction { $$ = new_while($2,$6); }
+ | '{' '\n' start_block gsl_code '}' '\n' { lastNode = $3->unode.opr.op[1]; $$=$3; }
+ | func_call { $$ = $1; }
+ | LTYPE_VAR PLUS_EQ expression { $$ = new_plus_eq(new_var($1,currentGoomSL->num_lines),$3); }
+ | LTYPE_VAR SUB_EQ expression { $$ = new_sub_eq(new_var($1,currentGoomSL->num_lines),$3); }
+ | LTYPE_VAR MUL_EQ expression { $$ = new_mul_eq(new_var($1,currentGoomSL->num_lines),$3); }
+ | LTYPE_VAR DIV_EQ expression { $$ = new_div_eq(new_var($1,currentGoomSL->num_lines),$3); }
+ | FOR LTYPE_VAR IN var_list DO instruction { $$ = new_static_foreach(new_var($2, currentGoomSL->num_lines), $4, $6); }
+ ;
+
+var_list: '(' var_list_content ')' { $$ = $2; }
+ ;
+var_list_content: LTYPE_VAR { $$ = new_var_list(new_var($1,currentGoomSL->num_lines), NULL); }
+ | LTYPE_VAR var_list_content { $$ = new_var_list(new_var($1,currentGoomSL->num_lines), $2); }
+ ;
+
+affectation: LTYPE_VAR '=' expression { $$ = new_set(new_var($1,currentGoomSL->num_lines),$3); } ;
+
+start_block: { $$ = new_block(lastNode); lastNode = $$->unode.opr.op[0]; }
+ ;
+
+expression: LTYPE_VAR { $$ = new_var($1,currentGoomSL->num_lines); }
+ | constValue { $$ = $1; }
+ | expression '*' expression { $$ = new_mul($1,$3); }
+ | expression '/' expression { $$ = new_div($1,$3); }
+ | expression '+' expression { $$ = new_add($1,$3); }
+ | expression '-' expression { $$ = new_sub($1,$3); }
+ | '-' expression { $$ = new_neg($2); }
+ | '(' expression ')' { $$ = $2; }
+ | func_call_expression { $$ = $1; }
+ ;
+
+test: expression '=' expression { $$ = new_equ($1,$3); }
+ | expression '<' expression { $$ = new_low($1,$3); }
+ | expression '>' expression { $$ = new_low($3,$1); }
+ | expression SUP_EQ expression { $$ = new_not(new_low($1,$3)); }
+ | expression LOW_EQ expression { $$ = new_not(new_low($3,$1)); }
+ | expression NOT_EQ expression { $$ = new_not(new_equ($1,$3)); }
+ | NOT test { $$ = new_not($2); }
+ ;
+
+constValue: LTYPE_FLOAT { $$ = new_constFloat($1,currentGoomSL->num_lines); }
+ | LTYPE_INTEGER { $$ = new_constInt($1,currentGoomSL->num_lines); }
+ | LTYPE_PTR { $$ = new_constPtr($1,currentGoomSL->num_lines); }
+ ;
+
+/* ---------------- Function Calls ------------------ */
+
+func_call: task_name '\n' leave_namespace { $$ = new_call($1,NULL); }
+ | task_name ':' affectation_list '\n' leave_namespace { $$ = new_call($1,$3); }
+ | '[' task_name ']' '\n' leave_namespace { $$ = new_call($2,NULL); }
+ | '[' task_name ':' affectation_list ']' '\n' leave_namespace { $$ = new_call($2,$4); }
+ ;
+
+func_call_expression:
+ '[' task_name leave_namespace ']' { $$ = new_call_expr($2,NULL); }
+ | '[' task_name ':' affectation_list ']' leave_namespace { $$ = new_call_expr($2,$4); }
+ ;
+
+affectation_list: affectation_in_list affectation_list { $$ = new_affec_list($1,$2); }
+ | affectation_in_list { $$ = new_affec_list($1,NULL); }
+
+affectation_in_list: LTYPE_VAR '=' leave_namespace expression {
+ gsl_reenternamespace($3);
+ $$ = new_set(new_var($1,currentGoomSL->num_lines),$4);
+ }
+ | ':' leave_namespace expression {
+ gsl_reenternamespace($2);
+ $$ = new_set(new_var("&this", currentGoomSL->num_lines),$3);
+ }
+ ;
+
+
+/* ------------ Misc ---------- */
+
+opt_nl: '\n' | ;
+
+
+%%
+
+
+void yyerror(char *str)
+{ /* {{{ */
+ fprintf(stderr, "ERROR: Line %d, %s\n", currentGoomSL->num_lines, str);
+ currentGoomSL->compilationOK = 0;
+ exit(1);
+} /* }}} */
+
diff --git a/gst/goom/graphic.c b/gst/goom/graphic.c
index c20f987d..2ee71a6d 100644
--- a/gst/goom/graphic.c
+++ b/gst/goom/graphic.c
@@ -1,14 +1,10 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "graphic.h"
+#include "goom_graphic.h"
const Color BLACK = { 0, 0, 0 };
const Color WHITE = { 0xff, 0xff, 0xff };
-const Color RED = { 0xff, 0, 0 };
-const Color GREEN = { 0, 0xff, 0 };
-const Color BLUE = { 0, 0, 0xff };
+const Color RED = { 0xff, 0x05, 0x05 };
+const Color GREEN = { 0x05, 0xff, 0x05 };
+const Color BLUE = { 0x05, 0x05, 0xff };
const Color YELLOW = { 0xff, 0xff, 0x33 };
-const Color ORANGE = { 0xff, 0xcc, 0x00 };
-const Color VIOLET = { 0x55, 0x00, 0xff };
+const Color ORANGE = { 0xff, 0xcc, 0x05 };
+const Color VIOLET = { 0x55, 0x05, 0xff };
diff --git a/gst/goom/graphic.h b/gst/goom/graphic.h
deleted file mode 100644
index 4154d7fd..00000000
--- a/gst/goom/graphic.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef GRAPHIC_H
-#define GRAPHIC_H
-
-#include <glib.h> /* defines inline for better portability */
-
-typedef unsigned int Uint;
-
-typedef struct
-{
- unsigned short r,v,b;
-}
-Color;
-
-extern const Color BLACK;
-extern const Color WHITE;
-extern const Color RED;
-extern const Color BLUE;
-extern const Color GREEN;
-extern const Color YELLOW;
-extern const Color ORANGE;
-extern const Color VIOLET;
-
-#endif /*GRAPHIC_H*/
diff --git a/gst/goom/gstgoom.c b/gst/goom/gstgoom.c
index ca9b3111..7ba6654a 100644
--- a/gst/goom/gstgoom.c
+++ b/gst/goom/gstgoom.c
@@ -44,7 +44,7 @@
#include <gst/gst.h>
#include "gstgoom.h"
#include <gst/video/video.h>
-#include "goom_core.h"
+#include "goom.h"
GST_DEBUG_CATEGORY_STATIC (goom_debug);
#define GST_CAT_DEFAULT goom_debug
@@ -187,7 +187,7 @@ gst_goom_init (GstGoom * goom)
goom->rate = 0;
goom->duration = 0;
- goom_init (&(goom->goomdata), goom->width, goom->height);
+ goom->plugin = goom_init (goom->width, goom->height);
}
static void
@@ -195,7 +195,7 @@ gst_goom_finalize (GObject * object)
{
GstGoom *goom = GST_GOOM (object);
- goom_close (&(goom->goomdata));
+ goom_close (goom->plugin);
g_object_unref (goom->adapter);
@@ -250,7 +250,7 @@ gst_goom_src_setcaps (GstPad * pad, GstCaps * caps)
&goom->fps_d))
return FALSE;
- goom_set_resolution (&(goom->goomdata), goom->width, goom->height);
+ goom_set_resolution (goom->plugin, goom->width, goom->height);
/* size of the output buffer in bytes, depth is always 4 bytes */
goom->outsize = goom->width * goom->height * 4;
@@ -523,7 +523,8 @@ gst_goom_chain (GstPad * pad, GstBuffer * buffer)
GST_BUFFER_DURATION (outbuf) = goom->duration;
GST_BUFFER_SIZE (outbuf) = goom->outsize;
- out_frame = (guchar *) goom_update (&(goom->goomdata), goom->datain);
+ out_frame = (guchar *) goom_update (goom->plugin, goom->datain, 0, 0,
+ NULL, NULL);
memcpy (GST_BUFFER_DATA (outbuf), out_frame, goom->outsize);
GST_DEBUG ("Pushing frame with time=%" GST_TIME_FORMAT ", duration=%"
diff --git a/gst/goom/gstgoom.h b/gst/goom/gstgoom.h
index 9c25f453..e9ca83ce 100644
--- a/gst/goom/gstgoom.h
+++ b/gst/goom/gstgoom.h
@@ -24,7 +24,7 @@ G_BEGIN_DECLS
#include <gst/gst.h>
#include <gst/base/gstadapter.h>
-#include "goom_core.h"
+#include "goom.h"
#define GOOM_SAMPLES 512
@@ -65,7 +65,7 @@ struct _GstGoom
/* goom stuff */
gint16 datain[2][GOOM_SAMPLES];
- GoomData goomdata;
+ PluginInfo *plugin;
/* segment state */
GstSegment segment;
diff --git a/gst/goom/ifs.c b/gst/goom/ifs.c
new file mode 100644
index 00000000..8e72548f
--- /dev/null
+++ b/gst/goom/ifs.c
@@ -0,0 +1,776 @@
+/*
+ * ifs.c --- modified iterated functions system for goom.
+ */
+
+/*-
+ * Copyright (c) 1997 by Massimino Pascal <Pascal.Massimon@ens.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind. The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof. In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ * If this mode is weird and you have an old MetroX server, it is buggy.
+ * There is a free SuSE-enhanced MetroX X server that is fine.
+ *
+ * When shown ifs, Diana Rose (4 years old) said, "It looks like dancing."
+ *
+ * Revision History:
+ * 13-Dec-2003: Added some goom specific stuffs (to make ifs a VisualFX).
+ * 11-Apr-2002: jeko@ios-software.com: Make ifs.c system-indendant. (ifs.h added)
+ * 01-Nov-2000: Allocation checks
+ * 10-May-1997: jwz@jwz.org: turned into a standalone program.
+ * Made it render into an offscreen bitmap and then copy
+ * that onto the screen, to reduce flicker.
+ */
+
+/* #ifdef STANDALONE */
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "goom_config.h"
+
+#ifdef HAVE_MMX
+#include "mmx.h"
+#endif
+
+#include "goom_graphic.h"
+#include "ifs.h"
+#include "goom_tools.h"
+
+typedef struct _ifsPoint
+{
+ gint32 x, y;
+}
+IFSPoint;
+
+
+#define MODE_ifs
+
+#define PROGCLASS "IFS"
+
+#define HACK_INIT init_ifs
+#define HACK_DRAW draw_ifs
+
+#define ifs_opts xlockmore_opts
+
+#define DEFAULTS "*delay: 20000 \n" \
+"*ncolors: 100 \n"
+
+#define SMOOTH_COLORS
+
+#define LRAND() ((long) (goom_random(goomInfo->gRandom) & 0x7fffffff))
+#define NRAND(n) ((int) (LRAND() % (n)))
+
+#if RAND_MAX < 0x10000
+#define MAXRAND (((float)(RAND_MAX<16)+((float)RAND_MAX)+1.0f)/127.0f)
+#else
+#define MAXRAND (2147483648.0/127.0) /* unsigned 1<<31 / 127.0 (cf goom_tools) as a float */
+#endif
+
+/*****************************************************/
+
+typedef float DBL;
+typedef int F_PT;
+
+/* typedef float F_PT; */
+
+/*****************************************************/
+
+#define FIX 12
+#define UNIT ( 1<<FIX )
+#define MAX_SIMI 6
+
+#define MAX_DEPTH_2 10
+#define MAX_DEPTH_3 6
+#define MAX_DEPTH_4 4
+#define MAX_DEPTH_5 2
+
+/* PREVIOUS VALUE
+#define MAX_SIMI 6
+
+ * settings for a PC 120Mhz... *
+#define MAX_DEPTH_2 10
+#define MAX_DEPTH_3 6
+#define MAX_DEPTH_4 4
+#define MAX_DEPTH_5 3
+*/
+
+#define DBL_To_F_PT(x) (F_PT)( (DBL)(UNIT)*(x) )
+
+typedef struct Similitude_Struct SIMI;
+typedef struct Fractal_Struct FRACTAL;
+
+struct Similitude_Struct
+{
+
+ DBL c_x, c_y;
+ DBL r, r2, A, A2;
+ F_PT Ct, St, Ct2, St2;
+ F_PT Cx, Cy;
+ F_PT R, R2;
+};
+
+
+struct Fractal_Struct
+{
+
+ int Nb_Simi;
+ SIMI Components[5 * MAX_SIMI];
+ int Depth, Col;
+ int Count, Speed;
+ int Width, Height, Lx, Ly;
+ DBL r_mean, dr_mean, dr2_mean;
+ int Cur_Pt, Max_Pt;
+
+ IFSPoint *Buffer1, *Buffer2;
+};
+
+typedef struct _IFS_DATA
+{
+ FRACTAL *Root;
+ FRACTAL *Cur_F;
+
+ /* Used by the Trace recursive method */
+ IFSPoint *Buf;
+ int Cur_Pt;
+ int initalized;
+} IfsData;
+
+
+/*****************************************************/
+
+static DBL
+Gauss_Rand (PluginInfo * goomInfo, DBL c, DBL A, DBL S)
+{
+ DBL y;
+
+ y = (DBL) LRAND () / MAXRAND;
+ y = A * (1.0 - exp (-y * y * S)) / (1.0 - exp (-S));
+ if (NRAND (2))
+ return (c + y);
+ return (c - y);
+}
+
+static DBL
+Half_Gauss_Rand (PluginInfo * goomInfo, DBL c, DBL A, DBL S)
+{
+ DBL y;
+
+ y = (DBL) LRAND () / MAXRAND;
+ y = A * (1.0 - exp (-y * y * S)) / (1.0 - exp (-S));
+ return (c + y);
+}
+
+static void
+Random_Simis (PluginInfo * goomInfo, FRACTAL * F, SIMI * Cur, int i)
+{
+ while (i--) {
+ Cur->c_x = Gauss_Rand (goomInfo, 0.0, .8, 4.0);
+ Cur->c_y = Gauss_Rand (goomInfo, 0.0, .8, 4.0);
+ Cur->r = Gauss_Rand (goomInfo, F->r_mean, F->dr_mean, 3.0);
+ Cur->r2 = Half_Gauss_Rand (goomInfo, 0.0, F->dr2_mean, 2.0);
+ Cur->A = Gauss_Rand (goomInfo, 0.0, 360.0, 4.0) * (M_PI / 180.0);
+ Cur->A2 = Gauss_Rand (goomInfo, 0.0, 360.0, 4.0) * (M_PI / 180.0);
+ Cur++;
+ }
+}
+
+static void
+free_ifs_buffers (FRACTAL * Fractal)
+{
+ if (Fractal->Buffer1 != NULL) {
+ (void) free ((void *) Fractal->Buffer1);
+ Fractal->Buffer1 = (IFSPoint *) NULL;
+ }
+ if (Fractal->Buffer2 != NULL) {
+ (void) free ((void *) Fractal->Buffer2);
+ Fractal->Buffer2 = (IFSPoint *) NULL;
+ }
+}
+
+
+static void
+free_ifs (FRACTAL * Fractal)
+{
+ free_ifs_buffers (Fractal);
+}
+
+/***************************************************************/
+
+static void
+init_ifs (PluginInfo * goomInfo, IfsData * data)
+{
+ int i;
+ FRACTAL *Fractal;
+ int width = goomInfo->screen.width;
+ int height = goomInfo->screen.height;
+
+ if (data->Root == NULL) {
+ data->Root = (FRACTAL *) malloc (sizeof (FRACTAL));
+ if (data->Root == NULL)
+ return;
+ data->Root->Buffer1 = (IFSPoint *) NULL;
+ data->Root->Buffer2 = (IFSPoint *) NULL;
+ }
+ Fractal = data->Root;
+
+ free_ifs_buffers (Fractal);
+
+ i = (NRAND (4)) + 2; /* Number of centers */
+ switch (i) {
+ case 3:
+ Fractal->Depth = MAX_DEPTH_3;
+ Fractal->r_mean = .6;
+ Fractal->dr_mean = .4;
+ Fractal->dr2_mean = .3;
+ break;
+
+ case 4:
+ Fractal->Depth = MAX_DEPTH_4;
+ Fractal->r_mean = .5;
+ Fractal->dr_mean = .4;
+ Fractal->dr2_mean = .3;
+ break;
+
+ case 5:
+ Fractal->Depth = MAX_DEPTH_5;
+ Fractal->r_mean = .5;
+ Fractal->dr_mean = .4;
+ Fractal->dr2_mean = .3;
+ break;
+
+ default:
+ case 2:
+ Fractal->Depth = MAX_DEPTH_2;
+ Fractal->r_mean = .7;
+ Fractal->dr_mean = .3;
+ Fractal->dr2_mean = .4;
+ break;
+ }
+ Fractal->Nb_Simi = i;
+ Fractal->Max_Pt = Fractal->Nb_Simi - 1;
+ for (i = 0; i <= Fractal->Depth + 2; ++i)
+ Fractal->Max_Pt *= Fractal->Nb_Simi;
+
+ if ((Fractal->Buffer1 = (IFSPoint *) calloc (Fractal->Max_Pt,
+ sizeof (IFSPoint))) == NULL) {
+ free_ifs (Fractal);
+ return;
+ }
+ if ((Fractal->Buffer2 = (IFSPoint *) calloc (Fractal->Max_Pt,
+ sizeof (IFSPoint))) == NULL) {
+ free_ifs (Fractal);
+ return;
+ }
+
+ Fractal->Speed = 6;
+ Fractal->Width = width; /* modif by JeKo */
+ Fractal->Height = height; /* modif by JeKo */
+ Fractal->Cur_Pt = 0;
+ Fractal->Count = 0;
+ Fractal->Lx = (Fractal->Width - 1) / 2;
+ Fractal->Ly = (Fractal->Height - 1) / 2;
+ Fractal->Col = rand () % (width * height); /* modif by JeKo */
+
+ Random_Simis (goomInfo, Fractal, Fractal->Components, 5 * MAX_SIMI);
+}
+
+
+/***************************************************************/
+
+static inline void
+Transform (SIMI * Simi, F_PT xo, F_PT yo, F_PT * x, F_PT * y)
+{
+ F_PT xx, yy;
+
+ xo = xo - Simi->Cx;
+ xo = (xo * Simi->R) >> FIX; /* / UNIT; */
+ yo = yo - Simi->Cy;
+ yo = (yo * Simi->R) >> FIX; /* / UNIT; */
+
+ xx = xo - Simi->Cx;
+ xx = (xx * Simi->R2) >> FIX; /* / UNIT; */
+ yy = -yo - Simi->Cy;
+ yy = (yy * Simi->R2) >> FIX; /* / UNIT; */
+
+ *x = ((xo * Simi->Ct - yo * Simi->St + xx * Simi->Ct2 - yy * Simi->St2)
+ >> FIX /* / UNIT */ ) + Simi->Cx;
+ *y = ((xo * Simi->St + yo * Simi->Ct + xx * Simi->St2 + yy * Simi->Ct2)
+ >> FIX /* / UNIT */ ) + Simi->Cy;
+}
+
+/***************************************************************/
+
+static void
+Trace (FRACTAL * F, F_PT xo, F_PT yo, IfsData * data)
+{
+ F_PT x, y, i;
+ SIMI *Cur;
+
+ Cur = data->Cur_F->Components;
+ for (i = data->Cur_F->Nb_Simi; i; --i, Cur++) {
+ Transform (Cur, xo, yo, &x, &y);
+
+ data->Buf->x = F->Lx + ((x * F->Lx) >> (FIX + 1) /* /(UNIT*2) */ );
+ data->Buf->y = F->Ly - ((y * F->Ly) >> (FIX + 1) /* /(UNIT*2) */ );
+ data->Buf++;
+
+ data->Cur_Pt++;
+
+ if (F->Depth && ((x - xo) >> 4) && ((y - yo) >> 4)) {
+ F->Depth--;
+ Trace (F, x, y, data);
+ F->Depth++;
+ }
+ }
+}
+
+static void
+Draw_Fractal (IfsData * data)
+{
+ FRACTAL *F = data->Root;
+ int i, j;
+ F_PT x, y, xo, yo;
+ SIMI *Cur, *Simi;
+
+ for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) {
+ Cur->Cx = DBL_To_F_PT (Cur->c_x);
+ Cur->Cy = DBL_To_F_PT (Cur->c_y);
+
+ Cur->Ct = DBL_To_F_PT (cos (Cur->A));
+ Cur->St = DBL_To_F_PT (sin (Cur->A));
+ Cur->Ct2 = DBL_To_F_PT (cos (Cur->A2));
+ Cur->St2 = DBL_To_F_PT (sin (Cur->A2));
+
+ Cur->R = DBL_To_F_PT (Cur->r);
+ Cur->R2 = DBL_To_F_PT (Cur->r2);
+ }
+
+
+ data->Cur_Pt = 0;
+ data->Cur_F = F;
+ data->Buf = F->Buffer2;
+ for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) {
+ xo = Cur->Cx;
+ yo = Cur->Cy;
+ for (Simi = F->Components, j = F->Nb_Simi; j; --j, Simi++) {
+ if (Simi == Cur)
+ continue;
+ Transform (Simi, xo, yo, &x, &y);
+ Trace (F, x, y, data);
+ }
+ }
+
+ /* Erase previous */
+
+ F->Cur_Pt = data->Cur_Pt;
+ data->Buf = F->Buffer1;
+ F->Buffer1 = F->Buffer2;
+ F->Buffer2 = data->Buf;
+}
+
+
+static IFSPoint *
+draw_ifs (PluginInfo * goomInfo, int *nbpt, IfsData * data)
+{
+ int i;
+ DBL u, uu, v, vv, u0, u1, u2, u3;
+ SIMI *S, *S1, *S2, *S3, *S4;
+ FRACTAL *F;
+
+ if (data->Root == NULL)
+ return NULL;
+ F = data->Root;
+ if (F->Buffer1 == NULL)
+ return NULL;
+
+ u = (DBL) (F->Count) * (DBL) (F->Speed) / 1000.0;
+ uu = u * u;
+ v = 1.0 - u;
+ vv = v * v;
+ u0 = vv * v;
+ u1 = 3.0 * vv * u;
+ u2 = 3.0 * v * uu;
+ u3 = u * uu;
+
+ S = F->Components;
+ S1 = S + F->Nb_Simi;
+ S2 = S1 + F->Nb_Simi;
+ S3 = S2 + F->Nb_Simi;
+ S4 = S3 + F->Nb_Simi;
+
+ for (i = F->Nb_Simi; i; --i, S++, S1++, S2++, S3++, S4++) {
+ S->c_x = u0 * S1->c_x + u1 * S2->c_x + u2 * S3->c_x + u3 * S4->c_x;
+ S->c_y = u0 * S1->c_y + u1 * S2->c_y + u2 * S3->c_y + u3 * S4->c_y;
+ S->r = u0 * S1->r + u1 * S2->r + u2 * S3->r + u3 * S4->r;
+ S->r2 = u0 * S1->r2 + u1 * S2->r2 + u2 * S3->r2 + u3 * S4->r2;
+ S->A = u0 * S1->A + u1 * S2->A + u2 * S3->A + u3 * S4->A;
+ S->A2 = u0 * S1->A2 + u1 * S2->A2 + u2 * S3->A2 + u3 * S4->A2;
+ }
+
+ Draw_Fractal (data);
+
+ if (F->Count >= 1000 / F->Speed) {
+ S = F->Components;
+ S1 = S + F->Nb_Simi;
+ S2 = S1 + F->Nb_Simi;
+ S3 = S2 + F->Nb_Simi;
+ S4 = S3 + F->Nb_Simi;
+
+ for (i = F->Nb_Simi; i; --i, S++, S1++, S2++, S3++, S4++) {
+ S2->c_x = 2.0 * S4->c_x - S3->c_x;
+ S2->c_y = 2.0 * S4->c_y - S3->c_y;
+ S2->r = 2.0 * S4->r - S3->r;
+ S2->r2 = 2.0 * S4->r2 - S3->r2;
+ S2->A = 2.0 * S4->A - S3->A;
+ S2->A2 = 2.0 * S4->A2 - S3->A2;
+
+ *S1 = *S4;
+ }
+ Random_Simis (goomInfo, F, F->Components + 3 * F->Nb_Simi, F->Nb_Simi);
+
+ Random_Simis (goomInfo, F, F->Components + 4 * F->Nb_Simi, F->Nb_Simi);
+
+ F->Count = 0;
+ } else
+ F->Count++;
+
+ F->Col++;
+
+ (*nbpt) = data->Cur_Pt;
+ return F->Buffer2;
+}
+
+
+/***************************************************************/
+
+static void
+release_ifs (IfsData * data)
+{
+ if (data->Root != NULL) {
+ free_ifs (data->Root);
+ (void) free ((void *) data->Root);
+ data->Root = (FRACTAL *) NULL;
+ }
+}
+
+#define RAND() goom_random(goomInfo->gRandom)
+
+static void
+ifs_update (PluginInfo * goomInfo, Pixel * data, Pixel * back, int increment,
+ IfsData * fx_data)
+{
+ static int couleur = 0xc0c0c0c0;
+ static int v[4] = { 2, 4, 3, 2 };
+ static int col[4] = { 2, 4, 3, 2 };
+
+#define MOD_MER 0
+#define MOD_FEU 1
+#define MOD_MERVER 2
+ static int mode = MOD_MERVER;
+ static int justChanged = 0;
+ static int cycle = 0;
+ int cycle10;
+
+ int nbpt;
+ IFSPoint *points;
+ int i;
+
+ int couleursl = couleur;
+ int width = goomInfo->screen.width;
+ int height = goomInfo->screen.height;
+
+ cycle++;
+ if (cycle >= 80)
+ cycle = 0;
+
+ if (cycle < 40)
+ cycle10 = cycle / 10;
+ else
+ cycle10 = 7 - cycle / 10;
+
+ {
+ unsigned char *tmp = (unsigned char *) &couleursl;
+
+ for (i = 0; i < 4; i++) {
+ *tmp = (*tmp) >> cycle10;
+ tmp++;
+ }
+ }
+
+ points = draw_ifs (goomInfo, &nbpt, fx_data);
+ nbpt--;
+
+#ifdef HAVE_MMX
+ movd_m2r (couleursl, mm1);
+ punpckldq_r2r (mm1, mm1);
+ for (i = 0; i < nbpt; i += increment) {
+ int x = points[i].x;
+ int y = points[i].y;
+
+ if ((x < width) && (y < height) && (x > 0) && (y > 0)) {
+ int pos = x + (y * width);
+
+ movd_m2r (back[pos], mm0);
+ paddusb_r2r (mm1, mm0);
+ movd_r2m (mm0, data[pos]);
+ }
+ }
+ emms (); /*__asm__ __volatile__ ("emms");*/
+#else
+ for (i = 0; i < nbpt; i += increment) {
+ int x = (int) points[i].x & 0x7fffffff;
+ int y = (int) points[i].y & 0x7fffffff;
+
+ if ((x < width) && (y < height)) {
+ int pos = x + (int) (y * width);
+ int tra = 0, i = 0;
+ unsigned char *bra = (unsigned char *) &back[pos];
+ unsigned char *dra = (unsigned char *) &data[pos];
+ unsigned char *cra = (unsigned char *) &couleursl;
+
+ for (; i < 4; i++) {
+ tra = *cra;
+ tra += *bra;
+ if (tra > 255)
+ tra = 255;
+ *dra = tra;
+ ++dra;
+ ++cra;
+ ++bra;
+ }
+ }
+ }
+#endif /*MMX*/
+ justChanged--;
+
+ col[ALPHA] = couleur >> (ALPHA * 8) & 0xff;
+ col[BLEU] = couleur >> (BLEU * 8) & 0xff;
+ col[VERT] = couleur >> (VERT * 8) & 0xff;
+ col[ROUGE] = couleur >> (ROUGE * 8) & 0xff;
+
+ if (mode == MOD_MER) {
+ col[BLEU] += v[BLEU];
+ if (col[BLEU] > 255) {
+ col[BLEU] = 255;
+ v[BLEU] = -(RAND () % 4) - 1;
+ }
+ if (col[BLEU] < 32) {
+ col[BLEU] = 32;
+ v[BLEU] = (RAND () % 4) + 1;
+ }
+
+ col[VERT] += v[VERT];
+ if (col[VERT] > 200) {
+ col[VERT] = 200;
+ v[VERT] = -(RAND () % 3) - 2;
+ }
+ if (col[VERT] > col[BLEU]) {
+ col[VERT] = col[BLEU];
+ v[VERT] = v[BLEU];
+ }
+ if (col[VERT] < 32) {
+ col[VERT] = 32;
+ v[VERT] = (RAND () % 3) + 2;
+ }
+
+ col[ROUGE] += v[ROUGE];
+ if (col[ROUGE] > 64) {
+ col[ROUGE] = 64;
+ v[ROUGE] = -(RAND () % 4) - 1;
+ }
+ if (col[ROUGE] < 0) {
+ col[ROUGE] = 0;
+ v[ROUGE] = (RAND () % 4) + 1;
+ }
+
+ col[ALPHA] += v[ALPHA];
+ if (col[ALPHA] > 0) {
+ col[ALPHA] = 0;
+ v[ALPHA] = -(RAND () % 4) - 1;
+ }
+ if (col[ALPHA] < 0) {
+ col[ALPHA] = 0;
+ v[ALPHA] = (RAND () % 4) + 1;
+ }
+
+ if (((col[VERT] > 32) && (col[ROUGE] < col[VERT] + 40)
+ && (col[VERT] < col[ROUGE] + 20) && (col[BLEU] < 64)
+ && (RAND () % 20 == 0)) && (justChanged < 0)) {
+ mode = RAND () % 3 ? MOD_FEU : MOD_MERVER;
+ justChanged = 250;
+ }
+ } else if (mode == MOD_MERVER) {
+ col[BLEU] += v[BLEU];
+ if (col[BLEU] > 128) {
+ col[BLEU] = 128;
+ v[BLEU] = -(RAND () % 4) - 1;
+ }
+ if (col[BLEU] < 16) {
+ col[BLEU] = 16;
+ v[BLEU] = (RAND () % 4) + 1;
+ }
+
+ col[VERT] += v[VERT];
+ if (col[VERT] > 200) {
+ col[VERT] = 200;
+ v[VERT] = -(RAND () % 3) - 2;
+ }
+ if (col[VERT] > col[ALPHA]) {
+ col[VERT] = col[ALPHA];
+ v[VERT] = v[ALPHA];
+ }
+ if (col[VERT] < 32) {
+ col[VERT] = 32;
+ v[VERT] = (RAND () % 3) + 2;
+ }
+
+ col[ROUGE] += v[ROUGE];
+ if (col[ROUGE] > 128) {
+ col[ROUGE] = 128;
+ v[ROUGE] = -(RAND () % 4) - 1;
+ }
+ if (col[ROUGE] < 0) {
+ col[ROUGE] = 0;
+ v[ROUGE] = (RAND () % 4) + 1;
+ }
+
+ col[ALPHA] += v[ALPHA];
+ if (col[ALPHA] > 255) {
+ col[ALPHA] = 255;
+ v[ALPHA] = -(RAND () % 4) - 1;
+ }
+ if (col[ALPHA] < 0) {
+ col[ALPHA] = 0;
+ v[ALPHA] = (RAND () % 4) + 1;
+ }
+
+ if (((col[VERT] > 32) && (col[ROUGE] < col[VERT] + 40)
+ && (col[VERT] < col[ROUGE] + 20) && (col[BLEU] < 64)
+ && (RAND () % 20 == 0)) && (justChanged < 0)) {
+ mode = RAND () % 3 ? MOD_FEU : MOD_MER;
+ justChanged = 250;
+ }
+ } else if (mode == MOD_FEU) {
+
+ col[BLEU] += v[BLEU];
+ if (col[BLEU] > 64) {
+ col[BLEU] = 64;
+ v[BLEU] = -(RAND () % 4) - 1;
+ }
+ if (col[BLEU] < 0) {
+ col[BLEU] = 0;
+ v[BLEU] = (RAND () % 4) + 1;
+ }
+
+ col[VERT] += v[VERT];
+ if (col[VERT] > 200) {
+ col[VERT] = 200;
+ v[VERT] = -(RAND () % 3) - 2;
+ }
+ if (col[VERT] > col[ROUGE] + 20) {
+ col[VERT] = col[ROUGE] + 20;
+ v[VERT] = -(RAND () % 3) - 2;
+ v[ROUGE] = (RAND () % 4) + 1;
+ v[BLEU] = (RAND () % 4) + 1;
+ }
+ if (col[VERT] < 0) {
+ col[VERT] = 0;
+ v[VERT] = (RAND () % 3) + 2;
+ }
+
+ col[ROUGE] += v[ROUGE];
+ if (col[ROUGE] > 255) {
+ col[ROUGE] = 255;
+ v[ROUGE] = -(RAND () % 4) - 1;
+ }
+ if (col[ROUGE] > col[VERT] + 40) {
+ col[ROUGE] = col[VERT] + 40;
+ v[ROUGE] = -(RAND () % 4) - 1;
+ }
+ if (col[ROUGE] < 0) {
+ col[ROUGE] = 0;
+ v[ROUGE] = (RAND () % 4) + 1;
+ }
+
+ col[ALPHA] += v[ALPHA];
+ if (col[ALPHA] > 0) {
+ col[ALPHA] = 0;
+ v[ALPHA] = -(RAND () % 4) - 1;
+ }
+ if (col[ALPHA] < 0) {
+ col[ALPHA] = 0;
+ v[ALPHA] = (RAND () % 4) + 1;
+ }
+
+ if (((col[ROUGE] < 64) && (col[VERT] > 32) && (col[VERT] < col[BLEU])
+ && (col[BLEU] > 32)
+ && (RAND () % 20 == 0)) && (justChanged < 0)) {
+ mode = RAND () % 2 ? MOD_MER : MOD_MERVER;
+ justChanged = 250;
+ }
+ }
+
+ couleur = (col[ALPHA] << (ALPHA * 8))
+ | (col[BLEU] << (BLEU * 8))
+ | (col[VERT] << (VERT * 8))
+ | (col[ROUGE] << (ROUGE * 8));
+}
+
+/** VISUAL_FX WRAPPER FOR IFS */
+
+static void
+ifs_vfx_apply (VisualFX * _this, Pixel * src, Pixel * dest,
+ PluginInfo * goomInfo)
+{
+
+ IfsData *data = (IfsData *) _this->fx_data;
+
+ if (!data->initalized) {
+ data->initalized = 1;
+ init_ifs (goomInfo, data);
+ }
+ ifs_update (goomInfo, dest, src, goomInfo->update.ifs_incr, data);
+ /*TODO: trouver meilleur soluce pour increment (mettre le code de gestion de l'ifs dans ce fichier: ifs_vfx_apply) */
+}
+
+static void
+ifs_vfx_init (VisualFX * _this, PluginInfo * info)
+{
+
+ IfsData *data = (IfsData *) malloc (sizeof (IfsData));
+
+ data->Root = (FRACTAL *) NULL;
+ data->initalized = 0;
+ _this->fx_data = data;
+}
+
+static void
+ifs_vfx_free (VisualFX * _this)
+{
+ IfsData *data = (IfsData *) _this->fx_data;
+
+ release_ifs (data);
+ free (data);
+}
+
+VisualFX
+ifs_visualfx_create (void)
+{
+ VisualFX vfx;
+
+ vfx.init = ifs_vfx_init;
+ vfx.free = ifs_vfx_free;
+ vfx.apply = ifs_vfx_apply;
+ return vfx;
+}
diff --git a/gst/goom/ifs.h b/gst/goom/ifs.h
new file mode 100644
index 00000000..fab04266
--- /dev/null
+++ b/gst/goom/ifs.h
@@ -0,0 +1,27 @@
+/*
+ * File created 11 april 2002 by JeKo <jeko@free.fr>
+ */
+
+#ifndef IFS_H
+#define IFS_H
+
+#include "goom_config.h"
+#include "goom_graphic.h"
+#include "goom_plugin_info.h"
+#include "goom_visual_fx.h"
+
+VisualFX ifs_visualfx_create(void);
+
+/* init ifs for a (width)x(height) output. * /
+void init_ifs (PluginInfo *goomInfo, int width, int height);
+
+/ * draw an ifs on the buffer (which size is width * height)
+ increment means that we draw 1/increment of the ifs's points * /
+void ifs_update (PluginInfo *goomInfo, Pixel * buffer, Pixel * back, int width, int height, int increment);
+
+/ * free all ifs's data. * /
+void release_ifs (void);
+*/
+
+
+#endif
diff --git a/gst/goom/lines.c b/gst/goom/lines.c
index 3214e1db..a2a94d43 100644
--- a/gst/goom/lines.c
+++ b/gst/goom/lines.c
@@ -1,107 +1,241 @@
/*
* lines.c
- * iTunesXPlugIn
- *
- * Created by guillaum on Tue Aug 14 2001.
- * Copyright (c) 2001 __CompanyName__. All rights reserved.
- *
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "lines.h"
#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "goom_tools.h"
+#include "drawmethods.h"
+#include "goom_plugin_info.h"
static inline unsigned char
-lighten (unsigned char value, unsigned char power)
+lighten (unsigned char value, float power)
{
- unsigned char i;
+ int val = value;
+ float t = (float) val * log10 (power) / 2.0;
- for (i = 0; i < power; i++)
- value += (255 - value) / 5;
- return value;
+ if (t > 0) {
+ val = (int) t; /* (32.0f * log (t)); */
+ if (val > 255)
+ val = 255;
+ if (val < 0)
+ val = 0;
+ return val;
+ } else {
+ return 0;
+ }
}
-void
-goom_lines (GoomData * goomdata, gint16 data[2][512], unsigned int ID,
- unsigned int *p, guint32 power)
+static void
+lightencolor (guint32 * col, float power)
{
- guint32 color1;
- guint32 color2;
- guint32 resolx = goomdata->resolx;
- guint32 resoly = goomdata->resoly;
- unsigned char *color = 1 + (unsigned char *) &color1;
-
- switch (ID) {
- case 0: /* Horizontal stereo lines */
- {
- color1 = 0x0000AA00;
- color2 = 0x00AA0000;
- break;
- }
+ unsigned char *color;
- case 1: /* Stereo circles */
- {
- color1 = 0x00AA33DD;
- color2 = 0x00AA33DD;
- break;
- }
- }
+ color = (unsigned char *) col;
*color = lighten (*color, power);
color++;
*color = lighten (*color, power);
color++;
*color = lighten (*color, power);
- color = 1 + (unsigned char *) &color2;
- *color = lighten (*color, power);
- color++;
- *color = lighten (*color, power);
color++;
*color = lighten (*color, power);
+}
- switch (ID) {
- case 0: /* Horizontal stereo lines */
- {
- unsigned int i;
+
+static void
+genline (int id, float param, GMUnitPointer * l, int rx, int ry)
+{
+ int i;
+
+ switch (id) {
+ case GML_HLINE:
for (i = 0; i < 512; i++) {
- guint32 plot;
-
- plot = i * resolx / 512 + (resoly / 4 + data[0][i] / 1600) * resolx;
- p[plot] = color1;
- p[plot + 1] = color1;
- plot = i * resolx / 512 + (resoly * 3 / 4 - data[1][i] / 1600) * resolx;
- p[plot] = color2;
- p[plot + 1] = color2;
+ l[i].x = ((float) i * rx) / 512.0f;
+ l[i].y = param;
+ l[i].angle = M_PI / 2.0f;
}
- break;
- }
+ return;
+ case GML_VLINE:
+ for (i = 0; i < 512; i++) {
+ l[i].y = ((float) i * ry) / 512.0f;
+ l[i].x = param;
+ l[i].angle = 0.0f;
+ }
+ return;
+ case GML_CIRCLE:
+ for (i = 0; i < 512; i++) {
+ float cosa, sina;
- case 1: /* Stereo circles */
- {
- float z;
- unsigned int monX = resolx / 2;
- float monY = resoly / 4;
- float monY2 = resoly / 2;
-
- for (z = 0; z < 6.2832f; z += 1.0f / monY) {
- /* float offset1 = 128+data[1][(unsigned int)(z*81.33f)])/200000; */
- p[monX + (unsigned int) ((monY + ((float) resoly) * (128 +
- data[1][(unsigned int) (z * 81.33f)]) / 200000) *
- cos (z) + resolx * (unsigned int) (monY2 + (monY +
- ((float) resoly) * (128 +
- data[1][(unsigned int) (z * 81.33f)]) / 400000) *
- sin (z)))] = color1;
- p[monX + (unsigned int) ((monY - ((float) resoly) * (128 +
- data[0][(unsigned int) (z * 81.33f)]) / 200000) *
- cos (z) + resolx * (unsigned int) (monY2 + (monY -
- ((float) resoly) * (128 +
- data[0][(unsigned int) (z * 81.33f)]) / 400000) *
- sin (z)))] = color2;
+ l[i].angle = 2.0f * M_PI * (float) i / 512.0f;
+ cosa = param * cos (l[i].angle);
+ sina = param * sin (l[i].angle);
+ l[i].x = ((float) rx / 2.0f) + cosa;
+ l[i].y = (float) ry / 2.0f + sina;
}
- break;
+ return;
+ }
+}
+
+static guint32
+getcouleur (int mode)
+{
+ switch (mode) {
+ case GML_RED:
+ return (230 << (ROUGE * 8)) | (120 << (VERT * 8)) | (18 << (BLEU * 8));
+ case GML_ORANGE_J:
+ return (120 << (VERT * 8)) | (252 << (ROUGE * 8)) | (18 << (BLEU * 8));
+ case GML_ORANGE_V:
+ return (160 << (VERT * 8)) | (236 << (ROUGE * 8)) | (40 << (BLEU * 8));
+ case GML_BLEUBLANC:
+ return (40 << (BLEU * 8)) | (220 << (ROUGE * 8)) | (140 << (VERT * 8));
+ case GML_VERT:
+ return (200 << (VERT * 8)) | (80 << (ROUGE * 8)) | (18 << (BLEU * 8));
+ case GML_BLEU:
+ return (250 << (BLEU * 8)) | (30 << (VERT * 8)) | (80 << (ROUGE * 8));
+ case GML_BLACK:
+ return (16 << (BLEU * 8)) | (16 << (VERT * 8)) | (16 << (ROUGE * 8));
+ }
+ return 0;
+}
+
+void
+goom_lines_set_res (GMLine * gml, int rx, int ry)
+{
+ if (gml != NULL) {
+ gml->screenX = rx;
+ gml->screenY = ry;
+
+ genline (gml->IDdest, gml->param, gml->points2, rx, ry);
+ }
+}
+
+
+static void
+goom_lines_move (GMLine * l)
+{
+ int i;
+ unsigned char *c1, *c2;
+
+ for (i = 0; i < 512; i++) {
+ l->points[i].x = (l->points2[i].x + 39.0f * l->points[i].x) / 40.0f;
+ l->points[i].y = (l->points2[i].y + 39.0f * l->points[i].y) / 40.0f;
+ l->points[i].angle =
+ (l->points2[i].angle + 39.0f * l->points[i].angle) / 40.0f;
+ }
+
+ c1 = (unsigned char *) &l->color;
+ c2 = (unsigned char *) &l->color2;
+ for (i = 0; i < 4; i++) {
+ int cc1, cc2;
+
+ cc1 = *c1;
+ cc2 = *c2;
+ *c1 = (unsigned char) ((cc1 * 63 + cc2) >> 6);
+ ++c1;
+ ++c2;
+ }
+
+ l->power += l->powinc;
+ if (l->power < 1.1f) {
+ l->power = 1.1f;
+ l->powinc = (float) (goom_irand (l->goomInfo->gRandom, 20) + 10) / 300.0f;
+ }
+ if (l->power > 17.5f) {
+ l->power = 17.5f;
+ l->powinc = -(float) (goom_irand (l->goomInfo->gRandom, 20) + 10) / 300.0f;
+ }
+
+ l->amplitude = (99.0f * l->amplitude + l->amplitudeF) / 100.0f;
+}
+
+void
+goom_lines_switch_to (GMLine * gml, int IDdest,
+ float param, float amplitude, int col)
+{
+ genline (IDdest, param, gml->points2, gml->screenX, gml->screenY);
+ gml->IDdest = IDdest;
+ gml->param = param;
+ gml->amplitudeF = amplitude;
+ gml->color2 = getcouleur (col);
+}
+
+GMLine *
+goom_lines_init (PluginInfo * goomInfo, int rx, int ry,
+ int IDsrc, float paramS, int coulS, int IDdest, float paramD, int coulD)
+{
+ GMLine *l = (GMLine *) malloc (sizeof (GMLine));
+
+ l->goomInfo = goomInfo;
+
+ l->points = (GMUnitPointer *) malloc (512 * sizeof (GMUnitPointer));
+ l->points2 = (GMUnitPointer *) malloc (512 * sizeof (GMUnitPointer));
+ l->nbPoints = 512;
+
+ l->IDdest = IDdest;
+ l->param = paramD;
+
+ l->amplitude = l->amplitudeF = 1.0f;
+
+ genline (IDsrc, paramS, l->points, rx, ry);
+ genline (IDdest, paramD, l->points2, rx, ry);
+
+ l->color = getcouleur (coulS);
+ l->color2 = getcouleur (coulD);
+
+ l->screenX = rx;
+ l->screenY = ry;
+
+ l->power = 0.0f;
+ l->powinc = 0.01f;
+
+ goom_lines_switch_to (l, IDdest, paramD, 1.0f, coulD);
+
+ return l;
+}
+
+void
+goom_lines_free (GMLine ** l)
+{
+ free ((*l)->points);
+ free (*l);
+ l = NULL;
+}
+
+void
+goom_lines_draw (PluginInfo * plug, GMLine * line, gint16 data[512], Pixel * p)
+{
+ if (line != NULL) {
+ int i, x1, y1;
+ guint32 color = line->color;
+ GMUnitPointer *pt = &(line->points[0]);
+
+ float cosa = cos (pt->angle) / 1000.0f;
+ float sina = sin (pt->angle) / 1000.0f;
+
+ lightencolor (&color, line->power);
+
+ x1 = (int) (pt->x + cosa * line->amplitude * data[0]);
+ y1 = (int) (pt->y + sina * line->amplitude * data[0]);
+
+ for (i = 1; i < 512; i++) {
+ int x2, y2;
+ GMUnitPointer *pt = &(line->points[i]);
+
+ float cosa = cos (pt->angle) / 1000.0f;
+ float sina = sin (pt->angle) / 1000.0f;
+
+ x2 = (int) (pt->x + cosa * line->amplitude * data[i]);
+ y2 = (int) (pt->y + sina * line->amplitude * data[i]);
+
+ plug->methods.draw_line (p, x1, y1, x2, y2, color, line->screenX,
+ line->screenY);
+
+ x1 = x2;
+ y1 = y2;
}
+ goom_lines_move (line);
}
}
diff --git a/gst/goom/lines.h b/gst/goom/lines.h
index 548f339a..9c6df924 100644
--- a/gst/goom/lines.h
+++ b/gst/goom/lines.h
@@ -1,16 +1,81 @@
+#ifndef _LINES_H
+#define _LINES_H
+
/*
* lines.h
- * iGoom
- *
- * Created by guillaum on Tue Aug 14 2001.
- * Copyright (c) 2001 ios. All rights reserved.
- *
+ * Goom
+ * Copyright (c) 2000-2003 iOS-software. All rights reserved.
*/
-#include <glib.h>
-#include "graphic.h"
-#include "goom_core.h"
+#include "goom_typedefs.h"
+#include "goom_graphic.h"
+#include "goom_config.h"
+
+struct _GMUNITPOINTER
+{
+ float x;
+ float y;
+ float angle;
+};
+
+/* tableau de points */
+struct _GMLINE
+{
+
+ GMUnitPointer *points;
+ GMUnitPointer *points2;
+ int IDdest;
+ float param;
+ float amplitudeF;
+ float amplitude;
+
+ int nbPoints;
+ guint32 color; /* pour l'instant je stocke la couleur a terme, on stockera le mode couleur et l'on animera */
+ guint32 color2;
+
+ int screenX;
+ int screenY;
+
+ float power;
+ float powinc;
+
+ PluginInfo *goomInfo;
+};
+
+/* les ID possibles */
+
+#define GML_CIRCLE 0
+/* (param = radius) */
+
+#define GML_HLINE 1
+/* (param = y) */
+
+#define GML_VLINE 2
+/* (param = x) */
+
+/* les modes couleur possible (si tu mets un autre c'est noir) */
+
+#define GML_BLEUBLANC 0
+#define GML_RED 1
+#define GML_ORANGE_V 2
+#define GML_ORANGE_J 3
+#define GML_VERT 4
+#define GML_BLEU 5
+#define GML_BLACK 6
+
+/* construit un effet de line (une ligne horitontale pour commencer) */
+GMLine *goom_lines_init (PluginInfo *goomInfo, int rx, int ry,
+ int IDsrc, float paramS, int modeCoulSrc,
+ int IDdest, float paramD, int modeCoulDest);
+
+void goom_lines_switch_to (GMLine * gml, int IDdest, float param,
+ float amplitude,
+ int modeCoul);
+
+void goom_lines_set_res (GMLine * gml, int rx, int ry);
-void goom_lines(GoomData *goomdata, gint16 data [2][512], unsigned int ID,unsigned int* p, guint32 power);
+void goom_lines_free (GMLine ** gml);
+void goom_lines_draw (PluginInfo *plugInfo, GMLine * gml, gint16 data[512], Pixel *p);
+#endif /* _LINES_H */
diff --git a/gst/goom/mathtools.c b/gst/goom/mathtools.c
new file mode 100644
index 00000000..4b275c62
--- /dev/null
+++ b/gst/goom/mathtools.c
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------------*/
+/*
+** mathtools.c
+** Goom Project
+**
+** Created by Jeko on Sun Jul 20 2003
+ ** Copyright (c) 2003 iOS. All rights reserved.
+*/
+/*---------------------------------------------------------------------------*/
+
+#include "mathtools.h"
+
+float sin256[256] = {
+ 0, 0.0245412, 0.0490677, 0.0735646, 0.0980171, 0.122411, 0.14673, 0.170962,
+ 0.19509, 0.219101, 0.24298, 0.266713, 0.290285, 0.313682, 0.33689,
+ 0.359895, 0.382683, 0.405241, 0.427555, 0.449611, 0.471397, 0.492898,
+ 0.514103, 0.534998, 0.55557, 0.575808, 0.595699, 0.615232, 0.634393,
+ 0.653173, 0.671559, 0.689541, 0.707107, 0.724247, 0.740951, 0.757209,
+ 0.77301, 0.788346, 0.803208, 0.817585, 0.83147, 0.844854, 0.857729,
+ 0.870087, 0.881921, 0.893224, 0.903989, 0.91421, 0.92388, 0.932993,
+ 0.941544, 0.949528, 0.95694, 0.963776, 0.970031, 0.975702, 0.980785,
+ 0.985278, 0.989177, 0.99248, 0.995185, 0.99729, 0.998795, 0.999699, 1,
+ 0.999699, 0.998795, 0.99729, 0.995185, 0.99248, 0.989177, 0.985278,
+ 0.980785, 0.975702, 0.970031, 0.963776, 0.95694, 0.949528, 0.941544,
+ 0.932993, 0.92388, 0.91421, 0.903989, 0.893224, 0.881921, 0.870087,
+ 0.857729, 0.844854, 0.83147, 0.817585, 0.803208, 0.788346, 0.77301,
+ 0.757209, 0.740951, 0.724247, 0.707107, 0.689541, 0.671559, 0.653173,
+ 0.634393, 0.615232, 0.595699, 0.575808, 0.55557, 0.534998, 0.514103,
+ 0.492898, 0.471397, 0.449611, 0.427555, 0.405241, 0.382683, 0.359895,
+ 0.33689, 0.313682, 0.290285, 0.266713, 0.24298, 0.219101, 0.19509,
+ 0.170962, 0.14673, 0.122411, 0.0980171, 0.0735646, 0.0490677, 0.0245412,
+ 1.22465e-16, -0.0245412, -0.0490677, -0.0735646, -0.0980171, -0.122411,
+ -0.14673, -0.170962, -0.19509, -0.219101, -0.24298, -0.266713, -0.290285,
+ -0.313682, -0.33689, -0.359895, -0.382683, -0.405241, -0.427555,
+ -0.449611, -0.471397, -0.492898, -0.514103, -0.534998, -0.55557,
+ -0.575808, -0.595699, -0.615232, -0.634393, -0.653173, -0.671559,
+ -0.689541, -0.707107, -0.724247, -0.740951, -0.757209, -0.77301,
+ -0.788346, -0.803208, -0.817585, -0.83147, -0.844854, -0.857729,
+ -0.870087, -0.881921, -0.893224, -0.903989, -0.91421, -0.92388, -0.932993,
+ -0.941544, -0.949528, -0.95694, -0.963776, -0.970031, -0.975702,
+ -0.980785, -0.985278, -0.989177, -0.99248, -0.995185, -0.99729, -0.998795,
+ -0.999699, -1, -0.999699, -0.998795, -0.99729, -0.995185, -0.99248,
+ -0.989177, -0.985278, -0.980785, -0.975702, -0.970031, -0.963776,
+ -0.95694, -0.949528, -0.941544, -0.932993, -0.92388, -0.91421, -0.903989,
+ -0.893224, -0.881921, -0.870087, -0.857729, -0.844854, -0.83147,
+ -0.817585, -0.803208, -0.788346, -0.77301, -0.757209, -0.740951,
+ -0.724247, -0.707107, -0.689541, -0.671559, -0.653173, -0.634393,
+ -0.615232, -0.595699, -0.575808, -0.55557, -0.534998, -0.514103,
+ -0.492898, -0.471397, -0.449611, -0.427555, -0.405241, -0.382683,
+ -0.359895, -0.33689, -0.313682, -0.290285, -0.266713, -0.24298, -0.219101,
+ -0.19509, -0.170962, -0.14673, -0.122411, -0.0980171, -0.0735646,
+ -0.0490677, -0.0245412
+};
+
+float cos256[256] = {
+ 0, 0.999699, 0.998795, 0.99729, 0.995185, 0.99248, 0.989177, 0.985278,
+ 0.980785, 0.975702, 0.970031, 0.963776, 0.95694, 0.949528, 0.941544,
+ 0.932993, 0.92388, 0.91421, 0.903989, 0.893224, 0.881921, 0.870087,
+ 0.857729, 0.844854, 0.83147, 0.817585, 0.803208, 0.788346, 0.77301,
+ 0.757209, 0.740951, 0.724247, 0.707107, 0.689541, 0.671559, 0.653173,
+ 0.634393, 0.615232, 0.595699, 0.575808, 0.55557, 0.534998, 0.514103,
+ 0.492898, 0.471397, 0.449611, 0.427555, 0.405241, 0.382683, 0.359895,
+ 0.33689, 0.313682, 0.290285, 0.266713, 0.24298, 0.219101, 0.19509,
+ 0.170962, 0.14673, 0.122411, 0.0980171, 0.0735646, 0.0490677, 0.0245412,
+ 6.12323e-17, -0.0245412, -0.0490677, -0.0735646, -0.0980171, -0.122411,
+ -0.14673, -0.170962, -0.19509, -0.219101, -0.24298, -0.266713, -0.290285,
+ -0.313682, -0.33689, -0.359895, -0.382683, -0.405241, -0.427555,
+ -0.449611, -0.471397, -0.492898, -0.514103, -0.534998, -0.55557,
+ -0.575808, -0.595699, -0.615232, -0.634393, -0.653173, -0.671559,
+ -0.689541, -0.707107, -0.724247, -0.740951, -0.757209, -0.77301,
+ -0.788346, -0.803208, -0.817585, -0.83147, -0.844854, -0.857729,
+ -0.870087, -0.881921, -0.893224, -0.903989, -0.91421, -0.92388, -0.932993,
+ -0.941544, -0.949528, -0.95694, -0.963776, -0.970031, -0.975702,
+ -0.980785, -0.985278, -0.989177, -0.99248, -0.995185, -0.99729, -0.998795,
+ -0.999699, -1, -0.999699, -0.998795, -0.99729, -0.995185, -0.99248,
+ -0.989177, -0.985278, -0.980785, -0.975702, -0.970031, -0.963776,
+ -0.95694, -0.949528, -0.941544, -0.932993, -0.92388, -0.91421, -0.903989,
+ -0.893224, -0.881921, -0.870087, -0.857729, -0.844854, -0.83147,
+ -0.817585, -0.803208, -0.788346, -0.77301, -0.757209, -0.740951,
+ -0.724247, -0.707107, -0.689541, -0.671559, -0.653173, -0.634393,
+ -0.615232, -0.595699, -0.575808, -0.55557, -0.534998, -0.514103,
+ -0.492898, -0.471397, -0.449611, -0.427555, -0.405241, -0.382683,
+ -0.359895, -0.33689, -0.313682, -0.290285, -0.266713, -0.24298, -0.219101,
+ -0.19509, -0.170962, -0.14673, -0.122411, -0.0980171, -0.0735646,
+ -0.0490677, -0.0245412, -1.83697e-16, 0.0245412, 0.0490677, 0.0735646,
+ 0.0980171, 0.122411, 0.14673, 0.170962, 0.19509, 0.219101, 0.24298,
+ 0.266713, 0.290285, 0.313682, 0.33689, 0.359895, 0.382683, 0.405241,
+ 0.427555, 0.449611, 0.471397, 0.492898, 0.514103, 0.534998, 0.55557,
+ 0.575808, 0.595699, 0.615232, 0.634393, 0.653173, 0.671559, 0.689541,
+ 0.707107, 0.724247, 0.740951, 0.757209, 0.77301, 0.788346, 0.803208,
+ 0.817585, 0.83147, 0.844854, 0.857729, 0.870087, 0.881921, 0.893224,
+ 0.903989, 0.91421, 0.92388, 0.932993, 0.941544, 0.949528, 0.95694,
+ 0.963776, 0.970031, 0.975702, 0.980785, 0.985278, 0.989177, 0.99248,
+ 0.995185, 0.99729, 0.998795, 0.999699
+};
diff --git a/gst/goom/mathtools.h b/gst/goom/mathtools.h
new file mode 100644
index 00000000..0e2293c3
--- /dev/null
+++ b/gst/goom/mathtools.h
@@ -0,0 +1,36 @@
+#ifndef MATHTOOLS_H
+#define MATHTOOLS_H
+
+
+#define _double2fixmagic (68719476736.0*1.5)
+/* 2^36 * 1.5, (52-_shiftamt=36) uses limited precisicion to floor */
+#define _shiftamt 16
+/* 16.16 fixed point representation */
+
+#if BigEndian_
+#define iexp_ 0
+#define iman_ 1
+#else
+#define iexp_ 1
+#define iman_ 0
+#endif /* BigEndian_ */
+
+/* TODO: this optimization is very efficient: put it again when all works
+#ifdef HAVE_MMX
+#define F2I(dbl,i) {double d = dbl + _double2fixmagic; i = ((int*)&d)[iman_] >> _shiftamt;}
+#else*/
+#define F2I(dbl,i) i=(int)dbl;
+/*#endif*/
+
+#if 0
+#define SINCOS(f,s,c) \
+ __asm__ __volatile__ ("fsincos" : "=t" (c), "=u" (s) : "0" (f))
+#else
+#define SINCOS(f,s,c) {s=sin(f);c=cos(f);}
+#endif
+
+extern float sin256[256];
+extern float cos256[256];
+
+#endif
+
diff --git a/gst/goom/mmx.c b/gst/goom/mmx.c
new file mode 100644
index 00000000..4cee0acb
--- /dev/null
+++ b/gst/goom/mmx.c
@@ -0,0 +1,256 @@
+#include "config.h"
+
+#if defined (HAVE_CPU_I386) || defined (HAVE_CPU_X86_64)
+
+#define BUFFPOINTNB 16
+#define BUFFPOINTMASK 0xffff
+#define BUFFINCR 0xff
+
+#include "mmx.h"
+#include "goom_graphic.h"
+
+#define sqrtperte 16
+// faire : a % sqrtperte <=> a & pertemask
+#define PERTEMASK 0xf
+// faire : a / sqrtperte <=> a >> PERTEDEC
+#define PERTEDEC 4
+
+int
+mmx_supported (void)
+{
+ return (mm_support () & 0x1);
+}
+
+void
+zoom_filter_mmx (int prevX, int prevY,
+ Pixel * expix1, Pixel * expix2,
+ int *brutS, int *brutD, int buffratio, int precalCoef[16][16])
+{
+ unsigned int ax = (prevX - 1) << PERTEDEC, ay = (prevY - 1) << PERTEDEC;
+
+ int bufsize = prevX * prevY;
+ int loop;
+
+ __asm__ __volatile__ ("pxor %mm7,%mm7");
+
+ for (loop = 0; loop < bufsize; loop++) {
+ /* int couleur; */
+ int px, py;
+ int pos;
+ int coeffs;
+
+ int myPos = loop << 1, myPos2 = myPos + 1;
+ int brutSmypos = brutS[myPos];
+
+ px = brutSmypos + (((brutD[myPos] -
+ brutSmypos) * buffratio) >> BUFFPOINTNB);
+ brutSmypos = brutS[myPos2];
+ py = brutSmypos + (((brutD[myPos2] -
+ brutSmypos) * buffratio) >> BUFFPOINTNB);
+
+ if ((py >= ay) || (px >= ax)) {
+ pos = coeffs = 0;
+ } else {
+ pos = ((px >> PERTEDEC) + prevX * (py >> PERTEDEC));
+ // coef en modulo 15
+ coeffs = precalCoef[px & PERTEMASK][py & PERTEMASK];
+ }
+
+ __asm__ __volatile__ ("movd %2, %%mm6 \n\t"
+ /* recuperation des deux premiers pixels dans mm0 et mm1 */
+ "movq (%3,%1,4), %%mm0 \n\t" /* b1-v1-r1-a1-b2-v2-r2-a2 */
+ "movq %%mm0, %%mm1 \n\t" /* b1-v1-r1-a1-b2-v2-r2-a2 */
+ /* depackage du premier pixel */
+ "punpcklbw %%mm7, %%mm0 \n\t" /* 00-b2-00-v2-00-r2-00-a2 */
+ "movq %%mm6, %%mm5 \n\t" /* ??-??-??-??-c4-c3-c2-c1 */
+ /* depackage du 2ieme pixel */
+ "punpckhbw %%mm7, %%mm1 \n\t" /* 00-b1-00-v1-00-r1-00-a1 */
+ /* extraction des coefficients... */
+ "punpcklbw %%mm5, %%mm6 \n\t" /* c4-c4-c3-c3-c2-c2-c1-c1 */
+ "movq %%mm6, %%mm4 \n\t" /* c4-c4-c3-c3-c2-c2-c1-c1 */
+ "movq %%mm6, %%mm5 \n\t" /* c4-c4-c3-c3-c2-c2-c1-c1 */
+ "punpcklbw %%mm5, %%mm6 \n\t" /* c2-c2-c2-c2-c1-c1-c1-c1 */
+ "punpckhbw %%mm5, %%mm4 \n\t" /* c4-c4-c4-c4-c3-c3-c3-c3 */
+ "movq %%mm6, %%mm3 \n\t" /* c2-c2-c2-c2-c1-c1-c1-c1 */
+ "punpcklbw %%mm7, %%mm6 \n\t" /* 00-c1-00-c1-00-c1-00-c1 */
+ "punpckhbw %%mm7, %%mm3 \n\t" /* 00-c2-00-c2-00-c2-00-c2 */
+ /* multiplication des pixels par les coefficients */
+ "pmullw %%mm6, %%mm0 \n\t" /* c1*b2-c1*v2-c1*r2-c1*a2 */
+ "pmullw %%mm3, %%mm1 \n\t" /* c2*b1-c2*v1-c2*r1-c2*a1 */
+ "paddw %%mm1, %%mm0 \n\t"
+ /* ...extraction des 2 derniers coefficients */
+ "movq %%mm4, %%mm5 \n\t" /* c4-c4-c4-c4-c3-c3-c3-c3 */
+ "punpcklbw %%mm7, %%mm4 \n\t" /* 00-c3-00-c3-00-c3-00-c3 */
+ "punpckhbw %%mm7, %%mm5 \n\t" /* 00-c4-00-c4-00-c4-00-c4 */
+ /* ajouter la longueur de ligne a esi */
+ "addl 8(%%ebp),%1 \n\t"
+ /* recuperation des 2 derniers pixels */
+ "movq (%3,%1,4), %%mm1 \n\t" "movq %%mm1, %%mm2 \n\t"
+ /* depackage des pixels */
+ "punpcklbw %%mm7, %%mm1 \n\t" "punpckhbw %%mm7, %%mm2 \n\t"
+ /* multiplication pas les coeffs */
+ "pmullw %%mm4, %%mm1 \n\t" "pmullw %%mm5, %%mm2 \n\t"
+ /* ajout des valeurs obtenues ? la valeur finale */
+ "paddw %%mm1, %%mm0 \n\t" "paddw %%mm2, %%mm0 \n\t"
+ /* division par 256 = 16+16+16+16, puis repackage du pixel final */
+ "psrlw $8, %%mm0 \n\t"
+ "packuswb %%mm7, %%mm0 \n\t" "movd %%mm0,%0 \n\t":"=g" (expix2[loop])
+ :"r" (pos), "r" (coeffs), "r" (expix1)
+
+ );
+
+ emms ();
+ }
+}
+
+#define DRAWMETHOD_PLUS_MMX(_out,_backbuf,_col) \
+{ \
+ movd_m2r(_backbuf, mm0); \
+ paddusb_m2r(_col, mm0); \
+ movd_r2m(mm0, _out); \
+}
+
+#define DRAWMETHOD DRAWMETHOD_PLUS_MMX(*p,*p,col)
+
+void
+draw_line_mmx (Pixel * data, int x1, int y1, int x2, int y2, int col,
+ int screenx, int screeny)
+{
+ int x, y, dx, dy, yy, xx;
+ Pixel *p;
+
+ if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny)
+ || (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx))
+ goto end_of_line;
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ if (x1 >= x2) {
+ int tmp;
+
+ tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ dx = x2 - x1;
+ dy = y2 - y1;
+ }
+
+ /* vertical line */
+ if (dx == 0) {
+ if (y1 < y2) {
+ p = &(data[(screenx * y1) + x1]);
+ for (y = y1; y <= y2; y++) {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ } else {
+ p = &(data[(screenx * y2) + x1]);
+ for (y = y2; y <= y1; y++) {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ }
+ goto end_of_line;
+ }
+ /* horizontal line */
+ if (dy == 0) {
+ if (x1 < x2) {
+ p = &(data[(screenx * y1) + x1]);
+ for (x = x1; x <= x2; x++) {
+ DRAWMETHOD;
+ p++;
+ }
+ goto end_of_line;
+ } else {
+ p = &(data[(screenx * y1) + x2]);
+ for (x = x2; x <= x1; x++) {
+ DRAWMETHOD;
+ p++;
+ }
+ goto end_of_line;
+ }
+ }
+ /* 1 */
+ /* \ */
+ /* \ */
+ /* 2 */
+ if (y2 > y1) {
+ /* steep */
+ if (dy > dx) {
+ dx = ((dx << 16) / dy);
+ x = x1 << 16;
+ for (y = y1; y <= y2; y++) {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1)) {
+ p++;
+ /* DRAWMETHOD; */
+ }
+ x += dx;
+ }
+ goto end_of_line;
+ }
+ /* shallow */
+ else {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++) {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1)) {
+ p += screeny;
+ /* DRAWMETHOD; */
+ }
+ y += dy;
+ }
+ }
+ }
+ /* 2 */
+ /* / */
+ /* / */
+ /* 1 */
+ else {
+ /* steep */
+ if (-dy > dx) {
+ dx = ((dx << 16) / -dy);
+ x = (x1 + 1) << 16;
+ for (y = y1; y >= y2; y--) {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1)) {
+ p--;
+ /* DRAWMETHOD; */
+ }
+ x += dx;
+ }
+ goto end_of_line;
+ }
+ /* shallow */
+ else {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++) {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1)) {
+ p += screeny;
+ /* DRAWMETHOD; */
+ }
+ y += dy;
+ }
+ goto end_of_line;
+ }
+ }
+end_of_line:
+ emms ();
+ /* __asm__ __volatile__ ("emms"); */
+}
+
+#endif /* HAVE_CPU_I386 || HAVE_CPU_X86_64 */
diff --git a/gst/goom/mmx.h b/gst/goom/mmx.h
new file mode 100644
index 00000000..3fae26b9
--- /dev/null
+++ b/gst/goom/mmx.h
@@ -0,0 +1,729 @@
+/* mmx.h
+
+ MultiMedia eXtensions GCC interface library for IA32.
+
+ To use this library, simply include this header file
+ and compile with GCC. You MUST have inlining enabled
+ in order for mmx_ok() to work; this can be done by
+ simply using -O on the GCC command line.
+
+ Compiling with -DMMX_TRACE will cause detailed trace
+ output to be sent to stderr for each mmx operation.
+ This adds lots of code, and obviously slows execution to
+ a crawl, but can be very useful for debugging.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR ANY PARTICULAR PURPOSE.
+
+ 1997-99 by H. Dietz and R. Fisher
+
+ Notes:
+ It appears that the latest gas has the pand problem fixed, therefore
+ I'll undefine BROKEN_PAND by default.
+*/
+
+#ifndef _MMX_H
+#define _MMX_H
+
+#include "goom_graphic.h"
+
+/* Warning: at this writing, the version of GAS packaged
+ with most Linux distributions does not handle the
+ parallel AND operation mnemonic correctly. If the
+ symbol BROKEN_PAND is defined, a slower alternative
+ coding will be used. If execution of mmxtest results
+ in an illegal instruction fault, define this symbol.
+*/
+#undef BROKEN_PAND
+
+
+/* The type of an value that fits in an MMX register
+ (note that long long constant values MUST be suffixed
+ by LL and unsigned long long values by ULL, lest
+ they be truncated by the compiler)
+*/
+typedef union {
+ long long q; /* Quadword (64-bit) value */
+ unsigned long long uq; /* Unsigned Quadword */
+ int d[2]; /* 2 Doubleword (32-bit) values */
+ unsigned int ud[2]; /* 2 Unsigned Doubleword */
+ short w[4]; /* 4 Word (16-bit) values */
+ unsigned short uw[4]; /* 4 Unsigned Word */
+ char b[8]; /* 8 Byte (8-bit) values */
+ unsigned char ub[8]; /* 8 Unsigned Byte */
+ float s[2]; /* Single-precision (32-bit) value */
+} __attribute__ ((aligned (8))) mmx_t; /* On an 8-byte (64-bit) boundary */
+
+
+
+/* Function to test if multimedia instructions are supported...
+*/
+static int
+mm_support(void)
+{
+ /* Returns 1 if MMX instructions are supported,
+ 3 if Cyrix MMX and Extended MMX instructions are supported
+ 5 if AMD MMX and 3DNow! instructions are supported
+ 13 if AMD Extended MMX, &3dNow supported
+ 0 if hardware does not support any of these
+ */
+ register int rval = 0;
+
+ __asm__ __volatile__ (
+ /* See if CPUID instruction is supported ... */
+ /* ... Get copies of EFLAGS into eax and ecx */
+ "pushl %%ebx\n\t"
+ "pushf\n\t"
+ "popl %%eax\n\t"
+ "movl %%eax, %%ecx\n\t"
+
+ /* ... Toggle the ID bit in one copy and store */
+ /* to the EFLAGS reg */
+ "xorl $0x200000, %%eax\n\t"
+ "push %%eax\n\t"
+ "popf\n\t"
+
+ /* ... Get the (hopefully modified) EFLAGS */
+ "pushf\n\t"
+ "popl %%eax\n\t"
+
+ /* ... Compare and test result */
+ "xorl %%eax, %%ecx\n\t"
+ "testl $0x200000, %%ecx\n\t"
+ "jz NotSupported1\n\t" /* CPUID not supported */
+
+
+ /* Get standard CPUID information, and
+ go to a specific vendor section */
+ "movl $0, %%eax\n\t"
+ "cpuid\n\t"
+
+ /* Check for Intel */
+ "cmpl $0x756e6547, %%ebx\n\t"
+ "jne TryAMD\n\t"
+ "cmpl $0x49656e69, %%edx\n\t"
+ "jne TryAMD\n\t"
+ "cmpl $0x6c65746e, %%ecx\n"
+ "jne TryAMD\n\t"
+ "jmp Intel\n\t"
+
+ /* Check for AMD */
+ "\nTryAMD:\n\t"
+ "cmpl $0x68747541, %%ebx\n\t"
+ "jne TryCyrix\n\t"
+ "cmpl $0x69746e65, %%edx\n\t"
+ "jne TryCyrix\n\t"
+ "cmpl $0x444d4163, %%ecx\n"
+ "jne TryCyrix\n\t"
+ "jmp AMD\n\t"
+
+ /* Check for Cyrix */
+ "\nTryCyrix:\n\t"
+ "cmpl $0x69727943, %%ebx\n\t"
+ "jne NotSupported2\n\t"
+ "cmpl $0x736e4978, %%edx\n\t"
+ "jne NotSupported3\n\t"
+ "cmpl $0x64616574, %%ecx\n\t"
+ "jne NotSupported4\n\t"
+ /* Drop through to Cyrix... */
+
+
+ /* Cyrix Section */
+ /* See if extended CPUID level 80000001 is supported */
+ /* The value of CPUID/80000001 for the 6x86MX is undefined
+ according to the Cyrix CPU Detection Guide (Preliminary
+ Rev. 1.01 table 1), so we'll check the value of eax for
+ CPUID/0 to see if standard CPUID level 2 is supported.
+ According to the table, the only CPU which supports level
+ 2 is also the only one which supports extended CPUID levels.
+ */
+ "cmpl $0x2, %%eax\n\t"
+ "jne MMXtest\n\t" /* Use standard CPUID instead */
+
+ /* Extended CPUID supported (in theory), so get extended
+ features */
+ "movl $0x80000001, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%eax\n\t" /* Test for MMX */
+ "jz NotSupported5\n\t" /* MMX not supported */
+ "testl $0x01000000, %%eax\n\t" /* Test for Ext'd MMX */
+ "jnz EMMXSupported\n\t"
+ "movl $1, %0\n\n\t" /* MMX Supported */
+ "jmp Return\n\n"
+ "EMMXSupported:\n\t"
+ "movl $3, %0\n\n\t" /* EMMX and MMX Supported */
+ "jmp Return\n\t"
+
+
+ /* AMD Section */
+ "AMD:\n\t"
+
+ /* See if extended CPUID is supported */
+ "movl $0x80000000, %%eax\n\t"
+ "cpuid\n\t"
+ "cmpl $0x80000000, %%eax\n\t"
+ "jl MMXtest\n\t" /* Use standard CPUID instead */
+
+ /* Extended CPUID supported, so get extended features */
+ "movl $0x80000001, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%edx\n\t" /* Test for MMX */
+ "jz NotSupported6\n\t" /* MMX not supported */
+ "testl $0x80000000, %%edx\n\t" /* Test for 3DNow! */
+ "jnz ThreeDNowSupported\n\t"
+ "movl $1, %0\n\n\t" /* MMX Supported */
+ "jmp Return\n\n"
+ "ThreeDNowSupported:\n\t"
+ "testl $0x40000000, %%edx\n\t" /* Test AMD Extended MMX */
+ "jnz AMDXMMXSupported\n\t"
+ "movl $5, %0\n\n\t" /* 3DNow! and MMX Supported */
+ "jmp Return\n\t"
+ "AMDXMMXSupported:\n\t"
+ "movl $13, %0\n\n\t" /* XMMX, 3DNow! and MMX Supported */
+ "jmp Return\n\t"
+
+
+ /* Intel Section */
+ "Intel:\n\t"
+
+ /* Check for MMX */
+ "MMXtest:\n\t"
+ "movl $1, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%edx\n\t" /* Test for MMX */
+ "jz NotSupported7\n\t" /* MMX Not supported */
+ "movl $1, %0\n\n\t" /* MMX Supported */
+ "jmp Return\n\t"
+
+ /* Nothing supported */
+ "\nNotSupported1:\n\t"
+ "#movl $101, %0\n\n\t"
+ "\nNotSupported2:\n\t"
+ "#movl $102, %0\n\n\t"
+ "\nNotSupported3:\n\t"
+ "#movl $103, %0\n\n\t"
+ "\nNotSupported4:\n\t"
+ "#movl $104, %0\n\n\t"
+ "\nNotSupported5:\n\t"
+ "#movl $105, %0\n\n\t"
+ "\nNotSupported6:\n\t"
+ "#movl $106, %0\n\n\t"
+ "\nNotSupported7:\n\t"
+ "#movl $107, %0\n\n\t"
+ "movl $0, %0\n\n\t"
+
+ "Return:\n\t"
+ "popl %%ebx\n\t"
+ : "=X" (rval)
+ : /* no input */
+ : "eax", "ecx", "edx"
+ );
+
+ /* Return */
+ return(rval);
+}
+
+/* Function to test if mmx instructions are supported...
+*/
+static inline int
+mmx_ok(void)
+{
+ /* Returns 1 if MMX instructions are supported, 0 otherwise */
+ return ( mm_support() & 0x1 );
+}
+
+int mmx_supported (void);
+int xmmx_supported (void);
+
+
+/* MMX optimized implementations */
+void draw_line_mmx (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny);
+void draw_line_xmmx (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny);
+void zoom_filter_mmx (int prevX, int prevY, Pixel *expix1, Pixel *expix2,
+ int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
+void zoom_filter_xmmx (int prevX, int prevY, Pixel *expix1, Pixel *expix2,
+ int *lbruS, int *lbruD, int buffratio, int precalCoef[16][16]);
+
+
+/* Helper functions for the instruction macros that follow...
+ (note that memory-to-register, m2r, instructions are nearly
+ as efficient as register-to-register, r2r, instructions;
+ however, memory-to-memory instructions are really simulated
+ as a convenience, and are only 1/3 as efficient)
+*/
+#ifdef MMX_TRACE
+
+/* Include the stuff for printing a trace to stderr...
+*/
+
+#include <stdio.h>
+
+#define mmx_i2r(op, imm, reg) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace.uq = (imm); \
+ printf(#op "_i2r(" #imm "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#reg "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm)); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#reg "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_m2r(op, mem, reg) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (mem); \
+ printf(#op "_m2r(" #mem "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#reg "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "m" (mem)); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#reg "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_r2m(op, reg, mem) \
+ { \
+ mmx_t mmx_trace; \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#op "_r2m(" #reg "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ mmx_trace = (mem); \
+ printf(#mem "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=m" (mem) \
+ : /* nothing */ ); \
+ mmx_trace = (mem); \
+ printf(#mem "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_r2r(op, regs, regd) \
+ { \
+ mmx_t mmx_trace; \
+ __asm__ __volatile__ ("movq %%" #regs ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#op "_r2r(" #regs "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #regd ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#regd "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd); \
+ __asm__ __volatile__ ("movq %%" #regd ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#regd "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_m2m(op, mems, memd) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (mems); \
+ printf(#op "_m2m(" #mems "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ mmx_trace = (memd); \
+ printf(#memd "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \
+ #op " %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=m" (memd) \
+ : "m" (mems)); \
+ mmx_trace = (memd); \
+ printf(#memd "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#else
+
+/* These macros are a lot simpler without the tracing...
+*/
+
+#define mmx_i2r(op, imm, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_m2r(op, mem, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "m" (mem))
+
+#define mmx_r2m(op, reg, mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=m" (mem) \
+ : /* nothing */ )
+
+#define mmx_r2r(op, regs, regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+#define mmx_m2m(op, mems, memd) \
+ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \
+ #op " %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=m" (memd) \
+ : "m" (mems))
+
+#endif
+
+
+/* 1x64 MOVe Quadword
+ (this is both a load and a store...
+ in fact, it is the only way to store)
+*/
+#define movq_m2r(var, reg) mmx_m2r(movq, var, reg)
+#define movq_r2m(reg, var) mmx_r2m(movq, reg, var)
+#define movq_r2r(regs, regd) mmx_r2r(movq, regs, regd)
+#define movq(vars, vard) \
+ __asm__ __volatile__ ("movq %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=X" (vard) \
+ : "X" (vars))
+
+
+/* 1x32 MOVe Doubleword
+ (like movq, this is both load and store...
+ but is most useful for moving things between
+ mmx registers and ordinary registers)
+*/
+#define movd_m2r(var, reg) mmx_m2r(movd, var, reg)
+#define movd_r2m(reg, var) mmx_r2m(movd, reg, var)
+#define movd_r2r(regs, regd) mmx_r2r(movd, regs, regd)
+#define movd(vars, vard) \
+ __asm__ __volatile__ ("movd %1, %%mm0\n\t" \
+ "movd %%mm0, %0" \
+ : "=X" (vard) \
+ : "X" (vars))
+
+
+/* 2x32, 4x16, and 8x8 Parallel ADDs
+*/
+#define paddd_m2r(var, reg) mmx_m2r(paddd, var, reg)
+#define paddd_r2r(regs, regd) mmx_r2r(paddd, regs, regd)
+#define paddd(vars, vard) mmx_m2m(paddd, vars, vard)
+
+#define paddw_m2r(var, reg) mmx_m2r(paddw, var, reg)
+#define paddw_r2r(regs, regd) mmx_r2r(paddw, regs, regd)
+#define paddw(vars, vard) mmx_m2m(paddw, vars, vard)
+
+#define paddb_m2r(var, reg) mmx_m2r(paddb, var, reg)
+#define paddb_r2r(regs, regd) mmx_r2r(paddb, regs, regd)
+#define paddb(vars, vard) mmx_m2m(paddb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel ADDs using Saturation arithmetic
+*/
+#define paddsw_m2r(var, reg) mmx_m2r(paddsw, var, reg)
+#define paddsw_r2r(regs, regd) mmx_r2r(paddsw, regs, regd)
+#define paddsw(vars, vard) mmx_m2m(paddsw, vars, vard)
+
+#define paddsb_m2r(var, reg) mmx_m2r(paddsb, var, reg)
+#define paddsb_r2r(regs, regd) mmx_r2r(paddsb, regs, regd)
+#define paddsb(vars, vard) mmx_m2m(paddsb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel ADDs using Unsigned Saturation arithmetic
+*/
+#define paddusw_m2r(var, reg) mmx_m2r(paddusw, var, reg)
+#define paddusw_r2r(regs, regd) mmx_r2r(paddusw, regs, regd)
+#define paddusw(vars, vard) mmx_m2m(paddusw, vars, vard)
+
+#define paddusb_m2r(var, reg) mmx_m2r(paddusb, var, reg)
+#define paddusb_r2r(regs, regd) mmx_r2r(paddusb, regs, regd)
+#define paddusb(vars, vard) mmx_m2m(paddusb, vars, vard)
+
+
+/* 2x32, 4x16, and 8x8 Parallel SUBs
+*/
+#define psubd_m2r(var, reg) mmx_m2r(psubd, var, reg)
+#define psubd_r2r(regs, regd) mmx_r2r(psubd, regs, regd)
+#define psubd(vars, vard) mmx_m2m(psubd, vars, vard)
+
+#define psubw_m2r(var, reg) mmx_m2r(psubw, var, reg)
+#define psubw_r2r(regs, regd) mmx_r2r(psubw, regs, regd)
+#define psubw(vars, vard) mmx_m2m(psubw, vars, vard)
+
+#define psubb_m2r(var, reg) mmx_m2r(psubb, var, reg)
+#define psubb_r2r(regs, regd) mmx_r2r(psubb, regs, regd)
+#define psubb(vars, vard) mmx_m2m(psubb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel SUBs using Saturation arithmetic
+*/
+#define psubsw_m2r(var, reg) mmx_m2r(psubsw, var, reg)
+#define psubsw_r2r(regs, regd) mmx_r2r(psubsw, regs, regd)
+#define psubsw(vars, vard) mmx_m2m(psubsw, vars, vard)
+
+#define psubsb_m2r(var, reg) mmx_m2r(psubsb, var, reg)
+#define psubsb_r2r(regs, regd) mmx_r2r(psubsb, regs, regd)
+#define psubsb(vars, vard) mmx_m2m(psubsb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel SUBs using Unsigned Saturation arithmetic
+*/
+#define psubusw_m2r(var, reg) mmx_m2r(psubusw, var, reg)
+#define psubusw_r2r(regs, regd) mmx_r2r(psubusw, regs, regd)
+#define psubusw(vars, vard) mmx_m2m(psubusw, vars, vard)
+
+#define psubusb_m2r(var, reg) mmx_m2r(psubusb, var, reg)
+#define psubusb_r2r(regs, regd) mmx_r2r(psubusb, regs, regd)
+#define psubusb(vars, vard) mmx_m2m(psubusb, vars, vard)
+
+
+/* 4x16 Parallel MULs giving Low 4x16 portions of results
+*/
+#define pmullw_m2r(var, reg) mmx_m2r(pmullw, var, reg)
+#define pmullw_r2r(regs, regd) mmx_r2r(pmullw, regs, regd)
+#define pmullw(vars, vard) mmx_m2m(pmullw, vars, vard)
+
+
+/* 4x16 Parallel MULs giving High 4x16 portions of results
+*/
+#define pmulhw_m2r(var, reg) mmx_m2r(pmulhw, var, reg)
+#define pmulhw_r2r(regs, regd) mmx_r2r(pmulhw, regs, regd)
+#define pmulhw(vars, vard) mmx_m2m(pmulhw, vars, vard)
+
+
+/* 4x16->2x32 Parallel Mul-ADD
+ (muls like pmullw, then adds adjacent 16-bit fields
+ in the multiply result to make the final 2x32 result)
+*/
+#define pmaddwd_m2r(var, reg) mmx_m2r(pmaddwd, var, reg)
+#define pmaddwd_r2r(regs, regd) mmx_r2r(pmaddwd, regs, regd)
+#define pmaddwd(vars, vard) mmx_m2m(pmaddwd, vars, vard)
+
+
+/* 1x64 bitwise AND
+*/
+#ifdef BROKEN_PAND
+#define pand_m2r(var, reg) \
+ { \
+ mmx_m2r(pandn, (mmx_t) -1LL, reg); \
+ mmx_m2r(pandn, var, reg); \
+ }
+#define pand_r2r(regs, regd) \
+ { \
+ mmx_m2r(pandn, (mmx_t) -1LL, regd); \
+ mmx_r2r(pandn, regs, regd) \
+ }
+#define pand(vars, vard) \
+ { \
+ movq_m2r(vard, mm0); \
+ mmx_m2r(pandn, (mmx_t) -1LL, mm0); \
+ mmx_m2r(pandn, vars, mm0); \
+ movq_r2m(mm0, vard); \
+ }
+#else
+#define pand_m2r(var, reg) mmx_m2r(pand, var, reg)
+#define pand_r2r(regs, regd) mmx_r2r(pand, regs, regd)
+#define pand(vars, vard) mmx_m2m(pand, vars, vard)
+#endif
+
+
+/* 1x64 bitwise AND with Not the destination
+*/
+#define pandn_m2r(var, reg) mmx_m2r(pandn, var, reg)
+#define pandn_r2r(regs, regd) mmx_r2r(pandn, regs, regd)
+#define pandn(vars, vard) mmx_m2m(pandn, vars, vard)
+
+
+/* 1x64 bitwise OR
+*/
+#define por_m2r(var, reg) mmx_m2r(por, var, reg)
+#define por_r2r(regs, regd) mmx_r2r(por, regs, regd)
+#define por(vars, vard) mmx_m2m(por, vars, vard)
+
+
+/* 1x64 bitwise eXclusive OR
+*/
+#define pxor_m2r(var, reg) mmx_m2r(pxor, var, reg)
+#define pxor_r2r(regs, regd) mmx_r2r(pxor, regs, regd)
+#define pxor(vars, vard) mmx_m2m(pxor, vars, vard)
+
+
+/* 2x32, 4x16, and 8x8 Parallel CoMPare for EQuality
+ (resulting fields are either 0 or -1)
+*/
+#define pcmpeqd_m2r(var, reg) mmx_m2r(pcmpeqd, var, reg)
+#define pcmpeqd_r2r(regs, regd) mmx_r2r(pcmpeqd, regs, regd)
+#define pcmpeqd(vars, vard) mmx_m2m(pcmpeqd, vars, vard)
+
+#define pcmpeqw_m2r(var, reg) mmx_m2r(pcmpeqw, var, reg)
+#define pcmpeqw_r2r(regs, regd) mmx_r2r(pcmpeqw, regs, regd)
+#define pcmpeqw(vars, vard) mmx_m2m(pcmpeqw, vars, vard)
+
+#define pcmpeqb_m2r(var, reg) mmx_m2r(pcmpeqb, var, reg)
+#define pcmpeqb_r2r(regs, regd) mmx_r2r(pcmpeqb, regs, regd)
+#define pcmpeqb(vars, vard) mmx_m2m(pcmpeqb, vars, vard)
+
+
+/* 2x32, 4x16, and 8x8 Parallel CoMPare for Greater Than
+ (resulting fields are either 0 or -1)
+*/
+#define pcmpgtd_m2r(var, reg) mmx_m2r(pcmpgtd, var, reg)
+#define pcmpgtd_r2r(regs, regd) mmx_r2r(pcmpgtd, regs, regd)
+#define pcmpgtd(vars, vard) mmx_m2m(pcmpgtd, vars, vard)
+
+#define pcmpgtw_m2r(var, reg) mmx_m2r(pcmpgtw, var, reg)
+#define pcmpgtw_r2r(regs, regd) mmx_r2r(pcmpgtw, regs, regd)
+#define pcmpgtw(vars, vard) mmx_m2m(pcmpgtw, vars, vard)
+
+#define pcmpgtb_m2r(var, reg) mmx_m2r(pcmpgtb, var, reg)
+#define pcmpgtb_r2r(regs, regd) mmx_r2r(pcmpgtb, regs, regd)
+#define pcmpgtb(vars, vard) mmx_m2m(pcmpgtb, vars, vard)
+
+
+/* 1x64, 2x32, and 4x16 Parallel Shift Left Logical
+*/
+#define psllq_i2r(imm, reg) mmx_i2r(psllq, imm, reg)
+#define psllq_m2r(var, reg) mmx_m2r(psllq, var, reg)
+#define psllq_r2r(regs, regd) mmx_r2r(psllq, regs, regd)
+#define psllq(vars, vard) mmx_m2m(psllq, vars, vard)
+
+#define pslld_i2r(imm, reg) mmx_i2r(pslld, imm, reg)
+#define pslld_m2r(var, reg) mmx_m2r(pslld, var, reg)
+#define pslld_r2r(regs, regd) mmx_r2r(pslld, regs, regd)
+#define pslld(vars, vard) mmx_m2m(pslld, vars, vard)
+
+#define psllw_i2r(imm, reg) mmx_i2r(psllw, imm, reg)
+#define psllw_m2r(var, reg) mmx_m2r(psllw, var, reg)
+#define psllw_r2r(regs, regd) mmx_r2r(psllw, regs, regd)
+#define psllw(vars, vard) mmx_m2m(psllw, vars, vard)
+
+
+/* 1x64, 2x32, and 4x16 Parallel Shift Right Logical
+*/
+#define psrlq_i2r(imm, reg) mmx_i2r(psrlq, imm, reg)
+#define psrlq_m2r(var, reg) mmx_m2r(psrlq, var, reg)
+#define psrlq_r2r(regs, regd) mmx_r2r(psrlq, regs, regd)
+#define psrlq(vars, vard) mmx_m2m(psrlq, vars, vard)
+
+#define psrld_i2r(imm, reg) mmx_i2r(psrld, imm, reg)
+#define psrld_m2r(var, reg) mmx_m2r(psrld, var, reg)
+#define psrld_r2r(regs, regd) mmx_r2r(psrld, regs, regd)
+#define psrld(vars, vard) mmx_m2m(psrld, vars, vard)
+
+#define psrlw_i2r(imm, reg) mmx_i2r(psrlw, imm, reg)
+#define psrlw_m2r(var, reg) mmx_m2r(psrlw, var, reg)
+#define psrlw_r2r(regs, regd) mmx_r2r(psrlw, regs, regd)
+#define psrlw(vars, vard) mmx_m2m(psrlw, vars, vard)
+
+
+/* 2x32 and 4x16 Parallel Shift Right Arithmetic
+*/
+#define psrad_i2r(imm, reg) mmx_i2r(psrad, imm, reg)
+#define psrad_m2r(var, reg) mmx_m2r(psrad, var, reg)
+#define psrad_r2r(regs, regd) mmx_r2r(psrad, regs, regd)
+#define psrad(vars, vard) mmx_m2m(psrad, vars, vard)
+
+#define psraw_i2r(imm, reg) mmx_i2r(psraw, imm, reg)
+#define psraw_m2r(var, reg) mmx_m2r(psraw, var, reg)
+#define psraw_r2r(regs, regd) mmx_r2r(psraw, regs, regd)
+#define psraw(vars, vard) mmx_m2m(psraw, vars, vard)
+
+
+/* 2x32->4x16 and 4x16->8x8 PACK and Signed Saturate
+ (packs source and dest fields into dest in that order)
+*/
+#define packssdw_m2r(var, reg) mmx_m2r(packssdw, var, reg)
+#define packssdw_r2r(regs, regd) mmx_r2r(packssdw, regs, regd)
+#define packssdw(vars, vard) mmx_m2m(packssdw, vars, vard)
+
+#define packsswb_m2r(var, reg) mmx_m2r(packsswb, var, reg)
+#define packsswb_r2r(regs, regd) mmx_r2r(packsswb, regs, regd)
+#define packsswb(vars, vard) mmx_m2m(packsswb, vars, vard)
+
+
+/* 4x16->8x8 PACK and Unsigned Saturate
+ (packs source and dest fields into dest in that order)
+*/
+#define packuswb_m2r(var, reg) mmx_m2r(packuswb, var, reg)
+#define packuswb_r2r(regs, regd) mmx_r2r(packuswb, regs, regd)
+#define packuswb(vars, vard) mmx_m2m(packuswb, vars, vard)
+
+
+/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK Low
+ (interleaves low half of dest with low half of source
+ as padding in each result field)
+*/
+#define punpckldq_m2r(var, reg) mmx_m2r(punpckldq, var, reg)
+#define punpckldq_r2r(regs, regd) mmx_r2r(punpckldq, regs, regd)
+#define punpckldq(vars, vard) mmx_m2m(punpckldq, vars, vard)
+
+#define punpcklwd_m2r(var, reg) mmx_m2r(punpcklwd, var, reg)
+#define punpcklwd_r2r(regs, regd) mmx_r2r(punpcklwd, regs, regd)
+#define punpcklwd(vars, vard) mmx_m2m(punpcklwd, vars, vard)
+
+#define punpcklbw_m2r(var, reg) mmx_m2r(punpcklbw, var, reg)
+#define punpcklbw_r2r(regs, regd) mmx_r2r(punpcklbw, regs, regd)
+#define punpcklbw(vars, vard) mmx_m2m(punpcklbw, vars, vard)
+
+
+/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK High
+ (interleaves high half of dest with high half of source
+ as padding in each result field)
+*/
+#define punpckhdq_m2r(var, reg) mmx_m2r(punpckhdq, var, reg)
+#define punpckhdq_r2r(regs, regd) mmx_r2r(punpckhdq, regs, regd)
+#define punpckhdq(vars, vard) mmx_m2m(punpckhdq, vars, vard)
+
+#define punpckhwd_m2r(var, reg) mmx_m2r(punpckhwd, var, reg)
+#define punpckhwd_r2r(regs, regd) mmx_r2r(punpckhwd, regs, regd)
+#define punpckhwd(vars, vard) mmx_m2m(punpckhwd, vars, vard)
+
+#define punpckhbw_m2r(var, reg) mmx_m2r(punpckhbw, var, reg)
+#define punpckhbw_r2r(regs, regd) mmx_r2r(punpckhbw, regs, regd)
+#define punpckhbw(vars, vard) mmx_m2m(punpckhbw, vars, vard)
+
+
+/* Empty MMx State
+ (used to clean-up when going from mmx to float use
+ of the registers that are shared by both; note that
+ there is no float-to-mmx operation needed, because
+ only the float tag word info is corruptible)
+*/
+#ifdef MMX_TRACE
+
+#define emms() \
+ { \
+ printf("emms()\n"); \
+ __asm__ __volatile__ ("emms" \
+ "st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)"); \
+ }
+
+#else
+
+#define emms() __asm__ __volatile__ ("emms"::: \
+ "st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)")
+
+#endif
+
+#endif
+
diff --git a/gst/goom/motif_goom1.h b/gst/goom/motif_goom1.h
new file mode 100644
index 00000000..b4a9f3f1
--- /dev/null
+++ b/gst/goom/motif_goom1.h
@@ -0,0 +1,1026 @@
+static Motif CONV_MOTIF1 = {
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,14,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,13,9,9,7,2,2,9,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,11,
+ 11,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,12,7,4,0,0,0,2,0,0,3,14,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,12,10,9,9,4,1,0,
+ 1,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,10,3,0,0,0,1,1,3,5,0,0,1,14,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,14,6,3,1,1,4,9,1,
+ 1,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 10,3,0,0,2,7,13,14,14,14,7,0,0,2,14,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,12,1,9,15,15,15,15,3,
+ 0,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,4,
+ 0,0,2,10,15,15,15,15,15,15,1,0,0,10,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,9,0,2,14,15,15,15,7,
+ 0,9,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,14,6,0,0,
+ 2,9,15,15,15,15,15,15,15,13,0,0,3,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,11,0,0,10,15,15,15,9,
+ 0,9,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,13,3,0,1,5,
+ 5,4,4,4,6,12,15,15,15,13,0,0,7,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,14,0,0,5,15,15,15,10,
+ 0,7,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,11,1,0,3,3,1,
+ 0,0,0,0,0,0,5,13,15,12,0,0,13,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,13,14,15,
+ 15,15,15,15,15,15,15,15,14,0,0,1,15,15,15,12,
+ 0,3,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,10,1,2,4,0,0,1,
+ 9,12,12,12,9,3,0,2,14,5,0,7,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,14,7,4,4,1,1,12,
+ 15,15,15,15,15,15,15,15,14,1,0,0,12,15,15,15,
+ 1,0,12,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,10,0,3,2,0,0,3,12,
+ 15,15,15,15,15,14,2,1,13,2,0,12,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,14,3,0,0,0,0,0,2,
+ 13,15,15,15,15,15,15,15,14,1,0,0,8,15,15,15,
+ 1,0,9,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,12,2,1,0,0,0,9,14,15,
+ 15,15,15,15,15,14,1,1,11,0,3,14,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,7,4,11,12,10,1,0,
+ 3,12,15,15,15,15,15,15,13,1,1,0,4,15,15,15,
+ 2,0,10,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,2,1,0,0,3,12,15,15,15,
+ 15,15,15,15,15,11,0,5,9,1,12,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,5,1,13,15,15,12,1,
+ 0,1,9,15,15,15,15,15,14,2,5,0,1,14,15,15,
+ 2,0,7,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,14,3,0,0,0,7,14,15,15,15,15,
+ 15,15,15,15,15,9,0,8,7,4,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,7,0,7,8,11,15,13,
+ 2,0,0,3,10,15,15,15,15,5,11,0,0,11,15,15,
+ 6,0,2,14,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,6,0,0,0,8,15,15,15,15,15,15,
+ 15,15,15,15,15,6,0,4,0,6,15,15,15,15,15,15,
+ 14,9,14,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,11,0,3,3,0,8,15,
+ 14,5,0,0,0,4,12,15,15,5,13,2,0,6,15,15,
+ 12,0,0,11,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,10,0,0,0,8,15,15,15,15,15,15,15,
+ 15,15,15,15,10,1,7,6,4,13,15,15,15,15,13,11,
+ 6,0,8,11,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,1,1,11,2,0,5,
+ 14,15,8,0,0,0,0,7,15,5,14,6,0,2,15,15,
+ 15,3,0,5,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,13,1,0,0,7,15,15,15,15,15,15,15,15,
+ 15,15,15,15,7,9,15,15,15,15,15,15,12,6,2,1,
+ 1,1,8,6,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,4,0,6,12,1,0,
+ 3,13,15,11,2,0,0,0,8,4,14,10,0,0,13,15,
+ 15,7,0,1,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,5,0,0,5,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,13,15,15,15,15,14,8,3,1,2,7,11,
+ 5,4,5,6,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,8,0,1,14,11,0,
+ 0,1,9,15,14,5,0,0,2,4,14,13,0,0,10,15,
+ 15,12,0,0,12,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,10,0,0,1,14,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,13,7,2,0,5,9,15,15,15,
+ 5,3,6,9,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,13,0,0,9,15,12,
+ 2,0,0,4,13,14,4,0,3,2,12,15,1,0,5,15,
+ 15,14,1,0,8,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,2,0,0,9,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,11,6,1,0,2,3,10,15,15,15,15,7,
+ 1,2,4,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,5,0,3,14,15,
+ 9,2,0,0,1,6,12,13,13,1,9,12,0,0,2,14,
+ 15,15,4,0,4,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,10,0,0,2,14,15,15,15,15,15,15,15,15,15,15,
+ 13,9,6,0,1,2,9,10,15,15,15,15,14,7,1,0,
+ 6,2,4,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,11,0,0,9,15,
+ 4,4,11,6,1,0,0,1,1,0,10,4,0,0,0,12,
+ 15,15,9,0,1,14,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,3,0,0,8,15,15,15,15,15,15,15,13,12,4,4,
+ 1,1,3,10,12,15,15,15,15,15,9,2,1,0,1,6,
+ 6,0,10,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,4,0,3,14,
+ 4,3,15,15,14,9,7,9,1,0,0,0,0,1,0,7,
+ 15,15,13,0,0,9,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 13,0,0,1,14,15,15,15,15,15,12,9,1,0,1,4,
+ 7,15,15,15,15,15,15,14,8,2,0,0,0,2,13,9,
+ 0,4,14,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,11,0,0,9,
+ 3,0,8,14,15,15,15,15,10,5,4,4,7,4,0,3,
+ 15,15,15,4,0,3,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 5,0,0,5,15,15,15,15,14,8,7,8,10,12,14,15,
+ 15,15,15,15,15,15,11,1,0,0,0,5,11,15,13,1,
+ 1,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,3,0,4,
+ 4,0,0,2,6,10,15,15,15,15,15,15,15,10,0,0,
+ 12,15,15,9,0,0,12,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 1,0,0,10,15,15,15,15,15,13,14,15,15,15,15,15,
+ 15,15,15,15,14,7,1,0,0,3,12,15,15,15,6,0,
+ 7,15,15,15,12,10,9,10,12,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,9,0,0,
+ 8,3,1,4,1,0,1,12,15,15,15,15,15,14,2,0,
+ 6,15,15,15,2,0,6,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 0,0,1,14,15,15,15,15,14,5,15,15,15,15,15,15,
+ 15,15,15,7,2,0,0,1,8,15,15,15,15,12,0,2,
+ 14,15,12,4,0,0,0,0,0,1,5,10,14,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,14,0,0,
+ 5,4,1,14,15,10,7,13,15,15,15,15,15,15,8,0,
+ 1,14,15,15,7,0,1,14,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,
+ 0,0,4,15,15,15,15,15,13,2,13,15,15,15,15,15,
+ 12,7,0,0,0,0,5,12,15,15,15,15,14,3,0,9,
+ 11,1,0,0,1,1,0,1,0,0,0,0,2,12,15,15,
+ 15,15,15,15,15,15,15,14,15,15,15,15,15,15,2,0,
+ 5,2,1,14,15,14,13,15,15,15,15,15,15,15,12,0,
+ 0,10,15,15,13,0,0,9,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,
+ 0,0,4,15,15,15,15,15,12,0,12,15,15,15,12,6,
+ 0,0,0,0,6,14,15,15,15,15,15,15,7,0,0,12,
+ 1,0,0,2,2,1,1,7,12,8,3,0,0,1,13,15,
+ 15,15,15,15,15,8,4,8,12,15,15,15,15,15,8,0,
+ 4,2,0,14,15,11,9,15,15,15,15,15,15,15,15,3,
+ 0,5,15,15,15,5,0,3,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,
+ 0,0,4,15,15,15,15,15,12,0,12,15,13,3,1,0,
+ 0,0,5,12,15,15,15,15,15,15,15,12,0,0,7,7,
+ 0,0,0,0,0,0,0,1,12,15,15,12,3,0,5,15,
+ 15,15,15,14,5,0,0,0,0,2,2,3,7,14,9,8,
+ 14,2,1,14,15,2,12,13,15,15,15,15,15,15,15,9,
+ 0,0,13,15,15,10,0,0,12,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,
+ 0,0,5,15,15,15,15,15,12,0,11,10,1,0,0,1,
+ 5,14,15,15,15,15,15,15,15,15,15,6,0,2,7,0,
+ 0,0,0,1,2,7,4,0,3,14,15,15,14,2,0,12,
+ 15,15,15,9,0,1,2,1,0,0,0,0,0,1,3,7,
+ 15,3,0,14,15,4,12,15,15,15,15,15,15,15,15,14,
+ 1,0,8,15,15,14,1,0,8,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,
+ 0,0,4,15,15,15,15,15,12,0,2,0,0,1,10,15,
+ 15,15,15,15,15,15,15,15,15,15,12,0,0,6,0,0,
+ 0,1,10,14,15,15,11,1,0,9,15,15,15,8,0,9,
+ 15,15,12,4,8,14,15,8,1,0,0,0,0,0,1,9,
+ 15,2,0,13,15,1,9,15,15,15,15,15,15,15,15,15,
+ 6,0,1,14,15,14,1,0,3,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,
+ 1,0,1,14,15,15,15,15,12,1,3,7,9,13,15,15,
+ 15,15,15,15,15,15,15,15,15,15,3,0,2,3,0,4,
+ 0,8,15,15,15,15,15,13,1,2,14,15,15,10,0,6,
+ 15,14,2,6,15,15,15,1,3,7,3,0,0,0,0,1,
+ 11,1,0,11,12,0,12,15,15,15,15,15,15,15,15,15,
+ 11,0,0,9,15,15,4,0,0,12,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 6,0,0,9,15,15,15,15,15,12,14,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,11,0,0,3,0,8,14,
+ 2,5,15,15,15,15,15,15,5,0,8,15,15,12,0,4,
+ 15,5,2,14,15,15,10,0,13,15,13,2,4,5,5,0,
+ 9,1,0,10,9,1,14,15,15,15,15,15,15,15,15,15,
+ 13,0,0,3,15,15,9,0,0,8,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 12,0,0,3,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,3,0,1,1,5,14,15,
+ 11,0,12,15,15,15,15,15,14,1,1,14,15,12,0,4,
+ 10,0,9,15,15,11,1,8,15,15,8,1,14,15,14,2,
+ 5,0,0,10,6,2,15,15,15,15,15,15,15,15,15,15,
+ 15,3,0,0,12,15,13,0,0,2,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,3,0,0,10,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,10,0,0,1,0,11,15,15,
+ 15,2,6,15,15,15,15,15,15,6,0,9,15,13,0,6,
+ 3,0,13,15,14,2,6,15,15,13,1,8,15,15,15,4,
+ 3,1,0,10,7,2,15,15,15,15,15,15,15,15,15,15,
+ 15,9,0,0,6,15,15,3,0,0,13,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,9,0,0,2,14,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,11,10,2,0,3,0,3,15,15,15,
+ 15,8,1,14,15,15,15,15,15,13,0,2,15,9,1,10,
+ 0,3,15,15,6,2,14,15,14,3,1,14,15,15,15,2,
+ 4,0,0,12,5,3,15,15,15,15,15,15,15,15,15,15,
+ 15,14,1,0,1,14,15,5,0,0,12,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,4,0,0,6,15,15,15,15,15,15,15,15,14,12,
+ 12,9,5,4,4,3,0,0,0,0,4,0,8,15,15,15,
+ 15,13,1,10,15,15,15,15,15,15,2,0,11,3,5,10,
+ 0,7,15,9,1,11,15,15,8,0,6,15,15,15,10,0,
+ 3,0,0,13,3,6,15,15,15,15,15,15,15,15,15,15,
+ 15,15,6,0,0,12,15,5,0,0,7,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,13,1,0,0,8,14,15,15,13,6,4,4,1,0,
+ 0,0,0,0,0,0,2,0,0,4,3,0,12,15,15,15,
+ 15,15,5,3,15,15,15,15,14,8,0,0,1,1,12,9,
+ 0,9,10,0,6,15,15,15,2,2,14,15,15,13,2,0,
+ 4,0,1,13,0,10,15,15,15,15,15,15,15,15,15,15,
+ 15,15,13,1,0,10,15,10,0,0,5,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,9,0,0,0,3,2,2,1,0,0,0,1,4,
+ 4,5,10,12,12,12,11,0,0,11,4,0,12,15,15,15,
+ 15,15,12,0,7,13,15,15,5,0,0,0,1,6,15,9,
+ 0,3,0,0,1,6,14,10,0,12,15,15,11,2,0,2,
+ 3,0,3,12,1,11,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,3,0,6,8,7,0,0,5,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,9,1,0,0,0,2,6,10,12,12,14,15,
+ 15,15,15,15,11,5,4,0,2,14,4,0,12,15,15,15,
+ 15,15,15,4,0,3,13,6,0,0,0,1,2,14,15,12,
+ 0,0,0,0,0,0,2,2,6,15,14,8,0,0,0,7,
+ 4,0,4,12,0,12,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,0,0,0,0,0,0,1,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,12,2,0,0,0,1,6,11,15,15,15,
+ 15,15,15,15,2,1,0,0,9,15,6,0,7,15,15,15,
+ 15,15,15,13,2,0,0,0,0,0,0,1,12,15,15,15,
+ 4,0,0,0,0,0,0,6,13,6,1,0,0,4,13,15,
+ 6,0,6,12,0,12,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,14,5,0,0,0,0,0,5,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,5,0,0,0,0,0,2,4,5,
+ 7,3,6,3,0,2,0,2,15,15,11,0,0,9,15,15,
+ 15,15,15,15,11,0,0,0,0,0,2,11,15,15,15,15,
+ 12,1,0,0,1,4,6,10,2,0,0,0,7,14,15,15,
+ 9,0,9,9,0,12,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,13,9,8,9,7,13,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,12,6,1,0,0,0,0,0,
+ 0,0,0,2,8,0,0,9,15,15,14,4,0,0,3,10,
+ 14,15,15,15,15,13,3,0,0,4,14,15,15,15,15,15,
+ 15,11,2,0,0,1,1,0,0,0,1,11,15,15,15,15,
+ 9,0,10,5,3,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,14,12,10,5,4,6,
+ 2,4,10,14,8,0,1,14,15,15,15,14,5,0,0,0,
+ 1,2,4,4,4,3,1,2,9,14,15,15,15,15,15,15,
+ 15,15,15,11,11,13,10,9,9,11,15,15,15,15,15,15,
+ 10,0,8,2,4,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 2,7,15,14,1,0,6,15,15,15,15,15,15,10,6,4,
+ 2,2,4,4,4,3,9,14,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 11,0,3,1,4,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,11,
+ 1,10,15,9,0,0,13,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 11,0,11,11,11,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,2,
+ 5,15,14,2,0,5,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 14,1,13,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,10,1,
+ 13,15,11,0,0,12,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,5,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,8,1,
+ 15,15,5,0,3,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,10,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,12,2,3,
+ 15,14,1,0,7,15,15,15,15,15,13,15,15,15,15,14,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,13,12,12,11,9,4,7,14,15,
+ 14,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,12,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,14,3,0,10,
+ 15,9,0,0,8,7,4,2,2,1,0,3,4,3,4,9,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,14,13,11,7,4,2,0,0,0,0,0,0,1,12,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,14,13,11,7,4,2,2,13,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,12,0,3,11,
+ 7,1,0,0,0,0,0,1,4,9,11,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,14,12,11,9,7,4,
+ 3,1,0,0,0,0,0,0,0,0,0,2,11,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,13,11,8,
+ 4,3,1,0,0,0,0,3,8,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,14,11,3,0,0,0,
+ 0,0,0,2,6,9,12,14,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,13,9,6,3,1,0,0,0,0,0,0,
+ 0,0,0,0,1,4,7,11,12,12,12,14,15,15,15,15,
+ 15,15,15,15,15,15,15,14,12,11,7,4,2,0,0,0,
+ 0,0,0,1,5,10,13,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,12,7,3,1,0,0,0,2,5,
+ 2,0,2,14,15,15,15,15,15,15,15,15,15,14,13,12,
+ 11,9,6,4,2,0,0,0,0,0,0,0,0,1,2,4,
+ 5,9,11,13,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,14,12,11,7,4,3,1,0,0,0,0,0,0,0,1,
+ 4,5,10,14,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,13,10,5,1,0,0,0,1,0,0,2,13,14,
+ 1,0,8,15,15,14,12,11,9,8,4,3,2,1,0,0,
+ 0,0,0,0,1,3,2,3,5,9,10,12,13,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,13,11,10,6,4,
+ 3,1,0,0,0,0,0,0,0,0,1,4,7,11,13,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,11,4,0,0,0,1,4,9,13,13,1,0,0,1,7,
+ 0,0,7,8,5,2,0,0,0,0,0,0,1,2,3,4,
+ 5,9,10,12,14,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,14,11,8,4,3,1,0,0,0,0,0,
+ 0,0,0,0,1,4,5,9,12,13,15,15,15,15,15,15,
+ 15,15,14,12,9,8,8,7,4,2,5,4,5,5,12,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,14,10,5,
+ 1,0,1,3,6,11,14,15,15,15,15,13,12,8,3,2,
+ 0,0,1,1,3,3,4,5,8,10,12,13,14,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,
+ 11,9,6,4,2,1,0,0,0,0,0,0,0,1,2,4,
+ 6,10,11,13,15,15,15,15,15,15,15,15,13,11,9,7,
+ 4,2,1,0,0,0,0,2,4,7,12,14,14,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,10,5,1,1,3,
+ 8,12,14,15,15,15,15,15,15,15,15,15,15,15,15,9,
+ 3,11,14,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,8,6,9,9,9,9,9,8,5,4,4,3,1,0,
+ 0,0,0,0,1,2,3,2,4,5,9,11,12,14,15,15,
+ 15,15,15,15,15,15,15,14,12,9,5,2,0,0,0,0,
+ 0,1,2,4,7,10,14,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,14,9,4,1,3,9,13,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,
+ 11,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,13,3,1,1,1,1,1,1,1,0,0,0,0,2,3,
+ 5,8,10,12,14,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,12,5,2,0,0,0,1,3,4,7,10,
+ 12,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,13,11,13,13,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,14,12,12,12,13,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,8,1,0,1,4,7,11,13,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,13,7,8,11,14,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
+ };
diff --git a/gst/goom/motif_goom2.h b/gst/goom/motif_goom2.h
new file mode 100644
index 00000000..4bde2a3d
--- /dev/null
+++ b/gst/goom/motif_goom2.h
@@ -0,0 +1,1026 @@
+static Motif CONV_MOTIF2 = {
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,12,5,14,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,12,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,10,1,14,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,10,0,12,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,6,0,12,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,7,0,8,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,13,2,0,10,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,6,0,2,14,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,5,0,0,10,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,9,0,0,12,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,14,9,0,0,1,14,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,8,0,0,8,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,14,8,3,0,0,0,9,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,11,0,0,2,14,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,13,9,5,3,4,1,0,0,0,0,7,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,14,4,0,0,4,11,13,13,15,15,14,12,10,8,5,
+ 6,4,1,0,0,0,0,0,0,0,0,0,0,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,12,1,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,9,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 13,9,10,13,14,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,3,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,2,5,6,0,0,0,0,12,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 5,0,0,0,3,10,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,14,9,2,1,0,0,0,1,4,6,6,1,
+ 0,0,0,8,13,15,15,15,12,1,0,2,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,
+ 2,0,0,0,0,0,4,12,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,3,0,0,10,15,15,15,10,
+ 0,0,4,15,15,15,15,15,15,2,0,6,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,5,
+ 3,11,5,0,0,0,0,0,4,11,14,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,0,13,15,15,15,11,
+ 0,0,7,15,15,15,15,15,15,1,0,9,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,9,0,
+ 13,15,15,12,5,0,0,0,0,0,1,8,14,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,1,14,15,15,15,11,
+ 0,0,7,15,15,15,15,15,14,0,0,9,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,11,1,10,
+ 15,15,15,15,15,11,5,0,0,0,0,0,1,6,13,15,
+ 15,15,15,15,14,8,11,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,6,0,2,15,15,15,15,11,
+ 0,0,6,15,15,15,15,15,13,0,0,11,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,11,1,6,15,
+ 15,15,15,15,15,15,15,14,5,0,0,0,0,0,0,6,
+ 14,15,15,15,6,0,4,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,5,15,15,15,15,11,
+ 0,0,5,15,15,15,15,15,12,0,0,12,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,13,2,1,13,15,
+ 15,15,15,15,15,15,15,15,15,12,2,0,0,0,0,0,
+ 1,6,11,7,0,0,4,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,7,15,15,15,15,11,
+ 0,0,6,15,15,15,15,15,12,0,0,12,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,5,0,7,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,11,5,0,0,0,
+ 0,0,0,0,0,1,11,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,10,15,15,15,15,11,
+ 0,0,6,15,15,15,15,15,12,0,0,12,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,10,0,4,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,13,7,0,
+ 0,0,0,0,0,1,6,12,14,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,10,15,15,15,15,11,
+ 0,0,7,15,15,15,15,15,12,0,0,12,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,13,1,1,12,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,
+ 5,0,0,0,0,0,0,0,3,10,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,10,15,15,15,15,11,
+ 0,0,7,15,15,15,15,15,11,0,0,13,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,14,4,0,8,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 13,0,0,0,1,0,0,0,0,1,13,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,10,15,15,15,15,11,
+ 0,0,8,15,15,15,15,15,8,0,2,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,9,0,4,14,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,
+ 4,0,0,5,13,12,6,2,0,2,13,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,10,15,15,15,15,11,
+ 0,0,7,15,15,15,15,15,4,0,4,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,13,1,1,13,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,11,
+ 0,0,1,13,15,15,15,14,9,13,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,5,0,6,15,15,15,15,11,
+ 0,0,8,15,15,15,15,15,2,0,8,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,5,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,11,15,15,15,15,15,15,15,9,
+ 0,0,10,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,4,0,4,15,15,15,15,11,
+ 0,0,7,15,15,15,15,13,0,0,11,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,10,0,3,14,15,15,15,15,15,15,
+ 15,15,15,15,15,14,3,0,13,15,15,15,15,15,15,14,
+ 9,11,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,4,0,4,15,15,15,15,11,
+ 0,0,8,15,15,15,15,12,0,0,12,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,14,2,1,12,15,15,15,15,15,15,15,
+ 15,15,15,15,14,3,0,0,9,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,6,0,3,15,15,15,15,13,
+ 1,0,8,15,15,15,15,12,0,0,12,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,9,0,5,15,15,15,15,15,15,15,15,
+ 15,15,15,14,4,0,0,0,10,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,8,0,2,15,15,15,15,15,
+ 3,0,13,15,15,15,15,12,0,0,12,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,13,2,1,12,15,15,15,15,15,15,15,15,
+ 15,15,15,7,0,0,0,0,8,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,10,0,1,14,15,15,15,15,
+ 11,5,15,15,15,15,15,12,0,0,11,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,6,0,7,15,15,15,15,15,15,15,15,15,
+ 15,15,8,0,0,0,0,0,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,12,0,0,12,15,15,15,15,
+ 15,14,15,15,15,15,15,10,0,0,12,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,13,1,2,14,15,15,15,15,15,15,15,15,15,
+ 15,10,0,0,0,6,6,0,0,0,5,12,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,12,
+ 15,15,15,15,15,15,15,15,13,0,0,11,15,15,15,15,
+ 15,15,15,15,15,15,15,9,0,1,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,7,0,8,15,15,15,15,15,15,15,15,15,15,
+ 15,9,0,0,4,15,15,8,0,0,0,1,5,13,15,15,
+ 15,15,15,15,15,15,15,15,15,15,12,8,7,6,5,3,
+ 3,3,4,12,15,15,15,15,15,15,15,15,15,7,0,6,
+ 15,15,15,15,15,15,15,15,14,1,0,10,15,15,15,15,
+ 15,15,15,15,15,15,15,6,0,3,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,13,1,0,13,15,15,15,15,15,15,15,15,15,15,
+ 15,14,7,8,13,15,15,15,11,2,0,0,0,0,5,11,
+ 15,15,15,15,15,15,15,15,13,3,0,0,0,0,0,0,
+ 0,0,0,5,15,15,15,15,15,15,15,15,12,1,0,0,
+ 3,11,15,15,15,15,15,15,13,1,0,10,15,15,15,15,
+ 15,15,15,15,15,15,15,3,0,5,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,9,0,5,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,14,8,1,0,0,0,0,
+ 4,12,15,15,15,15,15,15,4,0,0,0,0,0,0,0,
+ 0,0,0,2,15,15,15,15,15,15,15,14,4,0,0,0,
+ 0,0,9,15,15,15,15,15,14,1,0,10,15,15,15,15,
+ 15,15,15,15,15,15,15,2,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,14,4,0,11,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,14,8,2,0,0,
+ 0,0,4,10,14,15,15,15,4,0,0,0,0,0,0,0,
+ 0,0,0,3,15,15,15,15,15,15,15,6,0,0,0,2,
+ 3,0,0,8,15,15,15,15,14,1,0,10,15,15,15,15,
+ 15,15,15,15,15,15,15,1,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 14,5,0,4,14,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,14,9,3,
+ 0,0,0,0,2,5,10,15,5,0,1,11,11,12,13,15,
+ 11,0,0,7,15,15,15,15,15,15,8,0,0,0,1,12,
+ 14,6,0,0,7,14,15,15,14,1,0,9,15,15,15,15,
+ 15,15,15,15,15,15,15,2,0,10,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 9,0,1,13,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,
+ 10,2,0,0,0,0,1,14,4,0,1,14,15,15,15,15,
+ 9,0,0,9,15,15,15,15,15,9,0,0,0,0,9,15,
+ 15,15,7,0,0,6,14,15,15,3,0,6,15,15,15,15,
+ 15,15,15,15,15,15,15,1,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,9,
+ 0,0,1,10,14,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,13,1,0,0,0,1,14,3,0,0,14,15,15,15,15,
+ 5,0,0,11,15,15,15,15,13,1,0,0,0,6,15,15,
+ 15,15,15,8,0,0,2,10,15,6,0,3,15,15,15,15,
+ 15,15,15,15,15,15,15,2,0,10,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,1,
+ 0,0,0,0,3,9,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,6,1,0,0,0,8,15,1,0,0,14,15,15,15,15,
+ 4,0,0,13,15,15,15,14,4,0,0,0,3,14,15,15,
+ 15,15,15,15,5,0,0,1,14,9,0,1,14,15,15,15,
+ 15,15,15,15,15,15,15,1,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,1,
+ 0,0,0,0,0,0,4,12,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 9,0,0,0,0,7,15,15,1,0,0,14,15,15,15,14,
+ 2,0,1,14,15,15,15,12,0,0,0,3,13,15,15,15,
+ 15,15,15,9,0,0,0,1,14,12,0,0,12,15,15,15,
+ 15,15,15,15,15,15,14,1,0,10,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,
+ 3,0,0,0,0,0,0,1,8,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,9,
+ 0,0,0,0,7,15,15,15,1,0,0,14,15,15,15,13,
+ 0,0,1,15,15,15,15,12,0,0,0,6,14,15,15,15,
+ 15,15,12,0,0,0,0,3,14,12,0,0,12,15,15,15,
+ 15,15,15,15,15,15,12,0,0,12,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,13,3,0,0,0,0,0,0,1,6,13,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,0,
+ 0,0,0,3,15,15,15,12,0,0,0,14,15,15,15,11,
+ 0,0,3,15,15,15,15,15,12,7,0,0,4,14,15,15,
+ 15,11,1,0,0,0,4,13,15,12,0,0,12,15,15,15,
+ 15,15,15,15,15,15,10,0,1,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,7,0,0,0,0,0,0,0,3,8,12,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,4,0,
+ 0,0,1,13,15,15,15,6,0,0,0,14,15,15,15,8,
+ 0,0,7,15,15,15,15,15,15,15,8,1,0,2,13,15,
+ 14,2,0,0,0,4,14,15,15,13,1,0,10,15,15,15,
+ 15,15,15,15,15,15,9,0,2,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,11,6,2,0,0,0,0,0,0,0,1,
+ 10,15,15,15,15,15,15,15,15,15,15,15,15,8,0,0,
+ 0,0,10,15,15,15,15,4,0,0,1,15,15,15,15,4,
+ 0,0,8,15,15,15,15,15,15,15,15,10,1,0,1,8,
+ 2,0,0,0,5,15,15,15,15,15,2,0,6,15,15,15,
+ 15,15,15,15,15,15,9,0,1,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,9,1,0,0,0,0,0,0,
+ 0,1,7,13,14,15,15,15,15,15,15,15,9,0,0,0,
+ 0,6,15,15,15,15,15,4,0,0,4,15,15,15,14,1,
+ 0,0,9,15,15,15,15,15,15,15,15,15,12,2,0,0,
+ 0,0,0,4,14,15,15,15,15,15,4,0,4,15,15,15,
+ 15,15,15,15,15,15,7,0,0,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,14,11,6,2,0,0,0,
+ 0,0,0,0,1,9,12,15,15,15,15,14,3,0,0,0,
+ 4,15,15,15,15,15,15,4,0,0,3,6,4,4,2,0,
+ 0,0,13,15,15,15,15,15,15,15,15,15,15,12,1,0,
+ 0,0,3,14,15,15,15,15,15,15,4,0,4,15,15,15,
+ 15,15,15,15,15,15,5,0,0,12,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,8,2,0,
+ 0,0,0,0,0,0,0,1,9,15,15,5,0,0,0,0,
+ 12,15,15,15,15,15,15,4,0,0,0,0,0,0,0,0,
+ 0,3,15,15,15,15,15,15,15,15,15,15,15,14,4,0,
+ 0,1,12,15,15,15,15,15,15,15,6,0,1,14,15,15,
+ 15,15,15,15,15,15,5,0,0,13,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,
+ 7,1,0,0,0,0,0,0,0,5,7,0,0,0,0,10,
+ 15,15,15,15,15,15,15,7,0,0,0,0,0,0,0,0,
+ 1,10,15,15,15,15,15,15,15,15,15,15,15,14,3,0,
+ 3,12,15,15,15,15,15,15,15,15,12,0,0,12,15,15,
+ 15,15,15,15,15,15,5,0,0,1,1,4,11,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,11,6,1,0,0,0,0,0,0,0,0,0,7,15,
+ 15,15,15,15,15,15,15,14,7,4,4,4,5,9,12,13,
+ 14,15,15,15,15,15,15,15,15,15,15,15,15,15,11,9,
+ 14,15,15,14,12,11,11,11,10,9,7,0,0,5,13,15,
+ 15,15,15,15,15,12,1,0,0,0,0,0,0,10,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,14,7,1,0,0,0,0,0,3,14,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,13,2,0,0,0,0,0,0,0,0,0,0,0,8,
+ 15,15,15,15,15,11,0,0,0,0,0,0,0,9,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,13,5,0,0,0,0,12,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,8,0,0,0,0,0,0,0,0,0,0,0,0,5,
+ 15,15,15,15,15,15,10,5,6,7,7,7,9,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,8,3,2,2,2,2,5,14,15,
+ 15,15,15,15,15,15,15,15,15,10,3,0,6,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,13,3,1,0,1,0,1,1,2,4,4,3,9,14,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,12,4,0,1,6,7,7,4,1,3,13,
+ 15,15,15,15,15,15,15,15,15,15,14,10,13,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,11,11,15,15,15,15,
+ 15,15,15,14,14,14,14,14,14,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,14,2,0,4,13,15,15,15,15,10,0,12,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,13,14,12,12,12,12,12,12,12,
+ 12,14,15,15,15,15,15,15,15,15,4,14,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,7,1,5,14,15,15,15,15,15,12,1,11,
+ 15,15,15,13,12,13,15,15,14,11,13,15,15,15,15,15,
+ 15,15,15,11,6,3,1,1,1,0,0,0,0,0,0,0,
+ 0,1,4,7,11,14,15,15,15,14,4,15,13,10,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,14,7,4,5,
+ 12,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,13,1,1,14,15,15,14,10,12,15,11,1,12,
+ 15,15,11,1,0,4,15,15,6,0,2,14,15,15,15,15,
+ 15,15,14,8,6,3,3,2,2,1,0,0,0,0,0,0,
+ 0,0,0,0,0,3,11,15,15,11,8,15,12,6,15,9,
+ 8,15,15,15,15,15,15,15,15,15,15,15,10,4,4,1,
+ 4,15,15,15,15,11,6,2,8,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,0,4,15,15,15,11,2,10,15,9,1,13,
+ 15,13,1,7,6,2,14,14,1,2,1,14,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,13,12,12,12,12,12,12,
+ 11,11,11,10,9,10,12,15,15,6,7,15,9,4,15,4,
+ 1,14,15,15,15,15,15,15,15,15,15,15,2,11,15,4,
+ 4,15,15,15,15,3,9,4,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,0,4,15,15,15,5,0,6,6,1,9,15,
+ 15,4,1,13,10,1,13,9,2,7,1,14,14,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,3,5,15,3,5,14,1,
+ 0,12,13,9,14,15,15,15,15,15,15,15,2,2,4,1,
+ 6,15,15,15,14,1,5,6,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,0,4,15,15,15,12,4,2,2,10,15,15,
+ 11,0,6,15,12,0,10,7,9,10,1,14,7,14,15,15,
+ 15,15,15,15,15,15,13,12,11,11,10,9,9,10,11,13,
+ 15,15,15,15,15,15,15,15,15,1,9,15,2,7,14,1,
+ 0,10,7,0,8,15,15,15,15,15,15,15,11,4,4,4,
+ 13,15,15,15,15,10,2,2,4,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,0,4,15,15,15,15,15,15,15,15,15,15,
+ 4,2,14,15,15,1,9,5,14,9,1,14,8,14,15,15,
+ 15,15,15,15,15,10,3,0,1,0,0,0,0,0,0,5,
+ 15,15,15,15,15,15,15,15,15,1,9,14,1,8,14,1,
+ 0,11,13,6,11,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,0,4,15,15,15,15,15,15,15,15,15,11,
+ 0,6,15,15,15,1,5,3,13,10,0,6,8,15,15,15,
+ 15,15,15,15,15,15,13,12,12,11,10,9,9,10,11,13,
+ 15,15,15,15,15,15,15,15,15,1,9,12,1,11,15,4,
+ 1,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 14,10,4,2,12,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,1,3,14,15,15,15,15,15,15,15,15,4,
+ 3,14,15,15,15,5,1,8,15,14,5,2,9,15,15,15,
+ 15,15,15,15,15,15,15,15,15,11,9,13,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,1,9,12,1,12,15,13,
+ 11,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 10,2,9,2,3,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,14,4,0,5,14,15,15,15,15,15,15,11,0,
+ 6,15,15,15,15,15,14,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,8,1,0,3,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,1,9,15,11,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 7,1,12,6,1,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,11,1,0,3,8,9,9,10,11,9,5,4,
+ 13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,12,9,13,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,5,11,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 10,3,4,1,5,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,12,2,0,0,0,0,0,0,1,8,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,14,12,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,13,8,8,10,9,10,11,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
+ };
diff --git a/gst/goom/plugin_info.c b/gst/goom/plugin_info.c
new file mode 100644
index 00000000..2aeeb4fe
--- /dev/null
+++ b/gst/goom/plugin_info.c
@@ -0,0 +1,222 @@
+#include "config.h"
+
+#include "goom_plugin_info.h"
+#include "goom_fx.h"
+#include "default_scripts.h"
+#include "drawmethods.h"
+#include <math.h>
+#include <stdio.h>
+
+
+#if defined (HAVE_CPU_PPC64) || defined (HAVE_CPU_PPC)
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include "ppc_zoom_ultimate.h"
+#include "ppc_drawings.h"
+#endif /* HAVE_CPU_PPC64 || HAVE_CPU_PPC */
+
+
+#ifdef HAVE_CPU_I386
+#include "mmx.h"
+#endif /* HAVE_CPU_I386 */
+
+#include <liboil/liboil.h>
+#include <liboil/liboilfunction.h>
+#define VERBOSE 1
+
+static void
+setOptimizedMethods (PluginInfo * p)
+{
+
+ unsigned int cpuFlavour = oil_cpu_get_flags ();
+
+ /* set default methods */
+ p->methods.draw_line = draw_line;
+ p->methods.zoom_filter = zoom_filter_c;
+/* p->methods.create_output_with_brightness = create_output_with_brightness;*/
+
+#ifdef HAVE_CPU_I386
+ printf ("have an x86\n");
+ if (cpuFlavour & OIL_IMPL_FLAG_MMXEXT) {
+#ifdef VERBOSE
+ printf ("Extented MMX detected. Using the fastest methods !\n");
+#endif
+ p->methods.draw_line = draw_line_mmx;
+ p->methods.zoom_filter = zoom_filter_xmmx;
+ } else if (cpuFlavour & OIL_IMPL_FLAG_MMX) {
+#ifdef VERBOSE
+ printf ("MMX detected. Using fast methods !\n");
+#endif
+ p->methods.draw_line = draw_line_mmx;
+ p->methods.zoom_filter = zoom_filter_mmx;
+ }
+#ifdef VERBOSE
+ else
+ printf ("Too bad ! No SIMD optimization available for your CPU.\n");
+#endif
+#endif /* HAVE_CPU_I386 */
+
+#ifdef HAVE_CPU_PPC64
+ if ((cpuFlavour & CPU_OPTION_64_BITS) != 0) {
+/* p->methods.create_output_with_brightness = ppc_brightness_G5; */
+ p->methods.zoom_filter = ppc_zoom_generic;
+ }
+#endif /* HAVE_CPU_PPC64 */
+
+#ifdef HAVE_CPU_PPC
+ if ((cpuFlavour & OIL_IMPL_FLAG_ALTIVEC) != 0) {
+/* p->methods.create_output_with_brightness = ppc_brightness_G4; */
+ p->methods.zoom_filter = ppc_zoom_G4;
+ } else {
+/* p->methods.create_output_with_brightness = ppc_brightness_generic;*/
+ p->methods.zoom_filter = ppc_zoom_generic;
+ }
+#endif /* HAVE_CPU_PPC */
+
+}
+
+void
+plugin_info_init (PluginInfo * pp, int nbVisuals)
+{
+
+ PluginInfo p;
+ int i;
+
+ p.sound.speedvar = p.sound.accelvar = p.sound.totalgoom = 0;
+ p.sound.prov_max = 0;
+ p.sound.goom_limit = 1;
+ p.sound.allTimesMax = 1;
+
+ p.sound.volume_p = secure_f_feedback ("Sound Volume");
+ p.sound.accel_p = secure_f_feedback ("Sound Acceleration");
+ p.sound.speed_p = secure_f_feedback ("Sound Speed");
+ p.sound.goom_limit_p = secure_f_feedback ("Goom Limit");
+ p.sound.last_goom_p = secure_f_feedback ("Goom Detection");
+ p.sound.last_biggoom_p = secure_f_feedback ("Big Goom Detection");
+ p.sound.goom_power_p = secure_f_feedback ("Goom Power");
+
+ p.sound.biggoom_speed_limit_p = secure_i_param ("Big Goom Speed Limit");
+ IVAL (p.sound.biggoom_speed_limit_p) = 10;
+ IMIN (p.sound.biggoom_speed_limit_p) = 0;
+ IMAX (p.sound.biggoom_speed_limit_p) = 100;
+ ISTEP (p.sound.biggoom_speed_limit_p) = 1;
+
+ p.sound.biggoom_factor_p = secure_i_param ("Big Goom Factor");
+ IVAL (p.sound.biggoom_factor_p) = 10;
+ IMIN (p.sound.biggoom_factor_p) = 0;
+ IMAX (p.sound.biggoom_factor_p) = 100;
+ ISTEP (p.sound.biggoom_factor_p) = 1;
+
+ p.sound.params = plugin_parameters ("Sound", 11);
+
+ p.nbParams = 0;
+ p.nbVisuals = nbVisuals;
+ p.visuals = (VisualFX **) malloc (sizeof (VisualFX *) * nbVisuals);
+
+ *pp = p;
+ pp->sound.params.params[0] = &pp->sound.biggoom_speed_limit_p;
+ pp->sound.params.params[1] = &pp->sound.biggoom_factor_p;
+ pp->sound.params.params[2] = 0;
+ pp->sound.params.params[3] = &pp->sound.volume_p;
+ pp->sound.params.params[4] = &pp->sound.accel_p;
+ pp->sound.params.params[5] = &pp->sound.speed_p;
+ pp->sound.params.params[6] = 0;
+ pp->sound.params.params[7] = &pp->sound.goom_limit_p;
+ pp->sound.params.params[8] = &pp->sound.goom_power_p;
+ pp->sound.params.params[9] = &pp->sound.last_goom_p;
+ pp->sound.params.params[10] = &pp->sound.last_biggoom_p;
+
+ pp->statesNumber = 8;
+ pp->statesRangeMax = 510;
+ {
+ GoomState states[8] = {
+ {1, 0, 0, 1, 4, 0, 100}
+ ,
+ {1, 0, 0, 0, 1, 101, 140}
+ ,
+ {1, 0, 0, 1, 2, 141, 200}
+ ,
+ {0, 1, 0, 1, 2, 201, 260}
+ ,
+ {0, 1, 0, 1, 0, 261, 330}
+ ,
+ {0, 1, 1, 1, 4, 331, 400}
+ ,
+ {0, 0, 1, 0, 5, 401, 450}
+ ,
+ {0, 0, 1, 1, 1, 451, 510}
+ };
+ for (i = 0; i < 8; ++i)
+ pp->states[i] = states[i];
+ }
+ pp->curGState = &(pp->states[6]);
+
+ /* datas for the update loop */
+ pp->update.lockvar = 0;
+ pp->update.goomvar = 0;
+ pp->update.loopvar = 0;
+ pp->update.stop_lines = 0;
+ pp->update.ifs_incr = 1; /* dessiner l'ifs (0 = non: > = increment) */
+ pp->update.decay_ifs = 0; /* disparition de l'ifs */
+ pp->update.recay_ifs = 0; /* dedisparition de l'ifs */
+ pp->update.cyclesSinceLastChange = 0;
+ pp->update.drawLinesDuration = 80;
+ pp->update.lineMode = pp->update.drawLinesDuration;
+
+ pp->update.switchMultAmount = (29.0f / 30.0f);
+ pp->update.switchIncrAmount = 0x7f;
+ pp->update.switchMult = 1.0f;
+ pp->update.switchIncr = pp->update.switchIncrAmount;
+
+ pp->update.stateSelectionRnd = 0;
+ pp->update.stateSelectionBlocker = 0;
+ pp->update.previousZoomSpeed = 128;
+ pp->update.timeOfTitleDisplay = 0;
+
+ pp->update_message.affiche = 0;
+
+ {
+ ZoomFilterData zfd = {
+ 127, 8, 16,
+ 1, 1, 0, NORMAL_MODE,
+ 0, 0, 0, 0, 0
+ };
+ pp->update.zoomFilterData = zfd;
+ }
+
+ setOptimizedMethods (pp);
+
+ pp->scanner = gsl_new ();
+ pp->main_scanner = gsl_new ();
+ pp->main_script_str = GOOM_MAIN_SCRIPT;
+
+ for (i = 0; i < 0xffff; i++) {
+ pp->sintable[i] =
+ (int) (1024 * sin ((double) i * 360 / (sizeof (pp->sintable) /
+ sizeof (pp->sintable[0]) - 1) * 3.141592 / 180) + .5);
+ /* sintable [us] = (int)(1024.0f * sin (us*2*3.31415f/0xffff)) ; */
+ }
+}
+
+void
+plugin_info_add_visual (PluginInfo * p, int i, VisualFX * visual)
+{
+ p->visuals[i] = visual;
+ if (i == p->nbVisuals - 1) {
+ ++i;
+ p->nbParams = 1;
+ while (i--) {
+ if (p->visuals[i]->params)
+ p->nbParams++;
+ }
+ p->params =
+ (PluginParameters *) malloc (sizeof (PluginParameters) * p->nbParams);
+ i = p->nbVisuals;
+ p->nbParams = 1;
+ p->params[0] = p->sound.params;
+ while (i--) {
+ if (p->visuals[i]->params)
+ p->params[p->nbParams++] = *(p->visuals[i]->params);
+ }
+ }
+}
diff --git a/gst/goom/ppc_drawings.h b/gst/goom/ppc_drawings.h
new file mode 100644
index 00000000..ee438c28
--- /dev/null
+++ b/gst/goom/ppc_drawings.h
@@ -0,0 +1,18 @@
+/*
+ * ppc_drawings.h
+ * Goom
+ *
+ * Created by Guillaume Borios on Sun Dec 28 2003.
+ * Copyright (c) 2003 iOS. All rights reserved.
+ *
+ */
+
+/* Generic PowerPC Code */
+void ppc_brightness_generic(Pixel *src, Pixel *dest, int size, int coeff);
+
+/* G4 Specific PowerPC Code (Possible use of Altivec and Data Streams) */
+void ppc_brightness_G4(Pixel *src, Pixel *dest, int size, int coeff);
+
+/* G5 Specific PowerPC Code (Possible use of Altivec) */
+void ppc_brightness_G5(Pixel *src, Pixel *dest, int size, int coeff);
+
diff --git a/gst/goom/ppc_drawings.s b/gst/goom/ppc_drawings.s
new file mode 100644
index 00000000..845e5ea1
--- /dev/null
+++ b/gst/goom/ppc_drawings.s
@@ -0,0 +1,381 @@
+; PowerPC optimized drawing methods for Goom
+; © 2003 Guillaume Borios
+; This Source Code is released under the terms of the General Public License
+
+; Change log :
+; 30 May 2003 : File creation
+
+; Section definition : We use a read only code section for the whole file
+.section __TEXT,__text,regular,pure_instructions
+
+
+; --------------------------------------------------------------------------------------
+; Single 32b pixel drawing macros
+; Usage :
+; DRAWMETHOD_XXXX_MACRO *pixelIN, *pixelOUT, COLOR, WR1, WR2, WR3, WR4
+; Only the work registers (WR) can be touched by the macros
+;
+; Available methods :
+; DRAWMETHOD_DFLT_MACRO : Default drawing method (Actually OVRW)
+; DRAWMETHOD_PLUS_MACRO : RVB Saturated per channel addition (SLOWEST)
+; DRAWMETHOD_HALF_MACRO : 50% Transparency color drawing
+; DRAWMETHOD_OVRW_MACRO : Direct COLOR drawing (FASTEST)
+; DRAWMETHOD_B_OR_MACRO : Bitwise OR
+; DRAWMETHOD_BAND_MACRO : Bitwise AND
+; DRAWMETHOD_BXOR_MACRO : Bitwise XOR
+; DRAWMETHOD_BNOT_MACRO : Bitwise NOT
+; --------------------------------------------------------------------------------------
+
+.macro DRAWMETHOD_OVRW_MACRO
+ stw $2,0($1) ;; *$1 <- $2
+.endmacro
+
+.macro DRAWMETHOD_B_OR_MACRO
+ lwz $3,0($0) ;; $3 <- *$0
+ or $3,$3,$2 ;; $3 <- $3 | $2
+ stw $3,0($1) ;; *$1 <- $3
+.endmacro
+
+.macro DRAWMETHOD_BAND_MACRO
+ lwz $3,0($0) ;; $3 <- *$0
+ and $3,$3,$2 ;; $3 <- $3 & $2
+ stw $3,0($1) ;; *$1 <- $3
+.endmacro
+
+.macro DRAWMETHOD_BXOR_MACRO
+ lwz $3,0($0) ;; $3 <- *$0
+ xor $3,$3,$2 ;; $3 <- $3 ^ $2
+ stw $3,0($1) ;; *$1 <- $3
+.endmacro
+
+.macro DRAWMETHOD_BNOT_MACRO
+ lwz $3,0($0) ;; $3 <- *$0
+ nand $3,$3,$3 ;; $3 <- ~$3
+ stw $3,0($1) ;; *$1 <- $3
+.endmacro
+
+.macro DRAWMETHOD_PLUS_MACRO
+ lwz $4,0($0) ;; $4 <- *$0
+ andi. $3,$4,0xFF00 ;; $3 <- $4 & 0x0000FF00
+ andi. $5,$2,0xFF00 ;; $5 <- $2 & 0x0000FF00
+ add $3,$3,$5 ;; $3 <- $3 + $5
+ rlwinm $5,$3,15,0,0 ;; $5 <- 0 | ($3[15] << 15)
+ srawi $5,$5,23 ;; $5 <- $5 >> 23 (algebraic for sign extension)
+ or $3,$3,$5 ;; $3 <- $3 | $5
+ lis $5,0xFF ;; $5 <- 0x00FF00FF
+ addi $5,$5,0xFF
+ and $4,$4,$5 ;; $4 <- $4 & $5
+ and $6,$2,$5 ;; $6 <- $2 & $5
+ add $4,$4,$6 ;; $4 <- $4 + $6
+ rlwinm $6,$4,7,0,0 ;; $6 <- 0 | ($4[7] << 7)
+ srawi $6,$6,15 ;; $6 <- $6 >> 15 (algebraic for sign extension)
+ rlwinm $5,$4,23,0,0 ;; $5 <- 0 | ($4[23] << 23)
+ srawi $5,$5,31 ;; $5 <- $5 >> 31 (algebraic for sign extension)
+ rlwimi $6,$5,0,24,31 ;; $6[24..31] <- $5[24..31]
+ or $4,$4,$6 ;; $4 <- $4 | $6
+ rlwimi $4,$3,0,16,23 ;; $4[16..23] <- $3[16..23]
+ stw $4,0($1) ;; *$1 <- $4
+.endmacro
+
+.macro DRAWMETHOD_HALF_MACRO
+ lwz $4,0($0) ;; $4 <- *$0
+ andi. $3,$4,0xFF00 ;; $3 <- $4 & 0x0000FF00
+ andi. $5,$2,0xFF00 ;; $5 <- $2 & 0x0000FF00
+ add $3,$3,$5 ;; $3 <- $3 + $5
+ lis $5,0xFF ;; $5 <- 0x00FF00FF
+ addi $5,$5,0xFF
+ and $4,$4,$5 ;; $4 <- $4 & $5
+ and $5,$2,$5 ;; $5 <- $2 & $5
+ add $4,$4,$5 ;; $4 <- $4 + $5
+ srwi $4,$4,1 ;; $4 <- $4 >> 1
+ rlwimi $4,$3,31,16,23 ;; $4[16..23] <- $3[15..22]
+ stw $4,0($1) ;; *$1 <- $4
+.endmacro
+
+.macro DRAWMETHOD_DFLT_MACRO
+ DRAWMETHOD_PLUS_MACRO
+.endmacro
+
+; --------------------------------------------------------------------------------------
+
+
+
+; **************************************************************************************
+; void DRAWMETHOD_PLUS_PPC(unsigned int * buf, unsigned int _col);
+; void DRAWMETHOD_PLUS_2_PPC(unsigned * in, unsigned int * out, unsigned int _col);
+; **************************************************************************************
+.globl _DRAWMETHOD_PLUS_2_PPC
+.align 3
+_DRAWMETHOD_PLUS_2_PPC:
+ DRAWMETHOD_PLUS_MACRO r3,r4,r5,r6,r7,r8,r9
+ blr ;; return
+
+.globl _DRAWMETHOD_PLUS_PPC
+.align 3
+_DRAWMETHOD_PLUS_PPC:
+ DRAWMETHOD_PLUS_MACRO r3,r3,r4,r5,r6,r7,r9
+ blr ;; return
+
+
+; **************************************************************************************
+; void DRAWMETHOD_HALF_PPC(unsigned int * buf, unsigned int _col);
+; void DRAWMETHOD_HALF_2_PPC(unsigned * in, unsigned int * out, unsigned int _col);
+; **************************************************************************************
+.globl _DRAWMETHOD_HALF_2_PPC
+.align 3
+_DRAWMETHOD_HALF_2_PPC:
+ DRAWMETHOD_HALF_MACRO r3,r4,r5,r6,r7,r8
+ blr ;; return
+
+.globl _DRAWMETHOD_HALF_PPC
+.align 3
+_DRAWMETHOD_HALF_PPC:
+ DRAWMETHOD_HALF_MACRO r3,r3,r4,r5,r6,r7
+ blr ;; return
+
+
+; **************************************************************************************
+; void DRAW_LINE_PPC(unsigned int *data, int x1, int y1, int x2, int y2, unsigned int col,
+; unsigned int screenx, unsigned int screeny)
+; **************************************************************************************
+.globl _DRAW_LINE_PPC
+.align 3
+_DRAW_LINE_PPC:
+ ;; NOT IMPLEMENTED YET
+ blr ;; return
+
+
+; **************************************************************************************
+; void _ppc_brightness(Pixel * src, Pixel * dest, unsigned int size, unsigned int coeff)
+; **************************************************************************************
+
+
+.const
+.align 4
+vectorZERO:
+ .long 0,0,0,0
+ .long 0x10101000, 0x10101001, 0x10101002, 0x10101003
+ .long 0x10101004, 0x10101005, 0x10101006, 0x10101007
+ .long 0x10101008, 0x10101009, 0x1010100A, 0x1010100B
+ .long 0x1010100C, 0x1010100D, 0x1010100E, 0x1010100F
+
+
+.section __TEXT,__text,regular,pure_instructions
+
+.globl _ppc_brightness_G4
+.align 3
+_ppc_brightness_G4:
+
+
+;; PowerPC Altivec code
+ srwi r5,r5,2
+ mtctr r5
+
+;;vrsave
+ mfspr r11,256
+ lis r12,0xCFFC
+ mtspr 256,r12
+
+ mflr r0
+ bcl 20,31,"L00000000001$pb"
+"L00000000001$pb":
+ mflr r10
+ mtlr r0
+
+ addis r9,r10,ha16(vectorZERO-"L00000000001$pb")
+ addi r9,r9,lo16(vectorZERO-"L00000000001$pb")
+
+ vxor v0,v0,v0 ;; V0 = NULL vector
+
+ addi r9,r9,16
+ lvx v10,0,r9
+ addi r9,r9,16
+ lvx v11,0,r9
+ addi r9,r9,16
+ lvx v12,0,r9
+ addi r9,r9,16
+ lvx v13,0,r9
+
+ addis r9,r10,ha16(vectortmpwork-"L00000000001$pb")
+ addi r9,r9,lo16(vectortmpwork-"L00000000001$pb")
+ stw r6,0(r9)
+ li r6,8
+ stw r6,4(r9)
+ lvx v9,0,r9
+ li r9,128
+ vspltw v8,v9,0
+ vspltw v9,v9,1
+
+;; elt counter
+ li r9,0
+ lis r7,0x0F01
+ b L7
+.align 4
+L7:
+ lvx v1,r9,r3
+
+ vperm v4,v1,v0,v10
+ ;*********************
+ add r10,r9,r3
+ ;*********************
+ vperm v5,v1,v0,v11
+ vperm v6,v1,v0,v12
+ vperm v7,v1,v0,v13
+
+ vmulouh v4,v4,v8
+ ;*********************
+ dst r10,r7,3
+ ;*********************
+ vmulouh v5,v5,v8
+ vmulouh v6,v6,v8
+ vmulouh v7,v7,v8
+ vsrw v4,v4,v9
+ vsrw v5,v5,v9
+ vsrw v6,v6,v9
+ vsrw v7,v7,v9
+
+ vpkuwus v4,v4,v5
+ vpkuwus v6,v6,v7
+ vpkuhus v1,v4,v6
+
+ stvx v1,r9,r4
+ addi r9,r9,16
+
+ bdnz L7
+
+ mtspr 256,r11
+ blr
+
+
+.globl _ppc_brightness_G5
+.align 3
+_ppc_brightness_G5:
+
+;; PowerPC Altivec G5 code
+ srwi r5,r5,2
+ mtctr r5
+
+;;vrsave
+ mfspr r11,256
+ lis r12,0xCFFC
+ mtspr 256,r12
+
+ mflr r0
+ bcl 20,31,"L00000000002$pb"
+"L00000000002$pb":
+ mflr r10
+ mtlr r0
+
+ addis r9,r10,ha16(vectorZERO-"L00000000002$pb")
+ addi r9,r9,lo16(vectorZERO-"L00000000002$pb")
+
+ vxor v0,v0,v0 ;; V0 = NULL vector
+
+ addi r9,r9,16
+ lvx v10,0,r9
+ addi r9,r9,16
+ lvx v11,0,r9
+ addi r9,r9,16
+ lvx v12,0,r9
+ addi r9,r9,16
+ lvx v13,0,r9
+
+ addis r9,r10,ha16(vectortmpwork-"L00000000002$pb")
+ addi r9,r9,lo16(vectortmpwork-"L00000000002$pb")
+ stw r6,0(r9)
+ li r6,8
+ stw r6,4(r9)
+ lvx v9,0,r9
+ li r9,128
+ vspltw v8,v9,0
+ vspltw v9,v9,1
+
+;; elt counter
+ li r9,0
+ lis r7,0x0F01
+ b L6
+.align 4
+L6:
+ lvx v1,r9,r3
+
+ vperm v4,v1,v0,v10
+ ;*********************
+ add r10,r9,r3
+ ;*********************
+ vperm v5,v1,v0,v11
+ vperm v6,v1,v0,v12
+ vperm v7,v1,v0,v13
+
+ vmulouh v4,v4,v8
+ vmulouh v5,v5,v8
+ vmulouh v6,v6,v8
+ vmulouh v7,v7,v8
+ vsrw v4,v4,v9
+ vsrw v5,v5,v9
+ vsrw v6,v6,v9
+ vsrw v7,v7,v9
+
+ vpkuwus v4,v4,v5
+ vpkuwus v6,v6,v7
+ vpkuhus v1,v4,v6
+
+ stvx v1,r9,r4
+ addi r9,r9,16
+
+ bdnz L6
+
+ mtspr 256,r11
+ blr
+
+
+.globl _ppc_brightness_generic
+.align 3
+_ppc_brightness_generic:
+ lis r12,0x00FF
+ ori r12,r12,0x00FF
+ subi r3,r3,4
+ subi r4,r4,4
+ mtctr r5
+ b L1
+.align 4
+L1:
+ lwzu r7,4(r3)
+
+ rlwinm r8,r7,16,24,31
+ rlwinm r9,r7,24,24,31
+ mullw r8,r8,r6
+ rlwinm r10,r7,0,24,31
+ mullw r9,r9,r6
+ srwi r8,r8,8
+ mullw r10,r10,r6
+ srwi r9,r9,8
+
+ rlwinm. r11,r8,0,0,23
+ beq L2
+ li r8,0xFF
+L2:
+ srwi r10,r10,8
+ rlwinm. r11,r9,0,0,23
+ beq L3
+ li r9,0xFF
+L3:
+ rlwinm r7,r8,16,8,15
+ rlwinm. r11,r10,0,0,23
+ beq L4
+ li r10,0xFF
+L4:
+ rlwimi r7,r9,8,16,23
+ rlwimi r7,r10,0,24,31
+
+ stwu r7,4(r4)
+ bdnz L1
+
+ blr
+
+
+
+.static_data
+.align 4
+vectortmpwork:
+ .long 0,0,0,0
+
diff --git a/gst/goom/ppc_zoom_ultimate.h b/gst/goom/ppc_zoom_ultimate.h
new file mode 100644
index 00000000..d6932e7e
--- /dev/null
+++ b/gst/goom/ppc_zoom_ultimate.h
@@ -0,0 +1,14 @@
+/*
+ * ppc_zoom_ultimate.h
+ * Goom
+ *
+ * Created by Guillaume Borios on Sun Dec 28 2003.
+ * Copyright (c) 2003 iOS. All rights reserved.
+ *
+ */
+
+/* Generic PowerPC Code */
+void ppc_zoom_generic (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
+
+/* G4 Specific PowerPC Code (Possible use of Altivec and Data Streams) */
+void ppc_zoom_G4 (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]); \ No newline at end of file
diff --git a/gst/goom/ppc_zoom_ultimate.s b/gst/goom/ppc_zoom_ultimate.s
new file mode 100644
index 00000000..da252c67
--- /dev/null
+++ b/gst/goom/ppc_zoom_ultimate.s
@@ -0,0 +1,323 @@
+; PowerPC optimized zoom for Goom
+; © 2001-2003 Guillaume Borios
+; This Source Code is released under the terms of the General Public License
+
+; Change log :
+; 21 Dec 2003 : Use of altivec is now determined with a parameter
+
+; Section definition : We use a read only section
+.text
+
+; name of the function to call by C program : ppc_zoom
+; We declare this label as a global to extend its scope outside this file
+.globl _ppc_zoom_generic
+.globl _ppc_zoom_G4
+
+; Description :
+; This routine dynamically computes and applies a zoom filter
+
+; parameters :
+; r3 <=> unsigned int sizeX (in pixels)
+; r4 <=> unsigned int sizeY (in pixels)
+; r5 <=> unsigned int * frompixmap
+; r6 <=> unsigned int * topixmap
+; r7 <=> unsigned int * brutS
+; r8 <=> unsigned int * brutD
+; r9 <=> unsigned int buffratio
+; r10 <=> int [16][16] precalccoeffs
+
+; globals after init
+; r5 <=> frompixmap - 1 byte needed for preincremental fetch (replaces r5)
+; r6 <=> topixmap - 1 byte needed for preincremental fetch (replaces r6)
+; r3 <=> ax = x max in 16th of pixels (replaces old r3)
+; r4 <=> ay = y max in 16th of pixels (replaces old r4)
+; r20 <=> row size in bytes
+; r12 <=> 0xFF00FF (mask for parallel 32 bits pixs computing)
+; r30 <=> brutS - 1 byte needed for preincremental fetch (replaces r7)
+; r31 <=> brutD - 1 byte needed for preincremental fetch (replaces r8)
+
+; ABI notes :
+; r1 is the Stack Pointer (SP) => Do not use
+; r13..r31 are non-volatiles => Do not use
+
+_ppc_zoom_generic:
+
+; Saves the used non volatile registers in the Mach-O stack s Red-Zone
+stmw r18,-56(r1)
+
+; init
+li r18,0 ; Default value if out of range : 0 (Black)
+mr r11,r10
+lis r12,0xFF
+mullw r2,r3,r4 ; Number of pixels to compute
+subi r30,r8,0
+slwi r20,r3,2
+srawi r19,r20,2
+ori r12,r12,0xFF
+subi r3,r3,1
+subi r4,r4,1
+mtspr ctr,r2 ; Init the loop count (one loop per pixel computed)
+subi r31,r7,0
+subi r6,r6,4
+slwi r3,r3,4
+slwi r4,r4,4
+
+;pre init for loop
+lwz r2,0(r31) ; px
+lwz r29,4(r31) ; py
+lwz r8,0(r30) ; px2
+lwz r10,4(r30) ; py2
+
+b L1
+.align 5
+L1:
+
+; computes dynamically the position to fetch
+sub r8,r8,r2
+sub r10,r10,r29
+mullw r8,r8,r9
+addi r31,r31,8
+mullw r10,r10,r9
+addi r30,r30,8
+
+srawi r8,r8,16
+srawi r10,r10,16
+add r2,r2,r8
+add r29,r29,r10
+
+; if px>ax or py>ay goto outofrange
+; computes the attenuation coeffs and the original point address
+rlwinm r10,r2,6,28-6,31-6 ; r10 <- (r2 << 2) & 0x000002D0 (r10=(r2%16)*4*16)
+cmpl cr4,0,r2,r3
+rlwimi r10, r29, 2, 28-2, 31-2 ; r10 <- ((r29 << 2) & 0x0000002D) | (r10 & !0x0000002D) (r10=(r10%16)*4 | r10)
+cmpl cr7,0,r29,r4
+srawi r29,r29,4 ; pos computing
+bge- cr4,L4
+srawi r2,r2,4 ; pos computing
+mullw r29, r29,r19 ; pos computing
+bge- cr7,L4
+
+; Channels notation : 00112233 (AARRVVBB)
+
+add r2,r2,r29 ; pos computing
+lwzx r10,r11,r10 ; Loads coefs
+slwi r2,r2,2 ; pos computing
+add r2,r2,r5 ; pos computing
+rlwinm r21,r10,0,24,31 ; Isolates coef1 (??????11 -> 00000011)
+lwz r25,0(r2) ; Loads col1 -> r25
+lwz r26,4(r2) ; Loads col2 -> r26
+rlwinm r22,r10,24,24,31 ; Isolates coef2 (????22?? -> 00000022)
+rlwinm r23,r10,16,24,31 ; Isolates coef3 (??33???? -> 00000033)
+add r2,r2,r20 ; Adds one line for future load of col3 and col4
+and r8, r25,r12 ; Masks col1 channels 1 & 3 : 0x00XX00XX
+rlwinm r24,r10,8,24,31 ; Isolates coef4 (44?????? -> 00000044)
+andi. r25,r25,0xFF00 ; Masks col1 channel 2 : 0x0000XX00
+mullw r8, r8, r21 ; Applies coef1 on col1 channels 1 & 3
+
+
+; computes final pixel color
+and r10,r26,r12 ; Masks col2 channels 1 & 3 : 0x00XX00XX
+lwz r27,0(r2) ; Loads col3 -> r27
+mullw r10,r10,r22 ; Applies coef2 on col2 channels 1 & 3
+mullw r25,r25,r21 ; Applies coef1 on col1 channel 2
+andi. r29,r26,0xFF00 ; Masks col2 channel 2 : 0x0000XX00
+mullw r29,r29,r22 ; Applies coef2 on col2 channel 2
+lwz r28,4(r2) ; Loads col4 -> r28
+add r8 ,r8 ,r10 ; Adds col1 & col2 channels 1 & 3
+and r10,r27,r12 ; Masks col3 channels 1 & 3 : 0x00XX00XX
+add r25,r25,r29 ; Adds col1 & col2 channel 2
+mullw r10,r10,r23 ; Applies coef3 on col3 channels 1 & 3
+andi. r29,r27,0xFF00 ; Masks col3 channel 2 : 0x0000XX00
+mullw r29,r29,r23 ; Applies coef3 on col3 channel 2
+lwz r2,0(r31) ; px
+add r7 ,r8 ,r10 ; Adds col3 to (col1 + col2) channels 1 & 3
+and r10,r28,r12 ; Masks col4 channels 1 & 3 : 0x00XX00XX
+mullw r10,r10,r24 ; Applies coef4 on col4 channels 1 & 3
+add r25,r25,r29 ; Adds col 3 to (col1 + col2) channel 2
+lwz r8,0(r30) ; px2
+andi. r28,r28,0xFF00 ; Masks col4 channel 2 : 0x0000XX00
+add r7 ,r7 ,r10 ; Adds col4 to (col1 + col2 + col3) channels 1 & 3
+lwz r10,4(r30) ; py2
+mullw r28,r28,r24 ; Applies coef4 on col4 channel 2
+srawi r7, r7, 8 ; (sum of channels 1 & 3) >> 8
+lwz r29,4(r31) ; py
+add r25,r25,r28 ; Adds col 4 to (col1 + col2 + col3) channel 2
+rlwimi r7, r25, 24, 16, 23 ; (((sum of channels 2) >> 8 ) & 0x0000FF00) | ((sum of channels 1 and 3) & 0xFFFF00FF)
+stwu r7,4(r6) ; Stores the computed pixel
+bdnz L1 ; Iterate again if needed
+b L3 ;goto end ; If not, returns from the function
+
+
+; if out of range
+L4:
+stwu r18,4(r6)
+lwz r8,0(r30) ; px2
+lwz r10,4(r30) ; py2
+lwz r2,0(r31) ; px
+lwz r29,4(r31) ; py
+bdnz L1
+
+
+L3:
+
+; Restore saved registers and return
+lmw r18,-56(r1)
+blr
+
+
+
+
+
+
+
+
+_ppc_zoom_G4:
+
+; Saves the used non volatile registers in the Mach-O stack s Red-Zone
+stmw r17,-60(r1)
+
+; init
+li r18,0 ; Default value if out of range : 0 (Black)
+mr r11,r10
+lis r12,0xFF
+mullw r2,r3,r4 ; Number of pixels to compute
+subi r30,r8,0
+slwi r20,r3,2
+srawi r19,r20,2
+ori r12,r12,0xFF
+subi r3,r3,1
+subi r4,r4,1
+mtspr ctr,r2 ; Init the loop count (one loop per pixel computed)
+subi r31,r7,0
+subi r6,r6,4
+slwi r3,r3,4
+slwi r4,r4,4
+
+;pre init for loop
+lwz r2,0(r31) ; px
+lwz r29,4(r31) ; py
+lwz r8,0(r30) ; px2
+lwz r10,4(r30) ; py2
+
+;*********************
+lis r17,0x0F01
+
+b L100
+.align 5
+L100:
+
+addi r6,r6,4
+
+; Optimization to ensure the destination buffer
+; won't be loaded into the data cache
+rlwinm. r0,r6,0,27,31
+bne+ L500
+dcbz 0,r6
+;dcba 0,r6
+L500:
+
+; computes dynamically the position to fetch
+;mullw r8,r8,r29
+;mullw r2,r2,r29
+;add r2,r8,r2
+;srawi r2,r2,17
+
+sub r8,r8,r2
+sub r10,r10,r29
+mullw r8,r8,r9
+addi r31,r31,8
+mullw r10,r10,r9
+addi r30,r30,8
+
+dst r30,r17,0
+
+srawi r8,r8,16
+srawi r10,r10,16
+add r2,r2,r8
+add r29,r29,r10
+
+dst r31,r17,1
+
+; if px>ax or py>ay goto outofrange
+; computes the attenuation coeffs and the original point address
+rlwinm r10,r2,6,28-6,31-6 ; r10 <- (r2 << 2) & 0x000002D0 (r10=(r2%16)*4*16)
+cmpl cr4,0,r2,r3
+rlwimi r10, r29, 2, 28-2, 31-2 ; r10 <- ((r29 << 2) & 0x0000002D) | (r10 & !0x0000002D) (r10=(r29%16)*4 | r10)
+cmpl cr7,0,r29,r4
+srawi r29,r29,4 ; pos computing
+bge- cr4,L400
+srawi r2,r2,4 ; pos computing
+mullw r29, r29,r19 ; pos computing
+bge- cr7,L400
+
+; Channels notation : 00112233 (AARRVVBB)
+
+add r2,r2,r29 ; pos computing
+lwzx r10,r11,r10 ; Loads coefs
+slwi r2,r2,2 ; pos computing
+add r2,r2,r5 ; pos computing
+rlwinm r21,r10,0,24,31 ; Isolates coef1 (??????11 -> 00000011)
+lwz r25,0(r2) ; Loads col1 -> r25
+lwz r26,4(r2) ; Loads col2 -> r26
+rlwinm r22,r10,24,24,31 ; Isolates coef2 (????22?? -> 00000022)
+rlwinm r23,r10,16,24,31 ; Isolates coef3 (??33???? -> 00000033)
+add r2,r2,r20 ; Adds one line for future load of col3 and col4
+and r8, r25,r12 ; Masks col1 channels 1 & 3 : 0x00XX00XX
+rlwinm r24,r10,8,24,31 ; Isolates coef4 (44?????? -> 00000044)
+dst r2,r17,2
+rlwinm r25,r25,0,16,23 ; Masks col1 channel 2 : 0x0000XX00
+;andi. r25,r25,0xFF00 ; Masks col1 channel 2 : 0x0000XX00
+mullw r8, r8, r21 ; Applies coef1 on col1 channels 1 & 3
+
+
+; computes final pixel color
+and r10,r26,r12 ; Masks col2 channels 1 & 3 : 0x00XX00XX
+lwz r27,0(r2) ; Loads col3 -> r27
+mullw r10,r10,r22 ; Applies coef2 on col2 channels 1 & 3
+mullw r25,r25,r21 ; Applies coef1 on col1 channel 2
+rlwinm r29,r26,0,16,23 ; Masks col2 channel 2 : 0x0000XX00
+;andi. r29,r26,0xFF00 ; Masks col2 channel 2 : 0x0000XX00
+mullw r29,r29,r22 ; Applies coef2 on col2 channel 2
+lwz r28,4(r2) ; Loads col4 -> r28
+add r8 ,r8 ,r10 ; Adds col1 & col2 channels 1 & 3
+and r10,r27,r12 ; Masks col3 channels 1 & 3 : 0x00XX00XX
+add r25,r25,r29 ; Adds col1 & col2 channel 2
+mullw r10,r10,r23 ; Applies coef3 on col3 channels 1 & 3
+rlwinm r29,r27,0,16,23 ; Masks col3 channel 2 : 0x0000XX00
+;andi. r29,r27,0xFF00 ; Masks col3 channel 2 : 0x0000XX00
+mullw r29,r29,r23 ; Applies coef3 on col3 channel 2
+lwz r2,0(r31) ; px
+add r7 ,r8 ,r10 ; Adds col3 to (col1 + col2) channels 1 & 3
+and r10,r28,r12 ; Masks col4 channels 1 & 3 : 0x00XX00XX
+mullw r10,r10,r24 ; Applies coef4 on col4 channels 1 & 3
+add r25,r25,r29 ; Adds col 3 to (col1 + col2) channel 2
+lwz r8,0(r30) ; px2
+rlwinm r28,r28,0,16,23 ; Masks col4 channel 2 : 0x0000XX00
+;andi. r28,r28,0xFF00 ; Masks col4 channel 2 : 0x0000XX00
+add r7 ,r7 ,r10 ; Adds col4 to (col1 + col2 + col3) channels 1 & 3
+lwz r10,4(r30) ; py2
+mullw r28,r28,r24 ; Applies coef4 on col4 channel 2
+srawi r7, r7, 8 ; (sum of channels 1 & 3) >> 8
+lwz r29,4(r31) ; py
+add r25,r25,r28 ; Adds col 4 to (col1 + col2 + col3) channel 2
+rlwimi r7, r25, 24, 16, 23 ; (((sum of channels 2) >> 8 ) & 0x0000FF00) | ((sum of channels 1 and 3) & 0xFFFF00FF)
+stw r7,0(r6) ; Stores the computed pixel
+bdnz L100 ; Iterate again if needed
+b L300 ;goto end ; If not, returns from the function
+
+
+; if out of range
+L400:
+stw r18,0(r6)
+lwz r8,0(r30) ; px2
+lwz r10,4(r30) ; py2
+lwz r2,0(r31) ; px
+lwz r29,4(r31) ; py
+bdnz L100
+
+
+L300:
+
+; Restore saved registers and return
+lmw r17,-60(r1)
+blr
diff --git a/gst/goom/sound_tester.c b/gst/goom/sound_tester.c
new file mode 100644
index 00000000..214ca0ef
--- /dev/null
+++ b/gst/goom/sound_tester.c
@@ -0,0 +1,143 @@
+#include "sound_tester.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/* some constants */
+#define BIG_GOOM_DURATION 100
+#define BIG_GOOM_SPEED_LIMIT 0.1f
+
+#define ACCEL_MULT 0.95f
+#define SPEED_MULT 0.99f
+
+
+void
+evaluate_sound (gint16 data[2][512], SoundInfo * info)
+{
+
+ int i;
+ float difaccel;
+ float prevspeed;
+
+ /* find the max */
+ int incvar = 0;
+
+ for (i = 0; i < 512; i += 2) {
+ if (incvar < data[0][i])
+ incvar = data[0][i];
+ }
+
+ if (incvar > info->allTimesMax)
+ info->allTimesMax = incvar;
+
+ /* volume sonore */
+ info->volume = (float) incvar / (float) info->allTimesMax;
+ memcpy (info->samples[0], data[0], 512 * sizeof (short));
+ memcpy (info->samples[1], data[1], 512 * sizeof (short));
+
+ difaccel = info->accelvar;
+ info->accelvar = info->volume; /* accel entre 0 et 1 */
+
+ /* transformations sur la vitesse du son */
+ if (info->speedvar > 1.0f)
+ info->speedvar = 1.0f;
+
+ if (info->speedvar < 0.1f)
+ info->accelvar *= (1.0f - (float) info->speedvar);
+ else if (info->speedvar < 0.3f)
+ info->accelvar *= (0.9f - (float) (info->speedvar - 0.1f) / 2.0f);
+ else
+ info->accelvar *= (0.8f - (float) (info->speedvar - 0.3f) / 4.0f);
+
+ /* adoucissement de l'acceleration */
+ info->accelvar *= ACCEL_MULT;
+ if (info->accelvar < 0)
+ info->accelvar = 0;
+
+ difaccel = info->accelvar - difaccel;
+ if (difaccel < 0)
+ difaccel = -difaccel;
+
+ /* mise a jour de la vitesse */
+ prevspeed = info->speedvar;
+ info->speedvar = (info->speedvar + difaccel * 0.5f) / 2;
+ info->speedvar *= SPEED_MULT;
+ info->speedvar = (info->speedvar + 3.0f * prevspeed) / 4.0f;
+ if (info->speedvar < 0)
+ info->speedvar = 0;
+ if (info->speedvar > 1)
+ info->speedvar = 1;
+
+ /* temps du goom */
+ info->timeSinceLastGoom++;
+ info->timeSinceLastBigGoom++;
+ info->cycle++;
+
+ /* detection des nouveaux gooms */
+ if ((info->speedvar > (float) IVAL (info->biggoom_speed_limit_p) / 100.0f)
+ && (info->accelvar > info->bigGoomLimit)
+ && (info->timeSinceLastBigGoom > BIG_GOOM_DURATION)) {
+ info->timeSinceLastBigGoom = 0;
+ }
+
+ if (info->accelvar > info->goom_limit) {
+ /* TODO: tester && (info->timeSinceLastGoom > 20)) { */
+ info->totalgoom++;
+ info->timeSinceLastGoom = 0;
+ info->goomPower = info->accelvar - info->goom_limit;
+ }
+
+ if (info->accelvar > info->prov_max)
+ info->prov_max = info->accelvar;
+
+ if (info->goom_limit > 1)
+ info->goom_limit = 1;
+
+ /* toute les 2 secondes : vérifier si le taux de goom est correct
+ * et le modifier sinon.. */
+ if (info->cycle % 64 == 0) {
+ if (info->speedvar < 0.01f)
+ info->goom_limit *= 0.91;
+ if (info->totalgoom > 4) {
+ info->goom_limit += 0.02;
+ }
+ if (info->totalgoom > 7) {
+ info->goom_limit *= 1.03f;
+ info->goom_limit += 0.03;
+ }
+ if (info->totalgoom > 16) {
+ info->goom_limit *= 1.05f;
+ info->goom_limit += 0.04;
+ }
+ if (info->totalgoom == 0) {
+ info->goom_limit = info->prov_max - 0.02;
+ }
+ if ((info->totalgoom == 1) && (info->goom_limit > 0.02))
+ info->goom_limit -= 0.01;
+ info->totalgoom = 0;
+ info->bigGoomLimit =
+ info->goom_limit * (1.0f +
+ (float) IVAL (info->biggoom_factor_p) / 500.0f);
+ info->prov_max = 0;
+ }
+
+ /* mise a jour des parametres pour la GUI */
+ FVAL (info->volume_p) = info->volume;
+ info->volume_p.change_listener (&info->volume_p);
+ FVAL (info->speed_p) = info->speedvar * 4;
+ info->speed_p.change_listener (&info->speed_p);
+ FVAL (info->accel_p) = info->accelvar;
+ info->accel_p.change_listener (&info->accel_p);
+
+ FVAL (info->goom_limit_p) = info->goom_limit;
+ info->goom_limit_p.change_listener (&info->goom_limit_p);
+ FVAL (info->goom_power_p) = info->goomPower;
+ info->goom_power_p.change_listener (&info->goom_power_p);
+ FVAL (info->last_goom_p) = 1.0 - ((float) info->timeSinceLastGoom / 20.0f);
+ info->last_goom_p.change_listener (&info->last_goom_p);
+ FVAL (info->last_biggoom_p) =
+ 1.0 - ((float) info->timeSinceLastBigGoom / 40.0f);
+ info->last_biggoom_p.change_listener (&info->last_biggoom_p);
+
+ /* bigGoomLimit ==goomLimit*9/8+7 ? */
+}
diff --git a/gst/goom/sound_tester.h b/gst/goom/sound_tester.h
new file mode 100644
index 00000000..51545a80
--- /dev/null
+++ b/gst/goom/sound_tester.h
@@ -0,0 +1,11 @@
+#ifndef _SOUND_TESTER_H
+#define _SOUND_TESTER_H
+
+#include "goom_plugin_info.h"
+#include "goom_config.h"
+
+/** change les donnees du SoundInfo */
+void evaluate_sound(gint16 data[2][512], SoundInfo *sndInfo);
+
+#endif
+
diff --git a/gst/goom/surf3d.c b/gst/goom/surf3d.c
new file mode 100644
index 00000000..f6810f85
--- /dev/null
+++ b/gst/goom/surf3d.c
@@ -0,0 +1,123 @@
+#include "surf3d.h"
+#include "goom_plugin_info.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+grid3d *
+grid3d_new (int sizex, int defx, int sizez, int defz, v3d center)
+{
+ int x = defx;
+ int y = defz;
+ grid3d *g = malloc (sizeof (grid3d));
+ surf3d *s = &(g->surf);
+
+ s->nbvertex = x * y;
+ s->vertex = malloc (x * y * sizeof (v3d));
+ s->svertex = malloc (x * y * sizeof (v3d));
+ s->center = center;
+
+ g->defx = defx;
+ g->sizex = sizex;
+ g->defz = defz;
+ g->sizez = sizez;
+ g->mode = 0;
+
+ while (y) {
+ --y;
+ x = defx;
+ while (x) {
+ --x;
+ s->vertex[x + defx * y].x = (float) (x - defx / 2) * sizex / defx;
+ s->vertex[x + defx * y].y = 0;
+ s->vertex[x + defx * y].z = (float) (y - defz / 2) * sizez / defz;
+ }
+ }
+ return g;
+}
+
+void
+grid3d_draw (PluginInfo * plug, grid3d * g, int color, int colorlow,
+ int dist, Pixel * buf, Pixel * back, int W, int H)
+{
+
+ int x;
+ v2d v2, v2x;
+
+ v2d *v2_array = malloc (g->surf.nbvertex * sizeof (v2d));
+
+ v3d_to_v2d (g->surf.svertex, g->surf.nbvertex, W, H, dist, v2_array);
+
+ for (x = 0; x < g->defx; x++) {
+ int z;
+
+ v2x = v2_array[x];
+
+ for (z = 1; z < g->defz; z++) {
+ v2 = v2_array[z * g->defx + x];
+ if (((v2.x != -666) || (v2.y != -666))
+ && ((v2x.x != -666) || (v2x.y != -666))) {
+ plug->methods.draw_line (buf, v2x.x, v2x.y, v2.x, v2.y, colorlow, W, H);
+ plug->methods.draw_line (back, v2x.x, v2x.y, v2.x, v2.y, color, W, H);
+ }
+ v2x = v2;
+ }
+ }
+
+ free (v2_array);
+}
+
+void
+surf3d_rotate (surf3d * s, float angle)
+{
+ int i;
+ float cosa;
+ float sina;
+
+ SINCOS (angle, sina, cosa);
+ for (i = 0; i < s->nbvertex; i++) {
+ Y_ROTATE_V3D (s->vertex[i], s->svertex[i], cosa, sina);
+ }
+}
+
+void
+surf3d_translate (surf3d * s)
+{
+ int i;
+
+ for (i = 0; i < s->nbvertex; i++) {
+ TRANSLATE_V3D (s->center, s->svertex[i]);
+ }
+}
+
+void
+grid3d_update (grid3d * g, float angle, float *vals, float dist)
+{
+ int i;
+ float cosa;
+ float sina;
+ surf3d *s = &(g->surf);
+ v3d cam = s->center;
+
+ cam.z += dist;
+
+ SINCOS ((angle / 4.3f), sina, cosa);
+ cam.y += sina * 2.0f;
+ SINCOS (angle, sina, cosa);
+
+ if (g->mode == 0) {
+ if (vals)
+ for (i = 0; i < g->defx; i++)
+ s->vertex[i].y = s->vertex[i].y * 0.2 + vals[i] * 0.8;
+
+ for (i = g->defx; i < s->nbvertex; i++) {
+ s->vertex[i].y *= 0.255f;
+ s->vertex[i].y += (s->vertex[i - g->defx].y * 0.777f);
+ }
+ }
+
+ for (i = 0; i < s->nbvertex; i++) {
+ Y_ROTATE_V3D (s->vertex[i], s->svertex[i], cosa, sina);
+ TRANSLATE_V3D (cam, s->svertex[i]);
+ }
+}
diff --git a/gst/goom/surf3d.h b/gst/goom/surf3d.h
new file mode 100644
index 00000000..482b6a09
--- /dev/null
+++ b/gst/goom/surf3d.h
@@ -0,0 +1,38 @@
+#ifndef _SURF3D_H
+#define _SURF3D_H
+
+#include "v3d.h"
+#include "goom_graphic.h"
+#include "goom_typedefs.h"
+
+typedef struct {
+ v3d *vertex;
+ v3d *svertex;
+ int nbvertex;
+
+ v3d center;
+} surf3d;
+
+typedef struct {
+ surf3d surf;
+
+ int defx;
+ int sizex;
+ int defz;
+ int sizez;
+ int mode;
+} grid3d;
+
+/* hi-level */
+
+/* works on grid3d */
+grid3d *grid3d_new (int sizex, int defx, int sizez, int defz, v3d center);
+void grid3d_update (grid3d *s, float angle, float *vals, float dist);
+
+/* low level */
+void surf3d_draw (surf3d *s, int color, int dist, int *buf, int *back, int W,int H);
+void grid3d_draw (PluginInfo *plug, grid3d *g, int color, int colorlow, int dist, Pixel *buf, Pixel *back, int W,int H);
+void surf3d_rotate (surf3d *s, float angle);
+void surf3d_translate (surf3d *s);
+
+#endif
diff --git a/gst/goom/surf3d.s b/gst/goom/surf3d.s
new file mode 100644
index 00000000..f8c8c5d4
--- /dev/null
+++ b/gst/goom/surf3d.s
@@ -0,0 +1,484 @@
+ .file "surf3d.c"
+ .version "01.01"
+gcc2_compiled.:
+.text
+ .align 4
+.globl grid3d_new
+ .type grid3d_new,@function
+grid3d_new:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $44,%esp
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ movl 20(%ebp),%eax
+ movl 12(%ebp),%esi
+ movl %eax,-8(%ebp)
+ addl $-12,%esp
+ pushl $44
+ call malloc
+ movl %esi,%edx
+ imull -8(%ebp),%edx
+ movl %eax,%edi
+ movl %edx,-12(%ebp)
+ leal (%edx,%edx,2),%ebx
+ movl %edx,8(%edi)
+ addl $-12,%esp
+ sall $2,%ebx
+ pushl %ebx
+ call malloc
+ addl $32,%esp
+ movl %eax,(%edi)
+ addl $-12,%esp
+ pushl %ebx
+ call malloc
+ movl %eax,4(%edi)
+ movl 24(%ebp),%eax
+ movl %eax,12(%edi)
+ movl 28(%ebp),%eax
+ movl %eax,16(%edi)
+ movl 32(%ebp),%eax
+ movl %eax,20(%edi)
+ movl 8(%ebp),%eax
+ movl %eax,28(%edi)
+ movl %esi,24(%edi)
+ movl -8(%ebp),%edx
+ movl 16(%ebp),%eax
+ movl %edx,32(%edi)
+ movl %eax,36(%edi)
+ movl $0,40(%edi)
+ testl %edx,%edx
+ je .L480
+ movl %esi,%eax
+ movl %esi,-28(%ebp)
+ shrl $31,%eax
+ addl %eax,%esi
+ movl -8(%ebp),%eax
+ shrl $31,%eax
+ addl -8(%ebp),%eax
+ movl -12(%ebp),%edx
+ sarl $1,%eax
+ movl %edx,-24(%ebp)
+ negl -28(%ebp)
+ movl %esi,-16(%ebp)
+ movl %eax,-20(%ebp)
+ .p2align 4,,7
+.L481:
+ movl -28(%ebp),%eax
+ addl %eax,-24(%ebp)
+ decl -8(%ebp)
+ movl 12(%ebp),%esi
+ testl %esi,%esi
+ je .L479
+ movl -8(%ebp),%eax
+ subl -20(%ebp),%eax
+ movl %eax,-4(%ebp)
+ fildl -4(%ebp)
+ movl %esi,-4(%ebp)
+ movl -24(%ebp),%edx
+ leal (%edx,%esi),%eax
+ movl -16(%ebp),%ebx
+ fildl 16(%ebp)
+ leal (%eax,%eax,2),%eax
+ sarl $1,%ebx
+ leal 0(,%eax,4),%ecx
+ fmulp %st,%st(1)
+ fildl 20(%ebp)
+ fdivrp %st,%st(1)
+ fildl 8(%ebp)
+ fildl -4(%ebp)
+ jmp .L484
+.L487:
+ fxch %st(2)
+ .p2align 4,,7
+.L484:
+ decl %esi
+ movl %esi,%eax
+ movl (%edi),%edx
+ subl %ebx,%eax
+ movl %eax,-4(%ebp)
+ fildl -4(%ebp)
+ addl $-12,%ecx
+ fmul %st(2),%st
+ fdiv %st(1),%st
+ fstps (%edx,%ecx)
+ fxch %st(2)
+ movl (%edi),%eax
+ movl $0,4(%eax,%ecx)
+ movl (%edi),%eax
+ fsts 8(%eax,%ecx)
+ testl %esi,%esi
+ jne .L487
+ fstp %st(0)
+ fstp %st(0)
+ fstp %st(0)
+.L479:
+ cmpl $0,-8(%ebp)
+ jne .L481
+.L480:
+ leal -56(%ebp),%esp
+ popl %ebx
+ movl %edi,%eax
+ popl %esi
+ popl %edi
+ leave
+ ret
+.Lfe1:
+ .size grid3d_new,.Lfe1-grid3d_new
+.section .rodata
+ .align 8
+.LC48:
+ .long 0x0,0x3fe00000
+ .align 4
+.LC49:
+ .long 0x3f19999a
+ .align 4
+.LC50:
+ .long 0x3ee3d70a
+.text
+ .align 4
+.globl grid3d_update
+ .type grid3d_update,@function
+grid3d_update:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $32,%esp
+ pushl %esi
+ pushl %ebx
+ flds 12(%ebp)
+ movl 8(%ebp),%ebx
+ movl 16(%ebp),%ecx
+ fld %st(0)
+#APP
+ fsin
+#NO_APP
+ fstps -4(%ebp)
+ flds -4(%ebp)
+ fxch %st(1)
+#APP
+ fcos
+#NO_APP
+ fstps -4(%ebp)
+ flds -4(%ebp)
+ cmpl $0,40(%ebx)
+ jne .L519
+ testl %ecx,%ecx
+ je .L520
+ xorl %esi,%esi
+ cmpl 24(%ebx),%esi
+ jge .L520
+ fldl .LC48
+ xorl %edx,%edx
+ .p2align 4,,7
+.L524:
+ movl (%ebx),%eax
+ fld %st(0)
+ fld %st(1)
+ fxch %st(1)
+ fmuls 4(%eax,%edx)
+ fxch %st(1)
+ fmuls (%ecx,%esi,4)
+ faddp %st,%st(1)
+ incl %esi
+ fstps 4(%eax,%edx)
+ addl $12,%edx
+ cmpl 24(%ebx),%esi
+ jl .L524
+ fstp %st(0)
+.L520:
+ movl 24(%ebx),%esi
+ cmpl 8(%ebx),%esi
+ jge .L519
+ leal (%esi,%esi,2),%eax
+ flds .LC49
+ flds .LC50
+ leal 0(,%eax,4),%ecx
+ .p2align 4,,7
+.L529:
+ movl (%ebx),%eax
+ flds 4(%eax,%ecx)
+ fmul %st(2),%st
+ fstps 4(%eax,%ecx)
+ movl %esi,%eax
+ subl 24(%ebx),%eax
+ movl (%ebx),%edx
+ leal (%eax,%eax,2),%eax
+ flds 4(%edx,%eax,4)
+ fmul %st(1),%st
+ fadds 4(%edx,%ecx)
+ incl %esi
+ fstps 4(%edx,%ecx)
+ addl $12,%ecx
+ cmpl 8(%ebx),%esi
+ jl .L529
+ fstp %st(0)
+ fstp %st(0)
+.L519:
+ xorl %esi,%esi
+ cmpl 8(%ebx),%esi
+ jge .L536
+ xorl %ecx,%ecx
+ .p2align 4,,7
+.L534:
+ movl (%ebx),%eax
+ flds (%eax,%ecx)
+ flds 8(%eax,%ecx)
+ fmul %st(2),%st
+ fxch %st(1)
+ fmul %st(3),%st
+ fsubp %st,%st(1)
+ movl 4(%ebx),%edx
+ incl %esi
+ fstps (%edx,%ecx)
+ movl (%ebx),%eax
+ flds (%eax,%ecx)
+ flds 8(%eax,%ecx)
+ fxch %st(1)
+ fmul %st(2),%st
+ fxch %st(1)
+ fmul %st(3),%st
+ faddp %st,%st(1)
+ movl 4(%ebx),%edx
+ fstps 8(%edx,%ecx)
+ movl (%ebx),%eax
+ flds 4(%eax,%ecx)
+ movl 4(%ebx),%edx
+ fstps 4(%edx,%ecx)
+ movl 4(%ebx),%eax
+ flds (%eax,%ecx)
+ fadds 12(%ebx)
+ fstps (%eax,%ecx)
+ movl 4(%ebx),%eax
+ flds 4(%eax,%ecx)
+ fadds 16(%ebx)
+ fstps 4(%eax,%ecx)
+ movl 4(%ebx),%eax
+ flds 8(%eax,%ecx)
+ fadds 20(%ebx)
+ fstps 8(%eax,%ecx)
+ addl $12,%ecx
+ cmpl 8(%ebx),%esi
+ jl .L534
+.L536:
+ fstp %st(0)
+ fstp %st(0)
+ popl %ebx
+ popl %esi
+ leave
+ ret
+.Lfe2:
+ .size grid3d_update,.Lfe2-grid3d_update
+.section .rodata
+ .align 4
+.LC51:
+ .long 0x40000000
+ .align 8
+.LC52:
+ .long 0x0,0x42380000
+.text
+ .align 4
+.globl surf3d_draw
+ .type surf3d_draw,@function
+surf3d_draw:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $60,%esp
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ movl $0,-20(%ebp)
+ movl -20(%ebp),%edx
+ movl 8(%ebp),%eax
+ cmpl 8(%eax),%edx
+ jge .L493
+ fldl .LC52
+ flds .LC51
+ xorl %edi,%edi
+ .p2align 4,,7
+.L495:
+ movl 8(%ebp),%eax
+ movl 4(%eax),%eax
+ movl %eax,-36(%ebp)
+ fcoms 8(%eax,%edi)
+ fnstsw %ax
+ andb $69,%ah
+ cmpb $1,%ah
+ jne .L496
+ fildl 16(%ebp)
+ movl -36(%ebp),%edx
+ fld %st(0)
+ fmuls (%edx,%edi)
+ fdivs 8(%edx,%edi)
+ fld %st(3)
+ faddp %st,%st(1)
+ fstpl -32(%ebp)
+ movl -32(%ebp),%eax
+ movl -28(%ebp),%edx
+ movl %eax,-40(%ebp)
+ sarl $16,-40(%ebp)
+ movl -36(%ebp),%edx
+ fmuls 4(%edx,%edi)
+ fdivs 8(%edx,%edi)
+ movl -40(%ebp),%ecx
+ fld %st(2)
+ faddp %st,%st(1)
+ fstpl -32(%ebp)
+ movl -32(%ebp),%eax
+ movl -28(%ebp),%edx
+ movl %eax,-44(%ebp)
+ movl 28(%ebp),%eax
+ sarl $1,%eax
+ addl %eax,%ecx
+ movl 32(%ebp),%eax
+ sarl $16,-44(%ebp)
+ sarl $1,%eax
+ movl %ecx,%ebx
+ subl -44(%ebp),%eax
+ movl %eax,%esi
+ cmpl 28(%ebp),%ebx
+ jge .L496
+ testl %ecx,%ecx
+ jl .L496
+ cmpl 32(%ebp),%esi
+ jge .L496
+ testl %eax,%eax
+ jge .L499
+.L496:
+ xorl %esi,%esi
+ xorl %ebx,%ebx
+.L499:
+ movl 20(%ebp),%eax
+ movl %ebx,%edx
+ leal (%eax,%edx,4),%edx
+ movl 28(%ebp),%eax
+ imull %esi,%eax
+ leal (%edx,%eax,4),%eax
+ testl %ebx,%ebx
+ je .L494
+ testl %esi,%esi
+ je .L494
+#APP
+ movd (%eax), %mm0
+ paddusb 12(%ebp), %mm0
+ movd %mm0, (%eax)
+#NO_APP
+.L494:
+ incl -20(%ebp)
+ addl $12,%edi
+ movl -20(%ebp),%eax
+ movl 8(%ebp),%edx
+ cmpl 8(%edx),%eax
+ jl .L495
+ fstp %st(0)
+ fstp %st(0)
+.L493:
+ popl %ebx
+ popl %esi
+ popl %edi
+ leave
+ ret
+.Lfe3:
+ .size surf3d_draw,.Lfe3-surf3d_draw
+ .align 4
+.globl surf3d_rotate
+ .type surf3d_rotate,@function
+surf3d_rotate:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $32,%esp
+ pushl %esi
+ pushl %ebx
+ flds 12(%ebp)
+ movl 8(%ebp),%ebx
+ fld %st(0)
+#APP
+ fsin
+#NO_APP
+ fstps -4(%ebp)
+ flds -4(%ebp)
+ fxch %st(1)
+#APP
+ fcos
+#NO_APP
+ fstps -4(%ebp)
+ xorl %esi,%esi
+ flds -4(%ebp)
+ cmpl 8(%ebx),%esi
+ jge .L537
+ xorl %ecx,%ecx
+ .p2align 4,,7
+.L508:
+ movl (%ebx),%eax
+ flds (%eax,%ecx)
+ flds 8(%eax,%ecx)
+ fmul %st(2),%st
+ fxch %st(1)
+ fmul %st(3),%st
+ fsubp %st,%st(1)
+ movl 4(%ebx),%edx
+ incl %esi
+ fstps (%edx,%ecx)
+ movl (%ebx),%eax
+ flds (%eax,%ecx)
+ flds 8(%eax,%ecx)
+ fxch %st(1)
+ fmul %st(2),%st
+ fxch %st(1)
+ fmul %st(3),%st
+ faddp %st,%st(1)
+ movl 4(%ebx),%edx
+ fstps 8(%edx,%ecx)
+ movl (%ebx),%eax
+ flds 4(%eax,%ecx)
+ movl 4(%ebx),%edx
+ fstps 4(%edx,%ecx)
+ addl $12,%ecx
+ cmpl 8(%ebx),%esi
+ jl .L508
+.L537:
+ fstp %st(0)
+ fstp %st(0)
+ popl %ebx
+ popl %esi
+ leave
+ ret
+.Lfe4:
+ .size surf3d_rotate,.Lfe4-surf3d_rotate
+ .align 4
+.globl surf3d_translate
+ .type surf3d_translate,@function
+surf3d_translate:
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %ebx
+ movl 8(%ebp),%ecx
+ xorl %ebx,%ebx
+ cmpl 8(%ecx),%ebx
+ jge .L512
+ xorl %edx,%edx
+ .p2align 4,,7
+.L514:
+ movl 4(%ecx),%eax
+ flds (%eax,%edx)
+ fadds 12(%ecx)
+ incl %ebx
+ fstps (%eax,%edx)
+ movl 4(%ecx),%eax
+ flds 4(%eax,%edx)
+ fadds 16(%ecx)
+ fstps 4(%eax,%edx)
+ movl 4(%ecx),%eax
+ flds 8(%eax,%edx)
+ fadds 20(%ecx)
+ fstps 8(%eax,%edx)
+ addl $12,%edx
+ cmpl 8(%ecx),%ebx
+ jl .L514
+.L512:
+ popl %ebx
+ leave
+ ret
+.Lfe5:
+ .size surf3d_translate,.Lfe5-surf3d_translate
+ .ident "GCC: (GNU) 2.95.3 19991030 (prerelease)"
diff --git a/gst/goom/tentacle3d.c b/gst/goom/tentacle3d.c
new file mode 100644
index 00000000..44503934
--- /dev/null
+++ b/gst/goom/tentacle3d.c
@@ -0,0 +1,333 @@
+#include <stdlib.h>
+
+#include "v3d.h"
+#include "surf3d.h"
+#include "goom_tools.h"
+#include "goom_config.h"
+#include "goom_plugin_info.h"
+#include "tentacle3d.h"
+
+#define D 256.0f
+
+#define nbgrid 6
+#define definitionx 15
+#define definitionz 45
+
+typedef struct _TENTACLE_FX_DATA
+{
+ PluginParam enabled_bp;
+ PluginParameters params;
+
+ float cycle;
+ grid3d *grille[nbgrid];
+ float *vals;
+
+#define NB_TENTACLE_COLORS 4
+ int colors[NB_TENTACLE_COLORS];
+
+ int col;
+ int dstcol;
+ float lig;
+ float ligs;
+
+ /* statics from pretty_move */
+ float distt;
+ float distt2;
+ float rot; /* entre 0 et 2 * M_PI */
+ int happens;
+ int rotation;
+ int lock;
+} TentacleFXData;
+
+static void tentacle_new (TentacleFXData * data);
+static void tentacle_update (PluginInfo * goomInfo, Pixel * buf, Pixel * back,
+ int W, int H, short[2][512], float, int drawit, TentacleFXData * data);
+static void tentacle_free (TentacleFXData * data);
+
+/*
+ * VisualFX wrapper for the tentacles
+ */
+
+static void
+tentacle_fx_init (VisualFX * _this, PluginInfo * info)
+{
+
+ TentacleFXData *data = (TentacleFXData *) malloc (sizeof (TentacleFXData));
+
+ data->enabled_bp = secure_b_param ("Enabled", 1);
+ data->params = plugin_parameters ("3D Tentacles", 1);
+ data->params.params[0] = &data->enabled_bp;
+
+ data->cycle = 0.0f;
+ data->col =
+ (0x28 << (ROUGE * 8)) | (0x2c << (VERT * 8)) | (0x5f << (BLEU * 8));
+ data->dstcol = 0;
+ data->lig = 1.15f;
+ data->ligs = 0.1f;
+
+ data->distt = 10.0f;
+ data->distt2 = 0.0f;
+ data->rot = 0.0f; /* entre 0 et 2 * M_PI */
+ data->happens = 0;
+
+ data->rotation = 0;
+ data->lock = 0;
+ data->colors[0] =
+ (0x18 << (ROUGE * 8)) | (0x4c << (VERT * 8)) | (0x2f << (BLEU * 8));
+ data->colors[1] =
+ (0x48 << (ROUGE * 8)) | (0x2c << (VERT * 8)) | (0x6f << (BLEU * 8));
+ data->colors[2] =
+ (0x58 << (ROUGE * 8)) | (0x3c << (VERT * 8)) | (0x0f << (BLEU * 8));
+ data->colors[3] =
+ (0x87 << (ROUGE * 8)) | (0x55 << (VERT * 8)) | (0x74 << (BLEU * 8));
+ tentacle_new (data);
+
+ _this->params = &data->params;
+ _this->fx_data = (void *) data;
+}
+
+static void
+tentacle_fx_apply (VisualFX * _this, Pixel * src, Pixel * dest,
+ PluginInfo * goomInfo)
+{
+ TentacleFXData *data = (TentacleFXData *) _this->fx_data;
+
+ if (BVAL (data->enabled_bp)) {
+ tentacle_update (goomInfo, dest, src, goomInfo->screen.width,
+ goomInfo->screen.height, goomInfo->sound.samples,
+ (float) goomInfo->sound.accelvar,
+ goomInfo->curGState->drawTentacle, data);
+ }
+}
+
+static void
+tentacle_fx_free (VisualFX * _this)
+{
+ tentacle_free ((TentacleFXData *) _this->fx_data);
+ free (_this->fx_data);
+}
+
+VisualFX
+tentacle_fx_create (void)
+{
+ VisualFX fx;
+
+ fx.init = tentacle_fx_init;
+ fx.apply = tentacle_fx_apply;
+ fx.free = tentacle_fx_free;
+ return fx;
+}
+
+/* ----- */
+
+static void
+tentacle_free (TentacleFXData * data)
+{
+ /* TODO : un vrai FREE GRID!! */
+ free (data->vals);
+}
+
+static void
+tentacle_new (TentacleFXData * data)
+{
+ int tmp;
+
+ v3d center = { 0, -17.0, 0 };
+ data->vals = (float *) malloc ((definitionx + 20) * sizeof (float));
+
+ for (tmp = 0; tmp < nbgrid; tmp++) {
+ int x, z;
+
+ z = 45 + rand () % 30;
+ x = 85 + rand () % 5;
+ center.z = z;
+ data->grille[tmp] =
+ grid3d_new (x, definitionx, z, definitionz + rand () % 10, center);
+ center.y += 8;
+ }
+}
+
+static inline unsigned char
+lighten (unsigned char value, float power)
+{
+ int val = value;
+ float t = (float) val * log10 (power) / 2.0;
+
+ if (t > 0) {
+ val = (int) t; /* (32.0f * log (t)); */
+ if (val > 255)
+ val = 255;
+ if (val < 0)
+ val = 0;
+ return val;
+ } else {
+ return 0;
+ }
+}
+
+static void
+lightencolor (int *col, float power)
+{
+ unsigned char *color;
+
+ color = (unsigned char *) col;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+}
+
+/* retourne x>>s , en testant le signe de x */
+#define ShiftRight(_x,_s) ((_x<0) ? -(-_x>>_s) : (_x>>_s))
+
+static int
+evolutecolor (unsigned int src, unsigned int dest,
+ unsigned int mask, unsigned int incr)
+{
+
+ int color = src & (~mask);
+
+ src &= mask;
+ dest &= mask;
+
+ if ((src != mask)
+ && (src < dest))
+ src += incr;
+
+ if (src > dest)
+ src -= incr;
+ return (src & mask) | color;
+}
+
+static void
+pretty_move (PluginInfo * goomInfo, float cycle, float *dist, float *dist2,
+ float *rotangle, TentacleFXData * fx_data)
+{
+
+ float tmp;
+
+ /* many magic numbers here... I don't really like that. */
+ if (fx_data->happens)
+ fx_data->happens -= 1;
+ else if (fx_data->lock == 0) {
+ fx_data->happens =
+ goom_irand (goomInfo->gRandom,
+ 200) ? 0 : 100 + goom_irand (goomInfo->gRandom, 60);
+ fx_data->lock = fx_data->happens * 3 / 2;
+ } else
+ fx_data->lock--;
+
+ tmp = fx_data->happens ? 8.0f : 0;
+ *dist2 = fx_data->distt2 = (tmp + 15.0f * fx_data->distt2) / 16.0f;
+
+ tmp = 30 + D - 90.0f * (1.0f + sin (cycle * 19 / 20));
+ if (fx_data->happens)
+ tmp *= 0.6f;
+
+ *dist = fx_data->distt = (tmp + 3.0f * fx_data->distt) / 4.0f;
+
+ if (!fx_data->happens) {
+ tmp = M_PI * sin (cycle) / 32 + 3 * M_PI / 2;
+ } else {
+ fx_data->rotation =
+ goom_irand (goomInfo->gRandom,
+ 500) ? fx_data->rotation : goom_irand (goomInfo->gRandom, 2);
+ if (fx_data->rotation)
+ cycle *= 2.0f * M_PI;
+ else
+ cycle *= -1.0f * M_PI;
+ tmp = cycle - (M_PI * 2.0) * floor (cycle / (M_PI * 2.0));
+ }
+
+ if (abs (tmp - fx_data->rot) > abs (tmp - (fx_data->rot + 2.0 * M_PI))) {
+ fx_data->rot = (tmp + 15.0f * (fx_data->rot + 2 * M_PI)) / 16.0f;
+ if (fx_data->rot > 2.0 * M_PI)
+ fx_data->rot -= 2.0 * M_PI;
+ *rotangle = fx_data->rot;
+ } else if (abs (tmp - fx_data->rot) > abs (tmp - (fx_data->rot - 2.0 * M_PI))) {
+ fx_data->rot = (tmp + 15.0f * (fx_data->rot - 2.0 * M_PI)) / 16.0f;
+ if (fx_data->rot < 0.0f)
+ fx_data->rot += 2.0 * M_PI;
+ *rotangle = fx_data->rot;
+ } else
+ *rotangle = fx_data->rot = (tmp + 15.0f * fx_data->rot) / 16.0f;
+}
+
+static void
+tentacle_update (PluginInfo * goomInfo, Pixel * buf, Pixel * back, int W, int H,
+ short data[2][512], float rapport, int drawit, TentacleFXData * fx_data)
+{
+
+ int tmp;
+ int tmp2;
+
+ int color;
+ int colorlow;
+
+ float dist, dist2, rotangle;
+
+ if ((!drawit) && (fx_data->ligs > 0.0f))
+ fx_data->ligs = -fx_data->ligs;
+
+ fx_data->lig += fx_data->ligs;
+
+ if (fx_data->lig > 1.01f) {
+ if ((fx_data->lig > 10.0f) | (fx_data->lig < 1.1f))
+ fx_data->ligs = -fx_data->ligs;
+
+ if ((fx_data->lig < 6.3f) && (goom_irand (goomInfo->gRandom, 30) == 0))
+ fx_data->dstcol = goom_irand (goomInfo->gRandom, NB_TENTACLE_COLORS);
+
+ fx_data->col =
+ evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff,
+ 0x01);
+ fx_data->col =
+ evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff00,
+ 0x0100);
+ fx_data->col =
+ evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff0000,
+ 0x010000);
+ fx_data->col =
+ evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol],
+ 0xff000000, 0x01000000);
+
+ color = fx_data->col;
+ colorlow = fx_data->col;
+
+ lightencolor (&color, fx_data->lig * 2.0f + 2.0f);
+ lightencolor (&colorlow, (fx_data->lig / 3.0f) + 0.67f);
+
+ rapport = 1.0f + 2.0f * (rapport - 1.0f);
+ rapport *= 1.2f;
+ if (rapport > 1.12f)
+ rapport = 1.12f;
+
+ pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
+
+ for (tmp = 0; tmp < nbgrid; tmp++) {
+ for (tmp2 = 0; tmp2 < definitionx; tmp2++) {
+ float val =
+ (float) (ShiftRight (data[0][goom_irand (goomInfo->gRandom, 511)],
+ 10)) * rapport;
+ fx_data->vals[tmp2] = val;
+ }
+
+ grid3d_update (fx_data->grille[tmp], rotangle, fx_data->vals, dist2);
+ }
+ fx_data->cycle += 0.01f;
+ for (tmp = 0; tmp < nbgrid; tmp++)
+ grid3d_draw (goomInfo, fx_data->grille[tmp], color, colorlow, dist, buf,
+ back, W, H);
+ } else {
+ fx_data->lig = 1.05f;
+ if (fx_data->ligs < 0.0f)
+ fx_data->ligs = -fx_data->ligs;
+ pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
+ fx_data->cycle += 0.1f;
+ if (fx_data->cycle > 1000)
+ fx_data->cycle = 0;
+ }
+}
diff --git a/gst/goom/tentacle3d.h b/gst/goom/tentacle3d.h
new file mode 100644
index 00000000..ad0858fa
--- /dev/null
+++ b/gst/goom/tentacle3d.h
@@ -0,0 +1,8 @@
+#ifndef _TENTACLE3D_H
+#define _TENTACLE3D_H
+
+#include "goom_visual_fx.h"
+
+VisualFX tentacle_fx_create(void);
+
+#endif
diff --git a/gst/goom/v3d.c b/gst/goom/v3d.c
new file mode 100644
index 00000000..54e3c97d
--- /dev/null
+++ b/gst/goom/v3d.c
@@ -0,0 +1,20 @@
+#include "v3d.h"
+
+void
+v3d_to_v2d (v3d * v3, int nbvertex, int width, int height, float distance,
+ v2d * v2)
+{
+ int i;
+
+ for (i = 0; i < nbvertex; ++i) {
+ if (v3[i].z > 2) {
+ int Xp, Yp;
+
+ F2I ((distance * v3[i].x / v3[i].z), Xp);
+ F2I ((distance * v3[i].y / v3[i].z), Yp);
+ v2[i].x = Xp + (width >> 1);
+ v2[i].y = -Yp + (height >> 1);
+ } else
+ v2[i].x = v2[i].y = -666;
+ }
+}
diff --git a/gst/goom/v3d.h b/gst/goom/v3d.h
new file mode 100644
index 00000000..7690847f
--- /dev/null
+++ b/gst/goom/v3d.h
@@ -0,0 +1,65 @@
+#ifndef _V3D_H
+#define _V3D_H
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mathtools.h"
+
+typedef struct {
+ float x,y,z;
+} v3d;
+
+typedef struct {
+ int x,y;
+} v2d;
+
+typedef struct {
+ double x,y;
+} v2g;
+
+/*
+ * projete le vertex 3D sur le plan d'affichage
+ * retourne (0,0) si le point ne doit pas etre affiche.
+ *
+ * bonne valeur pour distance : 256
+ */
+#define V3D_TO_V2D(v3,v2,width,height,distance) \
+{ \
+ int Xp, Yp; \
+ if (v3.z > 2) { \
+ F2I((distance * v3.x / v3.z),Xp) ; \
+ F2I((distance * v3.y / v3.z),Yp) ; \
+ v2.x = Xp + (width>>1); \
+ v2.y = -Yp + (height>>1); \
+ } \
+ else v2.x=v2.y=-666; \
+}
+
+void v3d_to_v2d(v3d *src, int nbvertex, int width, int height, float distance, v2d *v2_array);
+
+/*
+ * rotation selon Y du v3d vi d'angle a (cosa=cos(a), sina=sin(a))
+ * centerz = centre de rotation en z
+ */
+#define Y_ROTATE_V3D(vi,vf,sina,cosa)\
+{\
+ vf.x = vi.x * cosa - vi.z * sina;\
+ vf.z = vi.x * sina + vi.z * cosa;\
+ vf.y = vi.y;\
+}
+
+/*
+ * translation
+ */
+#define TRANSLATE_V3D(vsrc,vdest)\
+{\
+ vdest.x += vsrc.x;\
+ vdest.y += vsrc.y;\
+ vdest.z += vsrc.z;\
+}
+
+#define MUL_V3D(lf,v) {v.x*=lf;v.y*=lf;v.z*=lf;}
+
+#endif
diff --git a/gst/goom/xmmx.c b/gst/goom/xmmx.c
new file mode 100644
index 00000000..40f27fbc
--- /dev/null
+++ b/gst/goom/xmmx.c
@@ -0,0 +1,364 @@
+
+#ifdef HAVE_MMX
+
+/* a definir pour avoir exactement le meme resultat que la fonction C
+ * (un chouillat plus lent).. mais la difference est assez peu notable.
+ */
+// #define STRICT_COMPAT
+
+#define BUFFPOINTNB 16
+#define BUFFPOINTMASK 0xffff
+#define BUFFINCR 0xff
+
+#define sqrtperte 16
+/* faire : a % sqrtperte <=> a & pertemask*/
+#define PERTEMASK 0xf
+/* faire : a / sqrtperte <=> a >> PERTEDEC*/
+#define PERTEDEC 4
+
+
+/*#define MMX_TRACE*/
+#include "mmx.h"
+/*#include "xmmx.h"*/
+#include "goom_graphic.h"
+
+int
+xmmx_supported (void)
+{
+ return (mm_support () & 0x8) >> 3;
+}
+
+void
+zoom_filter_xmmx (int prevX, int prevY,
+ Pixel * expix1, Pixel * expix2,
+ int *lbruS, int *lbruD, int buffratio, int precalCoef[16][16])
+{
+ int bufsize = prevX * prevY; /* taille du buffer */
+ volatile int loop; /* variable de boucle */
+
+ mmx_t *brutS = (mmx_t *) lbruS; /* buffer de transformation source */
+ mmx_t *brutD = (mmx_t *) lbruD; /* buffer de transformation dest */
+
+ volatile mmx_t prevXY;
+ volatile mmx_t ratiox;
+
+ /* volatile mmx_t interpix; */
+
+ expix1[0].val = expix1[prevX - 1].val = expix1[prevX * prevY - 1].val =
+ expix1[prevX * prevY - prevX].val = 0;
+
+ prevXY.ud[0] = (prevX - 1) << PERTEDEC;
+ prevXY.ud[1] = (prevY - 1) << PERTEDEC;
+
+ ratiox.d[0] = buffratio;
+ ratiox.d[1] = buffratio;
+
+ asm volatile ("\n\t movq %[ratio], %%mm6" "\n\t pslld $16, %%mm6" /* mm6 = [rat16=buffratio<<16 | rat16=buffratio<<16] */
+ "\n\t pxor %%mm7, %%mm7" /* mm7 = 0 */
+ ::[ratio] "m" (ratiox));
+
+ loop = 0;
+
+ /*
+ * NOTE : mm6 et mm7 ne sont pas modifies dans la boucle.
+ */
+ while (loop < bufsize) {
+ /* Thread #1
+ * pre : mm6 = [rat16|rat16]
+ * post : mm0 = S + ((D-S)*rat16 format [X|Y]
+ * modified = mm0,mm1,mm2
+ */
+
+ asm volatile ("#1 \n\t movq %[brutS], %%mm0" "#1 \n\t movq %[brutD], %%mm1" "#1 \n\t psubd %%mm0, %%mm1" /* mm1 = D - S */
+ "#1 \n\t movq %%mm1, %%mm2" /* mm2 = D - S */
+ "#1 \n\t pslld $16, %%mm1" "#1 \n\t pmullw %%mm6, %%mm2" "#1 \n\t pmulhuw %%mm6, %%mm1" "#1 \n\t pslld $16, %%mm0" "#1 \n\t paddd %%mm2, %%mm1" /* mm1 = (D - S) * buffratio >> 16 */
+ "#1 \n\t paddd %%mm1, %%mm0" /* mm0 = S + mm1 */
+ "#1 \n\t psrld $16, %%mm0"::[brutS] "g" (brutS[loop])
+ ,[brutD] "g" (brutD[loop])
+ ); /* mm0 = S */
+
+ /*
+ * pre : mm0 : position vector on screen
+ * prevXY : coordinate of the lower-right point on screen
+ * post : clipped mm0
+ * modified : mm0,mm1,mm2
+ */
+ asm volatile
+ ("#1 \n\t movq %[prevXY], %%mm1" "#1 \n\t pcmpgtd %%mm0, %%mm1"
+ /* mm0 en X contient (idem pour Y) :
+ * 1111 si prevXY > px
+ * 0000 si prevXY <= px */
+#ifdef STRICT_COMPAT
+ "#1 \n\t movq %%mm1, %%mm2"
+ "#1 \n\t punpckhdq %%mm2, %%mm2"
+ "#1 \n\t punpckldq %%mm1, %%mm1" "#1 \n\t pand %%mm2, %%mm0"
+#endif
+ "#1 \n\t pand %%mm1, %%mm0" /* on met a zero la partie qui deborde */
+ ::[prevXY] "m" (prevXY));
+
+ /* Thread #2
+ * pre : mm0 : clipped position on screen
+ *
+ * post : mm3 : coefs for this position
+ * mm1 : X vector [0|X]
+ *
+ * modif : eax,esi
+ */
+ __asm__ __volatile__ ("#2 \n\t movd %%mm0,%%esi"
+ "#2 \n\t movq %%mm0,%%mm1"
+ "#2 \n\t andl $15,%%esi"
+ "#2 \n\t psrlq $32,%%mm1"
+ "#2 \n\t shll $6,%%esi"
+ "#2 \n\t movd %%mm1,%%eax"
+ "#2 \n\t addl %[precalCoef],%%esi"
+ "#2 \n\t andl $15,%%eax"
+ "#2 \n\t movd (%%esi,%%eax,4),%%mm3"::[precalCoef]
+ "g" (precalCoef):"eax", "esi");
+
+ /*
+ * extraction des coefficients... (Thread #3)
+ *
+ * pre : coef dans mm3
+ *
+ * post : coef extraits dans mm3 (c1 & c2)
+ * et mm4 (c3 & c4)
+ *
+ * modif : mm5
+ */
+
+ /* (Thread #4)
+ * pre : mm0 : Y pos [*|Y]
+ * mm1 : X pos [*|X]
+ *
+ * post : mm0 : expix1[position]
+ * mm2 : expix1[position+largeur]
+ *
+ * modif : eax, esi
+ */
+ __asm__ __volatile__ ("#2 \n\t psrld $4, %%mm0" "#2 \n\t psrld $4, %%mm1" /* PERTEDEC = $4 */
+ "#4 \n\t movd %%mm1,%%eax"
+ "#3 \n\t movq %%mm3,%%mm5"
+ "#4 \n\t mull %[prevX]"
+ "#4 \n\t movd %%mm0,%%esi"
+ "#3 \n\t punpcklbw %%mm5, %%mm3"
+ "#4 \n\t addl %%esi, %%eax"
+ "#3 \n\t movq %%mm3, %%mm4"
+ "#3 \n\t movq %%mm3, %%mm5"
+ "#4 \n\t movl %[expix1], %%esi"
+ "#3 \n\t punpcklbw %%mm5, %%mm3"
+ "#4 \n\t movq (%%esi,%%eax,4),%%mm0"
+ "#3 \n\t punpckhbw %%mm5, %%mm4"
+ "#4 \n\t addl %[prevX],%%eax"
+ "#4 \n\t movq (%%esi,%%eax,4),%%mm2"::[expix1] "g" (expix1)
+ ,[prevX] "g" (prevX)
+ :"eax", "esi");
+
+ /*
+ * pre : mm0 : expix1[position]
+ * mm2 : expix1[position+largeur]
+ * mm3 & mm4 : coefs
+ */
+
+ /* recopie des deux premiers pixels dans mm0 et mm1 */
+ movq_r2r (mm0, mm1); /* b1-v1-r1-a1-b2-v2-r2-a2 */
+
+ /* depackage du premier pixel */
+ punpcklbw_r2r (mm7, mm0); /* 00-b2-00-v2-00-r2-00-a2 */
+
+ /* extraction des coefficients... */
+
+ movq_r2r (mm3, mm5); /* c2-c2-c2-c2-c1-c1-c1-c1 */
+
+ /*^en parrallele^ *//* depackage du 2ieme pixel */
+ /*^ */ punpckhbw_r2r (mm7, mm1);
+ /* 00-b1-00-v1-00-r1-00-a1 */
+
+ punpcklbw_r2r (mm7, mm5); /* 00-c1-00-c1-00-c1-00-c1 */
+ punpckhbw_r2r (mm7, mm3); /* 00-c2-00-c2-00-c2-00-c2 */
+
+ /* multiplication des pixels par les coefficients */
+ pmullw_r2r (mm5, mm0); /* c1*b2-c1*v2-c1*r2-c1*a2 */
+ pmullw_r2r (mm3, mm1); /* c2*b1-c2*v1-c2*r1-c2*a1 */
+ paddw_r2r (mm1, mm0);
+
+ /* ...extraction des 2 derniers coefficients */
+ movq_r2r (mm4, mm5); /* c4-c4-c4-c4-c3-c3-c3-c3 */
+ punpcklbw_r2r (mm7, mm4); /* 00-c3-00-c3-00-c3-00-c3 */
+ punpckhbw_r2r (mm7, mm5); /* 00-c4-00-c4-00-c4-00-c4 */
+
+ /* recuperation des 2 derniers pixels */
+ movq_r2r (mm2, mm1);
+
+ /* depackage des pixels */
+ punpcklbw_r2r (mm7, mm1);
+ punpckhbw_r2r (mm7, mm2);
+
+ /* multiplication pas les coeffs */
+ pmullw_r2r (mm4, mm1);
+ pmullw_r2r (mm5, mm2);
+
+ /* ajout des valeurs obtenues à la valeur finale */
+ paddw_r2r (mm1, mm0);
+ paddw_r2r (mm2, mm0);
+
+ /* division par 256 = 16+16+16+16, puis repackage du pixel final */
+ psrlw_i2r (8, mm0);
+ packuswb_r2r (mm7, mm0);
+
+ movd_r2m (mm0, expix2[loop]);
+
+ ++loop;
+ }
+ __asm__ __volatile__ ("femms\n");
+}
+
+#define DRAWMETHOD_PLUS_XMMX(_out,_backbuf,_col) \
+{ \
+ movd_m2r(_backbuf, mm0); \
+ paddusb_m2r(_col, mm0); \
+ movd_r2m(mm0, _out); \
+}
+
+#define DRAWMETHOD DRAWMETHOD_PLUS_XMMX(*p,*p,col)
+
+void
+draw_line_xmmx (Pixel * data, int x1, int y1, int x2, int y2, int col,
+ int screenx, int screeny)
+{
+ int x, y, dx, dy, yy, xx;
+ Pixel *p;
+
+ if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny)
+ || (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx))
+ goto end_of_line;
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ if (x1 >= x2) {
+ int tmp;
+
+ tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ dx = x2 - x1;
+ dy = y2 - y1;
+ }
+
+ /* vertical line */
+ if (dx == 0) {
+ if (y1 < y2) {
+ p = &(data[(screenx * y1) + x1]);
+ for (y = y1; y <= y2; y++) {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ } else {
+ p = &(data[(screenx * y2) + x1]);
+ for (y = y2; y <= y1; y++) {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ }
+ goto end_of_line;
+ }
+ /* horizontal line */
+ if (dy == 0) {
+ if (x1 < x2) {
+ p = &(data[(screenx * y1) + x1]);
+ for (x = x1; x <= x2; x++) {
+ DRAWMETHOD;
+ p++;
+ }
+ goto end_of_line;
+ } else {
+ p = &(data[(screenx * y1) + x2]);
+ for (x = x2; x <= x1; x++) {
+ DRAWMETHOD;
+ p++;
+ }
+ goto end_of_line;
+ }
+ }
+ /* 1 */
+ /* \ */
+ /* \ */
+ /* 2 */
+ if (y2 > y1) {
+ /* steep */
+ if (dy > dx) {
+ dx = ((dx << 16) / dy);
+ x = x1 << 16;
+ for (y = y1; y <= y2; y++) {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1)) {
+ p++;
+ /* DRAWMETHOD; */
+ }
+ x += dx;
+ }
+ goto end_of_line;
+ }
+ /* shallow */
+ else {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++) {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1)) {
+ p += screeny;
+ /* DRAWMETHOD; */
+ }
+ y += dy;
+ }
+ }
+ }
+ /* 2 */
+ /* / */
+ /* / */
+ /* 1 */
+ else {
+ /* steep */
+ if (-dy > dx) {
+ dx = ((dx << 16) / -dy);
+ x = (x1 + 1) << 16;
+ for (y = y1; y >= y2; y--) {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1)) {
+ p--;
+ /* DRAWMETHOD; */
+ }
+ x += dx;
+ }
+ goto end_of_line;
+ }
+ /* shallow */
+ else {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++) {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1)) {
+ p += screeny;
+ /* DRAWMETHOD; */
+ }
+ y += dy;
+ }
+ goto end_of_line;
+ }
+ }
+end_of_line:
+ __asm__ __volatile__ ("femms\n");
+}
+
+#endif
diff --git a/gst/goom/xmmx.h b/gst/goom/xmmx.h
new file mode 100644
index 00000000..70ef3614
--- /dev/null
+++ b/gst/goom/xmmx.h
@@ -0,0 +1,537 @@
+/* xmmx.h
+
+ eXtended MultiMedia eXtensions GCC interface library for IA32.
+
+ To use this library, simply include this header file
+ and compile with GCC. You MUST have inlining enabled
+ in order for xmmx_ok() to work; this can be done by
+ simply using -O on the GCC command line.
+
+ Compiling with -DXMMX_TRACE will cause detailed trace
+ output to be sent to stderr for each mmx operation.
+ This adds lots of code, and obviously slows execution to
+ a crawl, but can be very useful for debugging.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR ANY PARTICULAR PURPOSE.
+
+ 1999 by R. Fisher
+ Based on libmmx, 1997-99 by H. Dietz and R. Fisher
+
+ Notes:
+ It appears that the latest gas has the pand problem fixed, therefore
+ I'll undefine BROKEN_PAND by default.
+*/
+
+#ifndef _XMMX_H
+#define _XMMX_H
+
+
+/* Warning: at this writing, the version of GAS packaged
+ with most Linux distributions does not handle the
+ parallel AND operation mnemonic correctly. If the
+ symbol BROKEN_PAND is defined, a slower alternative
+ coding will be used. If execution of mmxtest results
+ in an illegal instruction fault, define this symbol.
+*/
+#undef BROKEN_PAND
+
+
+/* The type of an value that fits in an (Extended) MMX register
+ (note that long long constant values MUST be suffixed
+ by LL and unsigned long long values by ULL, lest
+ they be truncated by the compiler)
+*/
+#ifndef _MMX_H
+typedef union {
+ long long q; /* Quadword (64-bit) value */
+ unsigned long long uq; /* Unsigned Quadword */
+ int d[2]; /* 2 Doubleword (32-bit) values */
+ unsigned int ud[2]; /* 2 Unsigned Doubleword */
+ short w[4]; /* 4 Word (16-bit) values */
+ unsigned short uw[4]; /* 4 Unsigned Word */
+ char b[8]; /* 8 Byte (8-bit) values */
+ unsigned char ub[8]; /* 8 Unsigned Byte */
+ float s[2]; /* Single-precision (32-bit) value */
+} __attribute__ ((aligned (8))) mmx_t; /* On an 8-byte (64-bit) boundary */
+#endif
+
+
+
+/* Function to test if multimedia instructions are supported...
+*/
+static int
+mm_support(void)
+{
+ /* Returns 1 if MMX instructions are supported,
+ 3 if Cyrix MMX and Extended MMX instructions are supported
+ 5 if AMD MMX and 3DNow! instructions are supported
+ 0 if hardware does not support any of these
+ */
+ register int rval = 0;
+
+ __asm__ __volatile__ (
+ /* See if CPUID instruction is supported ... */
+ /* ... Get copies of EFLAGS into eax and ecx */
+ "pushf\n\t"
+ "popl %%eax\n\t"
+ "movl %%eax, %%ecx\n\t"
+
+ /* ... Toggle the ID bit in one copy and store */
+ /* to the EFLAGS reg */
+ "xorl $0x200000, %%eax\n\t"
+ "push %%eax\n\t"
+ "popf\n\t"
+
+ /* ... Get the (hopefully modified) EFLAGS */
+ "pushf\n\t"
+ "popl %%eax\n\t"
+
+ /* ... Compare and test result */
+ "xorl %%eax, %%ecx\n\t"
+ "testl $0x200000, %%ecx\n\t"
+ "jz NotSupported1\n\t" /* CPUID not supported */
+
+
+ /* Get standard CPUID information, and
+ go to a specific vendor section */
+ "movl $0, %%eax\n\t"
+ "cpuid\n\t"
+
+ /* Check for Intel */
+ "cmpl $0x756e6547, %%ebx\n\t"
+ "jne TryAMD\n\t"
+ "cmpl $0x49656e69, %%edx\n\t"
+ "jne TryAMD\n\t"
+ "cmpl $0x6c65746e, %%ecx\n"
+ "jne TryAMD\n\t"
+ "jmp Intel\n\t"
+
+ /* Check for AMD */
+ "\nTryAMD:\n\t"
+ "cmpl $0x68747541, %%ebx\n\t"
+ "jne TryCyrix\n\t"
+ "cmpl $0x69746e65, %%edx\n\t"
+ "jne TryCyrix\n\t"
+ "cmpl $0x444d4163, %%ecx\n"
+ "jne TryCyrix\n\t"
+ "jmp AMD\n\t"
+
+ /* Check for Cyrix */
+ "\nTryCyrix:\n\t"
+ "cmpl $0x69727943, %%ebx\n\t"
+ "jne NotSupported2\n\t"
+ "cmpl $0x736e4978, %%edx\n\t"
+ "jne NotSupported3\n\t"
+ "cmpl $0x64616574, %%ecx\n\t"
+ "jne NotSupported4\n\t"
+ /* Drop through to Cyrix... */
+
+
+ /* Cyrix Section */
+ /* See if extended CPUID level 80000001 is supported */
+ /* The value of CPUID/80000001 for the 6x86MX is undefined
+ according to the Cyrix CPU Detection Guide (Preliminary
+ Rev. 1.01 table 1), so we'll check the value of eax for
+ CPUID/0 to see if standard CPUID level 2 is supported.
+ According to the table, the only CPU which supports level
+ 2 is also the only one which supports extended CPUID levels.
+ */
+ "cmpl $0x2, %%eax\n\t"
+ "jne MMXtest\n\t" /* Use standard CPUID instead */
+
+ /* Extended CPUID supported (in theory), so get extended
+ features */
+ "movl $0x80000001, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%eax\n\t" /* Test for MMX */
+ "jz NotSupported5\n\t" /* MMX not supported */
+ "testl $0x01000000, %%eax\n\t" /* Test for Ext'd MMX */
+ "jnz EMMXSupported\n\t"
+ "movl $1, %0:\n\n\t" /* MMX Supported */
+ "jmp Return\n\n"
+ "EMMXSupported:\n\t"
+ "movl $3, %0:\n\n\t" /* EMMX and MMX Supported */
+ "jmp Return\n\t"
+
+
+ /* AMD Section */
+ "AMD:\n\t"
+
+ /* See if extended CPUID is supported */
+ "movl $0x80000000, %%eax\n\t"
+ "cpuid\n\t"
+ "cmpl $0x80000000, %%eax\n\t"
+ "jl MMXtest\n\t" /* Use standard CPUID instead */
+
+ /* Extended CPUID supported, so get extended features */
+ "movl $0x80000001, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%edx\n\t" /* Test for MMX */
+ "jz NotSupported6\n\t" /* MMX not supported */
+ "testl $0x80000000, %%edx\n\t" /* Test for 3DNow! */
+ "jnz ThreeDNowSupported\n\t"
+ "movl $1, %0:\n\n\t" /* MMX Supported */
+ "jmp Return\n\n"
+ "ThreeDNowSupported:\n\t"
+ "movl $5, %0:\n\n\t" /* 3DNow! and MMX Supported */
+ "jmp Return\n\t"
+
+
+ /* Intel Section */
+ "Intel:\n\t"
+
+ /* Check for MMX */
+ "MMXtest:\n\t"
+ "movl $1, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%edx\n\t" /* Test for MMX */
+ "jz NotSupported7\n\t" /* MMX Not supported */
+ "movl $1, %0:\n\n\t" /* MMX Supported */
+ "jmp Return\n\t"
+
+ /* Nothing supported */
+ "\nNotSupported1:\n\t"
+ "#movl $101, %0:\n\n\t"
+ "\nNotSupported2:\n\t"
+ "#movl $102, %0:\n\n\t"
+ "\nNotSupported3:\n\t"
+ "#movl $103, %0:\n\n\t"
+ "\nNotSupported4:\n\t"
+ "#movl $104, %0:\n\n\t"
+ "\nNotSupported5:\n\t"
+ "#movl $105, %0:\n\n\t"
+ "\nNotSupported6:\n\t"
+ "#movl $106, %0:\n\n\t"
+ "\nNotSupported7:\n\t"
+ "#movl $107, %0:\n\n\t"
+ "movl $0, %0:\n\n\t"
+
+ "Return:\n\t"
+ : "=a" (rval)
+ : /* no input */
+ : "eax", "ebx", "ecx", "edx"
+ );
+
+ /* Return */
+ return(rval);
+}
+
+/* Function to test if mmx instructions are supported...
+*/
+#ifndef _XMMX_H
+inline extern int
+mmx_ok(void)
+{
+ /* Returns 1 if MMX instructions are supported, 0 otherwise */
+ return ( mm_support() & 0x1 );
+}
+#endif
+
+/* Function to test if xmmx instructions are supported...
+*/
+inline extern int
+xmmx_ok(void)
+{
+ /* Returns 1 if Extended MMX instructions are supported, 0 otherwise */
+ return ( (mm_support() & 0x2) >> 1 );
+}
+
+
+/* Helper functions for the instruction macros that follow...
+ (note that memory-to-register, m2r, instructions are nearly
+ as efficient as register-to-register, r2r, instructions;
+ however, memory-to-memory instructions are really simulated
+ as a convenience, and are only 1/3 as efficient)
+*/
+#ifdef XMMX_TRACE
+
+/* Include the stuff for printing a trace to stderr...
+*/
+
+#include <stdio.h>
+
+#define mmx_i2r(op, imm, reg) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace.uq = (imm); \
+ fprintf(stderr, #op "_i2r(" #imm "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #reg "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm)); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #reg "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_m2r(op, mem, reg) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (mem); \
+ fprintf(stderr, #op "_m2r(" #mem "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #reg "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem)); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #reg "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_r2m(op, reg, mem) \
+ { \
+ mmx_t mmx_trace; \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #op "_r2m(" #reg "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ mmx_trace = (mem); \
+ fprintf(stderr, #mem "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ ); \
+ mmx_trace = (mem); \
+ fprintf(stderr, #mem "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_r2r(op, regs, regd) \
+ { \
+ mmx_t mmx_trace; \
+ __asm__ __volatile__ ("movq %%" #regs ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #op "_r2r(" #regs "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #regd ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #regd "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd); \
+ __asm__ __volatile__ ("movq %%" #regd ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #regd "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_m2m(op, mems, memd) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (mems); \
+ fprintf(stderr, #op "_m2m(" #mems "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ mmx_trace = (memd); \
+ fprintf(stderr, #memd "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \
+ #op " %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=X" (memd) \
+ : "X" (mems)); \
+ mmx_trace = (memd); \
+ fprintf(stderr, #memd "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#else
+
+/* These macros are a lot simpler without the tracing...
+*/
+
+#define mmx_i2r(op, imm, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_m2r(op, mem, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define mmx_m2ir(op, mem, rs) \
+ __asm__ __volatile__ (#op " %0, %%" #rs \
+ : /* nothing */ \
+ : "X" (mem) )
+
+#define mmx_r2m(op, reg, mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ )
+
+#define mmx_r2r(op, regs, regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+#define mmx_r2ir(op, rs1, rs2) \
+ __asm__ __volatile__ (#op " %%" #rs1 ", %%" #rs2 \
+ : /* nothing */ \
+ : /* nothing */ )
+
+#define mmx_m2m(op, mems, memd) \
+ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \
+ #op " %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=X" (memd) \
+ : "X" (mems))
+
+#endif
+
+
+
+/* 1x64 MOVe Quadword
+ (this is both a load and a store...
+ in fact, it is the only way to store)
+*/
+#define movq_m2r(var, reg) mmx_m2r(movq, var, reg)
+#define movq_r2m(reg, var) mmx_r2m(movq, reg, var)
+#define movq_r2r(regs, regd) mmx_r2r(movq, regs, regd)
+#define movq(vars, vard) \
+ __asm__ __volatile__ ("movq %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=X" (vard) \
+ : "X" (vars))
+
+
+/* 1x32 MOVe Doubleword
+ (like movq, this is both load and store...
+ but is most useful for moving things between
+ mmx registers and ordinary registers)
+*/
+#define movd_m2r(var, reg) mmx_m2r(movd, var, reg)
+#define movd_r2m(reg, var) mmx_r2m(movd, reg, var)
+#define movd_r2r(regs, regd) mmx_r2r(movd, regs, regd)
+#define movd(vars, vard) \
+ __asm__ __volatile__ ("movd %1, %%mm0\n\t" \
+ "movd %%mm0, %0" \
+ : "=X" (vard) \
+ : "X" (vars))
+
+
+
+/* 4x16 Parallel MAGnitude
+*/
+#define pmagw_m2r(var, reg) mmx_m2r(pmagw, var, reg)
+#define pmagw_r2r(regs, regd) mmx_r2r(pmagw, regs, regd)
+#define pmagw(vars, vard) mmx_m2m(pmagw, vars, vard)
+
+
+/* 4x16 Parallel ADDs using Saturation arithmetic
+ and Implied destination
+*/
+#define paddsiw_m2ir(var, rs) mmx_m2ir(paddsiw, var, rs)
+#define paddsiw_r2ir(rs1, rs2) mmx_r2ir(paddsiw, rs1, rs2)
+#define paddsiw(vars, vard) mmx_m2m(paddsiw, vars, vard)
+
+
+/* 4x16 Parallel SUBs using Saturation arithmetic
+ and Implied destination
+*/
+#define psubsiw_m2ir(var, rs) mmx_m2ir(psubsiw, var, rs)
+#define psubsiw_r2ir(rs1, rs2) mmx_r2ir(psubsiw, rs1, rs2)
+#define psubsiw(vars, vard) mmx_m2m(psubsiw, vars, vard)
+
+
+/* 4x16 Parallel MULs giving High 4x16 portions of results
+ Rounded with 1/2 bit 15.
+*/
+#define pmulhrw_m2r(var, reg) mmx_m2r(pmulhrw, var, reg)
+#define pmulhrw_r2r(regs, regd) mmx_r2r(pmulhrw, regs, regd)
+#define pmulhrw(vars, vard) mmx_m2m(pmulhrw, vars, vard)
+
+
+/* 4x16 Parallel MULs giving High 4x16 portions of results
+ Rounded with 1/2 bit 15, storing to Implied register
+*/
+#define pmulhriw_m2ir(var, rs) mmx_m2ir(pmulhriw, var, rs)
+#define pmulhriw_r2ir(rs1, rs2) mmx_r2ir(pmulhriw, rs1, rs2)
+#define pmulhriw(vars, vard) mmx_m2m(pmulhriw, vars, vard)
+
+
+/* 4x16 Parallel Muls (and ACcumulate) giving High 4x16 portions
+ of results Rounded with 1/2 bit 15, accumulating with Implied register
+*/
+#define pmachriw_m2ir(var, rs) mmx_m2ir(pmachriw, var, rs)
+#define pmachriw_r2ir(rs1, rs2) mmx_r2ir(pmachriw, rs1, rs2)
+#define pmachriw(vars, vard) mmx_m2m(pmachriw, vars, vard)
+
+
+/* 8x8u Parallel AVErage
+*/
+#define paveb_m2r(var, reg) mmx_m2r(paveb, var, reg)
+#define paveb_r2r(regs, regd) mmx_r2r(paveb, regs, regd)
+#define paveb(vars, vard) mmx_m2m(paveb, vars, vard)
+
+
+/* 8x8u Parallel DISTance and accumulate with
+ unsigned saturation to Implied register
+*/
+#define pdistib_m2ir(var, rs) mmx_m2ir(pdistib, var, rs)
+#define pdistib(vars, vard) mmx_m2m(pdistib, vars, vard)
+
+
+/* 8x8 Parallel conditional MoVe
+ if implied register field is Zero
+*/
+#define pmvzb_m2ir(var, rs) mmx_m2ir(pmvzb, var, rs)
+
+
+/* 8x8 Parallel conditional MoVe
+ if implied register field is Not Zero
+*/
+#define pmvnzb_m2ir(var, rs) mmx_m2ir(pmvnzb, var, rs)
+
+
+/* 8x8 Parallel conditional MoVe
+ if implied register field is Less than Zero
+*/
+#define pmvlzb_m2ir(var, rs) mmx_m2ir(pmvlzb, var, rs)
+
+
+/* 8x8 Parallel conditional MoVe
+ if implied register field is Greater than or Equal to Zero
+*/
+#define pmvgezb_m2ir(var, rs) mmx_m2ir(pmvgezb, var, rs)
+
+
+/* Fast Empty MMx State
+ (used to clean-up when going from mmx to float use
+ of the registers that are shared by both; note that
+ there is no float-to-xmmx operation needed, because
+ only the float tag word info is corruptible)
+*/
+#ifdef XMMX_TRACE
+
+#define femms() \
+ { \
+ fprintf(stderr, "femms()\n"); \
+ __asm__ __volatile__ ("femms"); \
+ }
+
+#else
+
+#define femms() __asm__ __volatile__ ("femms")
+
+#endif
+
+#endif
+