2024-09-24 12:54:57 +00:00
/*
LICENSE
- - - - - - -
Copyright 2005 Nullsoft , Inc .
All rights reserved .
Redistribution and use in source and binary forms , with or without modification ,
are permitted provided that the following conditions are met :
* Redistributions of source code must retain the above copyright notice ,
this list of conditions and the following disclaimer .
* Redistributions in binary form must reproduce the above copyright notice ,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution .
* Neither the name of Nullsoft nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS " AND ANY EXPRESS OR
IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER
IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
// alphachannel safe 11/21/99
# define M_PI 3.14159265358979323846
2024-09-29 02:04:03 +00:00
# include <arch.h>
2024-09-24 12:54:57 +00:00
# include <commctrl.h>
# include "r_defs.h"
# include "resource.h"
# include "timing.h"
# include "avs_eelif.h"
# include "../Agave/Language/api_language.h"
# include "../nu/AutoWide.h"
# include <math.h>
# ifndef LASER
# define C_THISCLASS C_TransTabClass
# define MOD_NAME "Trans / Movement"
# define REFFECT_MIN 3
# define REFFECT_MAX 23
typedef struct {
// int index; // Just here for descriptive purposes, makes it easy to match stuff up.
int list_desc ; // The string to show in the listbox.
char * eval_desc ; // The optional string to display in the evaluation editor.
char uses_eval ; // If this is true, the preset engages the eval library and there is NULL in the radial_effects array for its entry
char uses_rect ; // This value sets the checkbox for rectangular calculation
} Description ;
static Description descriptions [ ] =
{
{ /* 0,*/ IDS_NONE , " " , 0 , 0 } ,
{ /* 1,*/ IDS_SLIGHT_FUZZIFY , " " , 0 , 0 } ,
{ /* 2,*/ IDS_SHIFT_ROTATE_LEFT , " x=x+1/32; // use wrap for this one " , 0 , 1 } ,
{ /* 3,*/ IDS_BIG_SWIRL_OUT , " r = r + (0.1 - (0.2 * d)); \r \n d = d * 0.96; " , 0 , 0 } ,
{ /* 4,*/ IDS_MEDIUM_SWIRL , " d = d * (0.99 * (1.0 - sin(r-$PI*0.5) / 32.0)); \r \n r = r + (0.03 * sin(d * $PI * 4)); " , 0 , 0 } ,
{ /* 5,*/ IDS_SUNBURSTER , " d = d * (0.94 + (cos((r-$PI*0.5) * 32.0) * 0.06)); " , 0 , 0 } ,
{ /* 6,*/ IDS_SWIRL_TO_CENTER , " d = d * (1.01 + (cos((r-$PI*0.5) * 4) * 0.04)); \r \n r = r + (0.03 * sin(d * $PI * 4)); " , 0 , 0 } ,
{ /* 7,*/ IDS_BLOCKY_PARTIAL_OUT , " " , 0 , 0 } ,
{ /* 8,*/ IDS_SWIRLING_AROUND_BOTH_WAYS , " r = r + (0.1 * sin(d * $PI * 5)); " , 0 , 0 } ,
{ /* 9,*/ IDS_BUBBLING_OUTWARD , " t = sin(d * $PI); \r \n d = d - (8*t*t*t*t*t)/sqrt((sw*sw+sh*sh)/4); " , 0 , 0 } ,
{ /*10,*/ IDS_BUBBLING_OUTWARD_WITH_SWIRL , " t = sin(d * $PI); \r \n d = d - (8*t*t*t*t*t)/sqrt((sw*sw+sh*sh)/4); \r \n t=cos(d*$PI/2.0); \r \n r= r + 0.1*t*t*t; " , 0 , 0 } ,
{ /*11,*/ IDS_5_POINTED_DISTRO , " d = d * (0.95 + (cos(((r-$PI*0.5) * 5.0) - ($PI / 2.50)) * 0.03)); " , 0 , 0 } ,
{ /*12,*/ IDS_TUNNELING , " r = r + 0.04; \r \n d = d * (0.96 + cos(d * $PI) * 0.05); " , 0 , 0 } ,
{ /*13,*/ IDS_BLEEDIN , " t = cos(d * $PI); \r \n r = r + (0.07 * t); \r \n d = d * (0.98 + t * 0.10); " , 0 , 0 } ,
{ /*14,*/ IDS_SHIFTED_BIG_SWIRL_OUT , " // this is a very bad approximation in script. fixme. \r \n d=sqrt(x*x+y*y); r=atan2(y,x); \r \n r=r+0.1-0.2*d; d=d*0.96; \r \n x=cos(r)*d + 8/128; y=sin(r)*d; " , 0 , 1 } ,
{ /*15,*/ IDS_PSYCHOTIC_BEAMING_OUTWARD , " d = 0.15 " , 0 , 0 } ,
{ /*16,*/ IDS_COSINE_RADIAL_3_WAY , " r = cos(r * 3) " , 0 , 0 } ,
{ /*17,*/ IDS_SPINNY_TUBE , " d = d * (1 - ((d - .35) * .5)); \r \n r = r + .1; " , 0 , 0 } ,
{ /*18,*/ IDS_RADIAL_SWIRLIES , " d = d * (1 - (sin((r-$PI*0.5) * 7) * .03)); \r \n r = r + (cos(d * 12) * .03); " , 1 , 0 } ,
{ /*19,*/ IDS_SWILL , " d = d * (1 - (sin((r - $PI*0.5) * 12) * .05)); \r \n r = r + (cos(d * 18) * .05); \r \n d = d * (1-((d - .4) * .03)); \r \n r = r + ((d - .4) * .13) " , 1 , 0 } ,
{ /*20,*/ IDS_GRIDLEY , " x = x + (cos(y * 18) * .02); \r \n y = y + (sin(x * 14) * .03); " , 1 , 1 } ,
{ /*21,*/ IDS_GRAPEVINE , " x = x + (cos(abs(y-.5) * 8) * .02); \r \n y = y + (sin(abs(x-.5) * 8) * .05); \r \n x = x * .95; \r \n y = y * .95; " , 1 , 1 } ,
{ /*22,*/ IDS_QUADRANT , " y = y * ( 1 + (sin(r + $PI/2) * .3) ); \r \n x = x * ( 1 + (cos(r + $PI/2) * .3) ); \r \n x = x * .995; \r \n y = y * .995; " , 1 , 1 } ,
{ /*23,*/ IDS_6_WAY_KALAEIDA , " y = (r*6)/($PI); x = d; " , 1 , 1 } ,
} ;
# define MAKE_REFFECT(n,x) void _ref##n(double &r, double &d, double max_d, int &xo, int &yo) { x }
typedef void t_reffect ( double & r , double & d , double max_d , int & xo , int & yo ) ;
MAKE_REFFECT ( 3 , r + = 0.1 - 0.2 * ( d / max_d ) ; d * = 0.96 ; )
MAKE_REFFECT ( 4 , d * = 0.99 * ( 1.0 - sin ( r ) / 32.0 ) ; r + = 0.03 * sin ( d / max_d * M_PI * 4 ) ; )
MAKE_REFFECT ( 5 , d * = 0.94 + ( cos ( r * 32.0 ) * 0.06 ) ; )
MAKE_REFFECT ( 6 , d * = 1.01 + ( cos ( r * 4.0 ) * 0.04 ) ; r + = 0.03 * sin ( d / max_d * M_PI * 4 ) ; )
MAKE_REFFECT ( 8 , r + = 0.1 * sin ( d / max_d * M_PI * 5 ) ; )
MAKE_REFFECT ( 9 , double t ; t = sin ( d / max_d * M_PI ) ; d - = 8 * t * t * t * t * t ; )
MAKE_REFFECT ( 10 , double t ; t = sin ( d / max_d * M_PI ) ; d - = 8 * t * t * t * t * t ; t = cos ( ( d / max_d ) * M_PI / 2.0 ) ; r + = 0.1 * t * t * t ; )
MAKE_REFFECT ( 11 , d * = 0.95 + ( cos ( r * 5.0 - M_PI / 2.50 ) * 0.03 ) ; )
MAKE_REFFECT ( 12 , r + = 0.04 ; d * = 0.96 + cos ( d / max_d * M_PI ) * 0.05 ; )
MAKE_REFFECT ( 13 , double t ; t = cos ( d / max_d * M_PI ) ; r + = 0.07 * t ; d * = 0.98 + t * 0.10 ; )
MAKE_REFFECT ( 14 , r + = 0.1 - 0.2 * ( d / max_d ) ; d * = 0.96 ; xo = 8 ; )
MAKE_REFFECT ( 15 , d = max_d * 0.15 ; )
MAKE_REFFECT ( 16 , r = cos ( r * 3 ) ; )
MAKE_REFFECT ( 17 , d * = ( 1 - ( ( ( d / max_d ) - .35 ) * .5 ) ) ; r + = .1 ; )
static t_reffect * radial_effects [ REFFECT_MAX - REFFECT_MIN + 1 ] =
{
_ref3 , _ref4 , _ref5 , _ref6 , NULL , _ref8 , _ref9 , _ref10 , _ref11 , _ref12 , _ref13 ,
_ref14 , _ref15 , _ref16 , _ref17 , NULL /*18*/ , NULL /*19*/ , NULL /*20*/ , NULL /*21*/ ,
NULL /*22*/ , NULL /*23*/ ,
} ;
static inline bool effect_uses_eval ( int t )
{
bool retval = false ;
if ( ( t > = REFFECT_MIN ) & & ( t < = REFFECT_MAX ) )
{
if ( descriptions [ t ] . uses_eval )
{
retval = true ;
}
}
return retval ;
}
class C_THISCLASS : public C_RBASE2 {
protected :
public :
C_THISCLASS ( ) ;
virtual ~ C_THISCLASS ( ) ;
virtual int render ( char visdata [ 2 ] [ 2 ] [ 576 ] , int isBeat , int * framebuffer , int * fbout , int w , int h ) ;
virtual int smp_getflags ( ) { return 1 ; }
virtual int smp_begin ( int max_threads , char visdata [ 2 ] [ 2 ] [ 576 ] , int isBeat , int * framebuffer , int * fbout , int w , int h ) ;
virtual void smp_render ( int this_thread , int max_threads , char visdata [ 2 ] [ 2 ] [ 576 ] , int isBeat , int * framebuffer , int * fbout , int w , int h ) ;
virtual int smp_finish ( char visdata [ 2 ] [ 2 ] [ 576 ] , int isBeat , int * framebuffer , int * fbout , int w , int h ) ; // return value is that of render() for fbstuff etc
virtual char * get_desc ( ) { return MOD_NAME ; }
virtual HWND conf ( HINSTANCE hInstance , HWND hwndParent ) ;
virtual void load_config ( unsigned char * data , int len ) ;
virtual int save_config ( unsigned char * data ) ;
int * trans_tab , trans_tab_w , trans_tab_h , trans_tab_subpixel ;
int trans_effect ;
RString effect_exp ;
int effect_exp_ch ;
int effect , blend ;
int sourcemapped ;
int rectangular ;
int subpixel ;
int wrap ;
CRITICAL_SECTION rcs ;
} ;
# define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
# define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
void C_THISCLASS : : load_config ( unsigned char * data , int len )
{
int pos = 0 ;
if ( len - pos > = 4 ) { effect = GET_INT ( ) ; pos + = 4 ; }
if ( effect = = 32767 )
{
if ( ! memcmp ( data + pos , " !rect " , 6 ) )
{
pos + = 6 ;
rectangular = 1 ;
}
if ( data [ pos ] = = 1 )
{
pos + + ;
int l = GET_INT ( ) ; pos + = 4 ;
if ( l > 0 & & len - pos > = l )
{
effect_exp . resize ( l ) ;
memcpy ( effect_exp . get ( ) , data + pos , l ) ;
pos + = l ;
}
else
{
effect_exp . resize ( 1 ) ;
effect_exp . get ( ) [ 0 ] = 0 ;
}
}
else if ( len - pos > = 256 )
{
char buf [ 257 ] ;
int l = 256 - ( rectangular ? 6 : 0 ) ;
memcpy ( buf , data + pos , l ) ;
buf [ l ] = 0 ;
effect_exp . assign ( buf ) ;
pos + = l ;
}
}
if ( len - pos > = 4 ) { blend = GET_INT ( ) ; pos + = 4 ; }
if ( len - pos > = 4 ) { sourcemapped = GET_INT ( ) ; pos + = 4 ; }
if ( len - pos > = 4 ) { rectangular = GET_INT ( ) ; pos + = 4 ; }
if ( len - pos > = 4 ) { subpixel = GET_INT ( ) ; pos + = 4 ; }
else subpixel = 0 ;
if ( len - pos > = 4 ) { wrap = GET_INT ( ) ; pos + = 4 ; }
else wrap = 0 ;
if ( ! effect & & len - pos > = 4 )
{
effect = GET_INT ( ) ; pos + = 4 ;
}
if ( effect ! = 32767 & & effect > REFFECT_MAX | | effect < 0 )
effect = 0 ;
// Once we know what our _real_ effect value is, if it uses the evaluator, allocate and stuff the string, here.
/*
if ( effect_uses_eval ( effect ) )
{
const char * eval_string = descriptions [ effect ] . eval_desc ;
int length = strlen ( eval_string ) ;
effect_exp . resize ( length + 1 ) ;
strcpy ( effect_exp . get ( ) , eval_string ) ;
}
*/
effect_exp_ch = 1 ;
}
int C_THISCLASS : : save_config ( unsigned char * data )
{
int pos = 0 ;
// the reason this is 15, and not REFFECT_MAX, is because old versions of AVS barf
// if effect is > 15, so we put 0, and at the end put the new value
if ( effect > 15 & & effect ! = 32767 )
{
PUT_INT ( 0 ) ;
pos + = 4 ;
}
else
{
PUT_INT ( effect ) ;
pos + = 4 ;
}
if ( effect = = 32767 )
{
int l = strlen ( effect_exp . get ( ) ) + 1 ;
data [ pos + + ] = 1 ;
PUT_INT ( l ) ;
pos + = 4 ;
memcpy ( data + pos , effect_exp . get ( ) , strlen ( effect_exp . get ( ) ) + 1 ) ;
pos + = strlen ( effect_exp . get ( ) ) + 1 ;
}
PUT_INT ( blend ) ; pos + = 4 ;
PUT_INT ( sourcemapped ) ; pos + = 4 ;
PUT_INT ( rectangular ) ; pos + = 4 ;
PUT_INT ( subpixel ) ; pos + = 4 ;
PUT_INT ( wrap ) ; pos + = 4 ;
// see note on '15' above =)
if ( effect > 15 & & effect ! = 32767 )
{
PUT_INT ( effect ) ;
pos + = 4 ;
}
return pos ;
}
C_THISCLASS : : C_THISCLASS ( )
{
InitializeCriticalSection ( & rcs ) ;
sourcemapped = 0 ;
trans_tab = NULL ;
trans_tab_w = trans_tab_h = 0 ;
effect = 1 ;
trans_effect = 0 ;
blend = 0 ;
effect_exp . assign ( " " ) ;
rectangular = 0 ;
subpixel = 1 ;
wrap = 0 ;
trans_tab_subpixel = 0 ;
effect_exp_ch = 1 ;
}
C_THISCLASS : : ~ C_THISCLASS ( )
{
if ( trans_tab ) GlobalFree ( trans_tab ) ;
trans_tab = NULL ;
trans_tab_w = trans_tab_h = 0 ;
trans_effect = 0 ;
DeleteCriticalSection ( & rcs ) ;
}
int C_THISCLASS : : smp_begin ( int max_threads , char visdata [ 2 ] [ 2 ] [ 576 ] , int isBeat , int * framebuffer , int * fbout , int w , int h )
{
if ( ! effect ) return 0 ;
if ( ! trans_tab | | trans_tab_w ! = w | | trans_tab_h ! = h | | effect ! = trans_effect | |
effect_exp_ch )
{
int p ;
int * transp , x ;
if ( trans_tab ) GlobalFree ( trans_tab ) ;
trans_tab_w = w ;
trans_tab_h = h ;
trans_tab = ( int * ) GlobalAlloc ( GMEM_FIXED , trans_tab_w * trans_tab_h * sizeof ( int ) ) ;
trans_effect = effect ;
trans_tab_subpixel = ( subpixel & & trans_tab_w * trans_tab_h < ( 1 < < 22 ) & &
( ( trans_effect > = REFFECT_MIN & & trans_effect < = REFFECT_MAX
& & trans_effect ! = 1 & & trans_effect ! = 2 & & trans_effect ! = 7
) | | trans_effect = = 32767 ) ) ;
/* generate trans_tab */
transp = trans_tab ;
x = w * h ;
p = 0 ;
if ( trans_effect = = 1 )
{
while ( x - - )
{
int r = ( p + + ) + ( rand ( ) % 3 ) - 1 + ( ( rand ( ) % 3 ) - 1 ) * w ;
* transp + + = min ( w * h - 1 , max ( r , 0 ) ) ;
}
}
else if ( trans_effect = = 2 )
{
int y = h ;
while ( y - - )
{
int x = w ;
int lp = w / 64 ;
while ( x - - )
{
* transp + + = p + lp + + ;
if ( lp > = w ) lp - = w ;
}
p + = w ;
}
}
else if ( trans_effect = = 7 )
{
int y ;
for ( y = 0 ; y < h ; y + + )
{
for ( x = 0 ; x < w ; x + + )
{
if ( x & 2 | | y & 2 )
{
* transp + + = x + y * w ;
}
else
{
int xp = w / 2 + ( ( ( x & ~ 1 ) - w / 2 ) * 7 ) / 8 ;
int yp = h / 2 + ( ( ( y & ~ 1 ) - h / 2 ) * 7 ) / 8 ;
* transp + + = xp + yp * w ;
}
}
}
}
else if ( trans_effect > = REFFECT_MIN & & trans_effect < = REFFECT_MAX & & ! effect_uses_eval ( trans_effect ) )
{
double max_d = sqrt ( ( w * w + h * h ) / 4.0 ) ;
int y ;
t_reffect * ref = radial_effects [ trans_effect - REFFECT_MIN ] ;
if ( ref ) for ( y = 0 ; y < h ; y + + )
{
for ( x = 0 ; x < w ; x + + )
{
double r , d ;
double xd , yd ;
int ow , oh , xo = 0 , yo = 0 ;
xd = x - ( w / 2 ) ;
yd = y - ( h / 2 ) ;
d = sqrt ( xd * xd + yd * yd ) ;
r = atan2 ( yd , xd ) ;
ref ( r , d , max_d , xo , yo ) ;
double tmp1 , tmp2 ;
tmp1 = ( ( h / 2 ) + sin ( r ) * d + 0.5 ) + ( yo * h ) * ( 1.0 / 256.0 ) ;
tmp2 = ( ( w / 2 ) + cos ( r ) * d + 0.5 ) + ( xo * w ) * ( 1.0 / 256.0 ) ;
oh = ( int ) tmp1 ;
ow = ( int ) tmp2 ;
if ( trans_tab_subpixel )
{
int xpartial = ( int ) ( 32.0 * ( tmp2 - ow ) ) ;
int ypartial = ( int ) ( 32.0 * ( tmp1 - oh ) ) ;
if ( wrap )
{
ow % = ( w - 1 ) ;
oh % = ( h - 1 ) ;
if ( ow < 0 ) ow + = w - 1 ;
if ( oh < 0 ) oh + = h - 1 ;
}
else
{
if ( ow < 0 ) { xpartial = 0 ; ow = 0 ; }
if ( ow > = w - 1 ) { xpartial = 31 ; ow = w - 2 ; }
if ( oh < 0 ) { ypartial = 0 ; oh = 0 ; }
if ( oh > = h - 1 ) { ypartial = 31 ; oh = h - 2 ; }
}
* transp + + = ow + oh * w | ( ypartial < < 22 ) | ( xpartial < < 27 ) ;
}
else
{
if ( wrap )
{
ow % = ( w ) ;
oh % = ( h ) ;
if ( ow < 0 ) ow + = w ;
if ( oh < 0 ) oh + = h ;
}
else
{
if ( ow < 0 ) ow = 0 ;
if ( ow > = w ) ow = w - 1 ;
if ( oh < 0 ) oh = 0 ;
if ( oh > = h ) oh = h - 1 ;
}
* transp + + = ow + oh * w ;
}
}
}
}
else if ( trans_effect = = 32767 | | effect_uses_eval ( trans_effect ) )
{
NSEEL_VMCTX AVS_EEL_CONTEXTNAME ;
AVS_EEL_INITINST ( ) ;
double max_d = sqrt ( ( double ) ( w * w + h * h ) ) / 2.0 ;
double divmax_d = 1.0 / max_d ;
int y ;
double * d = registerVar ( " d " ) ;
double * r = registerVar ( " r " ) ;
double * px = registerVar ( " x " ) ;
double * py = registerVar ( " y " ) ;
double * pw = registerVar ( " sw " ) ;
double * ph = registerVar ( " sh " ) ;
NSEEL_CODEHANDLE codehandle = 0 ;
int offs = 0 ;
int is_rect = trans_effect = = 32767 ? rectangular : descriptions [ trans_effect ] . uses_rect ;
* pw = w ;
* ph = h ;
EnterCriticalSection ( & rcs ) ;
codehandle = compileCode (
trans_effect = = 32767 ? effect_exp . get ( ) : descriptions [ trans_effect ] . eval_desc
) ;
LeaveCriticalSection ( & rcs ) ;
if ( codehandle )
{
double w2 = w / 2 ;
double h2 = h / 2 ;
double xsc = 1.0 / w2 , ysc = 1.0 / h2 ;
for ( y = 0 ; y < h ; y + + )
{
for ( x = 0 ; x < w ; x + + )
{
double xd , yd ;
int ow , oh ;
xd = x - w2 ;
yd = y - h2 ;
* px = xd * xsc ;
* py = yd * ysc ;
* d = sqrt ( xd * xd + yd * yd ) * divmax_d ;
* r = atan2 ( yd , xd ) + M_PI * 0.5 ;
executeCode ( codehandle , visdata ) ;
double tmp1 , tmp2 ;
if ( ! is_rect )
{
* d * = max_d ;
* r - = M_PI / 2.0 ;
tmp1 = ( ( h / 2 ) + sin ( * r ) * * d ) ;
tmp2 = ( ( w / 2 ) + cos ( * r ) * * d ) ;
}
else
{
tmp1 = ( ( * py + 1.0 ) * h2 ) ;
tmp2 = ( ( * px + 1.0 ) * w2 ) ;
}
if ( trans_tab_subpixel )
{
oh = ( int ) tmp1 ;
ow = ( int ) tmp2 ;
int xpartial = ( int ) ( 32.0 * ( tmp2 - ow ) ) ;
int ypartial = ( int ) ( 32.0 * ( tmp1 - oh ) ) ;
if ( wrap )
{
ow % = ( w - 1 ) ;
oh % = ( h - 1 ) ;
if ( ow < 0 ) ow + = w - 1 ;
if ( oh < 0 ) oh + = h - 1 ;
}
else
{
if ( ow < 0 ) { xpartial = 0 ; ow = 0 ; }
if ( ow > = w - 1 ) { xpartial = 31 ; ow = w - 2 ; }
if ( oh < 0 ) { ypartial = 0 ; oh = 0 ; }
if ( oh > = h - 1 ) { ypartial = 31 ; oh = h - 2 ; }
}
* transp + + = ow + oh * w | ( ypartial < < 22 ) | ( xpartial < < 27 ) ;
}
else
{
tmp1 + = 0.5 ;
tmp2 + = 0.5 ;
oh = ( int ) tmp1 ;
ow = ( int ) tmp2 ;
if ( wrap )
{
ow % = ( w ) ;
oh % = ( h ) ;
if ( ow < 0 ) ow + = w ;
if ( oh < 0 ) oh + = h ;
}
else
{
if ( ow < 0 ) ow = 0 ;
if ( ow > = w ) ow = w - 1 ;
if ( oh < 0 ) oh = 0 ;
if ( oh > = h ) oh = h - 1 ;
}
* transp + + = ow + oh * w ;
}
}
}
}
else
{
transp = trans_tab ;
trans_tab_subpixel = 0 ;
for ( x = 0 ; x < w * h ; x + + )
* transp + + = x ;
}
freeCode ( codehandle ) ;
AVS_EEL_QUITINST ( ) ;
}
effect_exp_ch = 0 ;
}
if ( ! ( isBeat & 0x80000000 ) )
{
if ( ( sourcemapped & 2 ) & & isBeat ) sourcemapped ^ = 1 ;
if ( sourcemapped & 1 )
{
if ( ! blend ) memset ( fbout , 0 , w * h * sizeof ( int ) ) ;
else memcpy ( fbout , framebuffer , w * h * sizeof ( int ) ) ;
}
}
return max_threads ;
}
void C_THISCLASS : : smp_render ( int this_thread , int max_threads , char visdata [ 2 ] [ 2 ] [ 576 ] , int isBeat , int * framebuffer , int * fbout , int w , int h )
{
if ( ! effect ) return ;
# define OFFSET_MASK ((1<<22)-1)
unsigned int * inp = ( unsigned int * ) framebuffer ;
unsigned int * outp ;
int * transp , x ;
if ( max_threads < 1 ) max_threads = 1 ;
int start_l = ( this_thread * h ) / max_threads ;
int end_l ;
if ( this_thread > = max_threads - 1 ) end_l = h ;
else end_l = ( ( this_thread + 1 ) * h ) / max_threads ;
int outh = end_l - start_l ;
if ( outh < 1 ) return ;
int skip_pix = start_l * w ;
transp = trans_tab ;
outp = ( unsigned int * ) fbout ;
x = ( w * outh ) / 4 ;
if ( sourcemapped & 1 )
{
inp + = skip_pix ;
transp + = skip_pix ;
if ( trans_tab_subpixel )
{
timingEnter ( 3 ) ;
while ( x - - )
{
fbout [ transp [ 0 ] & OFFSET_MASK ] = BLEND_MAX ( inp [ 0 ] , fbout [ transp [ 0 ] & OFFSET_MASK ] ) ;
fbout [ transp [ 1 ] & OFFSET_MASK ] = BLEND_MAX ( inp [ 1 ] , fbout [ transp [ 1 ] & OFFSET_MASK ] ) ;
fbout [ transp [ 2 ] & OFFSET_MASK ] = BLEND_MAX ( inp [ 2 ] , fbout [ transp [ 2 ] & OFFSET_MASK ] ) ;
fbout [ transp [ 3 ] & OFFSET_MASK ] = BLEND_MAX ( inp [ 3 ] , fbout [ transp [ 3 ] & OFFSET_MASK ] ) ;
inp + = 4 ;
transp + = 4 ;
}
timingLeave ( 3 ) ;
x = ( w * outh ) & 3 ;
if ( x > 0 ) while ( x - - )
{
fbout [ transp [ 0 ] & OFFSET_MASK ] = BLEND_MAX ( inp + + [ 0 ] , fbout [ transp [ 0 ] & OFFSET_MASK ] ) ;
transp + + ;
}
}
else
{
{
timingEnter ( 3 ) ;
while ( x - - )
{
fbout [ transp [ 0 ] ] = BLEND_MAX ( inp [ 0 ] , fbout [ transp [ 0 ] ] ) ;
fbout [ transp [ 1 ] ] = BLEND_MAX ( inp [ 1 ] , fbout [ transp [ 1 ] ] ) ;
fbout [ transp [ 2 ] ] = BLEND_MAX ( inp [ 2 ] , fbout [ transp [ 2 ] ] ) ;
fbout [ transp [ 3 ] ] = BLEND_MAX ( inp [ 3 ] , fbout [ transp [ 3 ] ] ) ;
inp + = 4 ;
transp + = 4 ;
}
timingLeave ( 3 ) ;
x = ( w * outh ) & 3 ;
if ( x > 0 ) while ( x - - )
{
fbout [ transp [ 0 ] ] = BLEND_MAX ( inp + + [ 0 ] , fbout [ transp [ 0 ] ] ) ;
transp + + ;
}
}
}
if ( blend )
{
framebuffer + = skip_pix ;
fbout + = skip_pix ;
x = ( w * outh ) / 4 ;
while ( x - - )
{
fbout [ 0 ] = BLEND_AVG ( fbout [ 0 ] , framebuffer [ 0 ] ) ;
fbout [ 1 ] = BLEND_AVG ( fbout [ 1 ] , framebuffer [ 1 ] ) ;
fbout [ 2 ] = BLEND_AVG ( fbout [ 2 ] , framebuffer [ 2 ] ) ;
fbout [ 3 ] = BLEND_AVG ( fbout [ 3 ] , framebuffer [ 3 ] ) ;
fbout + = 4 ;
framebuffer + = 4 ;
}
x = ( w * outh ) & 3 ;
while ( x - - )
{
fbout [ 0 ] = BLEND_AVG ( fbout [ 0 ] , framebuffer [ 0 ] ) ;
fbout + + ;
framebuffer + + ;
}
}
}
else
{
inp + = skip_pix ;
outp + = skip_pix ;
transp + = skip_pix ;
if ( trans_tab_subpixel & & blend )
{
while ( x - - )
{
int offs = transp [ 0 ] & OFFSET_MASK ;
outp [ 0 ] = BLEND_AVG ( inp [ 0 ] , BLEND4 ( ( unsigned int * ) framebuffer + offs , w , ( ( transp [ 0 ] > > 24 ) & ( 31 < < 3 ) ) , ( ( transp [ 0 ] > > 19 ) & ( 31 < < 3 ) ) ) ) ;
offs = transp [ 1 ] & OFFSET_MASK ;
outp [ 1 ] = BLEND_AVG ( inp [ 1 ] , BLEND4 ( ( unsigned int * ) framebuffer + offs , w , ( ( transp [ 1 ] > > 24 ) & ( 31 < < 3 ) ) , ( ( transp [ 1 ] > > 19 ) & ( 31 < < 3 ) ) ) ) ;
offs = transp [ 2 ] & OFFSET_MASK ;
outp [ 2 ] = BLEND_AVG ( inp [ 2 ] , BLEND4 ( ( unsigned int * ) framebuffer + offs , w , ( ( transp [ 2 ] > > 24 ) & ( 31 < < 3 ) ) , ( ( transp [ 2 ] > > 19 ) & ( 31 < < 3 ) ) ) ) ;
offs = transp [ 3 ] & OFFSET_MASK ;
outp [ 3 ] = BLEND_AVG ( inp [ 3 ] , BLEND4 ( ( unsigned int * ) framebuffer + offs , w , ( ( transp [ 3 ] > > 24 ) & ( 31 < < 3 ) ) , ( ( transp [ 3 ] > > 19 ) & ( 31 < < 3 ) ) ) ) ;
transp + = 4 ;
outp + = 4 ;
inp + = 4 ;
}
x = ( w * outh ) & 3 ;
while ( x - - )
{
int offs = transp [ 0 ] & OFFSET_MASK ;
outp + + [ 0 ] = BLEND_AVG ( inp [ 0 ] , BLEND4 ( ( unsigned int * ) framebuffer + offs , w , ( ( transp [ 0 ] > > 24 ) & ( 31 < < 3 ) ) , ( ( transp [ 0 ] > > 19 ) & ( 31 < < 3 ) ) ) ) ;
transp + + ;
inp + + ;
}
# ifndef NO_MMX
__asm emms ;
# endif
}
else if ( trans_tab_subpixel )
{
while ( x - - )
{
int offs = transp [ 0 ] & OFFSET_MASK ;
outp [ 0 ] = BLEND4 ( ( unsigned int * ) framebuffer + offs , w , ( ( transp [ 0 ] > > 24 ) & ( 31 < < 3 ) ) , ( ( transp [ 0 ] > > 19 ) & ( 31 < < 3 ) ) ) ;
offs = transp [ 1 ] & OFFSET_MASK ;
outp [ 1 ] = BLEND4 ( ( unsigned int * ) framebuffer + offs , w , ( ( transp [ 1 ] > > 24 ) & ( 31 < < 3 ) ) , ( ( transp [ 1 ] > > 19 ) & ( 31 < < 3 ) ) ) ;
offs = transp [ 2 ] & OFFSET_MASK ;
outp [ 2 ] = BLEND4 ( ( unsigned int * ) framebuffer + offs , w , ( ( transp [ 2 ] > > 24 ) & ( 31 < < 3 ) ) , ( ( transp [ 2 ] > > 19 ) & ( 31 < < 3 ) ) ) ;
offs = transp [ 3 ] & OFFSET_MASK ;
outp [ 3 ] = BLEND4 ( ( unsigned int * ) framebuffer + offs , w , ( ( transp [ 3 ] > > 24 ) & ( 31 < < 3 ) ) , ( ( transp [ 3 ] > > 19 ) & ( 31 < < 3 ) ) ) ;
transp + = 4 ;
outp + = 4 ;
}
x = ( w * outh ) & 3 ;
while ( x - - )
{
int offs = transp [ 0 ] & OFFSET_MASK ;
outp + + [ 0 ] = BLEND4 ( ( unsigned int * ) framebuffer + offs , w , ( ( transp [ 0 ] > > 24 ) & ( 31 < < 3 ) ) , ( ( transp [ 0 ] > > 19 ) & ( 31 < < 3 ) ) ) ;
transp + + ;
}
# ifndef NO_MMX
__asm emms ;
# endif
}
else if ( blend )
{
timingEnter ( 3 ) ;
while ( x - - )
{
outp [ 0 ] = BLEND_AVG ( inp [ 0 ] , framebuffer [ transp [ 0 ] ] ) ;
outp [ 1 ] = BLEND_AVG ( inp [ 1 ] , framebuffer [ transp [ 1 ] ] ) ;
outp [ 2 ] = BLEND_AVG ( inp [ 2 ] , framebuffer [ transp [ 2 ] ] ) ;
outp [ 3 ] = BLEND_AVG ( inp [ 3 ] , framebuffer [ transp [ 3 ] ] ) ;
outp + = 4 ;
inp + = 4 ;
transp + = 4 ;
}
timingLeave ( 3 ) ;
x = ( w * outh ) & 3 ;
if ( x > 0 ) while ( x - - )
{
outp + + [ 0 ] = BLEND_AVG ( inp + + [ 0 ] , framebuffer [ transp + + [ 0 ] ] ) ;
}
}
else
{
timingEnter ( 4 ) ;
while ( x - - )
{
outp [ 0 ] = framebuffer [ transp [ 0 ] ] ;
outp [ 1 ] = framebuffer [ transp [ 1 ] ] ;
outp [ 2 ] = framebuffer [ transp [ 2 ] ] ;
outp [ 3 ] = framebuffer [ transp [ 3 ] ] ;
outp + = 4 ;
transp + = 4 ;
}
timingLeave ( 4 ) ;
x = ( w * outh ) & 3 ;
if ( x > 0 ) while ( x - - )
{
outp + + [ 0 ] = framebuffer [ transp + + [ 0 ] ] ;
}
}
}
}
int C_THISCLASS : : smp_finish ( char visdata [ 2 ] [ 2 ] [ 576 ] , int isBeat , int * framebuffer , int * fbout , int w , int h ) // return value is that of render() for fbstuff etc
{
return ! ! effect ;
}
int C_THISCLASS : : render ( char visdata [ 2 ] [ 2 ] [ 576 ] , int isBeat , int * framebuffer , int * fbout , int w , int h )
{
smp_begin ( 1 , visdata , isBeat , framebuffer , fbout , w , h ) ;
if ( isBeat & 0x80000000 ) return 0 ;
smp_render ( 0 , 1 , visdata , isBeat , framebuffer , fbout , w , h ) ;
return smp_finish ( visdata , isBeat , framebuffer , fbout , w , h ) ;
}
C_RBASE * R_Trans ( char * desc )
{
if ( desc ) { strcpy ( desc , MOD_NAME ) ; return NULL ; }
return ( C_RBASE * ) new C_THISCLASS ( ) ;
}
static C_THISCLASS * g_this ;
static BOOL CALLBACK g_DlgProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
static int isstart ;
switch ( uMsg )
{
case WM_INITDIALOG :
{
int x ;
for ( x = 0 ; x < sizeof ( descriptions ) / sizeof ( descriptions [ 0 ] ) ; x + + )
{
SendDlgItemMessage ( hwndDlg , IDC_LIST1 , LB_ADDSTRING , 0 , ( LPARAM ) ( const wchar_t * ) AutoWide ( WASABI_API_LNGSTRING ( descriptions [ x ] . list_desc ) , CP_UTF8 ) ) ;
}
isstart = 1 ;
SetDlgItemText ( hwndDlg , IDC_EDIT1 , g_this - > effect_exp . get ( ) ) ;
// After we set whatever value into the edit box, that's the new saved value (ie: don't change the save format)
isstart = 0 ;
if ( g_this - > blend )
CheckDlgButton ( hwndDlg , IDC_CHECK1 , BST_CHECKED ) ;
if ( g_this - > subpixel )
CheckDlgButton ( hwndDlg , IDC_CHECK4 , BST_CHECKED ) ;
if ( g_this - > wrap )
CheckDlgButton ( hwndDlg , IDC_WRAP , BST_CHECKED ) ;
if ( g_this - > rectangular )
CheckDlgButton ( hwndDlg , IDC_CHECK3 , BST_CHECKED ) ;
if ( g_this - > sourcemapped & 2 )
CheckDlgButton ( hwndDlg , IDC_CHECK2 , BST_INDETERMINATE ) ;
else if ( g_this - > sourcemapped & 1 )
CheckDlgButton ( hwndDlg , IDC_CHECK2 , BST_CHECKED ) ;
SendDlgItemMessage ( hwndDlg , IDC_LIST1 , LB_ADDSTRING , 0 , ( LPARAM ) ( const wchar_t * ) AutoWide ( WASABI_API_LNGSTRING ( IDS_USER_DEFINED ) , CP_UTF8 ) ) ;
SendDlgItemMessage ( hwndDlg , IDC_LIST1 , LB_SETCURSEL , ( g_this - > effect = = 32767 ) ? sizeof ( descriptions ) / sizeof ( descriptions [ 0 ] ) : g_this - > effect , 0 ) ;
if ( g_this - > effect = = 32767 )
{
EnableWindow ( GetDlgItem ( hwndDlg , IDC_EDIT1 ) , 1 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_CHECK3 ) , 1 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_LABEL1 ) , 1 ) ;
}
else if ( g_this - > effect > = 0 & & g_this - > effect < = REFFECT_MAX )
{
if ( strlen ( descriptions [ g_this - > effect ] . eval_desc ) > 0 )
{
SetDlgItemTextA ( hwndDlg , IDC_EDIT1 , descriptions [ g_this - > effect ] . eval_desc ) ;
CheckDlgButton ( hwndDlg , IDC_CHECK3 , descriptions [ g_this - > effect ] . uses_rect ? BST_CHECKED : 0 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_EDIT1 ) , 1 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_CHECK3 ) , 1 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_LABEL1 ) , 1 ) ;
}
else
{
EnableWindow ( GetDlgItem ( hwndDlg , IDC_EDIT1 ) , 0 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_CHECK3 ) , 0 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_LABEL1 ) , 0 ) ;
}
}
else
{
EnableWindow ( GetDlgItem ( hwndDlg , IDC_EDIT1 ) , 0 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_CHECK3 ) , 0 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_LABEL1 ) , 0 ) ;
}
}
return 1 ;
case WM_TIMER :
if ( wParam = = 1 )
{
KillTimer ( hwndDlg , 1 ) ;
EnterCriticalSection ( & g_this - > rcs ) ;
g_this - > effect = 32767 ;
g_this - > effect_exp . get_from_dlgitem ( hwndDlg , IDC_EDIT1 ) ;
g_this - > effect_exp_ch = 1 ;
LeaveCriticalSection ( & g_this - > rcs ) ;
}
return 0 ;
case WM_COMMAND :
if ( LOWORD ( wParam ) = = IDC_EDIT1 & & HIWORD ( wParam ) = = EN_CHANGE )
{
KillTimer ( hwndDlg , 1 ) ;
if ( ! isstart ) SetTimer ( hwndDlg , 1 , 1000 , NULL ) ;
// If someone edits the editwnd, force the "(user defined)" to be the new selection.
if ( SendDlgItemMessageA ( hwndDlg , IDC_LIST1 , LB_GETCURSEL , 0 , 0 ) ! = sizeof ( descriptions ) / sizeof ( descriptions [ 0 ] ) )
{
g_this - > rectangular = IsDlgButtonChecked ( hwndDlg , IDC_CHECK3 ) ? 1 : 0 ;
SendDlgItemMessageA ( hwndDlg , IDC_LIST1 , LB_SETCURSEL , sizeof ( descriptions ) / sizeof ( descriptions [ 0 ] ) , 0 ) ;
}
}
if ( LOWORD ( wParam ) = = IDC_LIST1 & & HIWORD ( wParam ) = = LBN_SELCHANGE )
{
int t ;
t = SendDlgItemMessageA ( hwndDlg , IDC_LIST1 , LB_GETCURSEL , 0 , 0 ) ;
if ( t = = sizeof ( descriptions ) / sizeof ( descriptions [ 0 ] ) )
{
g_this - > effect = 32767 ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_EDIT1 ) , 1 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_CHECK3 ) , 1 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_LABEL1 ) , 1 ) ;
SetDlgItemText ( hwndDlg , IDC_EDIT1 , g_this - > effect_exp . get ( ) ) ;
CheckDlgButton ( hwndDlg , IDC_CHECK3 , g_this - > rectangular ) ;
// always reinit =)
{
EnterCriticalSection ( & g_this - > rcs ) ;
g_this - > effect_exp . get_from_dlgitem ( hwndDlg , IDC_EDIT1 ) ;
g_this - > effect_exp_ch = 1 ;
LeaveCriticalSection ( & g_this - > rcs ) ;
}
}
else
{
g_this - > effect = t ;
// If there is a string to stuff in the eval box,
if ( strlen ( descriptions [ t ] . eval_desc ) > 0 )
{
// save the value to be able to restore it later
// stuff it and make sure the boxes are editable
SetDlgItemText ( hwndDlg , IDC_EDIT1 , descriptions [ t ] . eval_desc ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_EDIT1 ) , 1 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_CHECK3 ) , 1 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_LABEL1 ) , 1 ) ;
CheckDlgButton ( hwndDlg , IDC_CHECK3 , descriptions [ t ] . uses_rect ? BST_CHECKED : 0 ) ;
}
else
{
// otherwise, they're not editable.
CheckDlgButton ( hwndDlg , IDC_CHECK3 , g_this - > rectangular ? BST_CHECKED : 0 ) ;
SetDlgItemText ( hwndDlg , IDC_EDIT1 , " " ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_EDIT1 ) , 0 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_CHECK3 ) , 0 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , IDC_LABEL1 ) , 0 ) ;
}
}
}
if ( LOWORD ( wParam ) = = IDC_CHECK1 )
{
g_this - > blend = IsDlgButtonChecked ( hwndDlg , IDC_CHECK1 ) ? 1 : 0 ;
}
if ( LOWORD ( wParam ) = = IDC_CHECK4 )
{
g_this - > subpixel = IsDlgButtonChecked ( hwndDlg , IDC_CHECK4 ) ? 1 : 0 ;
g_this - > effect_exp_ch = 1 ;
}
if ( LOWORD ( wParam ) = = IDC_WRAP )
{
g_this - > wrap = IsDlgButtonChecked ( hwndDlg , IDC_WRAP ) ? 1 : 0 ;
g_this - > effect_exp_ch = 1 ;
}
if ( LOWORD ( wParam ) = = IDC_CHECK2 )
{
int a = IsDlgButtonChecked ( hwndDlg , IDC_CHECK2 ) ;
if ( a = = BST_INDETERMINATE )
g_this - > sourcemapped = 2 ;
else if ( a = = BST_CHECKED )
g_this - > sourcemapped = 1 ;
else
g_this - > sourcemapped = 0 ;
}
if ( LOWORD ( wParam ) = = IDC_CHECK3 )
{
g_this - > rectangular = IsDlgButtonChecked ( hwndDlg , IDC_CHECK3 ) ? 1 : 0 ;
if ( SendDlgItemMessageA ( hwndDlg , IDC_LIST1 , LB_GETCURSEL , 0 , 0 ) ! = sizeof ( descriptions ) / sizeof ( descriptions [ 0 ] ) )
{
EnterCriticalSection ( & g_this - > rcs ) ;
g_this - > effect = 32767 ;
g_this - > effect_exp . get_from_dlgitem ( hwndDlg , IDC_EDIT1 ) ;
g_this - > effect_exp_ch = 1 ;
LeaveCriticalSection ( & g_this - > rcs ) ;
SendDlgItemMessageA ( hwndDlg , IDC_LIST1 , LB_SETCURSEL , sizeof ( descriptions ) / sizeof ( descriptions [ 0 ] ) , 0 ) ;
}
else
g_this - > effect_exp_ch = 1 ;
}
if ( LOWORD ( wParam ) = = IDC_BUTTON2 )
{
/*
char text [ 4096 ] ;
WASABI_API_LNGSTRING_BUF ( IDS_MOVEMENT , text , 4096 ) ;
int titlelen = lstrlen ( text ) + 1 ;
lstrcpyn ( text + titlelen , GetTextResource ( IDR_MOVEMENT ) , 4095 - titlelen ) ;
*/
char * text = " Movement \0 "
" Movement help: \r \n "
" To use the custom table, modify r,d,x or y. \r \n "
" Rect coords: x,y are in (-1..1) . Otherwise: d is (0..1) and r is (0..2PI). \r \n "
" You can also access 'sw' and 'sh' for screen dimensions in pixels (might be useful) \r \n "
;
compilerfunctionlist ( hwndDlg , text ) ;
}
return 0 ;
return 0 ;
}
return 0 ;
}
HWND C_THISCLASS : : conf ( HINSTANCE hInstance , HWND hwndParent )
{
g_this = this ;
return WASABI_API_CREATEDIALOG ( IDD_CFG_TRANS , hwndParent , g_DlgProc ) ;
}
# else
C_RBASE * R_Trans ( char * desc ) { return NULL ; }
# endif