mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-09-24 15:54:12 +00:00
740 lines
16 KiB
C
740 lines
16 KiB
C
|
/*
|
||
|
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.
|
||
|
|
||
|
*/
|
||
|
#ifndef _R_DEFS_H_
|
||
|
#define _R_DEFS_H_
|
||
|
|
||
|
// base class declaration, compatibility class
|
||
|
class RString;
|
||
|
|
||
|
class C_RBASE {
|
||
|
public:
|
||
|
C_RBASE() { }
|
||
|
virtual ~C_RBASE() { };
|
||
|
virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)=0; // returns 1 if fbout has dest
|
||
|
virtual HWND conf(HINSTANCE hInstance, HWND hwndParent){return 0;};
|
||
|
virtual char *get_desc()=0;
|
||
|
virtual void load_config(unsigned char *data, int len) { }
|
||
|
virtual int save_config(unsigned char *data) { return 0; }
|
||
|
|
||
|
void load_string(RString &s,unsigned char *data, int &pos, int len);
|
||
|
void save_string(unsigned char *data, int &pos, RString &text);
|
||
|
|
||
|
};
|
||
|
|
||
|
class C_RBASE2 : public C_RBASE {
|
||
|
public:
|
||
|
C_RBASE2() { }
|
||
|
virtual ~C_RBASE2() { };
|
||
|
|
||
|
int getRenderVer2() { return 2; }
|
||
|
|
||
|
|
||
|
virtual int smp_getflags() { return 0; } // return 1 to enable smp support
|
||
|
|
||
|
// returns # of threads you desire, <= max_threads, or 0 to not do anything
|
||
|
// default should return max_threads if you are flexible
|
||
|
virtual int smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) { return 0; }
|
||
|
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 0; }; // return value is that of render() for fbstuff etc
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
// defined in main.cpp, render.cpp
|
||
|
extern char g_path[];
|
||
|
extern unsigned char g_blendtable[256][256];
|
||
|
|
||
|
extern int g_reset_vars_on_recompile;
|
||
|
|
||
|
// use this function to get a global buffer, and the last flag says whether or not to
|
||
|
// allocate it if it's not valid...
|
||
|
#define NBUF 8
|
||
|
void *getGlobalBuffer(int w, int h, int n, int do_alloc);
|
||
|
|
||
|
|
||
|
// implemented in util.cpp
|
||
|
char* GetTextResource(UINT id);
|
||
|
void GR_SelectColor(HWND hwnd, int *a);
|
||
|
void GR_DrawColoredButton(DRAWITEMSTRUCT *di, COLORREF color);
|
||
|
void loadComboBox(HWND dlg, char *ext, char *selectedName);
|
||
|
void compilerfunctionlist(HWND hwndDlg, char *localinfo=NULL);
|
||
|
|
||
|
// matrix.cpp
|
||
|
void matrixRotate(float matrix[], char m, float Deg);
|
||
|
void matrixTranslate(float m[], float x, float y, float z);
|
||
|
void matrixMultiply(float *dest, float src[]);
|
||
|
void matrixApply(float *m, float x, float y, float z, float *outx, float *outy, float *outz);
|
||
|
|
||
|
// linedraw.cpp
|
||
|
extern int g_line_blend_mode;
|
||
|
void line(int *fb, int x1,int y1,int x2,int y2, int width, int height, int color, int lw);
|
||
|
|
||
|
|
||
|
// inlines
|
||
|
static unsigned int __inline BLEND(unsigned int a, unsigned int b)
|
||
|
{
|
||
|
register unsigned int r,t;
|
||
|
r=(a&0xff)+(b&0xff);
|
||
|
t=min(r,0xff);
|
||
|
r=(a&0xff00)+(b&0xff00);
|
||
|
t|=min(r,0xff00);
|
||
|
r=(a&0xff0000)+(b&0xff0000);
|
||
|
t|=min(r,0xff0000);
|
||
|
r=(a&0xff000000)+(b&0xff000000);
|
||
|
return t|min(r,0xff000000);
|
||
|
}
|
||
|
|
||
|
#if 1
|
||
|
#define FASTMAX(x,y) max(x,y)
|
||
|
// (x-(((x-y)>>(32-1))&(x-y))) // hmm not faster :(
|
||
|
#define FASTMIN(x,y) min(x,y)
|
||
|
//(x+(((y-x)>>(32-1))&(y-x)))
|
||
|
#else
|
||
|
#pragma warning( push, 1 )
|
||
|
|
||
|
static __inline int FASTMAX(int x, int y)
|
||
|
{
|
||
|
__asm
|
||
|
{
|
||
|
mov ecx, [x]
|
||
|
mov eax, [y]
|
||
|
sub ecx, eax
|
||
|
cmc
|
||
|
and ecx, edx
|
||
|
add eax, ecx
|
||
|
}
|
||
|
}
|
||
|
static __inline int FASTMIN(int x, int y)
|
||
|
{
|
||
|
__asm
|
||
|
{
|
||
|
mov ecx, [x]
|
||
|
mov eax, [y]
|
||
|
sub ecx, eax
|
||
|
sbb edx, edx
|
||
|
and ecx, edx
|
||
|
add eax, ecx
|
||
|
}
|
||
|
}
|
||
|
#pragma warning( pop )
|
||
|
|
||
|
#endif
|
||
|
|
||
|
static unsigned int __inline BLEND_MAX(unsigned int a, unsigned int b)
|
||
|
{
|
||
|
register unsigned int t;
|
||
|
int _a=a&0xff;
|
||
|
int _b=b&0xff;
|
||
|
t=FASTMAX(_a,_b);
|
||
|
_a=a&0xff00; _b=b&0xff00;
|
||
|
t|=FASTMAX(_a,_b);
|
||
|
_a=a&0xff0000; _b=b&0xff0000;
|
||
|
t|=FASTMAX(_a,_b);
|
||
|
return t;
|
||
|
}
|
||
|
|
||
|
static unsigned int __inline BLEND_MIN(unsigned int a, unsigned int b)
|
||
|
{
|
||
|
#if 1
|
||
|
register unsigned int t;
|
||
|
int _a=a&0xff;
|
||
|
int _b=b&0xff;
|
||
|
t=FASTMIN(_a,_b);
|
||
|
_a=a&0xff00; _b=b&0xff00;
|
||
|
t|=FASTMIN(_a,_b);
|
||
|
_a=a&0xff0000; _b=b&0xff0000;
|
||
|
t|=FASTMIN(_a,_b);
|
||
|
return t;
|
||
|
#else
|
||
|
__asm
|
||
|
{
|
||
|
mov ecx, [a]
|
||
|
mov eax, [b]
|
||
|
|
||
|
and ecx, 0xff
|
||
|
and eax, 0xff
|
||
|
|
||
|
mov esi, [a]
|
||
|
mov ebx, [b]
|
||
|
|
||
|
sub ecx, eax
|
||
|
sbb edx, edx
|
||
|
|
||
|
and esi, 0xff00
|
||
|
and ebx, 0xff00
|
||
|
|
||
|
and ecx, edx
|
||
|
sub esi, ebx
|
||
|
|
||
|
sbb edx, edx
|
||
|
add eax, ecx
|
||
|
|
||
|
and esi, edx
|
||
|
mov ecx, [a]
|
||
|
|
||
|
add ebx, esi
|
||
|
and ecx, 0xff0000
|
||
|
|
||
|
mov esi, [b]
|
||
|
or eax, ebx
|
||
|
|
||
|
and esi, 0xff0000
|
||
|
|
||
|
sub ecx, esi
|
||
|
sbb edx, edx
|
||
|
|
||
|
and ecx, edx
|
||
|
add esi, ecx
|
||
|
|
||
|
or eax, esi
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#ifdef FASTMAX
|
||
|
#undef FASTMAX
|
||
|
#undef FASTMIN
|
||
|
#endif
|
||
|
|
||
|
|
||
|
static unsigned int __inline BLEND_AVG(unsigned int a, unsigned int b)
|
||
|
{
|
||
|
return ((a>>1)&~((1<<7)|(1<<15)|(1<<23)))+((b>>1)&~((1<<7)|(1<<15)|(1<<23)));
|
||
|
}
|
||
|
|
||
|
|
||
|
static unsigned int __inline BLEND_SUB(unsigned int a, unsigned int b)
|
||
|
{
|
||
|
register int r,t;
|
||
|
r=(a&0xff)-(b&0xff);
|
||
|
t=max(r,0);
|
||
|
r=(a&0xff00)-(b&0xff00);
|
||
|
t|=max(r,0);
|
||
|
r=(a&0xff0000)-(b&0xff0000);
|
||
|
t|=max(r,0);
|
||
|
r=(a&0xff000000)-(b&0xff000000);
|
||
|
return t|max(r,0);
|
||
|
}
|
||
|
|
||
|
#ifdef NO_MMX
|
||
|
#define BLEND_ADJ BLEND_ADJ_NOMMX
|
||
|
#endif
|
||
|
|
||
|
static unsigned int __inline BLEND_ADJ_NOMMX(unsigned int a, unsigned int b, int v)
|
||
|
{
|
||
|
register int t;
|
||
|
t=g_blendtable[a&0xFF][v]+g_blendtable[b&0xFF][0xFF-v];
|
||
|
t|=(g_blendtable[(a&0xFF00)>>8][v]+g_blendtable[(b&0xFF00)>>8][0xFF-v])<<8;
|
||
|
t|=(g_blendtable[(a&0xFF0000)>>16][v]+g_blendtable[(b&0xFF0000)>>16][0xFF-v])<<16;
|
||
|
return t;
|
||
|
}
|
||
|
|
||
|
static unsigned int __inline BLEND_MUL(unsigned int a, unsigned int b)
|
||
|
{
|
||
|
register int t;
|
||
|
t=g_blendtable[a&0xFF][b&0xFF];
|
||
|
t|=g_blendtable[(a&0xFF00)>>8][(b&0xFF00)>>8]<<8;
|
||
|
t|=g_blendtable[(a&0xFF0000)>>16][(b&0xFF0000)>>16]<<16;
|
||
|
return t;
|
||
|
}
|
||
|
|
||
|
static __inline void BLEND_LINE(int *fb, int color)
|
||
|
{
|
||
|
register int bm=g_line_blend_mode&0xff;
|
||
|
switch (g_line_blend_mode&0xff)
|
||
|
{
|
||
|
case 1: *fb=BLEND(*fb,color); break;
|
||
|
case 2: *fb=BLEND_MAX(*fb,color); break;
|
||
|
case 3: *fb=BLEND_AVG(*fb,color); break;
|
||
|
case 4: *fb=BLEND_SUB(*fb,color); break;
|
||
|
case 5: *fb=BLEND_SUB(color,*fb); break;
|
||
|
case 6: *fb=BLEND_MUL(*fb,color); break;
|
||
|
case 7: *fb=BLEND_ADJ_NOMMX(*fb,color,(g_line_blend_mode>>8)&0xff); break;
|
||
|
case 8: *fb=*fb^color; break;
|
||
|
case 9: *fb=BLEND_MIN(*fb,color); break;
|
||
|
default: *fb=color; break;
|
||
|
}
|
||
|
}
|
||
|
extern unsigned int const mmx_blend4_revn[2];
|
||
|
extern int const mmx_blend4_zero;
|
||
|
extern int const mmx_blendadj_mask[2];
|
||
|
// NOTE. WHEN USING THIS FUNCTION, BE SURE TO DO 'if (g_mmx_available) __asm emms;' before calling
|
||
|
// any fpu code, or before returning.
|
||
|
#pragma warning( push, 1 )
|
||
|
|
||
|
#ifndef NO_MMX
|
||
|
static unsigned int __inline BLEND_ADJ(unsigned int a, unsigned int b, int v)
|
||
|
{
|
||
|
__asm
|
||
|
{
|
||
|
movd mm3, [v] // VVVVVVVV
|
||
|
|
||
|
movd mm0, [a]
|
||
|
packuswb mm3, mm3 // 0000HHVV
|
||
|
|
||
|
movd mm1, [b]
|
||
|
punpcklwd mm3, mm3 // HHVVHHVV
|
||
|
|
||
|
movq mm4, [mmx_blend4_revn]
|
||
|
punpckldq mm3, mm3 // HHVVHHVV HHVVHHVV
|
||
|
|
||
|
punpcklbw mm0, [mmx_blend4_zero]
|
||
|
pand mm3, [mmx_blendadj_mask]
|
||
|
|
||
|
punpcklbw mm1, [mmx_blend4_zero]
|
||
|
psubw mm4, mm3
|
||
|
|
||
|
pmullw mm0, mm3
|
||
|
pmullw mm1, mm4
|
||
|
|
||
|
paddw mm0, mm1
|
||
|
|
||
|
psrlw mm0, 8
|
||
|
|
||
|
packuswb mm0, mm0
|
||
|
|
||
|
movd eax, mm0
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
static __inline unsigned int BLEND4(unsigned int *p1, unsigned int w, int xp, int yp)
|
||
|
{
|
||
|
#ifdef NO_MMX
|
||
|
register int t;
|
||
|
unsigned char a1,a2,a3,a4;
|
||
|
a1=g_blendtable[255-xp][255-yp];
|
||
|
a2=g_blendtable[xp][255-yp];
|
||
|
a3=g_blendtable[255-xp][yp];
|
||
|
a4=g_blendtable[xp][yp];
|
||
|
t=g_blendtable[p1[0]&0xff][a1]+g_blendtable[p1[1]&0xff][a2]+g_blendtable[p1[w]&0xff][a3]+g_blendtable[p1[w+1]&0xff][a4];
|
||
|
t|=(g_blendtable[(p1[0]>>8)&0xff][a1]+g_blendtable[(p1[1]>>8)&0xff][a2]+g_blendtable[(p1[w]>>8)&0xff][a3]+g_blendtable[(p1[w+1]>>8)&0xff][a4])<<8;
|
||
|
t|=(g_blendtable[(p1[0]>>16)&0xff][a1]+g_blendtable[(p1[1]>>16)&0xff][a2]+g_blendtable[(p1[w]>>16)&0xff][a3]+g_blendtable[(p1[w+1]>>16)&0xff][a4])<<16;
|
||
|
return t;
|
||
|
#else
|
||
|
__asm
|
||
|
{
|
||
|
movd mm6, xp
|
||
|
mov eax, p1
|
||
|
|
||
|
movd mm7, yp
|
||
|
mov esi, w
|
||
|
|
||
|
movq mm4, mmx_blend4_revn
|
||
|
punpcklwd mm6,mm6
|
||
|
|
||
|
movq mm5, mmx_blend4_revn
|
||
|
punpcklwd mm7,mm7
|
||
|
|
||
|
movd mm0, [eax]
|
||
|
punpckldq mm6,mm6
|
||
|
|
||
|
movd mm1, [eax+4]
|
||
|
punpckldq mm7,mm7
|
||
|
|
||
|
movd mm2, [eax+esi*4]
|
||
|
punpcklbw mm0, [mmx_blend4_zero]
|
||
|
|
||
|
movd mm3, [eax+esi*4+4]
|
||
|
psubw mm4, mm6
|
||
|
|
||
|
punpcklbw mm1, [mmx_blend4_zero]
|
||
|
pmullw mm0, mm4
|
||
|
|
||
|
punpcklbw mm2, [mmx_blend4_zero]
|
||
|
pmullw mm1, mm6
|
||
|
|
||
|
punpcklbw mm3, [mmx_blend4_zero]
|
||
|
psubw mm5, mm7
|
||
|
|
||
|
pmullw mm2, mm4
|
||
|
pmullw mm3, mm6
|
||
|
|
||
|
paddw mm0, mm1
|
||
|
// stall (mm0)
|
||
|
|
||
|
psrlw mm0, 8
|
||
|
// stall (waiting for mm3/mm2)
|
||
|
|
||
|
paddw mm2, mm3
|
||
|
pmullw mm0, mm5
|
||
|
|
||
|
psrlw mm2, 8
|
||
|
// stall (mm2)
|
||
|
|
||
|
pmullw mm2, mm7
|
||
|
// stall
|
||
|
|
||
|
// stall (mm2)
|
||
|
|
||
|
paddw mm0, mm2
|
||
|
// stall
|
||
|
|
||
|
psrlw mm0, 8
|
||
|
// stall
|
||
|
|
||
|
packuswb mm0, mm0
|
||
|
// stall
|
||
|
|
||
|
movd eax, mm0
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
static __inline unsigned int BLEND4_16(unsigned int *p1, unsigned int w, int xp, int yp)
|
||
|
{
|
||
|
#ifdef NO_MMX
|
||
|
register int t;
|
||
|
unsigned char a1,a2,a3,a4;
|
||
|
xp=(xp>>8)&0xff;
|
||
|
yp=(yp>>8)&0xff;
|
||
|
a1=g_blendtable[255-xp][255-yp];
|
||
|
a2=g_blendtable[xp][255-yp];
|
||
|
a3=g_blendtable[255-xp][yp];
|
||
|
a4=g_blendtable[xp][yp];
|
||
|
t=g_blendtable[p1[0]&0xff][a1]+g_blendtable[p1[1]&0xff][a2]+g_blendtable[p1[w]&0xff][a3]+g_blendtable[p1[w+1]&0xff][a4];
|
||
|
t|=(g_blendtable[(p1[0]>>8)&0xff][a1]+g_blendtable[(p1[1]>>8)&0xff][a2]+g_blendtable[(p1[w]>>8)&0xff][a3]+g_blendtable[(p1[w+1]>>8)&0xff][a4])<<8;
|
||
|
t|=(g_blendtable[(p1[0]>>16)&0xff][a1]+g_blendtable[(p1[1]>>16)&0xff][a2]+g_blendtable[(p1[w]>>16)&0xff][a3]+g_blendtable[(p1[w+1]>>16)&0xff][a4])<<16;
|
||
|
return t;
|
||
|
#else
|
||
|
__asm
|
||
|
{
|
||
|
movd mm6, xp
|
||
|
mov eax, p1
|
||
|
|
||
|
movd mm7, yp
|
||
|
mov esi, w
|
||
|
|
||
|
movq mm4, mmx_blend4_revn
|
||
|
psrlw mm6, 8
|
||
|
|
||
|
movq mm5, mmx_blend4_revn
|
||
|
psrlw mm7, 8
|
||
|
|
||
|
movd mm0, [eax]
|
||
|
punpcklwd mm6,mm6
|
||
|
|
||
|
movd mm1, [eax+4]
|
||
|
punpcklwd mm7,mm7
|
||
|
|
||
|
movd mm2, [eax+esi*4]
|
||
|
punpckldq mm6,mm6
|
||
|
|
||
|
movd mm3, [eax+esi*4+4]
|
||
|
punpckldq mm7,mm7
|
||
|
|
||
|
punpcklbw mm0, [mmx_blend4_zero]
|
||
|
psubw mm4, mm6
|
||
|
|
||
|
punpcklbw mm1, [mmx_blend4_zero]
|
||
|
pmullw mm0, mm4
|
||
|
|
||
|
punpcklbw mm2, [mmx_blend4_zero]
|
||
|
pmullw mm1, mm6
|
||
|
|
||
|
punpcklbw mm3, [mmx_blend4_zero]
|
||
|
psubw mm5, mm7
|
||
|
|
||
|
pmullw mm2, mm4
|
||
|
pmullw mm3, mm6
|
||
|
|
||
|
paddw mm0, mm1
|
||
|
// stall (mm0)
|
||
|
|
||
|
psrlw mm0, 8
|
||
|
// stall (waiting for mm3/mm2)
|
||
|
|
||
|
paddw mm2, mm3
|
||
|
pmullw mm0, mm5
|
||
|
|
||
|
psrlw mm2, 8
|
||
|
// stall (mm2)
|
||
|
|
||
|
pmullw mm2, mm7
|
||
|
// stall
|
||
|
|
||
|
// stall (mm2)
|
||
|
|
||
|
paddw mm0, mm2
|
||
|
// stall
|
||
|
|
||
|
psrlw mm0, 8
|
||
|
// stall
|
||
|
|
||
|
packuswb mm0, mm0
|
||
|
// stall
|
||
|
|
||
|
movd eax, mm0
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
#pragma warning( pop )
|
||
|
|
||
|
|
||
|
static __inline void mmx_avgblend_block(int *output, int *input, int l)
|
||
|
{
|
||
|
#ifdef NO_MMX
|
||
|
while (l--)
|
||
|
{
|
||
|
*output=BLEND_AVG(*input++,*output);
|
||
|
output++;
|
||
|
}
|
||
|
#else
|
||
|
static int mask[2]=
|
||
|
{
|
||
|
~((1<<7)|(1<<15)|(1<<23)),
|
||
|
~((1<<7)|(1<<15)|(1<<23))
|
||
|
};
|
||
|
__asm
|
||
|
{
|
||
|
mov eax, input
|
||
|
mov edi, output
|
||
|
mov ecx, l
|
||
|
shr ecx, 2
|
||
|
align 16
|
||
|
mmx_avgblend_loop:
|
||
|
movq mm0, [eax]
|
||
|
movq mm1, [edi]
|
||
|
psrlq mm0, 1
|
||
|
movq mm2, [eax+8]
|
||
|
psrlq mm1, 1
|
||
|
movq mm3, [edi+8]
|
||
|
psrlq mm2, 1
|
||
|
pand mm0, [mask]
|
||
|
psrlq mm3, 1
|
||
|
pand mm1, [mask]
|
||
|
pand mm2, [mask]
|
||
|
paddusb mm0, mm1
|
||
|
pand mm3, [mask]
|
||
|
add eax, 16
|
||
|
paddusb mm2, mm3
|
||
|
|
||
|
movq [edi], mm0
|
||
|
movq [edi+8], mm2
|
||
|
|
||
|
add edi, 16
|
||
|
|
||
|
dec ecx
|
||
|
jnz mmx_avgblend_loop
|
||
|
emms
|
||
|
};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
static __inline void mmx_addblend_block(int *output, int *input, int l)
|
||
|
{
|
||
|
#ifdef NO_MMX
|
||
|
while (l--)
|
||
|
{
|
||
|
*output=BLEND(*input++,*output);
|
||
|
output++;
|
||
|
}
|
||
|
#else
|
||
|
__asm
|
||
|
{
|
||
|
mov eax, input
|
||
|
mov edi, output
|
||
|
mov ecx, l
|
||
|
shr ecx, 2
|
||
|
align 16
|
||
|
mmx_addblend_loop:
|
||
|
movq mm0, [eax]
|
||
|
movq mm1, [edi]
|
||
|
movq mm2, [eax+8]
|
||
|
movq mm3, [edi+8]
|
||
|
paddusb mm0, mm1
|
||
|
paddusb mm2, mm3
|
||
|
add eax, 16
|
||
|
|
||
|
movq [edi], mm0
|
||
|
movq [edi+8], mm2
|
||
|
|
||
|
add edi, 16
|
||
|
|
||
|
dec ecx
|
||
|
jnz mmx_addblend_loop
|
||
|
emms
|
||
|
};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
static __inline void mmx_mulblend_block(int *output, int *input, int l)
|
||
|
{
|
||
|
#ifdef NO_MMX
|
||
|
while (l--)
|
||
|
{
|
||
|
*output=BLEND_MUL(*input++,*output);
|
||
|
output++;
|
||
|
}
|
||
|
#else
|
||
|
__asm
|
||
|
{
|
||
|
mov eax, input
|
||
|
mov edi, output
|
||
|
mov ecx, l
|
||
|
shr ecx, 1
|
||
|
align 16
|
||
|
mmx_mulblend_loop:
|
||
|
movd mm0, [eax]
|
||
|
movd mm1, [edi]
|
||
|
movd mm2, [eax+4]
|
||
|
punpcklbw mm0, [mmx_blend4_zero]
|
||
|
movd mm3, [edi+4]
|
||
|
punpcklbw mm1, [mmx_blend4_zero]
|
||
|
punpcklbw mm2, [mmx_blend4_zero]
|
||
|
pmullw mm0, mm1
|
||
|
punpcklbw mm3, [mmx_blend4_zero]
|
||
|
psrlw mm0, 8
|
||
|
pmullw mm2, mm3
|
||
|
packuswb mm0, mm0
|
||
|
psrlw mm2, 8
|
||
|
packuswb mm2, mm2
|
||
|
add eax, 8
|
||
|
|
||
|
movd [edi], mm0
|
||
|
movd [edi+4], mm2
|
||
|
|
||
|
add edi, 8
|
||
|
|
||
|
dec ecx
|
||
|
jnz mmx_mulblend_loop
|
||
|
emms
|
||
|
};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
static void __inline mmx_adjblend_block(int *o, int *in1, int *in2, int len, int v)
|
||
|
{
|
||
|
#ifdef NO_MMX
|
||
|
while (len--)
|
||
|
{
|
||
|
*o++=BLEND_ADJ(*in1++,*in2++,inblendval);
|
||
|
}
|
||
|
#else
|
||
|
__asm
|
||
|
{
|
||
|
movd mm3, [v] // VVVVVVVV
|
||
|
mov ecx, len
|
||
|
|
||
|
packuswb mm3, mm3 // 0000HHVV
|
||
|
mov edx, o
|
||
|
|
||
|
punpcklwd mm3, mm3 // HHVVHHVV
|
||
|
mov esi, in1
|
||
|
|
||
|
movq mm4, [mmx_blend4_revn]
|
||
|
punpckldq mm3, mm3 // HHVVHHVV HHVVHHVV
|
||
|
|
||
|
pand mm3, [mmx_blendadj_mask]
|
||
|
mov edi, in2
|
||
|
|
||
|
shr ecx, 1
|
||
|
psubw mm4, mm3
|
||
|
|
||
|
align 16
|
||
|
_mmx_adjblend_loop:
|
||
|
|
||
|
movd mm0, [esi]
|
||
|
|
||
|
movd mm1, [edi]
|
||
|
punpcklbw mm0, [mmx_blend4_zero]
|
||
|
|
||
|
movd mm6, [esi+4]
|
||
|
punpcklbw mm1, [mmx_blend4_zero]
|
||
|
|
||
|
movd mm7, [edi+4]
|
||
|
punpcklbw mm6, [mmx_blend4_zero]
|
||
|
|
||
|
pmullw mm0, mm3
|
||
|
punpcklbw mm7, [mmx_blend4_zero]
|
||
|
|
||
|
pmullw mm1, mm4
|
||
|
pmullw mm6, mm3
|
||
|
|
||
|
pmullw mm7, mm4
|
||
|
paddw mm0, mm1
|
||
|
|
||
|
paddw mm6, mm7
|
||
|
add edi, 8
|
||
|
|
||
|
psrlw mm0, 8
|
||
|
add esi, 8
|
||
|
|
||
|
psrlw mm6, 8
|
||
|
packuswb mm0, mm0
|
||
|
|
||
|
packuswb mm6, mm6
|
||
|
movd [edx], mm0
|
||
|
|
||
|
movd [edx+4], mm6
|
||
|
add edx, 8
|
||
|
dec ecx
|
||
|
jnz _mmx_adjblend_loop
|
||
|
|
||
|
emms
|
||
|
};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
class RString
|
||
|
{
|
||
|
public:
|
||
|
RString() { m_str=0; m_size=0; }
|
||
|
~RString() { if (m_str) GlobalFree(m_str); };
|
||
|
void resize(int size) { m_size=size; if (m_str) GlobalFree(m_str); m_str=0; if (size) m_str=(char*)GlobalAlloc(GPTR,size); }
|
||
|
char *get() { return m_str; }
|
||
|
int getsize() { if (!m_str) return 0; return m_size; }
|
||
|
void assign(char *s) { resize(strlen(s)+1); strcpy(m_str,s); }
|
||
|
void get_from_dlgitem(HWND hwnd, int dlgItem)
|
||
|
{
|
||
|
int l=SendDlgItemMessage(hwnd,dlgItem,WM_GETTEXTLENGTH,0,0);
|
||
|
if ( l < 256) l=256;
|
||
|
resize(l+1+256);
|
||
|
GetDlgItemText(hwnd,dlgItem, m_str, l+1);
|
||
|
m_str[l]=0;
|
||
|
}
|
||
|
private:
|
||
|
char *m_str;
|
||
|
int m_size;
|
||
|
};
|
||
|
|
||
|
void doAVSEvalHighLight(HWND hwndDlg, UINT sub, char *data);
|
||
|
|
||
|
#include "laser/laserline.h"
|
||
|
|
||
|
#endif
|