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:
Bastien Nocera 2008-02-23 01:51:37 +00:00
parent 7f0745bb7f
commit a7bc7485b1
82 changed files with 20125 additions and 998 deletions

View file

@ -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

@ -1 +1 @@
Subproject commit 135628f16d422584d3454fb9c9805e7be25760a1
Subproject commit bd6ec57040fe3fa93e21ca440dfe494e3ee18555

View file

@ -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

View file

@ -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:

View file

@ -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
View 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
View 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;
}

View 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
View 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
View 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 */

File diff suppressed because it is too large Load diff

View file

@ -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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

7
gst/goom/gfontrle.h Normal file
View 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
View 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
View 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

View 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

File diff suppressed because it is too large Load diff

52
gst/goom/goom_filters.h Normal file
View 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
View 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
View 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
View 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
View 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--;
}
}

View file

@ -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
View 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
View 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

File diff suppressed because it is too large Load diff

34
gst/goom/goomsl.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

View file

@ -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 };

View file

@ -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=%"

View file

@ -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
View 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
View 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

View file

@ -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);
}
}

View file

@ -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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

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
View 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
View 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
View 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

View 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]);

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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;&quot;../../gst-libs&quot;;../../../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;&quot;../../gst-libs&quot;;../../../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
View 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
View 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
View 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
View 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, &timestamp);
/* 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
View 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
View 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
View 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);