mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-03 15:06:34 +00:00
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
This commit is contained in:
parent
7f0745bb7f
commit
a7bc7485b1
82 changed files with 20125 additions and 998 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
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
|
||||
|
||||
2008-02-22 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||
|
||||
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_setup_streams):
|
||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
|||
Subproject commit 135628f16d422584d3454fb9c9805e7be25760a1
|
||||
Subproject commit bd6ec57040fe3fa93e21ca440dfe494e3ee18555
|
|
@ -94,6 +94,7 @@ GST_PLUGINS_ALL="\
|
|||
icydemux \
|
||||
flx \
|
||||
goom \
|
||||
goom2k1 \
|
||||
law \
|
||||
level \
|
||||
matroska \
|
||||
|
@ -329,6 +330,11 @@ AG_GST_SET_LEVEL_DEFAULT($GST_CVS)
|
|||
dnl used in examples
|
||||
AG_GST_DEFAULT_ELEMENTS
|
||||
|
||||
dnl Check for Yacc and Lex for the goom plugin
|
||||
AG_GST_BISON_CHECK
|
||||
AG_GST_FLEX_CHECK
|
||||
AM_PROG_AS
|
||||
|
||||
dnl *** sys plug-ins ***
|
||||
|
||||
echo
|
||||
|
@ -1019,6 +1025,7 @@ gst/equalizer/Makefile
|
|||
gst/id3demux/Makefile
|
||||
gst/icydemux/Makefile
|
||||
gst/goom/Makefile
|
||||
gst/goom2k1/Makefile
|
||||
gst/law/Makefile
|
||||
gst/level/Makefile
|
||||
gst/matroska/Makefile
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
141
gst/goom/config_param.c
Normal file
141
gst/goom/config_param.c
Normal file
|
@ -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);
|
||||
}
|
342
gst/goom/convolve_fx.c
Normal file
342
gst/goom/convolve_fx.c
Normal file
|
@ -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;
|
||||
}
|
6
gst/goom/default_scripts.h
Normal file
6
gst/goom/default_scripts.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef _DEFAULT_SCRIPTS_H
|
||||
#define _DEFAULT_SCRIPTS_H
|
||||
|
||||
#define GOOM_MAIN_SCRIPT ""
|
||||
|
||||
#endif
|
204
gst/goom/drawmethods.c
Normal file
204
gst/goom/drawmethods.c
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
9
gst/goom/drawmethods.h
Normal file
9
gst/goom/drawmethods.h
Normal file
|
@ -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 */
|
1320
gst/goom/filters.c
1320
gst/goom/filters.c
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
||||
movl prevX,%eax
|
||||
decl %eax
|
||||
sarl $4,%eax
|
||||
movl %eax,-4(%ebp)
|
||||
|
||||
movl prevY,%eax
|
||||
decl %eax
|
||||
sarl $4,%eax
|
||||
movl %eax,-8(%ebp)
|
||||
|
||||
;// initialisation du mm7 à zero
|
||||
movq (thezero), %mm7
|
||||
movq (thezero), %mm7
|
||||
|
||||
movl zoom_width, %eax
|
||||
movl $4, %ebx
|
||||
mull %ebx
|
||||
movl %eax, %ebp
|
||||
|
||||
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
|
||||
|
||||
;// enregistrement du resultat
|
||||
movl expix2,%eax
|
||||
/* movd %mm0,(%eax,%ecx,4)*/
|
||||
|
||||
decl %ecx
|
||||
;// enregistrement du resultat
|
||||
movd %mm0, (%ebx)
|
||||
leal 4(%ebx), %ebx
|
||||
|
||||
;// 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
|
||||
|
|
341
gst/goom/flying_stars_fx.c
Normal file
341
gst/goom/flying_stars_fx.c
Normal file
|
@ -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;
|
||||
}
|
260
gst/goom/gfontlib.c
Normal file
260
gst/goom/gfontlib.c
Normal file
|
@ -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++;
|
||||
}
|
||||
}
|
10
gst/goom/gfontlib.h
Normal file
10
gst/goom/gfontlib.h
Normal file
|
@ -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
|
3080
gst/goom/gfontrle.c
Normal file
3080
gst/goom/gfontrle.c
Normal file
File diff suppressed because it is too large
Load diff
7
gst/goom/gfontrle.h
Normal file
7
gst/goom/gfontrle.h
Normal file
|
@ -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 ;
|
30
gst/goom/goom.h
Normal file
30
gst/goom/goom.h
Normal file
|
@ -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
|
28
gst/goom/goom_config.h
Normal file
28
gst/goom/goom_config.h
Normal file
|
@ -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
|
115
gst/goom/goom_config_param.h
Normal file
115
gst/goom/goom_config_param.h
Normal file
|
@ -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
|
1101
gst/goom/goom_core.c
1101
gst/goom/goom_core.c
File diff suppressed because it is too large
Load diff
52
gst/goom/goom_filters.h
Normal file
52
gst/goom/goom_filters.h
Normal file
|
@ -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
|
12
gst/goom/goom_fx.h
Normal file
12
gst/goom/goom_fx.h
Normal file
|
@ -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
|
74
gst/goom/goom_graphic.h
Normal file
74
gst/goom/goom_graphic.h
Normal file
|
@ -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 */
|
176
gst/goom/goom_plugin_info.h
Normal file
176
gst/goom/goom_plugin_info.h
Normal file
|
@ -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
|
32
gst/goom/goom_tools.c
Normal file
32
gst/goom/goom_tools.c
Normal file
|
@ -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--;
|
||||
}
|
||||
}
|
|
@ -1,24 +1,33 @@
|
|||
#ifndef _GOOMTOOLS_H
|
||||
#define _GOOMTOOLS_H
|
||||
|
||||
#define NB_RAND 0x10000
|
||||
/**
|
||||
* Random number generator wrapper for faster random number.
|
||||
*/
|
||||
|
||||
#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 GOOM_NB_RAND 0x10000
|
||||
|
||||
#define RAND(gd) \
|
||||
(gd->rand_tab[gd->rand_pos = ((gd->rand_pos + 1) % NB_RAND)])
|
||||
typedef struct _GOOM_RANDOM {
|
||||
int array[GOOM_NB_RAND];
|
||||
unsigned short pos;
|
||||
} GoomRandom;
|
||||
|
||||
#define RAND_CLOSE(gd) \
|
||||
g_free (gd->rand_tab); \
|
||||
gd->rand_tab = NULL;
|
||||
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);
|
||||
|
||||
/*#define iRAND(i) ((guint32)((float)i * RAND()/RAND_MAX)) */
|
||||
#define iRAND(gd,i) (RAND(gd) % i)
|
||||
|
||||
#endif
|
||||
|
|
11
gst/goom/goom_typedefs.h
Normal file
11
gst/goom/goom_typedefs.h
Normal file
|
@ -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
|
26
gst/goom/goom_visual_fx.h
Normal file
26
gst/goom/goom_visual_fx.h
Normal file
|
@ -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
|
1660
gst/goom/goomsl.c
Normal file
1660
gst/goom/goomsl.c
Normal file
File diff suppressed because it is too large
Load diff
34
gst/goom/goomsl.h
Normal file
34
gst/goom/goomsl.h
Normal file
|
@ -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
|
153
gst/goom/goomsl_hash.c
Normal file
153
gst/goom/goomsl_hash.c
Normal file
|
@ -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;
|
||||
}
|
40
gst/goom/goomsl_hash.h
Normal file
40
gst/goom/goomsl_hash.h
Normal file
|
@ -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 */
|
126
gst/goom/goomsl_heap.c
Normal file
126
gst/goom/goomsl_heap.c
Normal file
|
@ -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);
|
||||
}
|
29
gst/goom/goomsl_heap.h
Normal file
29
gst/goom/goomsl_heap.h
Normal file
|
@ -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
|
||||
|
94
gst/goom/goomsl_lex.l
Normal file
94
gst/goom/goomsl_lex.l
Normal file
|
@ -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); }
|
||||
|
251
gst/goom/goomsl_private.h
Normal file
251
gst/goom/goomsl_private.h
Normal file
|
@ -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
|
1405
gst/goom/goomsl_yacc.y
Normal file
1405
gst/goom/goomsl_yacc.y
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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 };
|
||||
|
|
|
@ -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=%"
|
||||
|
|
|
@ -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;
|
||||
|
|
776
gst/goom/ifs.c
Normal file
776
gst/goom/ifs.c
Normal file
|
@ -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;
|
||||
}
|
27
gst/goom/ifs.h
Normal file
27
gst/goom/ifs.h
Normal file
|
@ -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
|
314
gst/goom/lines.c
314
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;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lightencolor (guint32 * 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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++) {
|
||||
l[i].x = ((float) i * rx) / 512.0f;
|
||||
l[i].y = param;
|
||||
l[i].angle = M_PI / 2.0f;
|
||||
}
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
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 (GoomData * goomdata, gint16 data[2][512], unsigned int ID,
|
||||
unsigned int *p, guint32 power)
|
||||
goom_lines_set_res (GMLine * gml, int rx, int ry)
|
||||
{
|
||||
guint32 color1;
|
||||
guint32 color2;
|
||||
guint32 resolx = goomdata->resolx;
|
||||
guint32 resoly = goomdata->resoly;
|
||||
unsigned char *color = 1 + (unsigned char *) &color1;
|
||||
if (gml != NULL) {
|
||||
gml->screenX = rx;
|
||||
gml->screenY = ry;
|
||||
|
||||
switch (ID) {
|
||||
case 0: /* Horizontal stereo lines */
|
||||
{
|
||||
color1 = 0x0000AA00;
|
||||
color2 = 0x00AA0000;
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: /* Stereo circles */
|
||||
{
|
||||
color1 = 0x00AA33DD;
|
||||
color2 = 0x00AA33DD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*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;
|
||||
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
void goom_lines(GoomData *goomdata, gint16 data [2][512], unsigned int ID,unsigned int* p, guint32 power);
|
||||
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_free (GMLine ** gml);
|
||||
|
||||
void goom_lines_draw (PluginInfo *plugInfo, GMLine * gml, gint16 data[512], Pixel *p);
|
||||
|
||||
#endif /* _LINES_H */
|
||||
|
|
95
gst/goom/mathtools.c
Normal file
95
gst/goom/mathtools.c
Normal file
|
@ -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
|
||||
};
|
36
gst/goom/mathtools.h
Normal file
36
gst/goom/mathtools.h
Normal file
|
@ -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
|
||||
|
256
gst/goom/mmx.c
Normal file
256
gst/goom/mmx.c
Normal file
|
@ -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 */
|
729
gst/goom/mmx.h
Normal file
729
gst/goom/mmx.h
Normal file
|
@ -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
|
||||
|
1026
gst/goom/motif_goom1.h
Normal file
1026
gst/goom/motif_goom1.h
Normal file
File diff suppressed because it is too large
Load diff
1026
gst/goom/motif_goom2.h
Normal file
1026
gst/goom/motif_goom2.h
Normal file
File diff suppressed because it is too large
Load diff
222
gst/goom/plugin_info.c
Normal file
222
gst/goom/plugin_info.c
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
18
gst/goom/ppc_drawings.h
Normal file
18
gst/goom/ppc_drawings.h
Normal file
|
@ -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);
|
||||
|
381
gst/goom/ppc_drawings.s
Normal file
381
gst/goom/ppc_drawings.s
Normal file
|
@ -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
|
||||
|
14
gst/goom/ppc_zoom_ultimate.h
Normal file
14
gst/goom/ppc_zoom_ultimate.h
Normal file
|
@ -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]);
|
323
gst/goom/ppc_zoom_ultimate.s
Normal file
323
gst/goom/ppc_zoom_ultimate.s
Normal file
|
@ -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
|
143
gst/goom/sound_tester.c
Normal file
143
gst/goom/sound_tester.c
Normal file
|
@ -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 ? */
|
||||
}
|
11
gst/goom/sound_tester.h
Normal file
11
gst/goom/sound_tester.h
Normal file
|
@ -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
|
||||
|
123
gst/goom/surf3d.c
Normal file
123
gst/goom/surf3d.c
Normal file
|
@ -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]);
|
||||
}
|
||||
}
|
38
gst/goom/surf3d.h
Normal file
38
gst/goom/surf3d.h
Normal file
|
@ -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
|
484
gst/goom/surf3d.s
Normal file
484
gst/goom/surf3d.s
Normal file
|
@ -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)"
|
333
gst/goom/tentacle3d.c
Normal file
333
gst/goom/tentacle3d.c
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
8
gst/goom/tentacle3d.h
Normal file
8
gst/goom/tentacle3d.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef _TENTACLE3D_H
|
||||
#define _TENTACLE3D_H
|
||||
|
||||
#include "goom_visual_fx.h"
|
||||
|
||||
VisualFX tentacle_fx_create(void);
|
||||
|
||||
#endif
|
20
gst/goom/v3d.c
Normal file
20
gst/goom/v3d.c
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
65
gst/goom/v3d.h
Normal file
65
gst/goom/v3d.h
Normal file
|
@ -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
|
364
gst/goom/xmmx.c
Normal file
364
gst/goom/xmmx.c
Normal file
|
@ -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
|
537
gst/goom/xmmx.h
Normal file
537
gst/goom/xmmx.h
Normal file
|
@ -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
|
||||
|
14
gst/goom2k1/Makefile.am
Normal file
14
gst/goom2k1/Makefile.am
Normal file
|
@ -0,0 +1,14 @@
|
|||
plugin_LTLIBRARIES = libgstgoom.la
|
||||
|
||||
GOOM_FILTER_FILES = filters.c
|
||||
GOOM_FILTER_CFLAGS = -UMMX -UUSE_ASM
|
||||
|
||||
noinst_HEADERS = gstgoom.h filters.h goom_core.h goom_tools.h graphic.h lines.h
|
||||
|
||||
libgstgoom_la_SOURCES = gstgoom.c goom_core.c $(GOOM_FILTER_FILES) graphic.c lines.c
|
||||
|
||||
libgstgoom_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GOOM_FILTER_CFLAGS)
|
||||
libgstgoom_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM)
|
||||
libgstgoom_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
|
||||
EXTRA_DIST = filters.c
|
5
gst/goom2k1/README
Normal file
5
gst/goom2k1/README
Normal file
|
@ -0,0 +1,5 @@
|
|||
The Goom plugin is based on the Goom visualization code from
|
||||
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
|
606
gst/goom2k1/filters.c
Normal file
606
gst/goom2k1/filters.c
Normal file
|
@ -0,0 +1,606 @@
|
|||
/* 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]
|
||||
*/
|
||||
|
||||
/*#define _DEBUG_PIXEL; */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "filters.h"
|
||||
#include "graphic.h"
|
||||
#include "goom_tools.h"
|
||||
#include "goom_core.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef MMX
|
||||
#define USE_ASM
|
||||
#endif
|
||||
#ifdef POWERPC
|
||||
#define USE_ASM
|
||||
#endif
|
||||
|
||||
#ifdef USE_ASM
|
||||
#define EFFECT_DISTORS 4
|
||||
#else
|
||||
#define EFFECT_DISTORS 10
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_ASM
|
||||
|
||||
#ifdef MMX
|
||||
int mmx_zoom ();
|
||||
guint32 mmx_zoom_size;
|
||||
#endif /* MMX */
|
||||
|
||||
#ifdef POWERPC
|
||||
extern unsigned int useAltivec;
|
||||
extern void ppc_zoom (void);
|
||||
extern void ppc_zoom_altivec (void);
|
||||
unsigned int ppcsize4;
|
||||
#endif /* PowerPC */
|
||||
|
||||
|
||||
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 */
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* retourne x>>s , en testant le signe de x */
|
||||
static inline int
|
||||
ShiftRight (int x, const unsigned char s)
|
||||
{
|
||||
if (x < 0)
|
||||
return -(-x >> s);
|
||||
else
|
||||
return x >> s;
|
||||
}
|
||||
|
||||
/*
|
||||
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)
|
||||
{
|
||||
ZoomFilterData *zf = gd->zfd;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*#define _DEBUG */
|
||||
|
||||
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
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
setPixelRGB_ (Uint * buffer, Uint x, Color c, guint32 resolx, guint32 resoly)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (x >= resolx * resoly) {
|
||||
printf ("setPixel ERROR : hors du tableau... %i >= %i*%i (%i)\n", x, resolx,
|
||||
resoly, resolx * resoly);
|
||||
exit (1);
|
||||
}
|
||||
#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
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline void
|
||||
getPixelRGB (Uint * buffer, Uint x, Uint y, Color * c,
|
||||
guint32 resolx, guint32 resoly)
|
||||
{
|
||||
register unsigned char *tmp8;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (x + y * resolx >= resolx * resoly) {
|
||||
printf ("getPixel ERROR : hors du tableau... %i, %i\n", x, y);
|
||||
exit (1);
|
||||
}
|
||||
#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
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
getPixelRGB_ (Uint * buffer, Uint x, Color * c, guint32 resolx, guint32 resoly)
|
||||
{
|
||||
register unsigned char *tmp8;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (x >= resolx * resoly) {
|
||||
printf ("getPixel ERROR : hors du tableau... %i\n", x);
|
||||
exit (1);
|
||||
}
|
||||
#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
|
||||
}
|
||||
|
||||
static void
|
||||
zoomFilterSetResolution (GoomData * gd, ZoomFilterData * zf)
|
||||
{
|
||||
unsigned short us;
|
||||
|
||||
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;
|
||||
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
zoomFilterDestroy (ZoomFilterData * zf)
|
||||
{
|
||||
if (zf) {
|
||||
if (zf->firedec)
|
||||
free (zf->firedec);
|
||||
if (zf->buffer)
|
||||
free (zf->buffer);
|
||||
free (zf);
|
||||
}
|
||||
}
|
||||
|
||||
/*===============================================================*/
|
||||
void
|
||||
zoomFilterFastRGB (GoomData * goomdata, ZoomFilterData * zf, int zfd_update)
|
||||
{
|
||||
guint32 prevX = goomdata->resolx;
|
||||
guint32 prevY = goomdata->resoly;
|
||||
|
||||
guint32 *pix1 = goomdata->p1;
|
||||
guint32 *pix2 = goomdata->p2;
|
||||
unsigned int *pos10;
|
||||
unsigned int **c;
|
||||
|
||||
Uint x, y;
|
||||
|
||||
/* static unsigned int prevX = 0, prevY = 0; */
|
||||
|
||||
#ifdef USE_ASM
|
||||
expix1 = pix1;
|
||||
expix2 = pix2;
|
||||
#else
|
||||
Color couleur;
|
||||
Color col1, col2, col3, col4;
|
||||
Uint position;
|
||||
#endif
|
||||
|
||||
if ((goomdata->resolx != zf->res_x) || (goomdata->resoly != zf->res_y)) {
|
||||
zoomFilterSetResolution (goomdata, zf);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
#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 ();
|
||||
}
|
||||
#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);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pointFilter (GoomData * goomdata, 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);
|
||||
}
|
||||
}
|
130
gst/goom2k1/filters_mmx.s
Normal file
130
gst/goom2k1/filters_mmx.s
Normal file
|
@ -0,0 +1,130 @@
|
|||
;// file : mmx_zoom.s
|
||||
;// author : JC Hoelt <jeko@free.fr>
|
||||
;//
|
||||
;// history
|
||||
;// 07/01/2001 : Changing FEMMS to EMMS : slower... but run on intel machines
|
||||
;// 03/01/2001 : WIDTH and HEIGHT are now variable
|
||||
;// 28/12/2000 : adding comments to the code, suppress some useless lines
|
||||
;// 27/12/2000 : reducing memory access... improving performance by 20%
|
||||
;// coefficients are now on 1 byte
|
||||
;// 22/12/2000 : Changing data structure
|
||||
;// 16/12/2000 : AT&T version
|
||||
;// 14/12/2000 : unrolling loop
|
||||
;// 12/12/2000 : 64 bits memory access
|
||||
|
||||
|
||||
.data
|
||||
|
||||
thezero:
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
|
||||
|
||||
.text
|
||||
|
||||
.globl mmx_zoom ;// name of the function to call by C program
|
||||
.extern coeffs ;// the transformation buffer
|
||||
.extern expix1,expix2 ;// the source and destination buffer
|
||||
.extern mmx_zoom_size, zoom_width ;// size of the buffers
|
||||
|
||||
.align 16
|
||||
mmx_zoom:
|
||||
|
||||
push %ebp
|
||||
push %esp
|
||||
|
||||
;// initialisation du mm7 à zero
|
||||
movq (thezero), %mm7
|
||||
|
||||
movl zoom_width, %eax
|
||||
movl $4, %ebx
|
||||
mull %ebx
|
||||
movl %eax, %ebp
|
||||
|
||||
movl (coeffs), %eax
|
||||
movl (expix1), %edx
|
||||
movl (expix2), %ebx
|
||||
movl $10, %edi
|
||||
movl mmx_zoom_size, %ecx
|
||||
|
||||
.while:
|
||||
;// esi <- nouvelle position
|
||||
movl (%eax), %esi
|
||||
leal (%edx, %esi), %esi
|
||||
|
||||
;// 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 */
|
||||
|
||||
;// 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 */
|
||||
|
||||
movq %mm6, %mm5 /* ??-??-??-??-c4-c3-c2-c1 */
|
||||
;// depackage du 2ieme pixel
|
||||
punpckhbw %mm7, %mm1 /* 00-b1-00-v1-00-r1-00-a1 */
|
||||
|
||||
;// extraction des coefficients...
|
||||
punpcklbw %mm5, %mm6 /* c4-c4-c3-c3-c2-c2-c1-c1 */
|
||||
movq %mm6, %mm4 /* c4-c4-c3-c3-c2-c2-c1-c1 */
|
||||
movq %mm6, %mm5 /* c4-c4-c3-c3-c2-c2-c1-c1 */
|
||||
|
||||
punpcklbw %mm5, %mm6 /* c2-c2-c2-c2-c1-c1-c1-c1 */
|
||||
punpckhbw %mm5, %mm4 /* c4-c4-c4-c4-c3-c3-c3-c3 */
|
||||
|
||||
movq %mm6, %mm3 /* c2-c2-c2-c2-c1-c1-c1-c1 */
|
||||
punpcklbw %mm7, %mm6 /* 00-c1-00-c1-00-c1-00-c1 */
|
||||
punpckhbw %mm7, %mm3 /* 00-c2-00-c2-00-c2-00-c2 */
|
||||
|
||||
;// multiplication des pixels par les coefficients
|
||||
pmullw %mm6, %mm0 /* c1*b2-c1*v2-c1*r2-c1*a2 */
|
||||
pmullw %mm3, %mm1 /* c2*b1-c2*v1-c2*r1-c2*a1 */
|
||||
paddw %mm1, %mm0
|
||||
|
||||
;// ...extraction des 2 derniers coefficients
|
||||
movq %mm4, %mm5 /* c4-c4-c4-c4-c3-c3-c3-c3 */
|
||||
punpcklbw %mm7, %mm4 /* 00-c3-00-c3-00-c3-00-c3 */
|
||||
punpckhbw %mm7, %mm5 /* 00-c4-00-c4-00-c4-00-c4 */
|
||||
|
||||
;// recuperation des 2 derniers pixels
|
||||
movq (%esi,%ebp), %mm1
|
||||
movq %mm1, %mm2
|
||||
|
||||
;// depackage des pixels
|
||||
punpcklbw %mm7, %mm1
|
||||
punpckhbw %mm7, %mm2
|
||||
|
||||
;// multiplication pas les coeffs
|
||||
pmullw %mm4, %mm1
|
||||
pmullw %mm5, %mm2
|
||||
|
||||
;// ajout des valeurs obtenues à la valeur finale
|
||||
paddw %mm1, %mm0
|
||||
paddw %mm2, %mm0
|
||||
|
||||
;// division par 256 = 16+16+16+16, puis repackage du pixel final
|
||||
psrlw $8, %mm0
|
||||
packuswb %mm7, %mm0
|
||||
|
||||
;// passage au suivant
|
||||
leal 8(%eax), %eax
|
||||
|
||||
decl %ecx
|
||||
;// enregistrement du resultat
|
||||
movd %mm0, (%ebx)
|
||||
leal 4(%ebx), %ebx
|
||||
|
||||
;// test de fin du tantque
|
||||
cmpl $0, %ecx ;// 400x300
|
||||
|
||||
jz .fin_while
|
||||
jmp .while
|
||||
|
||||
.fin_while:
|
||||
emms
|
||||
|
||||
pop %esp
|
||||
pop %ebp
|
||||
|
||||
ret ;//The End
|
172
gst/goom2k1/goom.vcproj
Normal file
172
gst/goom2k1/goom.vcproj
Normal file
|
@ -0,0 +1,172 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="goom"
|
||||
ProjectGUID="{979C216F-0ACF-4956-AE00-055A42D678B4}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../win32/Debug"
|
||||
IntermediateDirectory="../../win32/Debug"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../gstreamer/win32;../../../gstreamer;../../../gstreamer/libs;../../../glib;../../../glib/glib;../../../glib/gmodule;"../../gst-libs";../../../popt/include;../../../libxml2/include/libxml2"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;goom_EXPORTS;HAVE_CONFIG_H;_USE_MATH_DEFINES"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="glib-2.0.lib gmodule-2.0.lib gthread-2.0.lib gobject-2.0.lib libgstreamer.lib gstbytestream.lib iconv.lib intl.lib"
|
||||
OutputFile="$(OutDir)/gstgoom2k1.dll"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../../gstreamer/win32/Debug;../../../glib/glib;../../../glib/gmodule;../../../glib/gthread;../../../glib/gobject;../../../gettext/lib;../../../libiconv/lib"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/goom.pdb"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
ImportLibrary="$(OutDir)/gstgoom2k1.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="copy /Y $(TargetPath) c:\gstreamer\plugins"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../win32/Release"
|
||||
IntermediateDirectory="../../win32/Release"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../gstreamer/win32;../../../gstreamer;../../../gstreamer/libs;../../../glib;../../../glib/glib;../../../glib/gmodule;"../../gst-libs";../../../popt/include;../../../libxml2/include/libxml2"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;GST_DISABLE_GST_DEBUG;_WINDOWS;_USRDLL;goom_EXPORTS;HAVE_CONFIG_H;_USE_MATH_DEFINES"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="glib-2.0.lib gmodule-2.0.lib gthread-2.0.lib gobject-2.0.lib libgstreamer.lib gstbytestream.lib iconv.lib intl.lib"
|
||||
OutputFile="$(OutDir)/gstgoom2k1.dll"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../gstreamer/win32/Release;../../../glib/glib;../../../glib/gmodule;../../../glib/gthread;../../../glib/gobject;../../../gettext/lib;../../../libiconv/lib"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
ImportLibrary="$(OutDir)/gstgoom2k1.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="copy /Y $(TargetPath) c:\gstreamer\plugins"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\gstgoom2k1.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\goom_core.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\graphic.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lines.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\filters.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath=".\filters.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\goom_core.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\goom_tools.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\graphic.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lines.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
412
gst/goom2k1/goom_core.c
Normal file
412
gst/goom2k1/goom_core.c
Normal file
|
@ -0,0 +1,412 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <glib.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "goom_core.h"
|
||||
#include "goom_tools.h"
|
||||
#include "filters.h"
|
||||
#include "lines.h"
|
||||
|
||||
/*#define VERBOSE */
|
||||
|
||||
#ifdef VERBOSE
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define STOP_SPEED 128
|
||||
|
||||
void
|
||||
goom_init (GoomData * goomdata, guint32 resx, guint32 resy)
|
||||
{
|
||||
#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 */
|
||||
}
|
||||
|
||||
void
|
||||
goom_set_resolution (GoomData * goomdata, 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));
|
||||
}
|
||||
|
||||
goomdata->resolx = resx;
|
||||
goomdata->resoly = resy;
|
||||
|
||||
memset (goomdata->pixel, 0, buffsize * sizeof (guint32) + 128);
|
||||
memset (goomdata->back, 0, buffsize * sizeof (guint32) + 128);
|
||||
}
|
||||
|
||||
guint32 *
|
||||
goom_update (GoomData * goomdata, gint16 data[2][512])
|
||||
{
|
||||
guint32 *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;
|
||||
|
||||
/* test if the config has changed, update it if so */
|
||||
|
||||
pointWidth = (resolx * 2) / 5;
|
||||
pointHeight = (resoly * 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;
|
||||
|
||||
|
||||
/* ! calcul du deplacement des petits points ... */
|
||||
|
||||
largfactor =
|
||||
((float) goomdata->speedvar / 40.0f + (float) incvar / 50000.0f) / 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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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 */
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* tout ceci ne sera fait qu'en cas de non-blocage */
|
||||
if (goomdata->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) */
|
||||
{
|
||||
guint32 vtmp;
|
||||
guint32 newvit;
|
||||
|
||||
newvit = STOP_SPEED - goomdata->speedvar / 2;
|
||||
/* 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 (iRAND (goomdata, 10) == 0) {
|
||||
pzfd->reverse = 1;
|
||||
goomdata->lockvar = 100;
|
||||
}
|
||||
|
||||
/* changement de milieu.. */
|
||||
switch (iRAND (goomdata, 20)) {
|
||||
case 0:
|
||||
pzfd->middleY = resoly - 1;
|
||||
pzfd->middleX = resolx / 2;
|
||||
break;
|
||||
case 1:
|
||||
pzfd->middleX = resolx - 1;
|
||||
break;
|
||||
case 2:
|
||||
pzfd->middleX = 1;
|
||||
break;
|
||||
default:
|
||||
pzfd->middleY = resoly / 2;
|
||||
pzfd->middleX = resolx / 2;
|
||||
}
|
||||
|
||||
if (pzfd->mode == WATER_MODE) {
|
||||
pzfd->middleX = resolx / 2;
|
||||
pzfd->middleY = resoly / 2;
|
||||
}
|
||||
|
||||
switch (vtmp = (iRAND (goomdata, 27))) {
|
||||
case 0:
|
||||
pzfd->vPlaneEffect = iRAND (goomdata, 3);
|
||||
pzfd->vPlaneEffect -= iRAND (goomdata, 3);
|
||||
pzfd->hPlaneEffect = iRAND (goomdata, 3);
|
||||
pzfd->hPlaneEffect -= iRAND (goomdata, 3);
|
||||
break;
|
||||
case 3:
|
||||
pzfd->vPlaneEffect = 0;
|
||||
pzfd->hPlaneEffect = iRAND (goomdata, 8);
|
||||
pzfd->hPlaneEffect -= iRAND (goomdata, 8);
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
pzfd->vPlaneEffect = iRAND (goomdata, 5);
|
||||
pzfd->vPlaneEffect -= iRAND (goomdata, 5);
|
||||
pzfd->hPlaneEffect = -pzfd->vPlaneEffect;
|
||||
break;
|
||||
case 8:
|
||||
pzfd->hPlaneEffect = 5 + iRAND (goomdata, 8);
|
||||
pzfd->vPlaneEffect = -pzfd->hPlaneEffect;
|
||||
break;
|
||||
case 9:
|
||||
pzfd->vPlaneEffect = 5 + iRAND (goomdata, 8);
|
||||
pzfd->hPlaneEffect = -pzfd->hPlaneEffect;
|
||||
break;
|
||||
case 13:
|
||||
pzfd->hPlaneEffect = 0;
|
||||
pzfd->vPlaneEffect = iRAND (goomdata, 10);
|
||||
pzfd->vPlaneEffect -= iRAND (goomdata, 10);
|
||||
break;
|
||||
default:
|
||||
if (vtmp < 10) {
|
||||
pzfd->vPlaneEffect = 0;
|
||||
pzfd->hPlaneEffect = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (iRAND (goomdata, 3) != 0)
|
||||
pzfd->noisify = 0;
|
||||
else {
|
||||
pzfd->noisify = iRAND (goomdata, 3) + 2;
|
||||
goomdata->lockvar *= 3;
|
||||
}
|
||||
|
||||
if (pzfd->mode == AMULETTE_MODE) {
|
||||
pzfd->vPlaneEffect = 0;
|
||||
pzfd->hPlaneEffect = 0;
|
||||
pzfd->noisify = 0;
|
||||
}
|
||||
|
||||
if ((pzfd->middleX == 1) || (pzfd->middleX == resolx - 1)) {
|
||||
pzfd->vPlaneEffect = 0;
|
||||
pzfd->hPlaneEffect = iRAND (goomdata, 2) ? 0 : pzfd->hPlaneEffect;
|
||||
}
|
||||
|
||||
if (newvit < pzfd->vitesse) { /* on accelere */
|
||||
zfd_update = 1;
|
||||
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;
|
||||
} else {
|
||||
pzfd->vitesse = (newvit + pzfd->vitesse * 4) / 5;
|
||||
}
|
||||
goomdata->lockvar += 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* mode mega-lent */
|
||||
if (iRAND (goomdata, 1000) == 0) {
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
/*
|
||||
printf ("--slow part... %i\n", zfd.vitesse) ;
|
||||
*/
|
||||
}
|
||||
|
||||
/* baisser regulierement la vitesse... */
|
||||
if ((goomdata->cycle % 73 == 0) && (pzfd->vitesse < STOP_SPEED - 5)) {
|
||||
/*
|
||||
printf ("slow down...\n") ;
|
||||
*/
|
||||
zfd_update = 1;
|
||||
pzfd->vitesse++;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Zoom here ! */
|
||||
zoomFilterFastRGB (goomdata, pzfd, zfd_update);
|
||||
|
||||
/* 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);
|
||||
|
||||
return_val = goomdata->p2;
|
||||
tmp = goomdata->p1;
|
||||
goomdata->p1 = goomdata->p2;
|
||||
goomdata->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;
|
||||
}
|
||||
return return_val;
|
||||
}
|
||||
|
||||
void
|
||||
goom_close (GoomData * goomdata)
|
||||
{
|
||||
if (goomdata->pixel != NULL)
|
||||
free (goomdata->pixel);
|
||||
if (goomdata->back != NULL)
|
||||
free (goomdata->back);
|
||||
if (goomdata->zfd != NULL) {
|
||||
zoomFilterDestroy (goomdata->zfd);
|
||||
goomdata->zfd = NULL;
|
||||
}
|
||||
goomdata->pixel = goomdata->back = NULL;
|
||||
RAND_CLOSE (goomdata);
|
||||
}
|
24
gst/goom2k1/goom_tools.h
Normal file
24
gst/goom2k1/goom_tools.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#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)
|
||||
|
||||
#endif
|
14
gst/goom2k1/graphic.c
Normal file
14
gst/goom2k1/graphic.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "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 YELLOW = { 0xff, 0xff, 0x33 };
|
||||
const Color ORANGE = { 0xff, 0xcc, 0x00 };
|
||||
const Color VIOLET = { 0x55, 0x00, 0xff };
|
602
gst/goom2k1/gstgoom.c
Normal file
602
gst/goom2k1/gstgoom.c
Normal file
|
@ -0,0 +1,602 @@
|
|||
/* gstgoom.c: implementation of goom drawing element
|
||||
* Copyright (C) <2001> Richard Boulton <richard@tartarus.org>
|
||||
* (C) <2006> Wim Taymans <wim at fluendo dot com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:element-goom
|
||||
* @see_also: synaesthesia
|
||||
*
|
||||
* <refsect2>
|
||||
* <para>
|
||||
* Goom is an audio visualisation element. It creates warping structures
|
||||
* based on the incomming audio signal.
|
||||
* </para>
|
||||
* <title>Example launch line</title>
|
||||
* <para>
|
||||
* <programlisting>
|
||||
* gst-launch -v audiotestsrc ! goom2k1 ! ffmpegcolorspace ! xvimagesink
|
||||
* </programlisting>
|
||||
* </para>
|
||||
* </refsect2>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/gst.h>
|
||||
#include "gstgoom.h"
|
||||
#include <gst/video/video.h>
|
||||
#include "goom_core.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (goom_debug);
|
||||
#define GST_CAT_DEFAULT goom_debug
|
||||
|
||||
/* elementfactory information */
|
||||
static const GstElementDetails gst_goom_details =
|
||||
GST_ELEMENT_DETAILS ("GOOM: what a GOOM! 2k1",
|
||||
"Visualization",
|
||||
"Takes frames of data and outputs video frames using the GOOM 2k1 filter",
|
||||
"Wim Taymans <wim@fluendo.com>");
|
||||
|
||||
/* signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0
|
||||
/* FILL ME */
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_xRGB_HOST_ENDIAN)
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", /* the name of the pads */
|
||||
GST_PAD_SINK, /* type of the pad */
|
||||
GST_PAD_ALWAYS, /* ALWAYS/SOMETIMES */
|
||||
GST_STATIC_CAPS ("audio/x-raw-int, "
|
||||
"endianness = (int) BYTE_ORDER, "
|
||||
"signed = (boolean) TRUE, "
|
||||
"width = (int) 16, "
|
||||
"depth = (int) 16, "
|
||||
"rate = (int) [ 8000, 96000 ], " "channels = (int) { 1, 2 }")
|
||||
);
|
||||
|
||||
|
||||
static void gst_goom_class_init (GstGoomClass * klass);
|
||||
static void gst_goom_base_init (GstGoomClass * klass);
|
||||
static void gst_goom_init (GstGoom * goom);
|
||||
static void gst_goom_finalize (GObject * object);
|
||||
|
||||
static GstStateChangeReturn gst_goom_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
|
||||
static GstFlowReturn gst_goom_chain (GstPad * pad, GstBuffer * buffer);
|
||||
static gboolean gst_goom_src_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_goom_sink_event (GstPad * pad, GstEvent * event);
|
||||
|
||||
static gboolean gst_goom_sink_setcaps (GstPad * pad, GstCaps * caps);
|
||||
static gboolean gst_goom_src_setcaps (GstPad * pad, GstCaps * caps);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
GType
|
||||
gst_goom_get_type (void)
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if (!type) {
|
||||
static const GTypeInfo info = {
|
||||
sizeof (GstGoomClass),
|
||||
(GBaseInitFunc) gst_goom_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_goom_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstGoom),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_goom_init,
|
||||
};
|
||||
|
||||
type = g_type_register_static (GST_TYPE_ELEMENT, "GstGoom", &info, 0);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_goom_base_init (GstGoomClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_goom_details);
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&sink_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&src_template));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_goom_class_init (GstGoomClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
gobject_class->finalize = gst_goom_finalize;
|
||||
|
||||
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_goom_change_state);
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (goom_debug, "goom", 0, "goom visualisation element");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_goom_init (GstGoom * goom)
|
||||
{
|
||||
/* create the sink and src pads */
|
||||
goom->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
|
||||
gst_pad_set_chain_function (goom->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_goom_chain));
|
||||
gst_pad_set_event_function (goom->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_goom_sink_event));
|
||||
gst_pad_set_setcaps_function (goom->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_goom_sink_setcaps));
|
||||
gst_element_add_pad (GST_ELEMENT (goom), goom->sinkpad);
|
||||
|
||||
goom->srcpad = gst_pad_new_from_static_template (&src_template, "src");
|
||||
gst_pad_set_setcaps_function (goom->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_goom_src_setcaps));
|
||||
gst_pad_set_event_function (goom->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_goom_src_event));
|
||||
gst_element_add_pad (GST_ELEMENT (goom), goom->srcpad);
|
||||
|
||||
goom->adapter = gst_adapter_new ();
|
||||
|
||||
goom->width = 320;
|
||||
goom->height = 200;
|
||||
goom->fps_n = 25; /* desired frame rate */
|
||||
goom->fps_d = 1; /* desired frame rate */
|
||||
goom->channels = 0;
|
||||
goom->rate = 0;
|
||||
goom->duration = 0;
|
||||
|
||||
goom_init (&(goom->goomdata), goom->width, goom->height);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_goom_finalize (GObject * object)
|
||||
{
|
||||
GstGoom *goom = GST_GOOM (object);
|
||||
|
||||
goom_close (&(goom->goomdata));
|
||||
|
||||
g_object_unref (goom->adapter);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_goom_reset (GstGoom * goom)
|
||||
{
|
||||
goom->next_ts = -1;
|
||||
gst_adapter_clear (goom->adapter);
|
||||
gst_segment_init (&goom->segment, GST_FORMAT_UNDEFINED);
|
||||
|
||||
GST_OBJECT_LOCK (goom);
|
||||
goom->proportion = 1.0;
|
||||
goom->earliest_time = -1;
|
||||
GST_OBJECT_UNLOCK (goom);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_goom_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
GstGoom *goom;
|
||||
GstStructure *structure;
|
||||
gboolean res;
|
||||
|
||||
goom = GST_GOOM (GST_PAD_PARENT (pad));
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
res = gst_structure_get_int (structure, "channels", &goom->channels);
|
||||
res &= gst_structure_get_int (structure, "rate", &goom->rate);
|
||||
|
||||
goom->bps = goom->channels * sizeof (gint16);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_goom_src_setcaps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
GstGoom *goom;
|
||||
GstStructure *structure;
|
||||
|
||||
goom = GST_GOOM (GST_PAD_PARENT (pad));
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
if (!gst_structure_get_int (structure, "width", &goom->width) ||
|
||||
!gst_structure_get_int (structure, "height", &goom->height) ||
|
||||
!gst_structure_get_fraction (structure, "framerate", &goom->fps_n,
|
||||
&goom->fps_d))
|
||||
return FALSE;
|
||||
|
||||
goom_set_resolution (&(goom->goomdata), goom->width, goom->height);
|
||||
|
||||
/* size of the output buffer in bytes, depth is always 4 bytes */
|
||||
goom->outsize = goom->width * goom->height * 4;
|
||||
goom->duration =
|
||||
gst_util_uint64_scale_int (GST_SECOND, goom->fps_d, goom->fps_n);
|
||||
goom->spf = gst_util_uint64_scale_int (goom->rate, goom->fps_d, goom->fps_n);
|
||||
goom->bpf = goom->spf * goom->bps;
|
||||
|
||||
GST_DEBUG_OBJECT (goom, "dimension %dx%d, framerate %d/%d, spf %d",
|
||||
goom->width, goom->height, goom->fps_n, goom->fps_d, goom->spf);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_goom_src_negotiate (GstGoom * goom)
|
||||
{
|
||||
GstCaps *othercaps, *target, *intersect;
|
||||
GstStructure *structure;
|
||||
const GstCaps *templ;
|
||||
|
||||
templ = gst_pad_get_pad_template_caps (goom->srcpad);
|
||||
|
||||
GST_DEBUG_OBJECT (goom, "performing negotiation");
|
||||
|
||||
/* see what the peer can do */
|
||||
othercaps = gst_pad_peer_get_caps (goom->srcpad);
|
||||
if (othercaps) {
|
||||
intersect = gst_caps_intersect (othercaps, templ);
|
||||
gst_caps_unref (othercaps);
|
||||
|
||||
if (gst_caps_is_empty (intersect))
|
||||
goto no_format;
|
||||
|
||||
target = gst_caps_copy_nth (intersect, 0);
|
||||
gst_caps_unref (intersect);
|
||||
} else {
|
||||
target = gst_caps_ref ((GstCaps *) templ);
|
||||
}
|
||||
|
||||
structure = gst_caps_get_structure (target, 0);
|
||||
gst_structure_fixate_field_nearest_int (structure, "width", 320);
|
||||
gst_structure_fixate_field_nearest_int (structure, "height", 240);
|
||||
gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);
|
||||
|
||||
gst_pad_set_caps (goom->srcpad, target);
|
||||
gst_caps_unref (target);
|
||||
|
||||
return TRUE;
|
||||
|
||||
no_format:
|
||||
{
|
||||
gst_caps_unref (intersect);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_goom_src_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
gboolean res;
|
||||
GstGoom *goom;
|
||||
|
||||
goom = GST_GOOM (gst_pad_get_parent (pad));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_QOS:
|
||||
{
|
||||
gdouble proportion;
|
||||
GstClockTimeDiff diff;
|
||||
GstClockTime timestamp;
|
||||
|
||||
gst_event_parse_qos (event, &proportion, &diff, ×tamp);
|
||||
|
||||
/* save stuff for the _chain() function */
|
||||
GST_OBJECT_LOCK (goom);
|
||||
goom->proportion = proportion;
|
||||
if (diff >= 0)
|
||||
/* we're late, this is a good estimate for next displayable
|
||||
* frame (see part-qos.txt) */
|
||||
goom->earliest_time = timestamp + 2 * diff + goom->duration;
|
||||
else
|
||||
goom->earliest_time = timestamp + diff;
|
||||
GST_OBJECT_UNLOCK (goom);
|
||||
|
||||
res = gst_pad_push_event (goom->sinkpad, event);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = gst_pad_push_event (goom->sinkpad, event);
|
||||
break;
|
||||
}
|
||||
gst_object_unref (goom);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_goom_sink_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
gboolean res;
|
||||
GstGoom *goom;
|
||||
|
||||
goom = GST_GOOM (gst_pad_get_parent (pad));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_FLUSH_START:
|
||||
res = gst_pad_push_event (goom->srcpad, event);
|
||||
break;
|
||||
case GST_EVENT_FLUSH_STOP:
|
||||
gst_goom_reset (goom);
|
||||
res = gst_pad_push_event (goom->srcpad, event);
|
||||
break;
|
||||
case GST_EVENT_NEWSEGMENT:
|
||||
{
|
||||
GstFormat format;
|
||||
gdouble rate, arate;
|
||||
gint64 start, stop, time;
|
||||
gboolean update;
|
||||
|
||||
/* the newsegment values are used to clip the input samples
|
||||
* and to convert the incomming timestamps to running time so
|
||||
* we can do QoS */
|
||||
gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
|
||||
&start, &stop, &time);
|
||||
|
||||
/* now configure the values */
|
||||
gst_segment_set_newsegment_full (&goom->segment, update,
|
||||
rate, arate, format, start, stop, time);
|
||||
|
||||
res = gst_pad_push_event (goom->srcpad, event);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = gst_pad_push_event (goom->srcpad, event);
|
||||
break;
|
||||
}
|
||||
gst_object_unref (goom);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
get_buffer (GstGoom * goom, GstBuffer ** outbuf)
|
||||
{
|
||||
GstFlowReturn ret;
|
||||
|
||||
if (GST_PAD_CAPS (goom->srcpad) == NULL) {
|
||||
if (!gst_goom_src_negotiate (goom))
|
||||
return GST_FLOW_NOT_NEGOTIATED;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (goom, "allocating output buffer with caps %"
|
||||
GST_PTR_FORMAT, GST_PAD_CAPS (goom->srcpad));
|
||||
|
||||
ret =
|
||||
gst_pad_alloc_buffer_and_set_caps (goom->srcpad,
|
||||
GST_BUFFER_OFFSET_NONE, goom->outsize,
|
||||
GST_PAD_CAPS (goom->srcpad), outbuf);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_goom_chain (GstPad * pad, GstBuffer * buffer)
|
||||
{
|
||||
GstGoom *goom;
|
||||
GstFlowReturn ret;
|
||||
GstBuffer *outbuf = NULL;
|
||||
|
||||
goom = GST_GOOM (gst_pad_get_parent (pad));
|
||||
|
||||
/* If we don't have an output format yet, preallocate a buffer to try and
|
||||
* set one */
|
||||
if (GST_PAD_CAPS (goom->srcpad) == NULL) {
|
||||
ret = get_buffer (goom, &outbuf);
|
||||
if (ret != GST_FLOW_OK) {
|
||||
gst_buffer_unref (buffer);
|
||||
goto beach;
|
||||
}
|
||||
}
|
||||
|
||||
/* don't try to combine samples from discont buffer */
|
||||
if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
|
||||
gst_adapter_clear (goom->adapter);
|
||||
goom->next_ts = -1;
|
||||
}
|
||||
|
||||
/* Match timestamps from the incoming audio */
|
||||
if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE)
|
||||
goom->next_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
GST_DEBUG_OBJECT (goom,
|
||||
"Input buffer has %d samples, time=%" G_GUINT64_FORMAT,
|
||||
GST_BUFFER_SIZE (buffer) / goom->bps, GST_BUFFER_TIMESTAMP (buffer));
|
||||
|
||||
/* Collect samples until we have enough for an output frame */
|
||||
gst_adapter_push (goom->adapter, buffer);
|
||||
|
||||
ret = GST_FLOW_OK;
|
||||
|
||||
while (TRUE) {
|
||||
const guint16 *data;
|
||||
gboolean need_skip;
|
||||
guchar *out_frame;
|
||||
gint i;
|
||||
guint avail, to_flush;
|
||||
|
||||
avail = gst_adapter_available (goom->adapter);
|
||||
GST_DEBUG_OBJECT (goom, "avail now %u", avail);
|
||||
|
||||
/* we need GOOM_SAMPLES to get a meaningful result from goom. */
|
||||
if (avail < (GOOM_SAMPLES * goom->bps))
|
||||
break;
|
||||
|
||||
/* we also need enough samples to produce one frame at least */
|
||||
if (avail < goom->bpf)
|
||||
break;
|
||||
|
||||
GST_DEBUG_OBJECT (goom, "processing buffer");
|
||||
|
||||
if (goom->next_ts != -1) {
|
||||
gint64 qostime;
|
||||
|
||||
qostime = gst_segment_to_running_time (&goom->segment, GST_FORMAT_TIME,
|
||||
goom->next_ts);
|
||||
|
||||
GST_OBJECT_LOCK (goom);
|
||||
/* check for QoS, don't compute buffers that are known to be late */
|
||||
need_skip = goom->earliest_time != -1 && qostime <= goom->earliest_time;
|
||||
GST_OBJECT_UNLOCK (goom);
|
||||
|
||||
if (need_skip) {
|
||||
GST_WARNING_OBJECT (goom,
|
||||
"QoS: skip ts: %" GST_TIME_FORMAT ", earliest: %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (qostime), GST_TIME_ARGS (goom->earliest_time));
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
|
||||
/* get next GOOM_SAMPLES, we have at least this amount of samples */
|
||||
data =
|
||||
(const guint16 *) gst_adapter_peek (goom->adapter,
|
||||
GOOM_SAMPLES * goom->bps);
|
||||
|
||||
if (goom->channels == 2) {
|
||||
for (i = 0; i < GOOM_SAMPLES; i++) {
|
||||
goom->datain[0][i] = *data++;
|
||||
goom->datain[1][i] = *data++;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < GOOM_SAMPLES; i++) {
|
||||
goom->datain[0][i] = *data;
|
||||
goom->datain[1][i] = *data++;
|
||||
}
|
||||
}
|
||||
|
||||
/* alloc a buffer if we don't have one yet, this happens
|
||||
* when we pushed a buffer in this while loop before */
|
||||
if (outbuf == NULL) {
|
||||
ret = get_buffer (goom, &outbuf);
|
||||
if (ret != GST_FLOW_OK) {
|
||||
goto beach;
|
||||
}
|
||||
}
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = goom->next_ts;
|
||||
GST_BUFFER_DURATION (outbuf) = goom->duration;
|
||||
GST_BUFFER_SIZE (outbuf) = goom->outsize;
|
||||
|
||||
out_frame = (guchar *) goom_update (&(goom->goomdata), goom->datain);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), out_frame, goom->outsize);
|
||||
|
||||
GST_DEBUG ("Pushing frame with time=%" GST_TIME_FORMAT ", duration=%"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (goom->next_ts),
|
||||
GST_TIME_ARGS (goom->duration));
|
||||
|
||||
ret = gst_pad_push (goom->srcpad, outbuf);
|
||||
outbuf = NULL;
|
||||
|
||||
skip:
|
||||
/* interpollate next timestamp */
|
||||
if (goom->next_ts != -1)
|
||||
goom->next_ts += goom->duration;
|
||||
|
||||
/* Now flush the samples we needed for this frame, which might be more than
|
||||
* the samples we used (GOOM_SAMPLES). */
|
||||
to_flush = goom->bpf;
|
||||
|
||||
GST_DEBUG_OBJECT (goom, "finished frame, flushing %u bytes from input",
|
||||
to_flush);
|
||||
gst_adapter_flush (goom->adapter, to_flush);
|
||||
|
||||
if (ret != GST_FLOW_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
if (outbuf != NULL)
|
||||
gst_buffer_unref (outbuf);
|
||||
|
||||
beach:
|
||||
gst_object_unref (goom);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_goom_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstGoom *goom = GST_GOOM (element);
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
gst_goom_reset (goom);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "goom2k1", GST_RANK_NONE, GST_TYPE_GOOM);
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"goom2k1",
|
||||
"GOOM 2k1 visualization filter",
|
||||
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
|
91
gst/goom2k1/gstgoom.h
Normal file
91
gst/goom2k1/gstgoom.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* gstgoom.c: implementation of goom drawing element
|
||||
* Copyright (C) <2001> Richard Boulton <richard@tartarus.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_GOOM_H__
|
||||
#define __GST_GOOM_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
#include "goom_core.h"
|
||||
|
||||
#define GOOM_SAMPLES 512
|
||||
|
||||
#define GST_TYPE_GOOM (gst_goom_get_type())
|
||||
#define GST_GOOM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GOOM,GstGoom))
|
||||
#define GST_GOOM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GOOM,GstGoomClass))
|
||||
#define GST_IS_GOOM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GOOM))
|
||||
#define GST_IS_GOOM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GOOM))
|
||||
|
||||
typedef struct _GstGoom GstGoom;
|
||||
typedef struct _GstGoomClass GstGoomClass;
|
||||
|
||||
struct _GstGoom
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
/* pads */
|
||||
GstPad *sinkpad, *srcpad;
|
||||
GstAdapter *adapter;
|
||||
|
||||
/* input tracking */
|
||||
gint rate;
|
||||
gint channels;
|
||||
guint bps;
|
||||
|
||||
/* video state */
|
||||
gint fps_n;
|
||||
gint fps_d;
|
||||
gint width;
|
||||
gint height;
|
||||
GstClockTime duration;
|
||||
guint outsize;
|
||||
|
||||
/* samples per frame */
|
||||
guint spf;
|
||||
/* bytes per frame */
|
||||
guint bpf;
|
||||
|
||||
/* goom stuff */
|
||||
gint16 datain[2][GOOM_SAMPLES];
|
||||
GoomData goomdata;
|
||||
|
||||
/* segment state */
|
||||
GstSegment segment;
|
||||
|
||||
/* the timestamp of the next frame */
|
||||
GstClockTime next_ts;
|
||||
|
||||
/* QoS stuff *//* with LOCK */
|
||||
gdouble proportion;
|
||||
GstClockTime earliest_time;
|
||||
};
|
||||
|
||||
struct _GstGoomClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_goom_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GOOM_H__ */
|
||||
|
107
gst/goom2k1/lines.c
Normal file
107
gst/goom2k1/lines.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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>
|
||||
|
||||
static inline unsigned char
|
||||
lighten (unsigned char value, unsigned char power)
|
||||
{
|
||||
unsigned char i;
|
||||
|
||||
for (i = 0; i < power; i++)
|
||||
value += (255 - value) / 5;
|
||||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
goom_lines (GoomData * goomdata, gint16 data[2][512], unsigned int ID,
|
||||
unsigned int *p, guint32 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;
|
||||
}
|
||||
|
||||
case 1: /* Stereo circles */
|
||||
{
|
||||
color1 = 0x00AA33DD;
|
||||
color2 = 0x00AA33DD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*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;
|
||||
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
16
gst/goom2k1/lines.h
Normal file
16
gst/goom2k1/lines.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* lines.h
|
||||
* iGoom
|
||||
*
|
||||
* Created by guillaum on Tue Aug 14 2001.
|
||||
* Copyright (c) 2001 ios. All rights reserved.
|
||||
*
|
||||
*/
|
||||
#include <glib.h>
|
||||
|
||||
#include "graphic.h"
|
||||
#include "goom_core.h"
|
||||
|
||||
void goom_lines(GoomData *goomdata, gint16 data [2][512], unsigned int ID,unsigned int* p, guint32 power);
|
||||
|
||||
|
Loading…
Reference in a new issue